MCP Server — Safety, Scopes, and Rate Limits
How the WarmySender MCP server keeps your account safe when you grant an AI assistant access. Read this before handing a production API key to any AI tool.
CORE SAFETY INVARIANTS:
1) Workspace scoping — every single query
Your API key deterministically resolves to exactly one workspace at auth time. Every tool handler filters every database query by that workspace ID. A tool cannot be tricked via arguments into seeing or modifying another workspace's data. The workspace ID never appears in tool input schemas — there's no way for the AI to "pass" a workspace ID.
2) Scheduler-first for all LinkedIn + warmup actions
MCP never calls Unipile (LinkedIn API) directly. Tools like pause_linkedin_campaign, resume_linkedin_campaign, enroll_in_linkedin_campaign only flip database state or queue work. Our scheduler — the same one the UI uses — gates actual LinkedIn invites, messages, and profile views against: 4-week ramp schedule, per-account daily cap (invites + messages + profile views), per-account weekly cap (e.g., 200 invites/week for premium, 150 for free with notes), and Unipile's published per-account API budget. A compromised or hallucinating AI client cannot bypass these — the enforcement is in the scheduler, not the tool.
3) No send tools at all
No tool in the MCP catalog sends an email, invite, message, InMail, profile view, post comment, or reaction directly. The only way to make WarmySender do outreach is to start a campaign (which the scheduler then paces) or to enroll prospects in an already-running campaign (again, scheduler-paced). This removes an entire class of risk where an AI could be prompted into sending unintended messages.
4) No account connect / disconnect
Adding or removing a LinkedIn or email account stays in the web UI behind your logged-in session. A compromised AI assistant cannot drain your LinkedIn seats or provision new accounts on your bill.
5) No delete operations in V1
No delete_campaign, delete_mailbox, delete_prospect, delete_account. Soft-cancel via pause/archive only. Permanent deletes happen in the UI with explicit confirmation.
6) Warmup subject-line ref-tag is untouchable
Our warmup emails include a [ref: XXXXXXXX] tag in the subject so you can filter them from your inbox with a simple Gmail / Outlook rule. No MCP tool can remove or modify this tag — protects your inbox hygiene.
SCOPES — PRINCIPLE OF LEAST PRIVILEGE:
Your API key carries a list of scopes. Each tool requires specific scopes. Grant only what you need for the AI to do its job:
- Read-only monitoring (safe default): campaigns:read, prospects:read, mailboxes:read, warmup:read, linkedin:read, suppressions:read, jobs:read
- Campaign automation: add campaigns:write and enrollments:write
- Full prospect management: add prospects:write
- LinkedIn control: add linkedin:write (still scheduler-gated for actual sends)
- Warmup config: add warmup:write
- Suppression management: add suppressions:write
Revoking takes effect immediately — Settings > API Keys > Delete. The AI client's next call gets 401.
RATE LIMITS (per workspace, sliding 60-second window):
- Read tools: 120 / minute
- Write tools (email campaigns, prospects): 30 / minute
- LinkedIn writes (pause, resume, enroll): 10 / minute (stricter for safety)
- Bulk operations (bulk_create_prospects, bulk_update_warmup): 5 / minute
These are enforced in Upstash Redis at the MCP edge, independent of LinkedIn / warmup scheduler limits. Exceeding any category returns a 429 with retry_after_seconds.
IDEMPOTENCY:
Every write tool supports an optional idempotency_key argument. If the AI retries the same operation (same tool, same args, same key) within 24 hours, you get the original result back — no duplicate effect. Different args with the same key return 409 idempotency_conflict.
AUDIT LOG:
Every tool call is logged to our system_logs table with: tool name, workspace ID, API key ID, duration, outcome (ok / error / rate_limited / insufficient_scope), and a sanitized args summary (never full emails, names, phone numbers, or URLs — only hashes, domains, and counts). If something goes wrong, our support team can trace exactly what the AI tried to do.
TRANSPORT SECURITY:
- TLS 1.2+ only (HTTPS enforced at the edge).
- Bearer token auth — your API key (ws_ prefix, SHA-256 hashed server-side). Never sent as a query parameter, never logged.
- Session IDs bound to the API key at initialize time — a confused-deputy attack where a stolen session ID is reused with a different key is rejected.
DATA THE AI NEVER SEES:
- SMTP / IMAP passwords, OAuth refresh tokens for your mailboxes.
- Stripe / billing details.
- Other workspaces' data — ever.
- User login credentials / session cookies.
RED-TEAM TESTS WE RAN:
- Try to access another workspace by passing a forged ID in tool args — blocked (args never carry workspace ID).
- Try to exceed rate limits by opening multiple MCP sessions with the same key — blocked (limits are per-workspace, not per-session).
- Try to call write tools with a read-only key — blocked (-32001 insufficient_scope, message lists exactly which scope is missing).
- Try to retrieve mailbox credentials via list_mailboxes — blocked (response shape explicitly omits credential fields).
- Try to bypass LinkedIn daily caps by spamming enroll_in_linkedin_campaign — the scheduler still paces actual invites regardless of enrollment queue depth.
DISABLING MCP COMPLETELY:
MCP has no global kill switch — the controls are per-key: Settings > API Keys > Delete every key. With zero API keys, no MCP client can authenticate. You can always re-enable by creating new keys.
QUESTIONS?
If you need a scope combination not listed, or a tool that isn't in our catalog, contact [email protected] — we extend the server carefully (safety first), but legitimate requests are welcome.
See also: "MCP Server — Overview" and "MCP Server — Install in Claude Desktop / Claude Code / Cursor / Windsurf / Zed" and "MCP Server — Available Tools Reference."