> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mail MCP Server

> Drive every StateSet Mail operation from Claude, Cursor, or any MCP client — tools, resources, and prompts over stdio or HTTP.

# Mail MCP Server

StateSet Mail ships a [Model Context Protocol](https://modelcontextprotocol.io) server, so any
MCP-capable client — Claude Desktop, Cursor, Claude Code, the Anthropic SDK — can drive every
marketing and inbox operation as native tools.

The server advertises **tools**, **resources**, and **prompts** in its `initialize` response,
so clients enable the Resources panel and Prompts catalog in their UI.

## Transports

### stdio — recommended for desktop clients

`stateset-mail-mcp` is a second binary that reads newline-delimited JSON-RPC from stdin and
writes responses to stdout, logging to stderr. It reads the same environment variables as the
main HTTP server — point both binaries at the same SQLite file and the MCP server sees
everything the HTTP API has touched. All tools dispatch **in-process**, so there is no HTTP
round-trip.

Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):

```json theme={null}
{
  "mcpServers": {
    "stateset-mail": {
      "command": "/usr/local/bin/stateset-mail-mcp",
      "env": {
        "DATABASE_URL":           "sqlite:///Users/you/.stateset-mail/data/mail.db",
        "STATESET_MAIL_API_KEYS": "anything-nonempty-the-stdio-binary-doesnt-auth",
        "DEFAULT_FROM":           "Agent <agent@example.com>",
        "SMTP_HOST":              "smtp.example.com",
        "SMTP_USERNAME":          "agent@example.com",
        "SMTP_PASSWORD":          "...",
        "PUBLIC_BASE_URL":        "https://mail.example.com"
      }
    }
  }
}
```

Restart the client and the tools are live in the next chat.

### HTTP — recommended for remote clients

`POST /v1/mcp` accepts a single JSON-RPC request and returns a single response, with the same
bearer-token auth as the rest of `/v1`. Use this when the MCP client lives on a different
machine from the deployment.

```bash theme={null}
curl -sS -X POST -H "Authorization: Bearer $KEY" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' \
  https://mail.example.com/v1/mcp | jq '.result.tools[].name'
```

The tool context carries tenant identity, so a multi-tenant deployment scopes calls correctly.

## Tools

**26 marketing tools** cover profiles, lists, segments, templates, campaigns, flows,
suppressions, events, webhooks, and the activity log — `upsert_profile`, `add_to_list`,
`preview_segment`, `create_campaign`, `send_campaign`, `get_campaign_stats`,
`get_campaign_timeseries`, `suppress_email`, `track_event`, and more.

A further set of **conversation tools** covers the agent inbox — see
[Conversations](/stateset-mail/conversations#mcp-tools).

<Tip>
  The same 14-function marketing surface is also available as plain OpenAI- and
  Anthropic-format tool schemas at `GET /v1/tools`, if you'd rather wire it into an agent
  directly than go through MCP.
</Tip>

## Resources

`resources/list` enumerates recently-touched entities; `resources/read` returns the full JSON
body for one. Resources let a model read state **without burning a tool call**, and clients
render them in a panel so you can attach an entity to a chat with one click.

| URI                | What it returns                                  |
| ------------------ | ------------------------------------------------ |
| `profile://EMAIL`  | The full profile — consent, properties, timezone |
| `list://UUID`      | List metadata plus up to 200 member previews     |
| `list://name/NAME` | The same, looked up by list name                 |
| `segment://UUID`   | Definition, evaluated count, and a sample        |
| `template://UUID`  | Subject, HTML, text, and MJML source if any      |
| `campaign://UUID`  | Campaign plus live stats                         |

## Prompts

`prompts/list` advertises server-provided playbooks; `prompts/get` renders the body with the
caller's arguments substituted in. Each names the tools to call and the order to call them, so
picking a prompt is a one-shot way to trigger a multi-step workflow.

| Name                         | Arguments                             |
| ---------------------------- | ------------------------------------- |
| `draft_welcome_campaign`     | `list_name` (required), `brand_voice` |
| `analyze_campaign`           | `campaign_id` (required)              |
| `propose_engagement_segment` | `kind` (required), `window_days`      |
| `audit_suppressions`         | —                                     |
| `design_reengagement_flow`   | —                                     |
| `triage_inbox`               | —                                     |

## Related

* [Overview](/stateset-mail/overview)
* [Conversations](/stateset-mail/conversations)
* [MCP Integration Guide](/guides/mcp-integration-guide)
