Overview
tinypostcard exposes a remote Model Context Protocol server at:
https://tinypostcard.com/api/mcpUse the MCP server when you want an agent to find templates, price a send, and send physical postcards from a chat interface. The REST API remains the canonical integration layer; the MCP server wraps the same send and billing paths.
Authentication modes
The server supports four modes:
- Guest: no authentication. Guests can list shared templates, prepare a send, and send only when they provide a Stripe Link agent-wallet shared payment token through
agenticPayment.sharedPaymentTokenor the HTTP 402 machine-payment flow. - OAuth: connect a tinypostcard account through the remote MCP OAuth flow. This is the preferred ChatGPT/Claude connector path for private contacts, defaults, tokens, saved cards, and private templates.
- API key: pass
Authorization: Bearer <api_key>orx-api-key: <api_key>. Keep this for REST and developer agents, not as the primary ChatGPT connector path. - Session: browser/session-authenticated calls can use the signed-in account.
OAuth discovery is available at /.well-known/oauth-authorization-server and /.well-known/oauth-protected-resource/api/mcp.
Tools
get_account
Returns auth mode, token balance when authenticated, token packs, and Stripe agentic payment configuration.
list_templates
Finds templates. Guests can list shared templates. Authenticated users can also use scope=mine.
Preferred flow
Use this flow for physical mail:
validate_addresscreate_postcard_draftquote_postcard_sendrender_postcard_previewsend_postcardor ChatGPTcomplete_checkout
prepare_postcard_send
Validates recipient countries, estimates postcard cost, returns token/card/guest payment options, and produces send-ready metadata. If the user already asked to send, the agent should continue to send_postcard after required details are available; the MCP client can present its own consequential-action approval.
create_postcard_draft
Creates a server-side draft so clients do not need to repeat large HTML payloads across quote, preview, and send steps.
Default sends use imageUrl plus imageOrientation for the physical image/art side, and messageText plus messageFontFamily for the physical text/message side. frontHtml and backHtml are still supported for template output or advanced custom HTML overrides. tinypostcard places message content in the safe left message zone and reserves the right mailing zone. Do not draw recipient addresses, postage, postal barcodes, or stamp boxes into either HTML field; pass addresses through to and let tinypostcard handle mailing/addressing separately.
Image fronts are supported. Prefer passing a public generated/uploaded image URL directly:
{
"imageUrl": "https://example.com/front.png",
"imageOrientation": "landscape",
"messageText": "Your handwritten message here.",
"messageFontFamily": "tpc-letters-home"
}If a power user needs custom front HTML, put the image inside frontHtml, either as an <img> or a CSS background-image, and size the document to the full bleed canvas:
<!doctype html>
<html>
<body style="margin:0;width:6.25in;height:4.25in;overflow:hidden">
<img
src="https://example.com/front.png"
alt=""
style="width:100%;height:100%;object-fit:cover;display:block"
/>
</body>
</html>Do not simulate a requested generated image with HTML/CSS shapes. Generate or upload a real raster image and pass its URL as imageUrl.
For Lob postcard backs, treat backHtml as the handwritten message only. tinypostcard wraps it into the left message box, about 2.3165in x 3.75in, on the 6.25in x 4.25in bleed document. The lower-right 3.2835in x 2.375in area is reserved for Lob address, postage, barcode, and return-address handling, so agents should keep long copy short and never position content in that area.
Bundled handwritten fonts are available in rendered previews and physical output when referenced by CSS:
<p
style='font-family:"tpc-letters-home","Dancing Script",cursive;font-size:18pt;line-height:1.35'
>
Your note goes here.
</p>Supported bundled families include tpc-letters-home, tpc-ugly-dave, tpc-ugly-dave-alternates, tpc-marina-script, and Dancing Script.
quote_postcard_send
Returns current token/card/guest payment costs for a draft.
render_postcard_preview
Returns front/back preview images for a draft. Use this before any physical mail send.
send_postcard
Sends postcards. This is a write action. If the user already asked to send and the recipient/content/payment details are available, call this tool; do not add a redundant chat approval loop unless details are missing or changed.
Unauthenticated sends require one of:
agenticPayment.sharedPaymentTokenfrom Stripe agentic commerce / Link.
create_token_pack_checkout
Creates a hosted Stripe Checkout URL for authenticated token-pack purchases. The hosted checkout can use Link when available.
complete_checkout
ChatGPT Apps SDK checkout completion tool. The Apps SDK widget calls window.openai.requestCheckout(...), then calls complete_checkout with payment_data.token.
search_contacts and get_contact
OAuth/session/API-key authenticated contact lookup for prompts like “send Mom a birthday postcard.” Guests cannot read contacts.
search and fetch
Read-only docs discovery tools for deep-research clients.
Stripe Link and agentic payments
For one-off guest sends, generic agents can use Stripe shared payment tokens (SPTs). The expected flow is:
- Call
prepare_postcard_send. - If recipient, content, send date, and cost are missing or changed, ask for those details. If the user already asked to send, continue to the send/payment step.
- Read
https://link.com/skill.md. If Link is not authenticated, get the human set up with Link first. - Use Link to issue a shared payment token scoped to the tinypostcard Stripe business profile.
- Call
send_postcardwith:
{
"agenticPayment": {
"sharedPaymentToken": "spt_..."
}
}Set STRIPE_NETWORK_BUSINESS_PROFILE in the server environment so MCP clients can show the correct Stripe profile ID in prepare_postcard_send.
The REST send endpoint also supports Machine Payments Protocol probing for generic agents:
- Submit the final
POST /api/v1/postcards/sendpayload without payment. - Read the
402 Payment Requiredresponse and itsWWW-Authenticate: Paymentheader. - Use the Link skill/MCP or
link-cli mpp decode/mpp payto create an approved Stripe shared payment token. - Retry the same request with
Authorization: Payment ....
Set MPP_SECRET_KEY to a stable server secret for HMAC-bound payment challenges. If it is not set, the server falls back to AUTH_SECRET.
The current Link CLI manifest does not expose a shipping-address tool. For sender/return address, use authenticated tinypostcard defaults/contacts when available; otherwise ask the human directly.
ChatGPT setup
- Open ChatGPT Settings → Apps & Connectors.
- Enable developer mode if required for your plan or workspace.
- Add a custom MCP connector with server URL
https://tinypostcard.com/api/mcp. - Connect your tinypostcard account through OAuth when the client prompts.
- Test with:
Use tinypostcard to find birthday postcard templates, then draft, quote, preview, and prepare a send for one recipient.
Safety contract
- Always create/quote/preview a draft or call
prepare_postcard_sendbeforesend_postcard. - Include
idempotencyKeyon REST sends, or use draft IDs, so agent retries do not duplicate physical mail. - Never invent mailing addresses.
- Use
validate_address,search_contacts, or explicit human confirmation for addresses. - Do not render recipient address blocks, postage, postal barcodes, or fake stamp boxes into postcard artwork. The send payload already carries recipient addresses separately.
- Never include secrets, raw card numbers, passwords, or authentication codes in postcard HTML.
- Do not send harassment, threats, spam, or content outside the user’s send request.
- Treat
send_postcardas a write action. The agent should show recipient, address, content summary, schedule, and cost before sending. - For ChatGPT developer mode, read-only tools are annotated as read-only; send/payment tools are write tools and should require confirmation.
Apps SDK UI
The MCP server exposes an Apps SDK widget resource for checkout and confirmation. ChatGPT clients can use the widget output from prepare_postcard_send and complete payment with complete_checkout.
MCP feature review
The first production surface intentionally uses MCP tools, tool annotations, structured results, and server-side auth context. Those are the highest-value pieces for postcard sending because they give ChatGPT and other clients a reliable read → price → confirm → send workflow.
Included MCP features:
- Tools: draft, quote, preview, address validation, contacts, defaults, send, checkout completion, docs search/fetch.
- Resources: checkout widget, pricing, and template categories.
- Prompts: birthday, thank-you, and customer follow-up postcard starters.
- OAuth: dynamic client registration, authorization code + PKCE, token exchange, and protected resource metadata.
- Apps SDK metadata: output template and widget accessibility metadata for the checkout UI.
Useful next upgrades:
- Elicitation: ask the client for missing address fields or approval only when the user has not already asked to send or when details changed.
- Completion hints: autocomplete template categories, countries, and token-pack IDs.
Lower-priority features for now:
- Sampling: the server should not call back into the client’s model for core send logic; postcard copy generation already has app-owned AI endpoints and limits.
- Long-lived server sessions: current requests are stateless, which is simpler for serverless hosting and enough for the send workflow.