One toolbox. Two transports.
Every tool below is available over MCP (stdio + HTTP) and as a REST endpoint at api.cards-for-agents.com. We hold canonical order state — you don't have to round-trip it.
Install
Pick your client. Drag, click, or paste — whichever you like.
Paste this into Claude Code
Copy the prompt below. Swap the bracketed placeholders for your recipient, sender, and card details. Paste the whole thing into a fresh Claude Code session. It’ll compose the order via our REST API, show you a preview URL, dry-run the checkout on your machine, then ask you before spending real money.
Card details never touch our servers.They flow from the prompt into env vars for a local Playwright process that types them into Postable’s Stripe iframe.
Your task: send [recipient, e.g. my grandma] a Mother's Day card through cards-for-agents.com.
CRITICAL — follow these steps precisely. Do not improvise a different package name.
Step 1. Fetch https://cards-for-agents.com/llms.txt and read it fully. Pay special attention to the "Primary target: Claude Code" section.
Step 2. Do NOT add anything to my MCP config. We are NOT using an MCP server for this. You will use plain HTTPS curl calls plus one npx command. The two packages we publish are:
- @cards-for-agents/mcp (an MCP stdio server; DO NOT use this)
- @cards-for-agents/checkout (a CLI; THIS is what actually pays)
Step 3. Compose the order via our REST API at https://api.cards-for-agents.com. OpenAPI spec at https://api.cards-for-agents.com/openapi.json. Make these calls in sequence:
- POST /v1/orders (body: {"idempotency_key":"<unique>","receipt_email":"<my@email.com>"}) → grab the "id"
- POST /v1/orders/<id>/card (body: {"card_slug":"mothers-day-flowers-5"})
- POST /v1/orders/<id>/message (body: {"text":"<warm message you draft>","signoff":"Love, <my name>"})
- POST /v1/orders/<id>/recipient (body: {"name":"...","line1":"...","city":"...","state":"XX","zip":"..."})
- POST /v1/orders/<id>/sender (body: same shape as recipient)
- POST /v1/orders/<id>/preview → returns "preview_url"
Step 4. Tell me the preview_url and ask me to confirm it looks right.
Step 5. After I confirm, run the checkout CLI in dry-run mode to prove the Postable flow works without paying:
CFAC_CARD_NUMBER=<16 digits, no spaces> CFAC_CARD_EXP=MM/YY CFAC_CARD_CVC=<3-4 digits> CFAC_CARD_NAME='<name on card>' CFAC_CARD_ZIP=<zip> npx -y @cards-for-agents/checkout --order-id <the id from step 3> --dry-run
First run will download Chromium (~140MB, ~60 seconds). Subsequent runs are fast.
Expected output: JSON with {"ok":true,"dry_run":true,"cart_sanity":"passed"}.
If you see a "Cravory" or gift item in cart output: STOP immediately.
If you see a total > $10: STOP immediately.
Step 6. If dry-run succeeded, ASK ME before removing --dry-run for the real submit. I want to see the dry-run result first.
Start with Step 1.- Claude Code fetches
/llms.txtso it knows our exact flow and package names. - Six REST calls compose your order: create, pick card, write message, recipient, sender, preview.
- You get a signed preview URL. Eyeball the card art, the handwritten-style message, the addresses, the estimated total.
- Claude Code runs
npx -y @cards-for-agents/checkout --order-id <id> --dry-runwith your card inCFAC_CARD_*env vars. Local Playwright drives Postable, declines gift upsells, asserts[1 card, 1 stamp, 0 other], stops before payment. Expected output:{"ok":true,"dry_run":true,"cart_sanity":"passed"}. - You say go. Claude Code re-runs without
--dry-run. Stripe charges the card (typically $7.23). Postable emails the receipt. Card ships in 2–6 business days.
First npx run downloads Chromium (~140 MB, cached after). The --dry-run gate is your last chance to catch anything weird before real money moves.
Tool reference
search_cardsFind Mother's Day cards by text. Hand-picked illustrated folded cards only for v1.
get_card_detailsFetch a single card by slug. Use this after search_cards.
compose_messageAttach a message to the order. Accepts either the final text, or a short context for your own model to draft from. We do not run a model on your behalf.
set_recipientSet the person receiving the card. Full US street address required.
validate_recipientLightweight format check. Postable's own form is the final source of truth.
set_senderSet the sender's name and return address. Goes on the envelope so USPS can return bad addresses.
preview_orderMint a signed preview URL the user can open to review the composed order before anything ships. Returns instantly.
get_order_planReturn the Postable URL + composed order data + step-by-step plan + warnings for an agentic browser (or our checkout CLI) to execute. Call after the user approves the preview.
Happy-path script
What a Claude Code / Cursor / bash-capable agent does end-to-end. Compose via REST, preview for the user, then hand off to the checkout CLI to actually pay on Postable — card data stays on the user’s machine.
# 1. Compose the order (REST)
const { id } = await fetch('https://api.cards-for-agents.com/v1/orders', {
method: 'POST', headers: { 'content-type': 'application/json' },
body: JSON.stringify({ idempotency_key: 'mothers-day-2026-user-1',
receipt_email: 'you@example.com' })
}).then(r => r.json());
await POST(`/v1/orders/${id}/card`, { card_slug: 'mothers-day-flowers-5' });
await POST(`/v1/orders/${id}/message`, { text: "Mom — Happy Mother's Day.", signoff: "Love, me" });
await POST(`/v1/orders/${id}/recipient`,{ name: "Grandma Flora", line1: "5510 Hoover St",
city: "Bethesda", state: "MD", zip: "20817" });
await POST(`/v1/orders/${id}/sender`, { name: "Nicolas Goldberg", line1: "5 Rico Way",
city: "San Francisco", state: "CA", zip: "94123" });
# 2. Preview — show the URL to the user for approval
const { preview_url } = await POST(`/v1/orders/${id}/preview`);
console.log("Review the card here:", preview_url);
# 3. After the user approves, let the agent pay (bash)
$ CFAC_CARD_NUMBER=4432522629186373 \
CFAC_CARD_EXP=08/26 \
CFAC_CARD_CVC=434 \
CFAC_CARD_NAME='Nicolas Goldberg' \
CFAC_CARD_ZIP=92629 \
npx -y @cards-for-agents/checkout --order-id <id> --dry-run
# Local Playwright drives Postable, declines gift upsells, asserts cart
# sanity. Drop --dry-run to really pay. Card never touches our servers.