MCP Server Setup
Connect AI assistants like Claude, Cursor, VS Code, Codex, and Raycast to your email through Saymail's built-in MCP server.
Diperbarui: 2026-06-25
Saymail ships a built-in Model Context Protocol (MCP) server. Create one API key and any MCP-aware assistant — Claude Code, Claude Desktop, Cursor, VS Code, Codex, Raycast, and others — can read, search, draft, send, and sync your email, without you copying anything by hand.
What is the Model Context Protocol?
MCP is an open protocol that standardises how applications expose context and actions to large language models. Think of it as a USB-C port for AI: instead of a bespoke integration per tool, an assistant speaks one protocol and plugs into anything that implements it. Learn more at modelcontextprotocol.io.
Saymail’s MCP server runs on your device. It listens only on
http://127.0.0.1:17057/mcpand is never reachable from outside your machine. Saymail must be running, and the server only starts once you have at least one active API key — it stops again when the last active key is removed or deactivated.
Quick start
Step 1 — Create an API key
- Open the MCP API Keys panel (via the command palette or menu).
- Click New and give the key a recognisable name, such as Claude Code.
- Choose the permissions to grant (see Permissions below).
- Optionally link the key to specific email accounts. Leave this empty to allow all accounts.
- Make sure Active is checked, then click Save.
- Copy the generated key — it starts with
smk_and is shown only once. Store it somewhere safe. The panel also offers a Copy URL button with the token baked in, handy for clients that take a plain URL.
Step 2 — Connect your AI assistant
Pick your client. Every snippet registers a server named saymail pointing at
http://127.0.0.1:17057/mcp — replace smk_… with the key you copied.
Claude Code speaks Streamable HTTP natively. Run this in your terminal:
claude mcp add --transport http saymail http://127.0.0.1:17057/mcp \
--header "Authorization: Bearer smk_…"Then confirm it is registered:
claude mcp listOr type /mcp inside a Claude Code session to check the connection status. Add --scope user
to the add command to make the server available in every project.
Claude Desktop’s custom-connector UI only accepts a URL plus optional OAuth — it has no field
for a static Authorization header, and its config file launches stdio servers only. So
bridge to the HTTP server with mcp-remote (see The stdio bridge,
which also covers installing Node.js).
Open Settings → Developer → Edit Config and add:
{
"mcpServers": {
"saymail": {
"command": "npx",
"args": [
"mcp-remote",
"http://127.0.0.1:17057/mcp",
"--allow-http",
"--header",
"Authorization:${AUTH_HEADER}"
],
"env": {
"AUTH_HEADER": "Bearer smk_…"
}
}
}
}Restart Claude Desktop afterwards. The ${AUTH_HEADER} indirection avoids a Windows quoting bug
where spaces inside a single argument get mangled.
Cursor supports Streamable HTTP servers with custom headers. Edit ~/.cursor/mcp.json (global)
or .cursor/mcp.json in your project:
{
"mcpServers": {
"saymail": {
"url": "http://127.0.0.1:17057/mcp",
"headers": {
"Authorization": "Bearer smk_…"
}
}
}
}Cursor treats the presence of url as a remote server, so no type field is needed.
VS Code (GitHub Copilot) supports HTTP MCP servers. Create .vscode/mcp.json in your workspace:
{
"servers": {
"saymail": {
"type": "http",
"url": "http://127.0.0.1:17057/mcp",
"headers": {
"Authorization": "Bearer smk_…"
}
}
}
}To register it for every workspace instead, run MCP: Open User Configuration from the
Command Palette and add the same saymail entry there.
OpenAI Codex reads ~/.codex/config.toml. Add an HTTP MCP server:
[mcp_servers.saymail]
url = "http://127.0.0.1:17057/mcp"
http_headers = { "Authorization" = "Bearer smk_…" }To keep the token out of the file, use an environment variable instead:
[mcp_servers.saymail]
url = "http://127.0.0.1:17057/mcp"
bearer_token_env_var = "SAYMAIL_TOKEN"Then set SAYMAIL_TOKEN=smk_… (token only — Codex adds the Bearer prefix). If Codex reports
missing field 'command', your version is older than the streamable-HTTP support; see
Troubleshooting.
Raycast configures servers through a form, not a file. Run the Install Server command (or Manage MCP Servers → Install New Server) and fill in:
- Transport: HTTP
- URL:
http://127.0.0.1:17057/mcp - HTTP Headers: add
Authorization=Bearer smk_… - OAuth Type: None
Press Install MCP Server to finish. Raycast sends the header on every request, so no bridge is needed.
Connection details
For any client not listed above, these are the raw connection facts:
| Setting | Value |
|---|---|
| Transport | Streamable HTTP |
| URL | http://127.0.0.1:17057/mcp |
| Auth header | Authorization: Bearer smk_… |
| URL fallback | http://127.0.0.1:17057/mcp?token=smk_… |
Prefer the header. The ?token= query-string form exists for clients that can’t set custom
headers, and is safe only because the server listens on loopback. The Copy URL button in the
MCP API Keys panel produces exactly this token URL.
The stdio bridge (mcp-remote)
Some clients can only launch stdio servers, or can’t attach a static header (Claude Desktop
is the notable case). For those, mcp-remote bridges a
stdio client to the HTTP server. It needs Node.js 18+.
Install Node.js
- Download the macOS installer from nodejs.org.
- Open the
.pkgand follow the prompts. - Open Terminal and verify:
node -v - Download the Windows installer from nodejs.org.
- Run the
.msiand follow the prompts. - Open Command Prompt and verify:
node -v Install from your distribution’s package manager (or nodejs.org), then verify:
node -v Run the bridge
The wrapped command, used inside a stdio client’s config (see the Claude Desktop tab above):
npx mcp-remote http://127.0.0.1:17057/mcp --allow-http --header "Authorization: Bearer smk_…"
--allow-http is required because the endpoint is plain http:// on loopback rather than HTTPS.
Permissions
Each API key grants exactly the permissions you check. Tools that need a permission the key lacks return permission denied.
| Permission | In-app label | What it allows |
|---|---|---|
| Account info | Account info (metadata, labels, folder list) | List configured email accounts |
| Read | Read (list & fetch emails, search, folders) | List the inbox, search, read messages, view contacts, get unread counts, list tasks |
| Write | Write (drafts, move, archive, delete) | Mark read, delete, flag, mark/unmark spam, save drafts and reply drafts |
| Send | Send (dispatch mail via your provider) | Send mail — requires Write as well. Attachments aren’t supported yet |
| Sync control | Sync control (trigger sync, sync settings) | Trigger a manual sync, cancel a running task |
Granting Write without Send is useful for an agent-drafts / human-sends workflow: the assistant prepares messages, you press send.
Tools
The server exposes these tools, each gated by the permission shown:
| Tool | Requires | Description |
|---|---|---|
list_email_accounts | Account info | List the email accounts this key may see |
list_inbox_messages | Read | List inbox messages, newest first, paginated |
search_emails | Read | Search across subject, sender, and snippet |
get_email_detail | Read | Fetch one message including its body |
get_unread_count | Read | Count unread mail across allowed accounts |
list_contacts | Read | List contacts, optionally filtered by name or address |
list_running_tasks | Read | List background tasks currently running |
list_scheduled_tasks | Read | List scheduled tasks this key may see |
mark_email_as_read | Write | Mark a message as read |
delete_email | Write | Move a message to Trash |
toggle_email_flag | Write | Flag or unflag a message |
mark_email_as_spam | Write | Move a message to the Spam folder |
unmark_email_as_spam | Write | Move a message out of Spam back to the inbox |
create_email_draft | Write | Save a new draft without sending |
create_reply_draft | Write | Draft a reply to an existing message without sending |
send_email | Write + Send | Compose and send a new message (no attachments) |
sync_email_now | Sync control | Trigger a sync across allowed accounts |
cancel_running_task | Sync control | Cancel a running background task |
Account scoping
When a key is linked to specific accounts, assistants can only read or send mail for those accounts — even if the key has Write or Send. An empty account list grants access to every account configured in Saymail. Create multiple keys to give different tools different reach.
Resetting a key
If a key is exposed, open the MCP API Keys panel, select the key, and click Reset Key. A new key is generated immediately and the old one stops working at once. Update the registration in your assistant with the new token.
Stopping the server
To turn the MCP server off, deactivate every key (uncheck Active) or delete them. Once no active keys remain, Saymail closes port 17057 automatically.
Troubleshooting
- Connection refused / can’t reach the server. Saymail must be running and you need at least one active API key — the server only listens while a key is active.
- 401 Unauthorized. The token is wrong, was reset, or its key is inactive. Copy the current key (or reset it) and update your client.
- Codex says
missing field 'command'. Your Codex predates streamable-HTTP support. Upgrade Codex, or opt in by addingexperimental_use_rmcp_client = trueunder a[features]table in~/.codex/config.toml. mcp-remotefails on Windows with a mangled header. Move the header value into anenvvariable and reference it asAuthorization:${AUTH_HEADER}with no space after the colon, as shown in the Claude Desktop tab.mcp-remoterefuses to connect. Pass--allow-http; the loopback endpoint is plain HTTP, which the bridge otherwise rejects.