@create-send/mcp
v1.1.0
Published
Model Context Protocol server for the Campaign Monitor API.
Readme
createsend-mcp
A Model Context Protocol server that exposes every Campaign Monitor API operation (113 tools) over stdio. The tool table is generated from the Campaign Monitor OpenAPI spec; each tool is dispatched straight to the API over HTTP, so the server is self-contained with no SDK dependency.
Package managers
Examples below use npm. For pnpm or Yarn, swap commands as follows:
| Task | npm | pnpm | Yarn |
| --- | --- | --- | --- |
| Install dependencies | npm install | pnpm install | yarn |
| Run a package script | npm run <name> | pnpm <name> | yarn <name> |
| One-off run (no install) | npx @create-send/mcp | pnpm dlx @create-send/mcp | yarn dlx @create-send/mcp |
Run
CREATESEND_API_KEY=... npx @create-send/mcp…or from source:
npm install
npm run generate
npm run mcpWire it into Claude Desktop
~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"createsend": {
"command": "npx",
"args": ["-y", "@create-send/mcp"],
"env": { "CREATESEND_API_KEY": "your-key" }
}
}
}For pnpm or Yarn, set "command" to "pnpm" / "yarn" and "args" to
["dlx", "@create-send/mcp"], keeping the same env.
Tool naming and inputs
Tool names match the spec's operationIds (e.g. getCampaignOpens, getListStats,
addSubscribersConsentToTrack). Inputs follow the same shape across every tool:
- path params at the top level (e.g.
id,listId), - query string parameters under
query, - request body under
body.
So a call to getCampaignOpens looks like:
{
"id": "CAMPAIGN_ID",
"query": { "date": "2026-01-01", "page": 1, "pageSize": 1000 }
}On success the tool returns the API response body as text. API errors come back
as the error payload with isError: true (the constructor still throws if the
API key is missing).
Built-in guidance
The server ships guidance so any client can use it well without prior knowledge:
- Instructions — sent on connect and surfaced to the model automatically: tool shape, API-key/client scope, and the rules for getting HTML email in.
- Prompt
import-html-email— a step-by-step for turning HTML email into a template + campaign and sending it (clients surface prompts as commands). - Resource
createsend://guides/html-email— a reference covering hosting, template validation errors, the create-then-send flow, key scope, and personalization.
These live in src/guidance.ts and are not regenerated by npm run generate.
import_html_template
A composite tool that creates a template from raw HTML without you wiring up hosting: it validates CM's template rules, exposes the HTML + images on a temporary public URL (a tunnel CLI on PATH — cloudflared, ngrok, or lt — or your own publicUrlBase), calls createTemplate, and tears the tunnel down. No tunnel dependency is bundled; it shells out to whatever you have. Works on local (stdio) deployments only (it reads your local files). It does not send — create and send the campaign separately.
// arguments
{
"clientId": "...",
"name": "Spring sale",
"html": "/abs/path/email.html", // or the HTML string itself
"images": [{ "path": "/abs/hero.jpg", "as": "assets/hero.jpg" }],
"tunnel": "auto" // auto | cloudflared | ngrok | lt
}Embedding the server in your own process
import { createServer } from '@create-send/mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = createServer({ apiKey: process.env.CREATESEND_API_KEY });
await server.connect(new StdioServerTransport());Regenerating from the OpenAPI spec
The tool table in src/tools.generated.ts is generated from
spec/createsend-openapi.yaml:
npm run generateTo update for a new spec version, replace spec/createsend-openapi.yaml and
re-run the script. src/tools.generated.ts is overwritten; the hand-written
src/client.ts, src/server.ts, and src/index.ts are not.
Build
npm install
npm run generate
npm run typecheck
npm run build