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
Authentication: same Bearer token as REST. Token scope agents:dispatch (or admin) required.
Client configuration
Claude Code (Desktop)
Edit ~/.claude/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.
{
"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
- Host sends JSON-RPC:
{ method: "tools/call", params: { name: "send_email", arguments: {...} } }. - Mailgrid Worker receives at
/api/mcp. - Auth middleware verifies Bearer token.
- Dispatcher (
src/agents/handlers.ts) looks up the tool registry. - Arguments validated against the same Zod schema used by REST.
- Domain function called (same code path as the REST handler).
- Result wrapped as
{ content: [{ type: "text", text: JSON.stringify(result) }] }per MCP spec.
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."
- Agent calls
list_streams→ pickstransactional-prod. - Agent calls
get_template name="welcome"→ if missing, callsgenerate_templatewith voiceExamples. - Agent queries
GET /api/lists/beta-signups/members(or uses an MCP list tool when shipped). - Agent calls
send_batchwith rendered messages, scoped to the chosen stream. - Agent calls
get_event_log type="bounced"24h later to triage failures.
Security model
- API key scope: issue a key with only
agents:dispatchif you want the agent unable to touch other endpoints directly. - Per-tool host approval: MCP hosts can prompt the user before each tool call. Use this for destructive tools (
send_batch,suppress_email). - No code execution: tool arguments are typed JSON. There's no way for an agent to inject arbitrary code into Mailgrid via MCP.
- Audit trail: every MCP call appears in
audit_logswithactorset to the API key id.
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.