Docs Go to app →

MCP server

Letter runs a remote Model Context Protocol server at https://mcp.letter.app/. Add it to your AI assistant, sign in with your Letter account, and the assistant can work in your workspace: draft and publish sequences, schedule broadcasts, build forms and segments, look up contacts, and check how sends performed.

It acts as you, with your role in the workspace, so it can do what you can do in the dashboard and nothing more.

Wiring Letter into your app’s code with a coding agent? That’s a different job. See Agent setup for the CLI and the local @letterapp/mcp package.

URLhttps://mcp.letter.app/
TransportStreamable HTTP (stateless, JSON responses)
AuthOAuth 2.1: dynamic client registration and PKCE
Scopesworkspace:read, workspace:write

There is no API key to paste and nothing to install. Opening the URL in a browser shows a short “how to connect” page.

Connect

Claude

  1. Open Customize → Connectors and choose Add custom connector.
  2. Name it Letter, paste https://mcp.letter.app/, and click Add. Leave the OAuth client ID and secret empty.
  3. Click Connect, sign in to Letter, and approve.

Turn it on in a chat from the + menu. On Team and Enterprise plans, an owner adds the connector once in Organization settings → Connectors, then each member connects their own Letter account.

ChatGPT

  1. Open Plugins, click +, and choose Add custom MCP server.
  2. Name it Letter, paste https://mcp.letter.app/ as the Server URL, and pick OAuth for authentication.
  3. Click Create as a plugin, sign in to Letter, and approve.

Type @ in a chat and pick Letter. ChatGPT confirms with you before any tool that changes something. Whether you can add custom MCP servers depends on your ChatGPT plan and, on business plans, your workspace settings.

GitHub Copilot (VS Code)

  1. Run MCP: Add Server from the Command Palette and choose HTTP.
  2. Paste https://mcp.letter.app/ and name the server letter.
  3. VS Code opens your browser: sign in to Letter and approve.

The tools then show up in Copilot Chat in agent mode. To share the server with everyone working on a repository, commit it to .vscode/mcp.json:

{
  "servers": {
    "letter": {
      "type": "http",
      "url": "https://mcp.letter.app/"
    }
  }
}

Claude Code

claude mcp add --transport http letter https://mcp.letter.app/

Then run /mcp in Claude Code, pick letter, and sign in.

Cursor and other clients

Any client that supports remote MCP servers with OAuth connects the same way: give it the URL and sign in when it opens your browser. In Cursor, add this to .cursor/mcp.json (or ~/.cursor/mcp.json for every project):

{
  "mcpServers": {
    "letter": { "url": "https://mcp.letter.app/" }
  }
}

Sign-in and permissions

When you connect, Letter’s consent screen shows which app is asking, which workspace it will reach, and what it can do. Claude and ChatGPT are recognized by where they send you back to; other apps show the name they registered with.

  • Allow changes is the one choice you make. Leave it off for a read-only connection (workspace:read): the assistant can look but only sees read tools. Turn it on to also grant workspace:write.
  • Your role applies. Tools run as you, so workspace roles work exactly as in the dashboard. Admin-only tools (projects, members and invitations, sending domains, sender identity, sending mode, API keys) say so in their description and refuse for members.
  • Sessions refresh on their own. Access tokens last an hour and are renewed automatically. A connection unused for 90 days has to sign in again.
  • Tokens only work here. A connector’s token is bound to https://mcp.letter.app/. It can’t call the Management API directly, and an API key or access token can’t be used as an MCP connection.
  • Disconnect anytime from Settings → Connected apps (use.letter.app/connected-apps). The next call fails and the assistant asks you to reconnect.

What it can do

The tools cover the whole Management API, plus a few built for chat (Markdown email bodies, contacts by email, CSV imports as text). Read tools are always available; the rest need Allow changes.

AreaTools
Workspacelist_projects, get_project, create_project, update_project, delete_project, list_members, invite_member, remove_member, list_invitations, create_invitation, revoke_invitation
Contactsget_contact, list_contacts, upsert_contact, import_contacts, get_import_status, get_import_error_report, unsubscribe_contact, resubscribe_contact, delete_contact, delete_contacts, list_accounts, get_account, list_events, list_traits
Suppressionslist_suppressions, suppress_email, unsuppress_email
Listslist_lists, create_list, get_list, update_list, delete_list, list_list_members, add_contact_to_list, remove_contact_from_list
Segmentslist_segments, create_segment, get_segment, update_segment, preview_segment, delete_segment
Formslist_forms, create_form, get_form, update_form, duplicate_form, delete_form, list_form_submissions
Sequenceslist_sequences, create_sequence, get_sequence, update_sequence, save_sequence_draft, validate_sequence, preview_sequence_email, send_sequence_test, publish_sequence, list_sequence_versions, get_sequence_activity, delete_sequence
Broadcastslist_broadcasts, create_broadcast, get_broadcast, update_broadcast, send_broadcast_test, preflight_broadcast, schedule_broadcast, cancel_broadcast, get_broadcast_activity, delete_broadcast
Templateslist_templates, get_template, create_template, update_template, set_default_template, reset_template, remove_template_logo, delete_template
Sendinglist_domains, add_domain, verify_domain, remove_domain, set_sender_identity, set_sending_mode, list_transactional_messages, get_transactional_message
Credentialslist_api_keys, revoke_api_key, list_access_tokens, revoke_access_token

Some prompts to start with:

  • “Draft a three-email onboarding sequence for new trials, then validate it.”
  • “How did last week’s broadcast perform?”
  • “Build a segment of users who signed up but never invited a teammate.”
  • “Did jane@acme.com get her password reset email?”
  • “Add a waitlist form that drops signups into the Beta list.”

Good to know

  • Projects. Most tools take a project slug. It can be left out when the workspace has one project; otherwise the assistant starts with list_projects, or you can name the project in your request.
  • Email bodies are Markdown. Sequence emails and broadcasts take body_markdown, personalized with {{first_name}} or {{first_name|there}}. list_traits shows which trait keys exist. Letter converts the Markdown to its editor format, so the email stays editable in the dashboard.
  • Sequences are drafted, then published. save_sequence_draft replaces the draft graph and needs the draft_revision from get_sequence, so the assistant can’t overwrite edits someone made in the dashboard meanwhile. Nothing reaches contacts until publish_sequence.
  • Test emails only go to you. send_sequence_test and send_broadcast_test always mail the signed-in user, never an address the assistant picks.
  • Risky tools are flagged. Tools that email contacts or delete data carry MCP’s destructiveHint and read tools carry readOnlyHint, so clients that support it ask you before acting. The server also tells the assistant to confirm before scheduling a broadcast, publishing a sequence, or deleting anything.
  • CSV imports are passed as text, header row first, up to 5 MB. The import runs in the background; get_import_status reports progress.
  • Rate limit: 300 tool calls per minute per connection. Over that, calls get 429 with a Retry-After.
  • Errors explain themselves. A rejected call returns the API’s error with per-field details, so the assistant can correct its input and retry.

Not available over MCP

  • Creating API keys or access tokens. Secrets don’t belong in a chat transcript. You can list and revoke them from chat, but create them in the dashboard or with the CLI.
  • Billing and plan changes.
  • Uploading a template logo, which is a file upload. Use the dashboard.
  • The ingestion API (identify, track, POST /v1/send). Those authenticate with a project API key from your backend. See API and Transactional email.

Troubleshooting

SymptomFix
The assistant says it can’t make changesYou connected read-only. Disconnect in Settings → Connected apps, then connect again with Allow changes on.
”This action requires the admin role”Your workspace role doesn’t allow it. Ask an admin, or have them run it.
The assistant keeps asking you to sign inThe connection was disconnected or unused for 90 days. Reconnect from your assistant’s connector settings.
It works on the wrong projectName the project in your request, or ask it to run list_projects first.
Your client asks for an OAuth client ID or secretLeave them empty. Letter registers clients automatically.

For MCP client developers

  • Discovery. An unauthenticated POST https://mcp.letter.app/ returns 401 pointing at the protected resource metadata (RFC 9728):

    WWW-Authenticate: Bearer realm="letter",
      resource_metadata="https://mcp.letter.app/.well-known/oauth-protected-resource"

    It names https://use.letter.app as the authorization server, whose metadata (RFC 8414) is at https://use.letter.app/.well-known/oauth-authorization-server.

  • Registration. Dynamic client registration (RFC 7591) at https://use.letter.app/oauth/register. Redirect URIs may be https, http on a loopback host, or a private-use scheme. Client ID Metadata Documents aren’t supported.

  • Authorization. Authorization code flow with PKCE, S256 only. Authorization responses include iss (RFC 9207). The resource parameter (RFC 8707) is optional; if sent, it must be https://mcp.letter.app/. Tokens are always bound to that resource.

  • Tokens. Access tokens last one hour. Refresh tokens rotate on every use, and a replayed one is rejected. Revoke at https://use.letter.app/oauth/revoke (RFC 7009).

  • Transport. Stateless Streamable HTTP: every request is a POST with a JSON response, with no sessions or SSE stream. GET and DELETE return 405. Send the token as Authorization: Bearer ….