Use GetCourier as a hosted MCP server
GetCourier runs a hosted MCP server at https://getcourier.dev/mcp over streamable HTTP, so there is no package to install and no key to create. It is stateless — no Mcp-Session-Id, no signup, no API key — you POST JSON-RPC 2.0 objects to it at protocol version 2025-06-18, and tools/list returns 10 tools for creating inboxes, waiting for verification codes, reading and deleting mail, and handling prepaid credits.
Claude Code
claude mcp add --transport http getcourier https://getcourier.dev/mcp
Cursor
Add the server to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json inside one project:
{"mcpServers":{"getcourier":{"url":"https://getcourier.dev/mcp"}}}
Claude Desktop and claude.ai
Add a custom connector with the URL https://getcourier.dev/mcp: open Settings → Connectors, choose to add a custom connector, and paste the URL. There is no JSON file to edit and no key to supply.
Use GetCourier with Grok
The Grok CLI registers it in one command:
grok mcp add --transport http getcourier https://getcourier.dev/mcp
Grok also reads the other common MCP config files, so an existing entry is picked up as-is: ~/.claude.json, .cursor/mcp.json and a project .mcp.json.
xAI API
On the xAI API, a remote MCP server is a tool entry with type: "mcp" and a server_url, sent in the tools array of a POST https://api.x.ai/v1/responses:
{
"tools": [
{
"type": "mcp",
"server_url": "https://getcourier.dev/mcp",
"server_label": "getcourier",
"server_description": "Email inboxes for AI agents: create an inbox, wait for a verification code or magic link."
}
]
}
That API supports Streaming HTTP/SSE remote MCP servers only; GetCourier serves streamable HTTP, so the transport matches. No client install is needed on this path.
Any other client: project .mcp.json
Most clients that read a project-level .mcp.json accept the explicit transport form:
{"mcpServers":{"getcourier":{"type":"http","url":"https://getcourier.dev/mcp"}}}
Transport rules
POSTonly.GETandDELETEreturn 405 withAllow: POST.Acceptmay beapplication/jsonand/ortext/event-stream; responses are alwaysapplication/json.- Stateless: every request is independent, and no session id is required.
- A notification (a request with no
id) returns 202 with an empty body. - Batch arrays are rejected with
-32600; an unknown method gives-32601; an unknown tool or bad params gives-32602. - A
read_tokenoraccount_keymay be sent asAuthorization: Bearer <token>. Tool arguments win over the header. tools/callreturnscontent: [{type:"text", text:"<json>"}]plusstructuredContent; failures returnisError: truewith{error, message, hint}in the text content.
Test it with curl
curl -s https://getcourier.dev/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Call a tool:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "create_inbox", "arguments": { "purpose": "signup" } } }
The 10 tools
| Tool | Arguments | What it does |
|---|---|---|
create_inbox |
purpose?, alias?, ttl_hours?, account_key? |
Create an email inbox for an AI agent. Returns the address, a read_token (shown once) and an Ed25519 identity. Omit account_key for the free tier. |
wait_for_code |
read_token, timeout_seconds? (1–55, default 30), after? |
Blocks until a message with a verification code or magic link arrives, then returns it; answers {message:null, timeout:true} if nothing arrives. |
list_messages |
read_token, after?, limit? |
Lists messages, newest first (default 20, max 100), with codes and links already extracted; after polls for new mail. |
get_message |
read_token, message_id |
Returns one full message: text, codes, links and the auth verdict. |
delete_inbox |
read_token |
Deletes the inbox; it stops accepting mail and its messages become unreadable. |
create_account |
— | Creates a prepaid account and returns an account_key and account_id. |
get_balance |
account_key |
Returns the credit balance and deposits. |
create_deposit |
account_key, rail (usdc-base or btc), usd |
Creates a crypto deposit invoice: pay_to, exact amount, amount_atomic, wallet uri. Both rails are live; pricing reports the enabled rails and deposit addresses. |
deposit_status |
account_key, deposit_id |
Returns one deposit and its status. |
pricing |
— | Returns credit prices, the free tier and enabled payment rails. No auth. |
Auth over MCP
There is none to start: create_inbox without an account_key creates a free inbox (3 per hour and 5 per day per client IP, 72 hours, receive-only). Reads need the read_token returned by create_inbox. Paid calls need an account_key from create_account, topped up with create_deposit. Credits are live: deposits start at US$1 in USDC on Base or BTC on-chain, and pricing lists the rails that are enabled. GetCourier is a hosted service: there is no self-hosted MCP build and no code licence, and every inbox is receive-only - no outbound sending, no agent-to-agent relay and no Lightning.
FAQ
Does the MCP server need a session or an API key?
No. It is stateless, takes no Mcp-Session-Id and creates free inboxes without an account. Credentials matter only for reading a specific inbox (the read_token) and for paid use (an account_key).
Why does opening the MCP URL in a browser show an error?
/mcp serves JSON-RPC over POST only; GET and DELETE return 405 with Allow: POST. A browser tab or a plain health probe is not a valid test — POST a tools/list request instead.
Can Grok call GetCourier without a separate MCP client install?
Yes. Either add it in the Grok CLI with grok mcp add --transport http getcourier https://getcourier.dev/mcp, or send a remote MCP tool entry with server_url set to https://getcourier.dev/mcp in the tools array of a POST https://api.x.ai/v1/responses.