API Docs / MCP
MCP / Claude agents
A live Model Context Protocol server at POST /mcp. Point Claude, or any other MCP-compatible agent, at it to send email, list mailboxes, and search an inbox as tools. Available today, no pending steps, gated on a plan with AI agent tools.
Overview
Transport
Streamable HTTP, JSON-RPC 2.0 over a single POST /mcp endpoint. No SSE, no separate connection setup.
Auth
Reuses the existing X-API-Key mechanism instead of MCP's own OAuth flow, since the transport allows custom headers.
Tools
Four tools today: send_email, list_mailboxes, search_emails, list_recent_messages. Each delegates to the same code path the REST API uses.
Install
Copy-paste install snippets, with a real API key filled in, are also available from Tools in the console sidebar. The same three options:
Claude Code CLI
claude mcp add --transport http kerabie-mail https://api.kerabie.email/mcp \ --header "X-API-Key: YOUR_API_KEY"
Claude Desktop / any MCP client reading the mcpServers shape
{
"mcpServers": {
"kerabie-mail": {
"url": "https://api.kerabie.email/mcp",
"headers": { "X-API-Key": "YOUR_API_KEY" }
}
}
}Test with curl
curl -X POST https://api.kerabie.email/mcp \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Authentication and scopes
Every request must carry an X-API-Key header. Missing it returns 401 before any JSON-RPC method runs. The key is resolved the same way as any other API call (get_api_key_user), and the account must be on a plan with the AI agent tools feature enabled, checked once per request.
Beyond that account-level gate, each individual tool also requires its own scope on the key, checked at tools/call time. Create the key under Settings → API Keys with whichever scopes below your agent needs:
| Tool | Required scope |
|---|---|
| send_email | send |
| list_mailboxes | mailboxes:read |
| search_emails | mailboxes:read |
| list_recent_messages | mailboxes:read |
A call to a tool the key isn't scoped for returns a JSON-RPC error (code -32603) rather than a bare HTTP 403, so a well-behaved MCP client surfaces it to the agent as a normal tool-call failure instead of a broken connection.
Tools
tools/list returns all four with their full JSON Schema input shapes, as MCP expects. The reference below is the same schema, described in prose.
send_email
Send an email from one of the authenticated account's connected mailboxes. Defaults to a sandboxed send (no real delivery, doesn't count against quota) unless sandbox: false is explicitly passed, which the MCP tool description itself tells the calling agent to only do once the user has clearly confirmed a real send is wanted.
| Input | Type | Required |
|---|---|---|
| from_email | string | yes |
| to | string[] | yes |
| subject | string | yes |
| cc | string[] | no |
| bcc | string[] | no |
| body_html | string | no |
| body_text | string | no |
| sandbox | boolean (default true) | no |
Delegates to the same handler as POST /mail/send, so the response shape matches the Send email API reference.
list_mailboxes
No input. Lists the authenticated account's connected mailboxes, same data as the console's mailbox switcher.
search_emails
| Input | Type | Required |
|---|---|---|
| string | yes | |
| q | string | yes |
| folder | string (default "INBOX") | no |
Requires either a Kerabie-managed mailbox, or a DNS-connected mailbox with a recently cached IMAP session, since an agent has no way to supply an IMAP password interactively. A DNS mailbox with no cached session returns 403; that's a hard stop for the agent, not something worth retrying.
list_recent_messages
| Input | Type | Required |
|---|---|---|
| string | yes | |
| folder | string (default "INBOX") | no |
| per_page | integer (default 20) | no |
Same IMAP-session caveat as search_emails above.
Usage examples
Draft and send a sandboxed test email
Prompt Claude with something like:
Using the Kerabie Mail tools, draft a short reply from support@yourdomain.com to test@example.com confirming their refund was processed, and send it as a sandbox test first so I can see it before it goes out for real.
Claude calls send_email with sandbox: true by default, since it wasn't told the real send is confirmed. Nothing is actually delivered and nothing counts against quota.
Summarize your last 10 emails
Summarize the last 10 messages in my support@yourdomain.com inbox and flag any that look urgent.
Claude calls list_recent_messages with email: "support@yourdomain.com", per_page: 10, then reasons over the returned subjects and previews.