@mailtarget/mcp
v0.1.0
Published
Headless CLI + MCP server for the Mailtarget Open API (api.mailtarget.co) and Transmission API
Maintainers
Readme
mailtarget
Headless CLI + MCP server for Mailtarget. Spec-driven: wraps the live production surface of api.mailtarget.co without hardcoding each endpoint, plus the Transmission API (transmission.mailtarget.co) for sending. Source of truth = bundled openapi.yaml, mirroring what's actually deployed in prod (run mailtarget info for the current operation count/tags).
Auth
Two hosts, two separate keys — set both:
export MAILTARGET_API_KEY=... # Transmission key
export MT_OPEN_API_SECRET_KEY=... # Open API key (from the dashboard)MAILTARGET_API_KEY— Transmission key. Used fortransmission.mailtarget.co(thesend/mailtarget_send_emailpath) directly.MT_OPEN_API_SECRET_KEY— Open API key. Used as Bearer auth for everything onapi.mailtarget.co(templates, domains, contacts, ...;call/mailtarget_call_endpoint,describe,list).
One exception: openapi.yaml's own POST /transmissions operation (operationId post_transmissions) is a gateway that forwards to the Transmission upstream — calling it via call/mailtarget_call_endpoint needs MT_OPEN_API_SECRET_KEY for the request itself and MAILTARGET_API_KEY, which is auto-injected into the request body as apiKey (you don't need to pass it yourself).
There's no fallback between the two — a transmission-only key returns 401 against the Open API and vice versa, so both must be set for full functionality.
Base URLs
The Open API base URL defaults to openapi.yaml's first servers entry. To point at a different environment (e.g. staging) without touching openapi.yaml, set:
export MAILTARGET_OPEN_API_URL=https://openapi.lab.mailtarget.dev/v1Similarly, the Transmission API base URL can be overridden with MAILTARGET_TRANSMISSION_URL (defaults to https://transmission.mailtarget.co/v1/layang/transmissions).
CLI
mailtarget info # spec summary + tags
mailtarget list --tag Contacts # endpoints in a tag
mailtarget list --search template
mailtarget describe <operationId> # params + body shape
mailtarget call <operationId> -q page=1 perPage=10
mailtarget call <operationId> -p id=123 -b '{"name":"x"}'
mailtarget api GET /v1/template # raw escape hatch
# convenience: send transactional email (Transmission API)
mailtarget send --from [email protected] --to [email protected] \
--subject "Hello" --text "Hello"
mailtarget send --json @payload.json # full Transmission payload
# convenience: sending domains (Domain Auth)
mailtarget domain list
mailtarget domain dns <id> # DNS records to publish
mailtarget domain verify <id> # trigger verificationBefore publish, run via node src/cli.mjs ... or npm link.
MCP server
Stdio MCP exposing 4 tools (small surface, full coverage):
mailtarget_list_endpoints— discover endpoints (filter by tag/search)mailtarget_describe_endpoint— params + body shape for one endpointmailtarget_call_endpoint— execute against the live management APImailtarget_send_email— send transactional email (Transmission API)
Register in Claude Code / any MCP client:
{
"mcpServers": {
"mailtarget": {
"command": "node",
"args": ["/path/to/mailtarget-headless/src/mcp.mjs"],
"env": { "MAILTARGET_API_KEY": "...", "MT_OPEN_API_SECRET_KEY": "..." }
}
}
}Library
import { sendTransmission, callOperation, listOperations } from "mailtarget";TypeScript declarations ship in types/core.d.mts (payload shapes for the Transmission API included).
Development
Runtime is plain .mjs — no build step needed to run the CLI/MCP server. Types are authored as JSDoc directly in src/core.mjs and checked/generated via TypeScript:
npm run typecheck # tsc --noEmit — type-check src/*.mjs
npm run gen-types # tsc — (re)generate types/core.d.mtsgen-types runs automatically before npm publish (prepublishOnly), so shipped types can't go stale.
Scope (v1)
Wraps the current production surface as bundled in openapi.yaml as-is. Mutating calls hit the live account, use with care.
