All posts
Architecture··5 min read

MCP-native email — `from mails import agent` becomes the default agent comms primitive

MCP turned tool integration into a one-line config. Anthropic shipped the Model Context Protocol spec in November 2024, and within six months every major agent runtime supported it — Claude Code, Cursor, Cline, Continue, Windsurf, OpenAI’s Agents SDK, the Anthropic SDK’s own MCP client. Mails.ai shipped as an MCP server first. from mails import agent becomes the default agent email primitive for any developer already using one of those runtimes.

MCP in one paragraph

Model Context Protocol standardizes how an agent runtime discovers and calls tools. Tool servers are processes — usually distributed via npm, run on demand — that expose a JSON schema of tool definitions. The agent runtime spawns the server process, queries list_tools, then calls any tool by name with typed arguments and gets typed results back. The model picks tools to call autonomously based on the user’s request. Network effect: every MCP-capable runtime can use any MCP server with zero per-runtime integration work.

Why MCP-native distribution matters

The traditional alternatives to MCP both scale poorly:

  • Per-language SDKs. A TypeScript SDK, a Python SDK, a Go SDK, a Java SDK, a Ruby SDK, a Rust SDK. Each maintained separately, each with its own release cadence, each with its own surface drift over time. Customers running Mastra in TS but Pydantic AI in Python need two SDK versions kept in sync.
  • Per-runtime integrations.Claude Code has its own tool format. Cursor has its own. LangGraph defines tools differently. OpenAI Agents SDK uses its own schema. Building first-party integrations into every runtime is N×M engineering work that nobody wins on.

MCP collapses both. One server, every runtime. From mails.ai’s side, we maintain one tool surface. From your side, you drop one JSON snippet into your runtime config and your agent has email.

The distribution wedge is significant: every Claude Code user already has the runtime, already knows the config file, already has the muscle memory for adding MCP servers. The friction from “I need email in this agent” to “email is wired in” is one config edit and a restart.

The mails MCP server

The server exposes the agent-relevant slice of the mails.ai API as MCP tools:

  • mails.send— send an email from a named agent, returns send id and pool routing decision
  • mails.on_reply— register a webhook for structured reply events (Phase 2 adds streaming-inbox tool for runtimes that support long-running tools)
  • mails.list_threads— query the agent’s conversation history with filters (sender, intent, date range)
  • mails.suppress— add an address to the agent’s suppression list (or remove)
  • mails.get_reputation— query an agent’s reputation score (0-1), workspace-scoped, designed to propagate as the network grows (useful before processing high-stakes inbound)

All tools accept structured JSON arguments and return typed results. No raw text wrestling on either end — the structured reply events from the inbound side show up here too.

Drop-in for any MCP runtime

The full configuration:

{
  "mcpServers": {
    "mails": {
      "command": "npx",
      "args": ["-y", "@mailsai/mcp-server"],
      "env": {
        "MAILS_API_KEY": "mk_live_..."
      }
    }
  }
}

That same snippet works in:

  • Claude Code — drop into ~/.claude.json under mcpServers
  • Cursor — drop into ~/.cursor/mcp.json
  • Cline (VS Code)— MCP Settings panel, paste, save
  • Continueconfig.json under experimental.modelContextProtocolServer
  • Windsurf— MCP server registry, paste, restart
  • OpenAI Agents SDKMCPServerStdio constructor with the same command + args
  • Anthropic SDK(custom Node / Python agents) — the SDK ships MCP-client primitives that take the same shape

The server runs client-side via npx — fetched on demand, run in your local process, no infrastructure to host on your end. Restart the runtime once after the config edit and the agent has email.

What your agent gets automatically

Once configured, the runtime auto-discovers mails.*tools. The model picks them up by name and calls them when the user’s request implies email work. Your agent instructions can be as terse as:

# system prompt
You are Sarah, a sales operations assistant.
Use the mails.* tools to send and read email on behalf of yourcompany.com.
For inbound replies, check injection_score before acting.

That is enough. The runtime handles tool-schema marshaling, response parsing, error retry, idempotency. You write zero glue code.

The security model

  • Server runs client-side. Your runtime spawns it; we do not host it. The API key never leaves your machine except over HTTPS to api.mails.ai.
  • Per-agent token scope. A mk_live_xxxAPI key authorizes one agent. Compromised runtime → revoke that one key, mint a fresh one, agent resumes. Other agents on other keys are unaffected.
  • No long-lived sessions. Each tool call carries the API key in a header; we authorize per-call. No session hijack vector.
  • Idempotency keys. The server attaches a client-supplied request id to every sendcall. The same call retried is deduplicated — the model can be aggressive on retries without sending duplicate emails.
  • Tool-side safety: mails.suppress requires explicit confirmation; mails.send with a recipient on the suppression list returns a structured error rather than silently failing.

How to start

  1. Create an API key at api.mails.ai/keys (Phase 1 launch).
  2. Copy the JSON snippet above into your runtime’s MCP config, replacing mk_live_... with your key.
  3. Restart your runtime.
  4. Ask your agent to send a test email or list its recent threads. The model will reach for mails.* tools without further prompting.

Read the architecture page for the underlying pipeline, or the structured reply events post for what the inbound webhook events actually look like once tools start firing.

FAQ

The questions readers ask after this post.

Does the MCP server work without an MCP-capable runtime?

No. For non-MCP runtimes, use the TypeScript or Python SDK directly — same primitives, different transport. The MCP server depends on the runtime spawning the server process and querying its tool list, which only MCP-capable runtimes do. The SDK is what you reach for in a custom Node, Python, or Go agent loop.

Is the MCP server open source?

Yes — MIT-licensed at github.com/mailsai/mcp-server, ships at Phase 1 launch alongside the API. The server is intentionally thin: it is a tool-shape over the public REST API, with auth, retries, and idempotency keys handled in one place. Forking it to add custom tools or wrap additional endpoints is supported.

Where do tokens live?

In your runtime's MCP config — same place as any other MCP server's secrets. The MAILS_API_KEY env var stays on the machine running the agent, never sent anywhere except api.mails.ai over HTTPS. We never see your runtime config or the contents of the agent's tool calls beyond what hits our API.

Can I extend with custom tools?

Phase 2 ships a tool-extension SDK that lets you register additional tools alongside the built-ins. Today, the open-source server is a fork-friendly base — clone it, add your tools to the schema and dispatcher, point your runtime at the local fork. The built-in tools surface remains stable across forks.

Closed beta

Built for agents.
Self-serve at every volume.

Public API opens Q3 2026. Drop ~6 lines into your agent and ship.

npmpnpmbunpip
$ npm install @mailsai/sdk
Packages publish with cohort 1 · Q3 2026