WarmySender MCP Server

Run email warmup, mailbox health, deliverability, campaign analytics, and management of contacts you already have from Claude, ChatGPT, Cursor, Codex, OpenClaw or Hermes Agent, or any agent that speaks the Model Context Protocol, including Claude Desktop, Claude Code, Grok Bot, Windsurf and Zed. The scheduler paces every action. The agent never sends a message itself and cannot raise a limit.

What this is

WarmySender publishes a public Model Context Protocol server so a compatible AI client can check email warmup, mailbox health and deliverability, read campaign analytics, and manage contacts you already have. Point Claude, ChatGPT, Cursor, Codex, OpenClaw, and Hermes Agent, or any other MCP 2025-11 Streamable HTTP client, at https://warmysender.com/mcp and sign in, or use a Bearer API key. The protocol is the Model Context Protocol.

Full-surface tools for clients other than ChatGPT

Clients other than ChatGPT can also create and launch campaigns (cold email, LinkedIn, Instagram, WhatsApp, and multichannel), search leads, and verify addresses. The full catalog is 80 tools. Those tools are only available to clients other than ChatGPT. The scheduler always paces every action. The agent never sends a message, invite or DM directly and cannot raise a limit. Creating or launching a campaign only writes it and hands it to the scheduler.

Can Claude send cold emails for me?

Yes — Claude (or ChatGPT, Cursor, Codex, OpenClaw, Hermes Agent) can build, launch and manage your cold email, LinkedIn, Instagram and WhatsApp campaigns in WarmySender. It never sends a message itself: it writes the campaign and hands it to WarmySender's scheduler, which paces every send inside safe limits, and it can never raise a limit.

Why connect your AI assistant?

Ask your assistant questions like:

Every action runs through the same scheduler-first path as the web UI. Rate limits, warmup ramps, LinkedIn daily/weekly caps, and domain-level protections all apply identically. MCP is a protocol adapter, not a parallel implementation.

Quick start in 3 steps

  1. Pick sign-in or an API key. Sign in is the default and needs no key: your agent opens a WarmySender screen and you approve access. Prefer a key? In WarmySender, go to Settings → API Keys, click Create, and pick the scopes you want to expose. Available scopes are campaigns:read, campaigns:write, prospects:read, prospects:write, mailboxes:read, warmup:read, warmup:write, linkedin:read, linkedin:write, enrollments:write, suppressions:read, suppressions:write, and jobs:read. Save the key value — you'll only see it once.
  2. Add WarmySender to your agent. Pick your AI client below. Cursor is one click, Claude is one button, the rest is one command or one paste. In API-key mode, replace ws_YOUR_API_KEY_HERE with your real key.
  3. Ask your assistant to use WarmySender. Try “List my campaigns” or “What's my LinkedIn account health?” — the client discovers MCP tools automatically.

Connect your agent

Server URL: https://warmysender.com/mcp. Transport: Streamable HTTP (MCP spec 2025-11-25). Sign in with your WarmySender account (default) or switch to an API key — in API-key mode replace ws_YOUR_API_KEY_HERE with your key.

Claude

Claude on the web and the desktop app. Add WarmySender as a connector and sign in.

Sign in with WarmySender (no API key)

In Claude open Customize → Connectors, choose + then Add custom connector, paste this address and click Add. Claude then opens a WarmySender sign-in — approve it and you are connected.

https://warmysender.com/mcp

Use an API key

Paste into your claude_desktop_config.json and restart Claude Desktop. File: claude_desktop_config.json. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "mcpServers": {
    "warmysender": {
      "command": "npx",
      "args": [
        "-y",
        "@warmysender/mcp",
        "--api-key=ws_YOUR_API_KEY_HERE"
      ]
    }
  }
}

ChatGPT

Run WarmySender from Codex, included with ChatGPT Plus and up.

Sign in with WarmySender (no API key)

ChatGPT Work, Business and Enterprise/Edu: turn on developer mode, add this server address, and sign in — ChatGPT uses its own hosted callback, so you never paste a key into the chat. Codex inside ChatGPT Work has no local terminal and cannot finish that sign-in. ChatGPT Plus: run both lines in a local terminal; the second opens your browser.

codex mcp add warmysender --url https://warmysender.com/mcp
codex mcp login warmysender

Use an API key

ChatGPT Plus and every plan above it include Codex. Run both lines, adding the export to your shell profile so it sticks. Replace ws_YOUR_API_KEY_HERE with your key.

export WARMYSENDER_API_KEY=ws_YOUR_API_KEY_HERE
codex mcp add warmysender --url https://warmysender.com/mcp --bearer-token-env-var WARMYSENDER_API_KEY

Claude Code

One terminal command, then sign in.

Sign in with WarmySender (no API key)

Run this once in your terminal, then type /mcp inside Claude Code (or run claude mcp login warmysender) and sign in to WarmySender in the browser.

claude mcp add --transport http warmysender https://warmysender.com/mcp

Use an API key

Run this once in your terminal. Replace ws_YOUR_API_KEY_HERE with your key.

claude mcp add --transport http warmysender https://warmysender.com/mcp --header "Authorization: Bearer ws_YOUR_API_KEY_HERE"

Cursor

One click from your browser, or paste into .cursor/mcp.json.

Sign in with WarmySender (no API key)

Use the Add to Cursor button, or paste this into .cursor/mcp.json in your project root and sign in when Cursor asks. File: .cursor/mcp.json.

{
  "mcpServers": {
    "warmysender": {
      "url": "https://warmysender.com/mcp"
    }
  }
}

Use an API key

Use the Add to Cursor button, or paste this into .cursor/mcp.json in your project root. File: .cursor/mcp.json. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "mcpServers": {
    "warmysender": {
      "url": "https://warmysender.com/mcp",
      "headers": {
        "Authorization": "Bearer ws_YOUR_API_KEY_HERE"
      }
    }
  }
}

Codex

OpenAI's coding agent. One command, then sign in.

Sign in with WarmySender (no API key)

Run both lines in your terminal; the second opens your browser to sign in to WarmySender.

codex mcp add warmysender --url https://warmysender.com/mcp
codex mcp login warmysender

Use an API key

Run both lines, adding the export to your shell profile so it sticks. Replace ws_YOUR_API_KEY_HERE with your key.

export WARMYSENDER_API_KEY=ws_YOUR_API_KEY_HERE
codex mcp add warmysender --url https://warmysender.com/mcp --bearer-token-env-var WARMYSENDER_API_KEY

OpenClaw

The lobster-powered AI agent. Two CLI commands, then sign in.

Sign in with WarmySender (no API key)

Run both lines; the second opens a WarmySender sign-in in your browser. OpenClaw ignores static headers while sign-in is on, so no key is ever stored.

openclaw mcp add warmysender --url https://warmysender.com/mcp --transport streamable-http --auth oauth
openclaw mcp login warmysender

Use an API key

Run this once to register WarmySender. OpenClaw can then call any of WarmySender's 80 tools. Replace ws_YOUR_API_KEY_HERE with your key.

openclaw mcp set warmysender '{"url":"https://warmysender.com/mcp","headers":{"Authorization":"Bearer ws_YOUR_API_KEY_HERE"}}'

Hermes Agent

Add WarmySender to your Hermes config and reload.

Sign in with WarmySender (no API key)

Add this to ~/.hermes/config.yaml, then run /reload-mcp in the chat and sign in when prompted. File: ~/.hermes/config.yaml.

mcp_servers:
  warmysender:
    url: "https://warmysender.com/mcp"
    auth: oauth

Use an API key

Add this to ~/.hermes/config.yaml, then run /reload-mcp in the chat. File: ~/.hermes/config.yaml. Replace ws_YOUR_API_KEY_HERE with your key.

mcp_servers:
  warmysender:
    url: "https://warmysender.com/mcp"
    headers:
      Authorization: "Bearer ws_YOUR_API_KEY_HERE"

Muse Code

Meta's terminal coding agent. Add WarmySender to its settings file.

Muse Code connects with an API key.

Use an API key

Save this as ~/.config/muse/settings.json (create the folder if it is not there yet) and start Muse Code again. Keep the schema_version line — Muse Code rejects the file without it. If you already have a settings file, add only the warmysender block inside your existing mcp_servers. File: ~/.config/muse/settings.json. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "schema_version": 1,
  "mcp_servers": {
    "warmysender": {
      "transport": "streamable_http",
      "url": "https://warmysender.com/mcp",
      "headers": {
        "Authorization": "Bearer ws_YOUR_API_KEY_HERE"
      }
    }
  }
}

Grok Bot

xAI's AI teammate. Add WarmySender as a custom connector.

Grok Bot connects with an API key.

Use an API key

Open grok.com/connectors → New Connector → Custom, paste the server address and use your key as the bearer token. Type @ in a chat to attach WarmySender. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "name": "warmysender",
  "url": "https://warmysender.com/mcp",
  "headers": {
    "Authorization": "Bearer ws_YOUR_API_KEY_HERE"
  }
}

Windsurf

Connect Windsurf to your workspace.

Sign in with WarmySender (no API key)

Paste into ~/.codeium/windsurf/mcp_config.json and sign in when Windsurf asks. File: ~/.codeium/windsurf/mcp_config.json.

{
  "mcpServers": {
    "warmysender": {
      "serverUrl": "https://warmysender.com/mcp"
    }
  }
}

Use an API key

Paste into ~/.codeium/windsurf/mcp_config.json. File: ~/.codeium/windsurf/mcp_config.json. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "mcpServers": {
    "warmysender": {
      "serverUrl": "https://warmysender.com/mcp",
      "headers": {
        "Authorization": "Bearer ws_YOUR_API_KEY_HERE"
      }
    }
  }
}

Zed

Add to Zed's context_servers.

Zed connects with an API key.

Use an API key

Add to your Zed settings.json under context_servers. File: settings.json. Replace ws_YOUR_API_KEY_HERE with your key.

{
  "context_servers": {
    "warmysender": {
      "command": {
        "path": "npx",
        "args": [
          "-y",
          "@warmysender/mcp",
          "--api-key=ws_YOUR_API_KEY_HERE"
        ]
      }
    }
  }
}

No settings screen? Paste this into your agent

Any agent that can add an MCP server from a chat message sets itself up from this paragraph — sign-in only, never a key.

Connect to WarmySender: it is an MCP server at https://warmysender.com/mcp that uses OAuth sign-in (no API key needed). Add it as a streamable-HTTP MCP server, open the sign-in link it returns so I can approve access, then install the WarmySender skill from https://github.com/fortuneflick/warmysender-claude-plugin (`npx skills add fortuneflick/warmysender-claude-plugin`). Never send a message yourself — WarmySender's scheduler paces every email, LinkedIn, Instagram and WhatsApp action inside safe limits.

Your agent never sends a message itself and can never raise a limit — WarmySender's scheduler paces every email, LinkedIn, Instagram and WhatsApp action inside safe limits. Connecting or disconnecting accounts stays in the app.

Available tools

MCP tools are gated by the scopes on your API key. If a call returns insufficient_scope, add the missing scope in Settings → API Keys and create a new key. Every write tool accepts an optional idempotency_key argument so retries are safe. Destructive tools (pause_*, unenroll_*, add_to_suppression_list) set destructiveHint: true so MCP clients prompt the user for confirmation before calling.

Read tools

Query workspace state without side effects. Safe for LLMs to call freely. All tools are workspace-scoped — your key only sees data from its own workspace.

Rate limit: From 60 / min on Pro — scales with your plan

Tool Description Required scopes
list_campaigns List email campaigns, optionally filtered by status. Cursor-paginated. campaigns:read
get_campaign Fetch a single campaign with full step definitions, pacing config, and stats. campaigns:read
preview_campaign_emails Every contact's emails rendered exactly as they'll be sent (subject + body, per step) — read-only, for checking personalization before launch. campaigns:read
list_prospects List prospects in the workspace, with filters for status, list membership, and any field — job title, company, country, city or your own CSV columns. prospects:read
get_prospect Fetch a single prospect with history, custom fields, and enrollment state. prospects:read
list_sent_emails Every campaign email sent, one record each: recipient, campaign and step, From address, subject, Message-ID and sent time. Same fields as the email.sent webhook; replies link back through the Message-ID they answered. campaigns:read
list_mailboxes List connected email mailboxes with provider, warmup status, and daily pacing. mailboxes:read
get_mailbox_health Return per-mailbox health: deliverability, warmup score, bounce rate, recent issues. mailboxes:read
get_warmup_stats Warmup performance metrics: inbox placement, spam rescue events, ramp progress. warmup:read
list_linkedin_accounts List connected LinkedIn accounts with seat assignment, ramp stage, and proxy location. linkedin:read
get_linkedin_account_health LinkedIn account health: restriction status, acceptance rate, remaining daily/weekly budgets. linkedin:read
list_linkedin_campaigns List LinkedIn campaigns, optionally filtered by status. linkedin:read
get_linkedin_campaign_stats The numbers the campaign page shows: invites, accepts, people messaged, people who replied, failed and retried-later steps. linkedin:read
list_linkedin_posts List your LinkedIn posts — drafts, scheduled, and published — with engagement counts. linkedin:read
list_linkedin_jobs List your LinkedIn Recruiter job postings (requires a LinkedIn Recruiter seat). linkedin:read
list_linkedin_job_applicants List applicants for one of your LinkedIn Recruiter job postings. linkedin:read
list_whatsapp_accounts List connected WhatsApp numbers with seat assignment, ramp stage, and daily/hourly usage. whatsapp:read
get_whatsapp_account_health WhatsApp number health: restriction status, reply rate, remaining daily/new-chat/hourly budgets. whatsapp:read
list_whatsapp_campaigns List WhatsApp campaigns, optionally filtered by status. whatsapp:read
get_whatsapp_campaign_stats WhatsApp campaign performance: messages sent, new chats, replies — per-step and A/B variant breakdown. whatsapp:read
list_instagram_accounts List connected Instagram accounts with seat assignment, ramp stage, and daily/hourly usage. instagram:read
get_instagram_account_health Instagram account health: restriction status, reply rate, remaining daily/hourly budgets. instagram:read
list_instagram_campaigns List Instagram campaigns, optionally filtered by status. instagram:read
get_instagram_campaign_stats Instagram campaign performance: DMs sent, follows, replies — per-step and A/B variant breakdown. instagram:read
list_suppressions List workspace suppression entries (emails, domains, LinkedIn profiles) with reason and source. suppressions:read
list_skipped_actions Why a campaign sent nothing: today's actions that did not run, grouped by cause, each marked as either a normal wait or something worth a look. campaigns:read
list_email_templates Browse your saved email templates by name, category or subject, so your agent reuses copy you have already tuned. campaigns:read
get_email_template Read one saved template in full — subject, preview text and body — ready to reuse or adapt in a new campaign step. campaigns:read
get_job_status Check the status of an asynchronous job (bulk prospect import, audience enrichment, etc). jobs:read
get_workspace_info Smoke-test tool. Returns workspace ID, plan, active scopes on the current key, and server time. No scope required. (none)

Write tools — email & prospects

Modify email campaigns, prospects, and suppressions. All writes are idempotent when an optional idempotency_key is passed. Destructive tools (pause, archive, unenroll) set destructiveHint so MCP clients prompt the user for confirmation first.

Rate limit: From 15 / min on Pro (bulk 3 / min) — scales with your plan

Tool Description Required scopes
create_prospect Create a single prospect with email, name, company, LinkedIn URL, and custom fields. prospects:write
update_prospect Update an existing prospect. Only provided fields are changed; others are preserved. prospects:write
bulk_create_prospects Create up to 1,000 prospects at once. Returns a job id; poll with get_job_status. prospects:write
create_campaign Create a new email campaign with sequence steps, sending windows, and mailbox rotation config. campaigns:write
update_campaign Update an existing campaign. Cannot edit a running campaign's steps; pause first. campaigns:write
start_campaign Transition a draft or paused campaign to running. Scheduler takes over from here. campaigns:write
pause_campaign Pause a running campaign. In-flight emails complete; no new sends. Destructive hint = true. campaigns:write
resume_campaign Resume a paused campaign. Respects remaining daily/mailbox quota. campaigns:write
enroll_prospects Add prospects to a campaign. Dedupes against existing enrollments and workspace suppression list. enrollments:write
unenroll_prospects Remove prospects from a campaign. Destructive hint = true. enrollments:write
add_to_suppression_list Add an email, domain, or LinkedIn profile to the workspace suppression list. Stops all future sends. suppressions:write
update_workspace_settings Set the postal address printed in your cold email footer, choose how people opt out — an Unsubscribe link, or a reply saying "unsubscribe" — and word that opt-out sentence yourself. A reply asking to opt out is honored automatically either way. campaigns:write

Write tools — LinkedIn, Instagram & warmup

Safety-critical actions. Your agent can create and launch LinkedIn and Instagram campaigns end to end — but these tools NEVER call the underlying social integration send / follow / invite / message / view paths directly. They only touch scheduler entry points (create, launch, pause, resume, enroll); creating or launching a campaign just writes it and hands it to the scheduler — nothing sends in a burst. The scheduler enforces all daily, weekly/hourly, and ramp-schedule limits. MCP CANNOT bypass account safety. Connecting and disconnecting accounts stays in the UI.

Rate limit: LinkedIn & Instagram from 10 / min on Pro (warmup 15 / min) — scales with your plan

Tool Description Required scopes
create_linkedin_campaign Create a LinkedIn campaign with steps, accounts, and pacing. Written as a draft; nothing sends until launched and the scheduler paces it. linkedin:write + campaigns:write
start_linkedin_campaign Launch a draft or paused LinkedIn campaign. Hands it to the scheduler, which paces every invite within daily/weekly caps and the ramp. linkedin:write + campaigns:write
pause_linkedin_campaign Pause a running LinkedIn campaign. Destructive hint = true. linkedin:write + campaigns:write
resume_linkedin_campaign Resume a paused LinkedIn campaign. Scheduler re-checks account health before resuming. linkedin:write + campaigns:write
enroll_in_linkedin_campaign Enroll LinkedIn profile URLs into a campaign. Scheduler handles invite pacing and ramp. linkedin:write + campaigns:write
create_linkedin_post Draft a LinkedIn post, or schedule it for a future time (published automatically at a safe pace, to your profile or a company page). linkedin:write
delete_linkedin_post Delete a draft or scheduled LinkedIn post you haven't published yet. linkedin:write
publish_linkedin_post Publish a LinkedIn post you drafted or scheduled — at a safe pace within your daily posting limit. linkedin:write
create_linkedin_job Create a LinkedIn Recruiter job posting as a draft (requires a LinkedIn Recruiter seat). linkedin:write
publish_linkedin_job Publish a LinkedIn Recruiter job posting (defaults to a free listing, no ad spend). linkedin:write
close_linkedin_job Close a LinkedIn Recruiter job posting so it stops accepting applicants. linkedin:write
create_whatsapp_campaign Create a WhatsApp campaign with steps, numbers, and pacing. Written as a draft; nothing sends until launched and the scheduler paces it. whatsapp:write + campaigns:write
start_whatsapp_campaign Launch a draft or paused WhatsApp campaign. Hands it to the scheduler, which paces every message within daily, new-chat and hourly caps and the ramp. whatsapp:write + campaigns:write
pause_whatsapp_campaign Pause a running WhatsApp campaign. Destructive hint = true. whatsapp:write + campaigns:write
resume_whatsapp_campaign Resume a paused WhatsApp campaign. Scheduler re-checks number health before resuming. whatsapp:write + campaigns:write
enroll_in_whatsapp_campaign Enroll phone numbers into a WhatsApp campaign. Scheduler handles message pacing and ramp. whatsapp:write + campaigns:write
create_instagram_campaign Create an Instagram DM campaign with steps, accounts, and pacing. Written as a draft; nothing sends until launched and the scheduler paces it. instagram:write + campaigns:write
start_instagram_campaign Launch a draft or paused Instagram campaign. Hands it to the scheduler, which paces every DM within daily/hourly caps and the ramp. instagram:write + campaigns:write
pause_instagram_campaign Pause a running Instagram campaign. Destructive hint = true. instagram:write + campaigns:write
resume_instagram_campaign Resume a paused Instagram campaign. Scheduler re-checks account health before resuming. instagram:write + campaigns:write
enroll_in_instagram_campaign Enroll Instagram profile URLs into a campaign. Scheduler handles DM pacing and ramp. instagram:write + campaigns:write
update_warmup_settings Update per-mailbox warmup settings: daily volume, ramp mode, spam rescue toggle, [ref: XXXX] tag (preserved). warmup:write
bulk_update_warmup Update warmup settings across multiple mailboxes at once. Returns a job id. warmup:write

Write & read tools — email verification

Verify email addresses before you send. Verification shares the same allowance, credit balance and safe pacing as the in-app verifier — an agent cannot burst it, and it can check what is left before spending it. Single-address checks return inline; batches return a job id you poll for per-email results.

Rate limit: 20 single checks / min and 5 runs started / min, per workspace — the same ceiling the app enforces, on every plan. Your plan sets how much you can verify, not how fast.

Tool Description Required scopes
verify_email Verify a single email address. Returns deliverability status (valid, invalid, risky, unknown) inline. verification:write
submit_verification_batch Submit a list of email addresses for verification. Returns a job id; poll it with get_verification_result. When it finishes, the campaign-ready addresses are saved as a "- Verified" list unless you pass create_list=false. verification:write
get_verification_result Poll a verification run: overall progress plus per-address results AS THEY ARRIVE — you do not have to wait for the run to finish. Optionally filter to one outcome. verification:read
list_verification_batches List your verification runs, newest first, with status and result counts. Reading costs nothing against your allowance. verification:read
get_verification_allowance Check what is left before you spend it: allowance remaining this month and today, purchased credit balance, and the largest batch accepted. verification:read
cancel_verification_batch Stop a run that is still in progress and return the unused credits. Addresses already checked keep their results. Safe to call twice. verification:write
create_list_from_verification Turn a finished run into a reusable prospect list. Default is confirmed plus catch-all. Pass keep=valid for confirmed-only. Calling it twice with the same keep returns the same list. verification:write

Safety & account protection

WarmySender's MCP server is designed so that a compromised or confused AI cannot burn your sending reputation or ban your LinkedIn accounts. Five guardrails always apply:

  1. Workspace scoping on every call. Your API key resolves to exactly one workspace. Every query is filtered by that workspace id — there is no path to read or mutate another tenant's data.
  2. Scheduler-first execution. LinkedIn invite/message/view calls never happen inline from MCP. The scheduler owns the rate limits, ramp schedule, and per-account safety caps. Enrolling 1,000 prospects at once still sends at the safe rate.
  3. LinkedIn daily/weekly limits & 4-week ramp are non-negotiable. A new account starts at ~10 invites/day and grows over 4 weeks to safe maximums (50 invites/day, 150 messages/day). MCP cannot raise these — account safety always wins over speed.
  4. Per-mailbox sending pacer and warmup [ref: XXXX] tag stay intact. MCP does not expose any tool that modifies or removes the warmup subject-line identifier or bypasses per-mailbox daily caps.
  5. No account connect / disconnect / delete tools. Connecting and disconnecting email or LinkedIn accounts stays in the UI. No delete_campaign, delete_mailbox, or delete_account tools exist in V1 — soft-cancel via pause/archive only.

Read more about the LinkedIn safety model in our LinkedIn Safety FAQ.

Rate limits

Limits are per workspace, in a rolling 60-second window, and separate from your monthly call allowance. Every budget scales with your plan — read down your plan's column. These are in addition to — not replacing — the scheduler's hard LinkedIn, Instagram, and warmup caps.

Tool category Pro Enterprise Ultimate Typical tools
Read 60240480 list_*, get_*
Write 1560120 create_campaign, pause_campaign, verify_email
LinkedIn & Instagram writes 102040 start_linkedin_campaign, pause_instagram_campaign
Bulk 31020 bulk_create_prospects, submit_verification_batch

Figures are calls per minute, per workspace. Agent actions start on the Pro plan — a Free plan has no agent allowance yet, so there is no per-minute budget to spend on one and calls come back pointing at where to change plan instead of running. Customers on the legacy Starter and Business plans keep their own pace; the AI Agents page lists every plan side by side.

Exceeding a per-minute budget returns a rate_limited error carrying retry_after_seconds, so your assistant knows when to retry. A plan refusal is a different answer — plan_upgrade_required, with no wait hint, because waiting cannot cure it.

Error codes

MCP tools use JSON-RPC error codes. The WarmySender server reserves the -32000…-32099 range for protocol-specific errors on top of the standard JSON-RPC codes.

Code Name Meaning
-32001 insufficient_scope The tool requires a scope your API key doesn't have. error.data.missing_scopes lists them. NOT retryable — re-issue the key with the missing permissions.
-32002 rate_limited Per-workspace per-minute budget exceeded. TRANSIENT — error.data.retry_after_seconds tells you when to retry.
-32003 idempotency_conflict The same idempotency_key was reused with different arguments. NOT retryable — change the key or send the original arguments.
-32004 unauthorized Bearer token missing, invalid, revoked, or the session expired. NOT retryable — reconnect.
-32005 plan_upgrade_required Your plan does not include AI agent actions, or its monthly allowance is used up. NOT retryable — there is deliberately no retry_after_seconds, because waiting cannot cure it. error.data.upgrade_url is where to change plan.
-32006 not_found No such item in this workspace. NOT retryable — the same id will not start existing. List the items to find the right one.
-32007 forbidden The item exists, but this workspace isn't allowed to do that. NOT retryable — it needs a change in WarmySender first.
-32008 conflict Something already exists or is already under way that clashes with this request. NOT retryable — repeating it hits the same clash.
-32009 failed_precondition Your arguments were fine, but the item is in the wrong state for this action (already running, not connected yet, end date passed). NOT retryable as-is — fix what the message describes, then repeat the same call.
-32010 temporarily_unavailable Something the tool depends on is momentarily down. TRANSIENT — error.data.retry_after_seconds tells you when to retry.
-32602 invalid_params The tool arguments did not match what it expects, or a value was rejected. error.data.issues shows which fields failed and why. NOT retryable unchanged — correct the values first.
-32603 internal_error An unexpected server-side error — and only that; ordinary refusals now have their own codes above. Details are in our logs; the response includes a request_id to quote in support.

Frequently asked questions

Which MCP clients work with WarmySender?

Claude, ChatGPT, Cursor, Codex, OpenClaw, and Hermes Agent all connect — plus any other client that speaks the Model Context Protocol 2025-11 Streamable HTTP spec. We've tested Claude, Claude Code, Cursor, Windsurf, and Zed, and ChatGPT connects through Codex. Continue, Cline, Goose, and other MCP clients should also work — just point them at https://warmysender.com/mcp and sign in, or use your Bearer token. Clients that only launch local commands (like Zed) use the npx @warmysender/mcp launcher shown in the API-key form above.

Can Claude send cold emails for me?

Yes — Claude (or ChatGPT, Cursor, Codex, OpenClaw, Hermes Agent) can build, launch and manage your cold email, LinkedIn, Instagram and WhatsApp campaigns in WarmySender. It never sends a message itself: it writes the campaign and hands it to WarmySender's scheduler, which paces every send inside safe limits, and it can never raise a limit.

Can I sign in with OAuth instead of an API key?

Yes. You can connect by signing in (OAuth) or with an API key. If your AI client supports MCP sign-in, add the server URL https://warmysender.com/mcp and choose Sign in — you'll approve access on a WarmySender consent screen, and we issue a token scoped to your workspace. Prefer a key? Use Authorization: Bearer ws_… from Settings → API Keys (the same ws_ keys you use for our REST API).

Can I expose this to other AI tools — ChatGPT, Gemini, custom agents?

Yes. MCP is a transport-neutral protocol. Any client that implements Streamable HTTP with Bearer auth can connect. For bespoke integrations, use the official @modelcontextprotocol/sdk in Node/Python and pass the Authorization header in each request.

Does connecting via MCP cost anything extra?

No. MCP usage is included in all paid plans (Pro, Business, Enterprise, Ultimate, and the Starter legacy plan). The only cost is the subscription you're already paying. A LinkedIn add-on seat is required per LinkedIn account if you call LinkedIn tools — see the pricing page for current rates.

How do I revoke access?

Revoke the API key in Settings > API Keys. Revocation is instant; the next MCP call from any client using that key gets an unauthorized error. You can also narrow the scopes on a key to tighten what the AI can do without fully revoking access.

My browser says 127.0.0.1 is blocked after I approve — is the connection broken?

No. Approve already succeeded. A browser extension (an ad or privacy blocker) or a managed-browser policy stopped the last hop to the app on this computer — Claude, ChatGPT, Cursor, Codex, OpenClaw, or Hermes Agent. Pause the blocker for 127.0.0.1 and localhost, or open the link in another browser on the same computer, then start once more from the agent if the original link expired. Full walkthrough: /documentation/my-browser-says-127-0-0-1-is-blocked-when-connecting-an-ai-agent

Can the AI accidentally ban my LinkedIn account or burn my sending reputation?

No. Every LinkedIn action routes through our scheduler, which enforces LinkedIn per-account daily and weekly limits plus the 4-week ramp schedule. Every email send respects the per-mailbox pacer, domain caps, and warmup ramp. MCP cannot bypass any of these — if your AI asks to enroll 500 prospects at once, the scheduler still sends at the safe rate. Connecting and disconnecting accounts stays in the UI for the same reason.

This server, by agent and channel

What each agent can and cannot do on each channel through this server, how it connects, and prompts phrased for its own surface — one page per pair. The agent never sends a message itself and can never raise a limit on any of them.