Docs / MCP server

MCP Server

Drop one config block into Claude Code or Cursor. 18 typed tools become first-class agent capabilities. No glue code, no prompt hacks, full Zod validation.

What is MCP?

The Model Context Protocol is an open standard from Anthropic for connecting AI assistants to data sources and tools. Servers expose resources (read-only data) and tools (actions). Hosts (Claude Code, Cursor, Continue, Zed, etc.) consume them.

Mailgrid speaks MCP 2024-11-05 over JSON-RPC 2.0 transported as HTTP POST.

Endpoint

POST /api/mcp

Authentication: same Bearer token as REST. Token scope agents:dispatch (or admin) required.

Client configuration

Claude Code (Desktop)

Edit ~/.claude/claude_desktop_config.json:

claude_desktop_config.json
{
  "mcpServers": {
    "mailgrid": {
      "url": "https://api.mailgrid.space/api/mcp",
      "headers": {
        "Authorization": "Bearer mb_live_..."
      }
    }
  }
}

Restart Claude. The 18 tools will appear in the "mailgrid" namespace.

Cursor

Create .cursor/mcp.json at the project root with the same shape. Cursor picks it up automatically on next AI invocation.

Continue / Zed / generic MCP host

Any MCP-over-HTTP client that supports custom headers works. The bearer token is the same Mailgrid API key — issue a narrow-scope key (agents:dispatch only) for safer agent use.

All 18 tools, with full schemas

send_email

Single transactional send. Mirrors POST /api/emails exactly.

schema
{
  "from": "string (email)",
  "to":   "string | string[]",
  "subject": "string",
  "html": "string?",
  "text": "string?",
  "templateId": "string?",
  "variables": "object?",
  "streamId": "string?",
  "trackOpens": "boolean?",
  "trackClicks": "boolean?",
  "attachments": "array?"
}

send_batch

Up to 100 messages in one call. Accepts { emails: SendEmailRequest[] }.

create_template

Persist a Handlebars template. Accepts { name, subject, html, text?, description? }.

get_template

Fetch by id or name. Accepts { id: string }.

generate_template

AI-generate. Accepts { prompt, audience?, tone?, voiceExamples? }. Returns subject, html, text, and detected variables.

verify_domain

Provisions SES identity + Easy DKIM. Idempotent. Accepts { domain: string }. Returns DKIM tokens + DNS records to add.

get_domain

Current verification + DKIM/SPF/DMARC validation state. Accepts { domain: string }.

analyze_deliverability

Computes a 0-100 score from recent bounce/complaint rates + DNS auth state, plus prioritized recommendations.

get_event_log

Cursor-paginated event stream. Accepts filters: type, email, messageId, since, limit, cursor.

suppress_email

Add an address to the suppression list. Accepts { email, reason: "bounce" | "complaint" | "manual" | "unsubscribe" }.

unsuppress_email

Remove from suppression list. Accepts { email: string }.

summarize

Summarize an email body. Accepts { html?, text? }. Returns { summary, tldr }.

ask_ai

NL query over the tenant's event data + knowledge base. Accepts { question, contextDays? }.

auto_label

Run rules + AI fallback on a message. Accepts { emailId: string }.

smart_send_at

Returns the optimal next send time from historical open patterns. No input.

create_stream

Create a stream. Accepts { name, type?, description?, defaultFrom?, configSet?, ipPool? }.

list_streams

List all tenant streams. No input.

upload_file

File Cache upload. Accepts { filename, content (base64), contentType?, expiresAt? }.

list_files

List uploaded files. No input.

invite_user

Invite a team member. Accepts { email, role? }. Returns the invite token to share with the invitee.

list_users

List all team members (active + invited + suspended). No input.

register_dedicated_ip

Register a dedicated SES IP for the tenant. Accepts { ipAddress, poolName, configSet? }.

Tool dispatch — what happens inside

  1. Host sends JSON-RPC: { method: "tools/call", params: { name: "send_email", arguments: {...} } }.
  2. Mailgrid Worker receives at /api/mcp.
  3. Auth middleware verifies Bearer token.
  4. Dispatcher (src/agents/handlers.ts) looks up the tool registry.
  5. Arguments validated against the same Zod schema used by REST.
  6. Domain function called (same code path as the REST handler).
  7. Result wrapped as { content: [{ type: "text", text: JSON.stringify(result) }] } per MCP spec.
Single source of truth

The Zod schemas live in src/types.ts. REST routes, MCP tools, and the OpenAPI spec all consume them. There's exactly one definition of "what's a valid SendEmailRequest" across the entire codebase.

Example end-to-end agent task

Prompt: "Send the welcome email to all contacts in our beta-signups list, using our friendly voice."

  1. Agent calls list_streams → picks transactional-prod.
  2. Agent calls get_template name="welcome" → if missing, calls generate_template with voiceExamples.
  3. Agent queries GET /api/lists/beta-signups/members (or uses an MCP list tool when shipped).
  4. Agent calls send_batch with rendered messages, scoped to the chosen stream.
  5. Agent calls get_event_log type="bounced" 24h later to triage failures.

Security model

Versioning

Mailgrid follows MCP 2024-11-05. When the MCP spec advances to a new version, we maintain backward compatibility on the existing endpoint for at least 12 months and announce the deprecation timeline in the changelog.