MCP server
Connect Claude, ChatGPT, Cursor or another MCP client to your letr.dev account.
letr.dev runs a hosted MCP server. An assistant can send email, inspect delivery and manage sending domains, webhooks and suppressions with the same rules as the API. There is nothing to install.
Endpoint
https://api.letr.dev/mcp speaks Streamable HTTP, stateless, protocol revision 2025-11-25: JSON-RPC over POST. GET and DELETE answer 405, and the Origin header is validated. Clients on 2025-06-18 or 2025-03-26 are accepted too; a client on a newer revision gets 400 for its MCP-Protocol-Version and falls back to initialize. GET https://api.letr.dev/mcp/server-card answers the server card (application/mcp-server-card+json, no credential): the name dev.letr/letr and this endpoint as its one remote.
Sign in
- OAuth. Clients such as Claude and ChatGPT sign you in through the browser. A request without a credential answers
401with aWWW-Authenticateheader that points to/.well-known/oauth-protected-resource/mcp, where the client finds the authorization server. The flow is the usual one: PKCE withS256, dynamic client registration or a client ID metadata document, then the token withhttps://api.letr.dev/mcpas its audience. An OAuth token acts withfull_accessfor your account. - API key. Send
Authorization: Bearer letr_.... The key's permission decides which tools the client sees at all.
For agents, use a sending_access key limited to one domain.
What it cannot do
No tool returns or accepts a secret: API keys, webhook signing secrets and private keys stay in the dashboard. Every tool runs through the same validation and limits as /v1, so MCP adds no capability. Calls are limited to 120 tool calls a minute per credential, on top of the account's 600 requests a minute. Past the 120, a tool call answers a tool error rate_limited: Too many requests; the X-RateLimit-* headers count the account's 600, not this budget. Billing is not reachable.
Activity
The dashboard lists every tool call of the last 30 days with the tool, the outcome, the credential, the client's name and, for send tools, the recipient count. Addresses and content are never logged.
Safety
Send tools are marked as not read-only and flagged to ask you before they run; clients that honour the flag ask first. Read tools are marked read-only. Send tools require an idempotencyKey: the assistant picks a new one per send (one for a whole batch) and reuses it when it retries, so a repeated call never sends twice. An assistant that reads untrusted content (inboxes, web pages, tickets) and can send email can be tricked into sending. Keep sending keys narrow.
Resources and prompts
The server offers the public API reference (OpenAPI), the same document as letr.dev/docs/openapi.json, as letr://docs/api and a domain's DNS records as letr://domains/{id}/dns-records, plus two prompts: set_up_sending_domain and diagnose_delivery.
Setup
claude mcp add --transport http letr https://api.letr.dev/mcp \
--header "Authorization: Bearer $LETR_API_KEY".cursor/mcp.json
{
"mcpServers": {
"letr": {
"url": "https://api.letr.dev/mcp",
"headers": {
"Authorization": "Bearer ${env:LETR_API_KEY}"
}
}
}
}mcp_config.json
{
"mcpServers": {
"letr": {
"serverUrl": "https://api.letr.dev/mcp",
"headers": {
"Authorization": "Bearer ${env:LETR_API_KEY}"
}
}
}
}.vscode/mcp.json
{
"inputs": [
{
"type": "promptString",
"id": "letr-api-key",
"description": "letr.dev API key",
"password": true
}
],
"servers": {
"letr": {
"type": "http",
"url": "https://api.letr.dev/mcp",
"headers": {
"Authorization": "Bearer ${input:letr-api-key}"
}
}
}
}settings.json
{
"context_servers": {
"letr": {
"url": "https://api.letr.dev/mcp",
"headers": {
"Authorization": "Bearer letr_..."
}
}
}
}Claude: Customize > Connectors > Add custom connector.
ChatGPT: Plugins > add a custom MCP server, where your plan allows it.
URL: https://api.letr.dev/mcp
Then sign in with your letr.dev account.Tools by permission
The tools a credential sees depend on its permission; an OAuth token sees all of them.
| Tool | Permission | Kind |
|---|---|---|
send_email | sending_access | asks before sending |
send_batch_emails | sending_access | asks before sending |
get_email | read_only, sending_access (own emails) | read only |
list_emails | read_only | read only |
list_domains | read_only | read only |
get_domain | read_only | read only |
add_domain | full_access | changes data |
verify_domain | full_access | changes data |
remove_domain | full_access | deletes |
list_webhooks | read_only | read only |
update_webhook | full_access | changes data |
delete_webhook | full_access | deletes |
send_test_webhook | full_access | changes data |
list_suppressions | read_only | read only |
remove_suppression | full_access | deletes |
get_usage | read_only | read only |
get_metrics | read_only | read only |