Developer docs
Test mode only. The endpoint below currently runs in test mode. No payment is collected, nothing is printed or mailed, and tracking numbers are clearly marked fake. Certimail is not live in Muse yet.
Overview
Certimail is a remote Model Context Protocol (MCP) server that lets an assistant mail a real USPS Certified Mail or First-Class letter. It exposes three tools: get a price, place an order, and check an order.
- Endpoint:
https://mcp.certimail.guaranteecheck.org/mcp - Transport: MCP Streamable HTTP, stateless. Send each JSON-RPC message with
POST; responses areapplication/json. There is no standalone SSE stream, soGETreturns 405. - Protocol versions: 2025-06-18, 2025-03-26, 2024-11-05. The server echoes your version if supported, otherwise 2025-06-18.
- Notifications (for example
notifications/initialized) return 202 with no body. JSON-RPC batches are supported.
Authentication
Every request needs a bearer API key in the Authorization header. Requests without a valid key get 401 with a WWW-Authenticate: Bearer header and an error body. Keys are compared in constant time and are never logged.
Authorization: Bearer <your key>
Reviewers receive a test-mode key with the connector submission. To request one, email support@certimail.guaranteecheck.org. A test-mode key can only ever create and read test orders. We chose API-key auth because it is the simplest robust option while Meta's connector terms are unpublished. OAuth 2.0 with PKCE can be added behind the same check if Meta requires it.
Test mode
- No real charge, no Stripe call, no PostGrid call, no mail.
create_letter_orderreturnstestMode: trueand a placeholdercheckoutUrlthat explains the test.- An order shows
awaiting_paymentfor 30 seconds, thenmailedwith a tracking number that starts withTEST-NOT-A-REAL-TRACKING-NUMBER. - All validation is real: address checks, the 3-sheet cap, and the basic threat and harassment pattern check behave as they will in production. Refused letters are not charged.
Note: Cloudflare blocks the default Python-urllib User-Agent (error 1010). Use curl, requests or any client that sets its own User-Agent.
Quick start
curl -s https://mcp.certimail.guaranteecheck.org/mcp \
-H "Authorization: Bearer $CERTIMAIL_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"quote_letter","arguments":{"mailType":"certified","pageCount":1}}}'
Tools
quote_letter
Returns the flat price for a letter. Read-only.
| Input | Type | Notes |
|---|---|---|
| mailType | string | certified, certified_return_receipt or first_class |
| pageCount | integer | 1 to 3 sheets |
Output (JSON text): {"mailType":"certified","pageCount":1,"priceUsd":19.99}. Launch prices: certified $19.99, certified with electronic return receipt $24.99, first-class $4.99.
create_letter_order
Validates the letter and addresses, screens the text, records the order and returns a payment link. In test mode the link is a placeholder page; at launch it is a Stripe checkout link.
| Input | Type | Notes |
|---|---|---|
| mailType, pageCount | as above | Same limits as quote_letter |
| recipient | address | Required. US addresses only |
| sender | address | Required return address, US only |
| letterBody | string | Up to 20,000 characters |
| successUrl, cancelUrl | URL | Required. https only, public hostname (no IP addresses, localhost or internal names). Used by the payment page |
| customerEmail | string | Optional |
An address is {name, addressLine1, addressLine2?, city, state, postalCode, country?} where state is a two-letter US state or territory code, postalCode is a 5-digit ZIP or ZIP+4, and country, if given, must be US.
Output (JSON text): {"status":"awaiting_payment","testMode":true,"simulated":true,"order":{...},"checkoutUrl":"...","note":"..."}. The order object contains orderId, mailType, pageCount, priceUsd, createdAt, recipientName, status, paymentStatus, trackingNumber, testMode, simulated, contentDeleted and note. It never echoes the letter text.
get_letter_status
Returns the current state of an order. Read-only.
| Input | Type | Notes |
|---|---|---|
| orderId | string | From create_letter_order |
Output (JSON text): the same order object, with trackingNumber null until mailed. After the retention period the letter text and addresses are deleted, and contentDeleted is true.
Errors
| Where | What you see |
|---|---|
| Missing or wrong key | HTTP 401, WWW-Authenticate: Bearer |
| Non-POST on /mcp | HTTP 405 |
| Body over 100 KB | HTTP 413 |
| Malformed JSON | HTTP 400, JSON-RPC error -32700 |
| Unknown method or tool | JSON-RPC error -32601 or -32602 |
| Bad tool input, over 3 sheets, non-US address, content refused | Tool result with isError: true and text starting INVALID_INPUT: |
| More than 120 requests per minute per key | HTTP 429 with Retry-After: 60. The limit is per key, so everyone sharing a key shares it; wait and retry |
| Daily cap of 300 test orders reached | Tool result with isError: true, RATE_LIMITED: |
| Unknown order id | Tool result with isError: true, INVALID_INPUT: |
Data handling
Orders are stored in Cloudflare KV. Letter text and addresses are deleted 90 days after an order finishes, and the minimal order record is deleted after 7 years, as described in the privacy policy. Rules for what can be sent are in the terms.
Contact
support@certimail.guaranteecheck.org. Developer: Georgina Hawley.