Give Claude, Cursor or any other Model Context Protocol client the PostStack API as 117 tools, 5 guided prompts and 5 readable resources, either from the hosted endpoint or from a local process.
The Model Context Protocol lets an AI client call tools a server exposes. PostStack's server wraps the same REST API the TypeScript SDK calls: every tool call becomes one or more ordinary API requests made with your API key, so the same permissions, rate limits, suppression checks and sending rules apply as if your own code had made them.
Hosted
Local (stdio)
Endpoint
https://api.poststack.dev/mcp
npx -y @poststack.dev/mcp
Transport
Streamable HTTP
stdio
Install
Nothing
Node.js with npx
Auth
API key in Authorization: Bearer
POSTSTACK_API_KEY environment variable
Usage analytics
Recorded in the dashboard
Not recorded
Both serve the identical set of tools, prompts and resources. Create the key under API keys in the dashboard, and read Permissions before choosing its permission level.
Point any MCP client that speaks Streamable HTTP and lets you set a request header at https://api.poststack.dev/mcp, with the header Authorization: Bearer sk_live_…. The server is stateless: each request builds a fresh server, so there is no session to keep alive or resume. In Claude Code:
Requests to the endpoint are limited per API key: 120 a minute on paid plans, 60 on the Free plan, on top of the limits of the API endpoints each tool calls. The current ceiling is in the X-RateLimit-Limit response header. Responses also carry X-Poststack-Mcp: v1.
Claude Desktop reads ~/Library/Application Support/Claude/claude_desktop_config.json on macOS and %APPDATA%\Claude\claude_desktop_config.json on Windows. Cursor reads ~/.cursor/mcp.json, or .cursor/mcp.json in a project.
Restart the client
Claude Desktop and Cursor read the file at startup. Once connected the client lists the PostStack tools; ask it to “list my sending domains” to confirm the key works.
npx @poststack.dev/mcp --print-config <target> prints a snippet for claude-desktop, cursor or claude-code, filled with POSTSTACK_API_KEY if it is set. The claude-desktop and cursor output is the whole file shown above, ready to save; the claude-code output is the claude mcp add command.
POSTSTACK_API_KEYstringrequired
The key every tool call authenticates with. Without it the process prints POSTSTACK_API_KEY environment variable is required and exits with status 1.
117 tools in 16 groups. Arguments marked ? are optional; the client shows the agent each argument's type and description. Every tool returns a short text summary plus the data as structuredContent. When the API rejects a call the tool returns isError: true with structuredContent of { statusCode, code } and the API's error message, so the agent can tell a validation error from a missing permission.
Edit a draft broadcast in place. Only draft broadcasts can be updated.
send_broadcast
id
Dispatch a draft broadcast to its segment immediately.
resend_broadcast
id, target?, subject?
Resend a sent broadcast to the subset that didn't open or didn't click — a fresh broadcast is created targeting an auto-built segment of those recipients.
cancel_broadcast
id
Cancel a queued or sending broadcast.
broadcast_performance
broadcast_id?, since?, best_metric?, limit?
Get broadcast performance — either for one broadcast (variant breakdown if A/B) or for a leaderboard ranked by a chosen metric.
find_non_clickers
broadcast_id, limit?
List contacts who received a broadcast but did NOT click any tracked link in it.
Workflows
Tool
Arguments
What it does
list_workflows
none
List all workflows (event-triggered automation pipelines) defined for this team.
get_workflow
id
Get a workflow's metadata and its graph (nodes + edges).
create_workflow
name, trigger_type, trigger_config?
Create a draft workflow. Its graph starts with a single trigger node.
update_workflow
id, name?, trigger_type?, trigger_config?
Update a workflow's name, trigger type, or trigger config.
delete_workflow
id
Permanently delete a draft or paused workflow, its graph and its run history. Runs still in progress are deleted with it.
add_workflow_node
id, type, config, after_node?
Add a node to a workflow's graph and (by default) wire it after an existing node.
connect_workflow_nodes
id, from, to, branch?
Add an edge between two nodes.
update_workflow_node
id, node_id, config
Replace a node's config. Cannot change its type or edges (use connect_workflow_nodes / remove_workflow_node).
remove_workflow_node
id, node_id
Remove a node and every edge touching it.
activate_workflow
id
Move a workflow from draft/paused to active so new trigger events start runs.
pause_workflow
id
Pause an active workflow so new trigger events DO NOT start runs. In-flight runs continue to completion.
trigger_workflow
id, contact_id
Start a run for one contact. Only for an active workflow whose trigger_type is manual; anything else fails with 422.
post_workflow_event
event, contact_id?, email?
Post an application-defined event, enrolling a contact into every ACTIVE workflow whose trigger is "custom" with a matching event name.
Signup forms
Tool
Arguments
What it does
list_signup_forms
page?, per_page?
List embeddable signup forms.
get_signup_form
id
Get full details of a signup form including its fields, target segment, and submission count.
Send a reply to an inbound email (subject and threading headers are set automatically).
forward_inbound_email
id, from, to, cc?, bcc?, message?
Forward an inbound email to other recipients with an optional cover note.
draft_from_thread
inbound_id, tone?
Build a reply-draft skeleton for an inbound email — proper threading, quoted original, salutation/sign-off, suggested from + subject. The agent writes the body.
Webhooks
Tool
Arguments
What it does
create_webhook
url, events
Subscribe a URL to receive event notifications via signed POST requests.
list_webhooks
none
List configured webhook endpoints.
get_webhook
id
Get a webhook's details.
update_webhook
id, url?, events?, enabled?
Edit a webhook's URL, event list, or enabled state.
delete_webhook
id
Permanently delete a webhook endpoint.
test_webhook
id
Send a test event to a webhook's URL to verify it's reachable and the signature verifies.
get_webhook_deliveries
id, page?, per_page?
List recent delivery attempts for a webhook (status, response code, timestamps).
replay_webhook_delivery
id, delivery_id
Re-deliver a single past webhook delivery (e.g. one that failed because the endpoint was down).
batch_replay_webhook_deliveries
id, within_minutes?, event_type?, limit?
Re-deliver EVERY failed delivery for a webhook, oldest first.
rotate_webhook_secret
id, graceHours?
Rotate a webhook's signing secret, keeping the old one valid for a grace window. The new secret is returned ONCE here.
Suppressions
Tool
Arguments
What it does
list_suppressions
page?, per_page?
List suppressed addresses (PostStack will not send to them).
add_suppression
email, reason?
Suppress an address so future sends to it are skipped. reason defaults to manual.
remove_suppression
email
Remove an address from the suppression list (sends will resume).
API keys
Tool
Arguments
What it does
create_api_key
name, permission, mode?, domain_id?
Generate a new PostStack API key. The full key is returned ONCE in this response and cannot be retrieved again.
list_api_keys
none
List every API key (not paginated; only the prefix is returned, never the full secret).
get_api_key
id
Get an API key's metadata (the secret is never returned after creation).
revoke_api_key
id
Permanently revoke an API key — all subsequent requests using it will fail.
rotate_api_key
id
Rotate an API key: issue a new secret and invalidate the old one. The new full key is returned ONCE in this response and cannot be retrieved again.
Prompts are playbooks the client offers you by name (in Claude, from the prompt picker). Each tells the agent which tools to call in which order. tone is formal, friendly or casual and defaults to friendly.
Prompt
Arguments
What the agent does
draft_welcome_email
contact_email, tone?, template_hint?
Looks the contact up, picks a published welcome template, renders it, lints it, and sends only if the preview passes.
reengage_dormant
segment_id?, days_dormant?, tone?
Sizes the audience of contacts inactive for days_dormant days (default 90), picks a template and stages a broadcast for you to review.
followup_non_clickers
broadcast_id?, since?, tone?
Takes the given broadcast, or the best by click rate since the cutoff (default 30 days ago), pulls the recipients who did not click, and drafts a follow-up.
summarize_campaign
broadcast_id
A short performance report: headline metrics, the A/B winner if there was a test, and a one-line recommendation.
triage_inbound
inbound_id, tone?
Reads an inbound email, classifies it (support, sales, billing, spam, other), looks up the sender and proposes the next action, with a reply skeleton when one fits.
Every tool call made through the hosted endpoint is recorded and shown on the MCP analytics page of the dashboard: total calls, error rate, p50 and p95 latency, top tools, hourly activity and recent errors, over the last 24 hours, 7 days or 30 days. Calls made through the local stdio server are not recorded.
Each record holds the tool name, duration, success or failure, error code, transport and the API key used, plus a hash of the arguments used to group identical calls. The arguments themselves are never stored. The hash is not cryptographic, so do not rely on it to hide low-entropy values such as an email address. Records older than 30 days are deleted.
For the local server, run POSTSTACK_API_KEY=sk_live_... npx -y @poststack.dev/mcp in a terminal: it should start and wait silently. If it prints POSTSTACK_API_KEY environment variable is required, the env block in your config is missing or misspelled. Restart the client after editing its config.
Every call fails with 401
The key is missing, revoked or mistyped. For the hosted server, check the header is Authorization: Bearer sk_… with a single space and no quotes around the key.
A tool fails with 403 insufficient_scope
The key is a sending_access key and the tool needs more. Use a full_access key for an agent that manages domains, contacts or templates.
Calls fail with 429
The agent is calling faster than the rate limit allows (120 requests a minute to the hosted endpoint on paid plans, 60 on Free, plus each API endpoint's own limit). The error reaches the agent as a tool error; ask it to slow down or batch, e.g. send_batch_emails instead of many send_email calls.