Skip to content

Connect Mailshake to Claude: Automate Leads and Sales Engagement

A definitive engineering guide to connecting Mailshake to Claude via MCP. Learn how to securely automate campaigns, lead management, and email outreach.

Sidharth Verma Sidharth Verma · · 9 min read
Connect Mailshake to Claude: Automate Leads and Sales Engagement

If you need to connect Mailshake to Claude to automate sales outreach, qualify leads, launch targeted campaigns, or track recipient engagement, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's tool calls and Mailshake's REST API. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on connecting Mailshake to ChatGPT or explore our broader architectural overview on connecting Mailshake to AI Agents.

Giving a Large Language Model (LLM) read and write access to a highly structured sales engagement platform like Mailshake is an engineering challenge. You have to handle specific rate limits, map dense email activity schemas to MCP tool definitions, and deal with Mailshake's strict quota-based endpoint limits. Every time Mailshake updates an endpoint or changes a lead state rule, you have to update your server code, redeploy, and test the integration.

This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Mailshake, connect it natively to Claude Desktop, and execute complex outreach workflows using natural language.

The Engineering Reality of the Mailshake API

A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against specialized B2B APIs is painful. Mailshake is built for high-volume, compliant outbound email. Its API reflects that complexity.

If you decide to build a custom Mailshake MCP server, here are the specific integration challenges you will face:

Asynchronous Bulk Operations and Status Polling

Many high-value operations in Mailshake do not complete synchronously. For example, exporting campaigns (mailshake_campaigns_export) or adding large lists of recipients (mailshake_recipients_add) are queued operations. The initial API call returns a 202 Accepted with a statusID or checkStatusID. If you hand this directly to Claude, the LLM assumes the job is done. You must build tools that explicitly instruct Claude to poll the corresponding status endpoints (like mailshake_recipients_add_status) until isFinished evaluates to true.

API Quota Units

Unlike standard APIs that limit by request volume alone, Mailshake assigns "Quota Units" to expensive operations. For instance, creating a new lead via create_a_mailshake_lead costs 25 quota units, and setting up a webhook push costs 100 quota units. If you run an autonomous agent that aggressively loops through recipients to create leads, you will instantly exhaust your Mailshake quota. A managed MCP server forces you to be explicit about method filtering to restrict what tools the LLM can call, protecting your quota budgets.

Strict Lead State Machines

Mailshake enforces a rigid state machine for Leads. A lead can be opened, closed, ignored, or reopened. You cannot simply PATCH a status string. You have to use dedicated procedural endpoints (mailshake_leads_close, mailshake_leads_ignore, mailshake_leads_reopen). Your MCP server must expose these as discrete tools and instruct the LLM on exactly which state transitions are mathematically valid, otherwise the LLM will hallucinate standard CRUD operations.

Pass-Through Rate Limit Handling

One of the most critical architectural details of building against Mailshake is how rate limits are processed. Truto does not retry, throttle, or apply backoff on rate limit errors. When Mailshake returns an HTTP 429 (Too Many Requests), Truto passes that error directly to the caller. Truto normalizes the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. The caller - whether it is Claude Desktop or a LangGraph orchestrator - is entirely responsible for reading these headers and executing retry and backoff logic.

Generating a Mailshake MCP Server

Truto's MCP architecture dynamically generates tool definitions based on Mailshake's integration documentation. Tools are not cached or pre-built; they are compiled at runtime when Claude requests tools/list. This guarantees the model always sees the most up-to-date representation of your Mailshake workspace.

You can generate your Mailshake MCP Server in two ways:

1. Via the Truto UI

This is the fastest method for internal teams and ad-hoc agent workflows.

  1. Navigate to the Integrated Accounts page for your Mailshake connection in the Truto dashboard.
  2. Click the MCP Servers tab.
  3. Click Create MCP Server.
  4. Configure the server name, expiration, and any method or tag filters (e.g., restrict to "read" methods for safe analysis).
  5. Copy the generated MCP Server URL (e.g., https://api.truto.one/mcp/a1b2c3d4e5f6...).

2. Via the Truto API

If you are provisioning MCP servers programmatically for your end-users, you can create them via a REST endpoint. Truto hashes the generated token and stores it in Cloudflare KV for high-performance authentication.

Request:

curl -X POST https://api.truto.one/integrated-account/{integrated_account_id}/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Claude Mailshake Assistant",
    "config": {
      "methods": ["read", "write", "custom"],
      "tags": ["campaigns", "leads"]
    },
    "expires_at": "2026-12-31T23:59:59Z"
  }'

Response:

{
  "id": "mcp_srv_99x88y77",
  "name": "Claude Mailshake Assistant",
  "config": { 
    "methods": ["read", "write", "custom"],
    "tags": ["campaigns", "leads"]
  },
  "expires_at": "2026-12-31T23:59:59.000Z",
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f67890"
}

Connecting the MCP Server to Claude

Once you have your Truto MCP URL, you can plug it into Claude. Because Truto handles the OAuth token lifecycle and session refreshment under the hood, the URL is entirely self-contained.

Option A: Via the Claude UI

If you are using Claude's enterprise interface or ChatGPT's custom connectors, the setup is entirely visual.

  1. Open your Claude settings.
  2. Navigate to Integrations -> Add MCP Server.
  3. Provide a name (e.g., "Mailshake Integration").
  4. Paste your Truto MCP Server URL.
  5. Click Add. Claude will instantly handshake with Truto, fetch the Mailshake schemas, and populate the tools.

Option B: Via Manual Config File (Claude Desktop)

For developers using the Claude Desktop application, you can configure the MCP connection via the claude_desktop_config.json file. Because Truto MCP servers speak standard JSON-RPC over Server-Sent Events (SSE), you use the official MCP SSE transport.

Update your config file (located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "mailshake_truto": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/a1b2c3d4e5f67890"
      ]
    }
  }
}

Restart Claude Desktop. The Mailshake tools will immediately appear in your contextual tool palette.

Mailshake Hero Tools for Claude

Truto maps Mailshake's complex endpoints into descriptive, snake_case tools that Claude intuitively understands. Here are the highest-leverage tools available for automating sales engagement.

1. list_all_mailshake_campaigns

Retrieves all campaigns for a team. This is usually the first tool Claude calls to map out your active outreach efforts and capture exact campaignID strings required by downstream tools.

"Claude, pull a list of all active Mailshake campaigns. Show me the ID, title, and the number of messages in the sequence for each one."

2. mailshake_recipients_add

Adds new recipients to a Mailshake campaign in bulk. This is an asynchronous operation. Claude can pass an array of email addresses or a raw CSV string. Claude will receive a statusID in response.

"Take this list of 50 newly qualified marketing leads and add them to the 'Q4 Enterprise Outbound' campaign. Wait for the import to finish and let me know if any emails bounced."

3. mailshake_activity_replies

Fetches recent replies to your sent emails, including bounces, out-of-office responses, and actual prospect messages. This is the ultimate tool for LLM-driven sentiment analysis.

"Fetch the latest replies from the Mailshake activity feed. Filter out the out-of-office autoreplies, and give me a summary of any prospects who expressed positive intent."

4. list_all_mailshake_leads

Lists current leads filtered by campaign, status, or assignee. Essential for building pipeline reports or identifying stale leads that need follow-up.

"List all open leads assigned to me in Mailshake. Flag any lead that hasn't had a status change in the last 14 days."

5. create_a_mailshake_lead

Converts existing campaign recipients into tracked Leads. Note that this consumes 25 quota units per request. Claude must supply the campaignID and the emailAddresses.

"Create a new lead for sarah.connor@example.com based on her recent positive reply in the 'Tech Founders Outreach' campaign."

6. mailshake_leads_close

Advances the lead state machine by marking a lead as 'closed' or 'lost'. This enforces Mailshake's specific lifecycle rules rather than relying on standard updates.

"Mark the lead ID 89012 as closed, and update the CRM notes to reflect that they signed a contract with a competitor."

For the complete schema definitions and full inventory of Mailshake operations - including tools for exports, unsubscribe lists, and webhooks - visit the Truto Mailshake Integration Reference.

Workflows in Action

When Claude is equipped with Truto's Mailshake tools, it can string together multi-step operations that traditionally require jumping between the Mailshake UI and a spreadsheet. Here are three concrete workflows.

Workflow 1: The Automated Campaign Onboarding

Sales operations teams frequently need to drop lists of newly enriched prospects into existing sequences.

"I have a CSV file of 120 new prospects from the London trade show. Find the 'UK Executive Outreach' campaign and upload this list. Let me know when the import is fully processed."

  1. Claude calls list_all_mailshake_campaigns using "UK Executive" as a search parameter to locate the precise campaignID.
  2. Claude formats the user's data and calls mailshake_recipients_add, submitting the payload and receiving a statusID.
  3. Claude calls mailshake_recipients_add_status repeatedly (based on the tool's instructions) until isFinished returns true.
  4. Claude reports back with a success summary, noting any invalid email addresses flagged by Mailshake.
sequenceDiagram
    participant User
    participant Claude as Claude Desktop
    participant MCP as Truto MCP Server
    participant Mailshake as Mailshake API
    
    User->>Claude: "Add these 120 prospects..."
    Claude->>MCP: Call list_all_mailshake_campaigns (search: "UK")
    MCP->>Mailshake: GET /campaigns
    Mailshake-->>MCP: [Campaign Object]
    MCP-->>Claude: campaignID: 5591
    Claude->>MCP: Call mailshake_recipients_add (campaignID: 5591, csvData)
    MCP->>Mailshake: POST /recipients/add
    Mailshake-->>MCP: statusID: 9942
    MCP-->>Claude: Status Tracking ID
    Claude->>MCP: Call mailshake_recipients_add_status (statusID: 9942)
    MCP->>Mailshake: GET /recipients/add/status
    Mailshake-->>MCP: {isFinished: true, problems: []}
    MCP-->>Claude: Import Complete
    Claude-->>User: "Successfully added 120 prospects."

Workflow 2: Inbox Triage and Lead Generation

Sorting through hundreds of campaign replies to identify actual buyers is tedious. Claude can read the replies, perform sentiment analysis, and elevate hot prospects to Leads.

"Review all recent replies across my active campaigns. Ignore the bounces and OOO messages. For anyone asking for a demo, create a Lead in Mailshake."

  1. Claude calls mailshake_activity_replies to pull the latest batch of responses.
  2. Claude analyzes the body of each message locally. It discards automated responses and isolates emails expressing positive intent.
  3. For each positive reply, Claude extracts the campaign ID and recipient email.
  4. Claude calls create_a_mailshake_lead to officially convert that prospect, tracking the returned lead ID.

Workflow 3: Stale Pipeline Cleanup

Keeping your lead lists clean is critical for accurate forecasting.

"Find any leads in Mailshake that have been open for more than 30 days without any status changes. Close them out and give me a summary of who we lost."

  1. Claude calls list_all_mailshake_leads with parameters targeting open statuses.
  2. Claude inspects the openedDate and lastStatusChangeDate fields in the returned array.
  3. For leads exceeding the 30-day threshold, Claude extracts the id.
  4. Claude loops through and calls mailshake_leads_close for each stale lead, returning an empty 204 response on success.
  5. Claude outputs a final markdown table summarizing the closed accounts.

Security and Access Control

Giving an LLM access to your primary outbound email engine requires strict security boundaries. Truto provides absolute control over what the MCP server can execute via the mcp_token configuration.

  • Method Filtering: You can restrict a Mailshake MCP server to read-only operations. By setting methods: ["read"] during server creation, Truto will strip out all tools that mutate state (like create, update, or custom actions). Claude will only see tools like list_all_mailshake_campaigns and mailshake_activity_opens.
  • Tag Filtering: Limit access by domain. If you tag your Mailshake resources in Truto (e.g., tagging campaigns as "marketing"), you can configure the MCP server to only serve tools matching tags: ["marketing"].
  • Secondary Authentication (require_api_token_auth): For maximum security, you can configure the MCP server to require a valid Truto API token in the Authorization header. This ensures that even if the MCP Server URL is leaked, the endpoints cannot be called without secondary user credentials.
  • Automatic Expiration (expires_at): You can generate ephemeral MCP servers for specific automation runs. Set an ISO timestamp, and Truto will automatically revoke the token and schedule a Durable Object cleanup alarm, leaving zero stale credentials behind.

Stop Writing Point-to-Point Mailshake Code

Building a custom Mailshake integration for AI agents requires managing asynchronous loops, state machines, and rate limit architectures. Truto eliminates this overhead entirely. By converting Mailshake's actual API documentation into strongly typed, LLM-optimized tools, Truto lets you focus on building agent logic, not maintaining API boilerplate.

If you are ready to give Claude, LangChain, or your custom agents secure access to Mailshake, deploy a Truto MCP server in minutes.

FAQ

Does Truto automatically retry Mailshake API rate limits?
No. Truto passes HTTP 429 errors directly back to the caller (your LLM or orchestrator) alongside normalized IETF standard headers (`ratelimit-limit`, `ratelimit-remaining`, `ratelimit-reset`). The caller is responsible for retry and backoff logic.
How do AI agents handle Mailshake's asynchronous bulk jobs?
Truto generates specific status polling tools (like `mailshake_campaigns_export_status`) alongside the execution tools. You must prompt Claude to use the returned status ID and poll the endpoint until it completes.
Can I prevent Claude from sending emails or mutating campaigns?
Yes. When generating the MCP Server via Truto, you can pass `methods: ["read"]`. This restricts the token so Claude only receives safe, read-only tools like listing campaigns or checking activity.
How are Mailshake API quotas managed?
Mailshake charges 'quota units' for expensive operations (like creating leads). Because Truto provides direct proxy access via MCP, these quota rules still apply. Developers must configure prompts carefully to prevent the LLM from aggressively looping and exhausting quota limits.

More from our Blog