Connect Mailshake to ChatGPT: Manage Campaigns and Monitor Activity
Learn how to connect Mailshake to ChatGPT using an auto-generated MCP server to manage sales campaigns, add recipients, and monitor activity.
If you need to connect Mailshake to ChatGPT to automate sales engagement workflows, orchestrate outreach campaigns, or monitor lead activity, you need a Model Context Protocol (MCP) server. This server translates ChatGPT's natural language tool calls into Mailshake's specific JSON REST structures. You can either spend weeks building, hosting, and maintaining this translation layer yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL.
If your team uses Claude, check out our guide on connecting Mailshake to Claude or explore our broader architectural overview on connecting Mailshake to AI Agents.
Giving a Large Language Model (LLM) read and write access to a sales engagement platform is a significant engineering challenge. You have to handle complex asynchronous operations for bulk data imports, navigate a unique quota-based rate limiting system, and map dynamic sales stages to LLM tool definitions.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Mailshake, connect it natively to ChatGPT, and execute complex sales workflows using natural language.
Stop writing boilerplate API integration code. Let Truto generate secure, managed MCP servers for your AI agents in seconds. :::
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 over JSON-RPC, implementing it against Mailshake's highly specific API is exceptionally painful.
If you decide to build a custom MCP server for Mailshake, you own the entire API lifecycle. Here are the specific integration challenges that break standard CRUD assumptions when working with Mailshake:
Asynchronous Bulk Operations and Status Polling
Mailshake optimizes for large lists of recipients. When you add recipients to a campaign or trigger an export, the API does not execute the request synchronously. Instead, endpoints like POST /recipients/add return a statusID. The operation processes in the background. If you want an AI agent to add 500 contacts to a campaign and then report on any invalid emails, your custom MCP server must implement a stateful polling mechanism against the GET /recipients/add-status endpoint. You must write the logic that allows the LLM to yield execution, poll the status, and resume once isFinished evaluates to true.
Quota Unit Accounting
Unlike standard SaaS platforms that rate-limit strictly by HTTP request counts, Mailshake utilizes a quota system based on the computational weight of the operation. Simple reads might cost 1 unit, while actions like creating a lead cost 25 quota units, and setting up a push webhook costs 100 units. If an LLM attempts to loop through an array of 200 prospects and individually create leads via create_a_mailshake_lead, it will rapidly exhaust the team's quota. Your MCP server must expose tools that encourage bulk operations where possible and provide the LLM with clear context about the cost of its actions.
The Lead Catcher State Machine
Mailshake separates the concept of a "Recipient" (someone receiving a campaign) from a "Lead" (someone who has engaged and entered the Lead Catcher pipeline). Leads have a specific lifecycle: they are created, assigned, opened, closed, ignored, or reopened. The LLM must understand that modifying a recipient's pause status does not automatically update their Lead Catcher status. Mapping this state machine into LLM-friendly schemas requires deep API knowledge.
Handling Rate Limits Without Black-Boxing
When connecting AI agents to production systems, visibility into rate limiting is critical. Factual note on rate limits: Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream Mailshake API returns an HTTP 429 (Too Many Requests), Truto passes that error directly to the caller.
However, Truto normalizes Mailshake's upstream rate limit info into standardized headers per the IETF specification:
ratelimit-limitratelimit-remainingratelimit-reset
The caller (your LLM orchestration framework or the agent itself) is entirely responsible for reading these headers and implementing its own retry or backoff logic. Truto will not absorb rate limit errors on your behalf. This design ensures your agent remains deterministic and aware of the actual state of the upstream system.
Step 1: Create the Mailshake MCP Server
Instead of writing a custom server to handle these quirks, Truto automatically generates a compliant MCP server from the Mailshake API documentation. You can generate this server via the Truto UI or programmatically via the API.
Method A: Via the Truto UI
For immediate testing and manual setup, the UI provides the fastest path:
- Log into your Truto dashboard and navigate to the Integrated Accounts page.
- Select your connected Mailshake account.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Select your desired configuration (e.g., allow read and write methods, restrict to specific tags like
campaignsorleads). - Click Save and copy the generated MCP server URL (it will look like
https://api.truto.one/mcp/<secure-token>).
Method B: Via the Truto API
For production workflows, you should generate MCP servers programmatically. This scopes the server securely to a specific tenant's integrated account.
Make a POST request to /integrated-account/:id/mcp with your Truto API token:
curl -X POST https://api.truto.one/integrated-account/<INTEGRATED_ACCOUNT_ID>/mcp \
-H "Authorization: Bearer $TRUTO_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Mailshake Sales Agent",
"config": {
"methods": ["read", "write", "custom"],
"tags": ["campaigns", "recipients", "activity", "leads"]
}
}'The API returns a payload containing the unique, authenticated URL for this server:
{
"id": "mcp_8a9b2c1d",
"name": "Mailshake Sales Agent",
"config": { "methods": ["read", "write", "custom"] },
"expires_at": null,
"url": "https://api.truto.one/mcp/a1b2c3d4e5f6g7h8..."
}This url is all the LLM client needs. It handles protocol negotiation, authentication against Mailshake, schema enforcement, and tool listing dynamically.
Step 2: Connect the MCP Server to ChatGPT
Once you have the Truto MCP URL, you must register it with ChatGPT so the model can discover and execute the Mailshake tools.
Method A: Via the ChatGPT UI
If you are using ChatGPT Pro, Plus, Business, Enterprise, or Education accounts with Developer Mode enabled:
- Open ChatGPT and navigate to Settings -> Apps -> Advanced settings.
- Ensure Developer mode is toggled on.
- Under MCP servers / Custom connectors, click to add a new server.
- Enter a name (e.g., "Mailshake Integration").
- Paste the Truto MCP URL into the Server URL field.
- Click Add.
ChatGPT will immediately ping the server, complete the JSON-RPC handshake, and populate its context window with the available Mailshake tools.
Method B: Via Manual Config File (SSE Transport)
If you are running a local MCP inspector, a custom LangGraph orchestration layer, or a headless client relying on a configuration file, you can connect using the Server-Sent Events (SSE) transport wrapper.
Add the following configuration to your MCP client's JSON config:
{
"mcpServers": {
"mailshake": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"--url",
"https://api.truto.one/mcp/<YOUR_SECURE_TOKEN>"
]
}
}
}This instructs the framework to wrap the remote HTTP endpoints into a local stdio stream if required by your specific agentic architecture.
Mailshake Hero Tools
Truto automatically exposes dozens of endpoints based on the Mailshake API. Below are the highest-leverage "hero tools" that enable end-to-end sales orchestration inside ChatGPT.
1. List Campaigns (list_all_mailshake_campaigns)
The foundation of any outreach workflow is understanding what campaigns are currently running. This tool returns all campaigns for a team, including their pause status, title, and tracking URL.
Usage note: Encourage the LLM to use the optional search filter to find specific campaigns rather than paginating through hundreds of historical records.
"List all active Mailshake campaigns that include 'Q3 Outreach' in the title and tell me if any of them are currently paused."
2. Create a Campaign (create_a_mailshake_campaign)
Agents can instantly spin up new campaign structures. Note that a newly created campaign cannot be sent immediately—a human must complete the setup wizard in the Mailshake UI—but recipients can be seeded into it immediately by the API.
Usage note: Returns the campaign object with the newly minted id which is required for all subsequent recipient additions.
"Create a new Mailshake campaign titled 'Enterprise Cold Outbound Q4'. Give me the new campaign ID when you are done."
3. Add Recipients (mailshake_recipients_add)
This is where Mailshake's asynchronous architecture kicks in. The tool allows the agent to push new prospects into a campaign using listOfEmails, addresses, or csvData.
Usage note: This tool does not return success immediately. It returns a statusID. The agent must be instructed to use the status tool afterward.
"Add alice@example.com and bob@example.com as recipients to campaign ID 12345. Provide me with the status ID so we can check if the import worked."
4. Check Recipient Add Status (mailshake_recipients_add_status)
The required follow-up to adding recipients. It checks the asynchronous queue.
Usage note: Returns isFinished. If false, the agent should wait and check again. If true, it returns any problems (like invalid emails or duplicates).
"Check the status of the recipient import using status ID 9876. If it is finished, summarize any problems or bounces that were detected."
5. Get Recent Replies (mailshake_activity_replies)
This tool allows the AI to monitor the inbox for engagement. It returns recent replies to sent emails, including bounces, out-of-office autoreplies, and human responses.
Usage note: This is a paginated list returning up to 25 replies per page. Excellent for building AI triage agents that read responses and draft counter-replies.
"Fetch the most recent replies across all Mailshake campaigns. Identify any that look like out-of-office messages and any that are asking for a demo."
6. Create a Lead (create_a_mailshake_lead)
Push engaged recipients directly into the Lead Catcher for the sales team to work.
Usage note: This operation costs 25 quota units per call. Agents should only execute this for high-intent replies to preserve API quota.
"Take the recipient who just asked for a demo (ID 555) and create a lead for them in Mailshake so the SDR team gets notified."
For the complete inventory of tools, including pagination inputs, required JSON properties, and comprehensive schema details, visit the Mailshake integration page.
Workflows in Action
Connecting tools to ChatGPT is only valuable if the LLM can chain them together to solve real business problems. Here is how specific personas utilize these tools in practice.
Workflow 1: Campaign Generation & Recipient Seeding
Persona: Sales Development Representative (SDR)
Instead of navigating through multiple UI screens, an SDR can prompt the agent to build the foundation of a campaign and populate it with target data.
"Create a new Mailshake campaign called 'Q3 VP of Sales Outreach'. Once created, add these three emails to it: vp1@example.com, vp2@example.com, and vp3@example.com. Poll the status until the import is finished and let me know if there were any errors."
Execution Steps:
create_a_mailshake_campaignis called with the title 'Q3 VP of Sales Outreach'. The API returns the newcampaignID(e.g., 9912).mailshake_recipients_addis called usingcampaignID: 9912and the array of email addresses. The API returns astatusID(e.g., 4455).mailshake_recipients_add_statusis called withstatusID: 4455. IfisFinishedis false, the LLM pauses and retries.- Once
isFinishedis true, the LLM reads the result and outputs a final confirmation to the user, noting any rejected addresses.
sequenceDiagram
participant User as User
participant ChatGPT as ChatGPT
participant Truto as Truto MCP Server
participant Mailshake as Mailshake API
User ->> ChatGPT: "Create campaign and add recipients..."
ChatGPT ->> Truto: "Call create_a_mailshake_campaign"
Truto ->> Mailshake: "POST /campaigns/create"
Mailshake -->> Truto: "Returns campaignID: 9912"
Truto -->> ChatGPT: "Tool Result"
ChatGPT ->> Truto: "Call mailshake_recipients_add (campaignID: 9912)"
Truto ->> Mailshake: "POST /recipients/add"
Mailshake -->> Truto: "Returns statusID: 4455"
Truto -->> ChatGPT: "Tool Result"
ChatGPT ->> Truto: "Call mailshake_recipients_add_status (statusID: 4455)"
Truto ->> Mailshake: "GET /recipients/add-status?statusID=4455"
Mailshake -->> Truto: "Returns isFinished: true"
Truto -->> ChatGPT: "Tool Result"
ChatGPT ->> User: "Campaign created and recipients added successfully."Workflow 2: Engagement Triage & Lead Routing
Persona: RevOps Manager
A RevOps manager wants to ensure no positive replies are slipping through the cracks. They deploy ChatGPT to analyze the inbox and escalate high-value responses.
"Check the recent replies across our active campaigns. Find any human responses that seem positive or ask for a meeting. If you find any, manually create a lead for that recipient in Lead Catcher."
Execution Steps:
list_all_mailshake_campaignsis called to identify the active campaigns the team is running.mailshake_activity_repliesis called. The LLM receives the array of recent replies.- The LLM processes the text of the
bodyfield of the replies, filtering out "Out of Office" auto-responders or aggressive opt-outs. It identifies one reply saying "Sure, I have time next Tuesday." create_a_mailshake_leadis called using therecipientIDassociated with that positive reply, pushing the prospect into the Lead Catcher UI for human follow-up.
flowchart TD
A["ChatGPT: Call mailshake_activity_replies"] --> B["Truto: Proxies request to Mailshake"]
B --> C["Mailshake: Returns array of Reply objects"]
C --> D["ChatGPT evaluates reply body text"]
D --> E{"Is reply positive?"}
E -->|"Yes (e.g. 'Let's chat')"| F["Call create_a_mailshake_lead"]
E -->|"No (e.g. 'Unsubscribe')"| G["Ignore or call mailshake_recipients_unsubscribe"]
F --> H["Mailshake: Creates Lead in UI and deducts 25 quota units"]Security and Access Control
Giving an AI agent access to your outbound email infrastructure requires strict governance. Truto MCP servers provide robust security constraints at the configuration level:
- Method Filtering: Limit the server to read-only operations by passing
"methods": ["read"]during creation. This allows the LLM to analyze replies and campaign stats without the risk of it creating campaigns or launching unauthorized outbound sequences. - Tag Filtering: Restrict access to specific domains of the API. By setting
"tags": ["activity", "leads"], the server will only expose monitoring and Lead Catcher tools, completely hiding configuration and push webhook tools from the LLM context. - Extra Authentication Layer: Setting
require_api_token_auth: trueensures that possessing the MCP URL is not enough; the connecting client must also supply a valid Truto API token in the Authorization header. This protects your endpoints even if the URL leaks. - Time-to-Live (TTL): Set an
expires_atISO datetime when generating the server. Truto's backend handles automatic expiration and credential cleanup, ideal for granting temporary access to contractors or short-lived AI workflows.
Moving Past Integration Boilerplate
Building a custom Mailshake integration for ChatGPT requires deeply understanding quotas, asynchronous status polling, and Lead Catcher logic. By utilizing a managed MCP server via Truto, you bypass the infrastructure overhead entirely.
Truto automatically maps the Mailshake API into JSON-RPC schemas, normalizes authentication, and exposes rate limits transparently via standard headers—allowing you to focus on writing high-value AI workflows rather than debugging pagination logic.
Stop wrangling API documentation and JSON schemas. Generate secure MCP servers for your SaaS integrations in minutes with Truto.
FAQ
- How does Truto handle Mailshake rate limits for AI agents?
- Truto does not retry, throttle, or apply backoff on rate limit errors. When Mailshake returns an HTTP 429, Truto passes the error to the caller and normalizes the rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The caller is responsible for implementing retry and backoff logic.
- Why do some Mailshake API actions return a status ID instead of data?
- Mailshake utilizes asynchronous operations for heavy tasks like adding bulk recipients or exporting campaigns. The API returns a status ID, and your AI agent or application must poll the status endpoint until the operation completes.
- How do Mailshake's quota units work with MCP servers?
- Mailshake limits API usage by quota units rather than raw request counts. Simple reads cost less, while actions like creating a lead cost 25 units. AI agents must be instructed to use these tools carefully to avoid draining the account's quota.
- Can I prevent ChatGPT from sending campaigns via Mailshake?
- Yes. When creating the Truto MCP server, you can configure method filtering (e.g., "methods": ["read"]) to expose only read-only endpoints, preventing the LLM from making any destructive or outbound actions.