PostcardPal connector (MCP)
PostcardPal prints and mails real postcards on a user's behalf from a conversation. The assistant designs the card (photo of the place or the user's own photo, a suggested message, the user's signature), shows a preview and the exact price, and nothing is printed or charged until the user approves. Recipients are US addresses; the sender can be anywhere. Operated by Havenwood Holdings; support ch@havenwood.holdings.
Connect
- MCP endpoint:
https://postcardpal.app/mcp(Streamable HTTP; MCP 2025-06-18 and 2026-07-28 clients) - Authorization: OAuth 2.1 with PKCE. Discovery at
https://postcardpal.app/.well-known/oauth-protected-resource/mcpandhttps://postcardpal.app/.well-known/oauth-authorization-server/api/auth. Dynamic client registration and CIMD are both supported; theresourceparameter is optional. Sign-in is a 6-digit emailed code on one page; consent is automatic. - Alternative: a per-user API key from
https://postcardpal.app/account, sent asAuthorization: Bearer pp_…. - Scope:
postcards:send.
Flow
create_postcardwith the recipient (saved nickname or a full address), the place, and optionally a message and photo. Returns a preview page, the front image, a free share image, message and photo alternatives, and the price. Nothing is mailed.- Show the user the preview and price; adjust with
update_postcardif they want. send_postcardwith the postcard_id and the exact quoted total. First time: a Stripe Checkout link (Link-enabled). After that the saved card is charged and the postcard goes straight to print. Idempotent.get_postcard/list_postcardsfor status;cancel_postcardrefunds in full until the nightly print cut-off.
Guarantees
- Two separate tool calls (design → send) and an exact-price check on every send.
- Payment is authorized at approval and captured only after the print vendor accepts the job; vendor rejection releases the authorization.
- Every card is screened against the acceptable use policy before it can be sent.
- Stock photos are Wikimedia Commons images under licenses that permit commercial reuse; attribution is printed on the back.
Pricing (US postage included)
- Classic 6×4 in: $3.99
- Large 9×6 in: $5.99
Tools
set_sender_details
Save how the user signs their postcards (e.g. "Chris" or "Mom & Dad") and, optionally, a US return address. Only the name is needed; postcards don't require a return address.
You rarely need this: create_postcard accepts from_name directly and remembers it. Use set_sender_details when the user wants to change the saved name, or add/remove a return address. Saving records acceptance of the Terms and Acceptable Use Policy at postcardpal.app/terms.
save_contact
Save a person's mailing address under a nickname ("Mom", "Grandma Jo", "Alex") so future postcards can be sent with just "send a postcard to Mom". The address is USPS-verified and standardized; if USPS can't verify it you get a specific reason to fix with the user.
You don't have to call this separately: create_postcard with a full address and save_as does the same thing in one step. Use save_contact when the user just wants to add people to their address book. US addresses only.
list_contacts
List the user's saved postcard recipients (nickname, name, city/state, when they last got a card). Use it to resolve "send one to my sister" when you're unsure of the nickname, or when the user asks who is in their address book. Never guess an address: if the person isn't saved, ask the user for it.
create_postcard
Design a real, printed postcard and get a preview + price. NOTHING IS MAILED and NOTHING IS CHARGED until send_postcard is called with the returned postcard_id.
When the user says something like "send a postcard to Mom" while travelling, aim for ONE short question at most before calling this:
"Want to use one of your own photos from the trip, or should I pick a nice photo of {place}?"
Then call create_postcard. Don't ask about size, style, wording or price up front; the response contains a suggested message, a photo, alternatives and the exact price, and the user can adjust anything afterwards with update_postcard.
What you need:
- to: a saved nickname ("Mom") OR a full US address. If the nickname isn't saved, ask for the address once and pass save_as so it's remembered.
- place: where the user is, e.g. "Lisbon, Portugal" or "Big Sur, California". Ask or infer from the conversation; it drives the photo, the caption and the dateline.
- from_name: how the user signs cards ("Chris"). Needed the first time only; it's remembered.
- message: optional. You know the trip better than we do, so write one (warm, specific, under 280 characters, no sign-off) or leave it out and we suggest three; pick the first and offer the others.
- photo: optional. Omit for a licensed stock photo of the place (the response lists alternatives). Pass photo.url for the user's own photo, or hand them upload_url if you can't get a URL.
The response includes preview_url (front and back), share_image_url (a free, downloadable image of the front the user can text to anyone, even if they never mail the card), the price, message alternatives, photo alternatives and suggested_recipients (saved contacts who haven't received a card from this trip yet; mention them briefly after the send, not before).
Show the user the preview and the price and ask for a simple yes. Then call send_postcard. US recipient addresses only; the user can be anywhere in the world.
update_postcard
Change an unsent postcard and get a fresh preview. Pass only the fields to change: message, signature, caption, photo (a different option_id or the user's URL), style, size, or a different recipient. The price is re-quoted only if the size changes. Use this for "make it say...", "use the other photo", "use my photo instead", "make it the bigger one".
send_postcard
Print and mail a postcard the user has approved. THIS CHARGES THE USER for the quoted amount and hands the card to the print vendor. Irreversible once the cancel window closes (usually the same evening).
Only call this after the user has seen the preview and price and said yes. Never call it speculatively.
Idempotent: calling it twice with the same postcard_id returns the existing job without charging again.
First send ever: the response contains checkout_url (Stripe Checkout, Link-enabled). Give it to the user; the card mails automatically once paid and the card is saved, so every later send completes in this one call with no extra steps. Returns the expected mailing date and cancellable_until.
get_postcard
Status of one postcard: draft, awaiting_payment, submitted (with the vendor), processing (printing), in_transit, delivered, cancelled, or failed, plus dates and the preview/share links. Postcards travel as First-Class Mail and are not individually tracked; delivery usually takes 3-6 business days after mailing.
list_postcards
The user's recent postcards, newest first, with recipient, place, status and links. Use for "did Mom's card go out?", "what have I sent from this trip?", or to find a postcard_id.
cancel_postcard
Cancel a sent postcard if it hasn't been printed yet, and refund the charge in full. Postcards go to print each evening; the send_postcard response includes cancellable_until. After that it can't be recalled. If cancellation isn't possible, this returns cancelled=false with the reason. Unsent drafts can be cancelled any time (nothing was charged).