@letterapp/mcp
v0.5.0
Published
Letter MCP server - give your AI agent tools to set up a Letter integration, send transactional email, create custom HTML email templates, and delete contacts. Reads the credential written by `letter login`; no secret in your MCP config.
Maintainers
Readme
@letterapp/mcp
Letter MCP server — a Model Context Protocol server that gives your AI coding agent tools to set up and verify a Letter integration, send transactional email, and create custom HTML email templates.
Built for AI coding agents (Claude Code, Cursor, Codex, Windsurf, Cline, OpenClaw). It reads the credential written by @letterapp/cli (~/.letter/credentials.json), so your MCP config never contains a secret and the key never appears in chat.
Installation
No install needed - your MCP client launches it on demand with npx. Add it to your client config:
{
"mcpServers": {
"letter": { "command": "npx", "args": ["-y", "@letterapp/mcp"] }
}
}Or install globally:
npm install -g @letterapp/mcpSetup
First authenticate once from your project (this is what writes the credential the server reads):
npx @letterapp/cliWhat happens:
- The CLI opens a browser to confirm a short code and pick the project to connect.
- Letter mints a project API key and delivers it to the CLI over a secure back channel. The CLI writes
LETTER_API_KEYto.env.localand stores a copy in~/.letter/credentials.json. - This server resolves that credential automatically - no API key in your MCP config.
The API key is never printed to the terminal or chat. In CI you can instead set LETTER_API_KEY in the environment.
Tools
| Tool | Description |
| --- | --- |
| setup_guide | Returns Letter's current step-by-step integration guide (markdown an agent can follow). |
| check_connection | Reports whether the connected project has received any contacts or events yet. |
| send_test_event | Sends a test identify + track to prove the pipe works end to end. Optional userId / email. |
| identify | Report a user to Letter (userId, optional email, traits). |
| track | Report an event a user performed (userId, event, optional properties). |
| send_email | Send one transactional email (to, subject, html/text, optional from, replyTo, tag, metadata, idempotencyKey). |
| html_template_guide | Returns the custom HTML layout contract ({{{content}}} required, {{unsubscribe_url}} recommended). |
| list_templates | List templates in the project (kind is html or visual). |
| get_template | Get one template, including html_source. |
| create_html_template | Create a custom HTML layout. html_source must include {{{content}}}. Optional hide_badge. |
| update_html_template | Update html_source, name, and/or hide_badge. Pass html_source: null to clear. |
| delete_contacts | Delete contacts by external_ids (identify userIds). Suppression list entries are kept. Optional project. |
When no credential is found, every tool returns a friendly "run npx @letterapp/cli first" message instead of failing.
send_email is the only tool with a side effect the user will see in their
inbox. It is for mail the application owes a specific person - a reset link, a
receipt, an alert - and sends immediately from the project's verified domain.
Marketing belongs in a sequence or a broadcast, not here.
Custom HTML templates
A template can be Visual, Text-only, or a custom HTML layout — your chrome around the TipTap body that sequences and broadcasts still author. This is an available option when the user wants their own header, footer, or table layout.
html_source must include {{{content}}} (or {{content}}) where the
body is inserted. Include {{unsubscribe_url}} in an <a href> (or
{{{unsubscribe}}} for a ready-made Unsubscribe link). If those tags are
missing, Letter appends a footer. hide_badge hides the "Sent with Letter"
pill (same as Visual and Text-only; paid plans). Max 500 KB.
These tools use the workspace PAT (lt_pat_*) from letter login or
LETTER_PAT. The project ingestion key (LETTER_API_KEY) cannot create
templates. See Email templates.
Environment Variables
| Variable | Default | Purpose |
| --- | --- | --- |
| LETTER_API_KEY | (from credential file) | Project ingestion key (lt_live_*) for identify/track/send. Overrides the stored key (CI). |
| LETTER_PAT | (from credential file) | Workspace PAT (lt_pat_*) for template (Management API) tools. |
| LETTER_PROJECT | (connected project) | Default project slug for template tools. |
| LETTER_BASE_URL | https://api.letter.app | API origin for self-host / local dev. |
| LETTER_DOCS_URL | https://letter.app | Docs origin used by setup_guide and html_template_guide. |
Security
The server never receives or stores a raw key in its config. It resolves the project ingestion key from ~/.letter/credentials.json or LETTER_API_KEY, and the workspace PAT (pat in that file, or LETTER_PAT) for Management API tools such as templates. Secrets are never logged or echoed back through tool results. Treat .env.local and ~/.letter/credentials.json as secrets and keep them out of source control.
Project Structure
src/
├── index.ts # MCP server entry — registers tools over stdio
├── credentials.ts # Resolves the Letter credential (env or ~/.letter)
└── html-templates.ts # Custom HTML layout contract + validation
package.json
tsconfig.json
tsup.config.tsDevelopment
npm install # install dependencies
npm run build # bundle to dist/ with tsup
npm run dev # watch mode
npm run typecheck
node dist/index.js # run the server over stdioSee Also
@letterapp/cli— connect your app to Letter in one command.@letterapp/node— Node.js SDK.
Links
- Website: letter.app
- npm: @letterapp/mcp
- GitHub: vincenzor/letter-mcp
- Issues: Report a bug
License
MIT
