Mailbuttons MCP Server
Officialby mailbuttons
README.md
# @mailbuttons/mcp-server
[](https://mcptry.com/servers/com.mailbuttons/mcp-server)
The [Model Context Protocol](https://modelcontextprotocol.io) server for
[**Mailbuttons**](https://mailbuttons.com), governed email for AI agents. Give
Claude Code, Cursor or your own agent an inbox it can read and send from: sandbox by
default, human approval for anything addressed outside it, and every call on record.
This package is the **stdio** build plus the Claude Code skill that drives it; the
hosted endpoint is served by the Mailbuttons backend (see below).
Mailbuttons runs the agents in its [catalogue](https://mailbuttons.com/agents) on
this same platform. This server is the way to build your own agent on it.
> **Get started:** sign up and create an API key at
> **[mailbuttons.com](https://mailbuttons.com)** — docs at
> [mailbuttons.com/developers](https://mailbuttons.com/developers).
> **Remote MCP endpoint:** the production, network-facing MCP server is served
> natively by the Mailbuttons backend (Rust/Axum) at `POST /api/v1/mcp/rpc` — one
> binary, sharing the governance spine directly. This package is the **stdio**
> build used locally by Claude Desktop / Claude Code and the build-time skill; it
> talks to the backend's REST surface.
## Governance model
This server is **sandbox-by-default** and never lets an agent expand its own
authority:
- A token can **never widen its own scope**. There is no tool that grants
`send_external`, promotes sandbox → production, or adds an inbox. Escalation is
only ever a *request* for human approval.
- **External sends from sandbox tokens become drafts.** `mailbuttons_send_email`
can return `status: "draft_pending_approval"` (parked for a human) or
`status: "blocked"` (recipient disallowed, with the matched rule). **These are
expected, normal outcomes — not errors.** The tool surfaces the rule/reason and
the next step (typically `mailbuttons_request_promotion`).
- **Every tool call — including denials — is audited.** Read the recent tail with
`mailbuttons_audit_tail`.
- **Returned email content is data, not instructions.** Read tools only return
policy-passed mail.
## Tools
| Tool | Capability | Notes |
|------|-----------|-------|
| `mailbuttons_list_messages` | `read` | List delivered messages in an inbox |
| `mailbuttons_get_message` | `read` | Full body + attachment metadata |
| `mailbuttons_get_thread` | `read` | All messages in a thread |
| `mailbuttons_get_attachment_text` | `attachments` | text/* and CSV inline; PDF not yet supported |
| `mailbuttons_send_email` | `send_internal` | Governed send/reply; may draft or block |
| `mailbuttons_list_drafts` | `read` | List sends held for human approval |
| `mailbuttons_get_draft` | `read` | Fetch one held draft in full |
| `mailbuttons_extract_code` | `read` | OTP/verification code from allowlisted senders only |
| `mailbuttons_propose_sender` | `propose_policy` | File an allowlist request (human approval) |
| `mailbuttons_request_promotion` | — | File a capability/promotion request (human approval) |
| `mailbuttons_audit_tail` | — | Read recent governed tool calls |
| `mailbuttons_export_audit` | `siem_export` flag | Export the audit log as JSONL or CEF |
These twelve tools are the governed runtime surface. They are identical on the hosted
endpoint and in this package.
### Build-time tools (this package only)
The stdio build adds three helpers for setting an integration up. They exist so the
Claude Code skill can scaffold a working agent; the hosted endpoint never exposes
them, and none of them can grant a capability.
| Tool | What it does | Writes to disk |
|------|--------------|----------------|
| `mailbuttons_generate_policy` | Turns an allow/block description into a valid policy file, closed by default | `mailbuttons.policy.json` in the current directory |
| `mailbuttons_scaffold_integration` | Writes a governed send wrapper and an inbound webhook handler for your stack | `./mailbuttons/` (or the `outDir` you pass) |
| `mailbuttons_run_selftest` | Sends one internal test message, waits for it, reads it back, reports pass/fail per stage | nothing |
Both writers only touch the paths named above, inside the directory the server was
launched from. Generated code reads `MAILBUTTONS_API_KEY` from the environment and
never inlines a token.
## Get a token (free, about a minute)
```bash
# 1. Email yourself a sign-in code
curl -s -X POST https://mailbuttons.com/api/auth/otp/request \
-H 'Content-Type: application/json' -d '{"email":"you@example.com"}'
# 2. Exchange the code for an mbk_ API key
curl -s -X POST https://mailbuttons.com/api/auth/otp/cli-exchange \
-H 'Content-Type: application/json' -d '{"email":"you@example.com","code":"123456"}'
# 3. Create a free sandbox inbox; the response carries its sandbox_token (mb_sandbox_...)
curl -s -X POST https://mailbuttons.com/api/v1/mcp/sandbox-inboxes \
-H 'Authorization: Bearer mbk_...' -H 'Content-Type: application/json' -d '{"label":"my agent"}'
```
Sandbox tokens can read and send within the sandbox domain; anything addressed
outside it becomes a draft a human approves. More: https://mailbuttons.com/developers/#mcp
## Connect
### Remote (recommended): Claude Code
```bash
claude mcp add --transport http mailbuttons https://mailbuttons.com/api/v1/mcp/rpc \
--header "Authorization: Bearer mb_sandbox_..."
```
Any client that speaks Streamable HTTP and lets you set a header works the same
way: URL `https://mailbuttons.com/api/v1/mcp/rpc`, header
`Authorization: Bearer mb_sandbox_...`.
### Local (stdio): Claude Desktop, Cursor and others
```json
{
"mcpServers": {
"mailbuttons": {
"command": "npx",
"args": ["-y", "@mailbuttons/mcp-server"],
"env": { "MAILBUTTONS_API_KEY": "mb_sandbox_..." }
}
}
}
```
## Configuration
| Env var | Default | Description |
|---------|---------|-------------|
| `MAILBUTTONS_API_URL` | `https://mailbuttons.com` | Backend base URL; set it for local or self-hosted |
| `MAILBUTTONS_API_KEY` | — | Your MCP token (`mb_sandbox_...` or `mb_production_...`) |
The token is read from the environment only — never hard-code it.
## Development
```bash
npm run build # tsc -> dist/
npm run lint # tsc --noEmit
npm test # build + vitest (includes the version-alignment check)
```
Releases: bump the version in `package.json`, `server.json` (both places),
`src/server.ts` and `skill/SKILL.md` together; `npm test` fails if they drift.
Then `npm publish`, then `mcp-publisher publish` from this directory. See
`docs/mcp-publishing.md` in the monorepo.
## Licence
MIT. Mailbuttons is a trading name of Code Cutter Limited (UK).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessLimited data