Connect Lettr to Claude: Design templates and automate delivery
A definitive engineering guide to connecting Lettr to Claude using a managed MCP server. Learn to automate campaigns, bulk contact operations, and email events.
If you need to connect Lettr to Claude to automate newsletter delivery, manage bulk contact segmentation, or track transactional email events, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's natural language tool calls and Lettr's REST APIs. 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 sibling guide on connecting Lettr to ChatGPT or explore our broader architectural overview on connecting Lettr to AI Agents.
Giving a Large Language Model (LLM) read and write access to an email delivery and campaign management system like Lettr is an engineering challenge. You have to map massive JSON schemas to MCP tool definitions, handle disparate pagination mechanisms, and navigate Lettr's strict integration constraints with underlying providers like SparkPost. Every time you expose an endpoint to an AI, you must ensure the LLM understands exactly how to format the payload to avoid cascading failures.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Lettr, connect it natively to Claude Desktop, and execute complex email delivery workflows using natural language.
The Engineering Reality of the Lettr 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. Lettr's API handles high-volume data and orchestrates complex integrations with SparkPost for delivery.
If you decide to build a custom Lettr MCP server, here are the specific integration challenges you will face:
Dual Pagination Schemes
Lettr does not use a single pagination standard. Core entity endpoints - like listing contacts, lists, and templates - rely on a standard page and per_page mechanism (with a maximum limit of 100). However, engagement endpoints like GET /api/campaigns/{campaignId}/events or GET /api/emails/events use cursor-based pagination. An LLM has no intuition for this. If you do not explicitly instruct the model on how to handle the next_cursor property, it will either hallucinate page numbers or get trapped in infinite pagination loops.
Bulk Operation Response Matrices
When you use Lettr's bulk operations - such as attaching up to 1000 contacts to 50 lists via POST /api/audience/contacts/lists/bulk - the API does not simply return a standard 200 OK. It returns complex matrices reporting on existing states, such as already_attached or not_present. An LLM interpreting this payload must be explicitly told via JSON schema descriptions that an already_attached response is not an error state, but rather a successful idempotent confirmation.
SparkPost Transmission Idempotency
Lettr relies heavily on SparkPost for transactional email delivery (POST /api/emails). To prevent an LLM from accidentally sending duplicate emails if a tool call times out and retries, you must pass an Idempotency-Key header. This key is namespaced per Lettr API key and retained by SparkPost for exactly 24 hours. A custom MCP server must map the LLM's tool arguments into this specific header rather than the request body, requiring custom translation logic.
Sandbox API Key Restrictions and Opt-In States
Lettr completely blocks write operations (like creating campaigns or adding contacts) if you are using a sandbox API key. Furthermore, if an LLM creates a contact and passes the double_opt_in flag, that contact is created in an unverified status until the user clicks a confirmation link. The LLM must be aware of these state transitions, otherwise it will hallucinate that the contact is immediately subscribed and available for campaign targeting.
429 Rate Limits and Backoff
It is critical to note how rate limits function in this architecture. When Lettr returns an HTTP 429 Rate Limit Exceeded error, Truto does not retry, throttle, or apply backoff. Truto normalizes the upstream rate limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec and passes that error directly to the caller. The LLM or the agent orchestration framework is entirely responsible for reading these headers and executing the retry backoff.
Generating the Lettr MCP Server
To bridge Claude and Lettr, we need an MCP server endpoint. Truto dynamically generates this server from Lettr's resource definitions and documentation records. You can create this server through the Truto UI or programmatically via the API.
Method 1: Via the Truto UI
For teams deploying one-off agents or testing Claude Desktop workflows, the UI is the fastest path.
- Log into Truto and navigate to the Integrated Accounts page.
- Select your connected Lettr account.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Select your desired configuration (e.g., restrict to
readmethods only, or filter by specific tool tags likecampaigns). - Copy the generated secure URL (e.g.,
https://api.truto.one/mcp/a1b2c3d4e5f6...).
Method 2: Via the Truto API
For production use cases where you are provisioning agents for your customers programmatically, use the REST API. This validates that Lettr is AI-ready, hashes a secure token, stores it in Cloudflare KV, and returns the endpoint.
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 Lettr Automator",
"config": {
"methods": ["read", "write"],
"tags": ["audience", "campaigns"]
},
"expires_at": "2026-12-31T23:59:59Z"
}'The response will contain the self-contained URL you need for Claude:
{
"id": "mcp_8a9b0c...",
"name": "Claude Lettr Automator",
"url": "https://api.truto.one/mcp/a1b2c3d4e5f6..."
}Connecting the MCP Server to Claude
Once you have the Truto MCP URL, connecting it to Claude is a matter of configuration. Because Truto's MCP server uses a JSON-RPC 2.0 endpoint over HTTP (Server-Sent Events), the URL itself contains the cryptographic token required for authentication.
Method A: Via the Claude UI (or ChatGPT Developer Mode)
If you are using Claude's web interface or ChatGPT Plus (which supports custom connectors via remote MCP):
- In Claude, navigate to Settings -> Integrations -> Add MCP Server (in ChatGPT, this is under Settings -> Apps -> Advanced settings -> Custom connectors).
- Give the connector a name (e.g., "Lettr API via Truto").
- Paste the
https://api.truto.one/mcp/...URL generated in the previous step. - Click Add. Claude will instantly send an
initializerequest, discover the Lettr tools, and make them available in your chat context.
Method B: Via the Claude Desktop Config File
If you are running Claude Desktop locally, you must configure the SSE transport via the claude_desktop_config.json file. Truto provides a dedicated NPX package to bridge local standard input/output (stdio) to the remote SSE endpoint.
Open your configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add the Lettr server configuration:
{
"mcpServers": {
"lettr_production": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://api.truto.one/mcp/a1b2c3d4e5f6..."
]
}
}
}Save the file and restart Claude Desktop. The Lettr tools will now appear as an attachment icon in your prompt bar.
Security and Access Control
Giving an LLM access to your Lettr database - especially endpoints capable of bulk-deleting contacts or dispatching thousands of emails - requires strict access control. Truto enforces this at the token level using four mechanisms:
- Method Filtering (
config.methods): Restrict the server to specific operations. Passing["read"]ensures the LLM can only executegetandlistoperations, physically preventing it from creating or deleting campaigns. - Tag Filtering (
config.tags): Scope the server to specific Lettr resources. If you only want Claude to manage contacts, pass["audience"]to exclude campaign and domain administration tools. - Extra Authentication (
require_api_token_auth): By default, the MCP URL acts as a bearer token. For high-security environments, setting this totruerequires the MCP client to also pass a valid Truto API token in theAuthorizationheader, adding a second layer of identity verification. - Time-to-Live (
expires_at): Set an ISO datetime to automatically expire the MCP server. Truto schedules a Durable Object alarm that permanently cleans up the token and KV entries once the timestamp is reached.
Hero Lettr Tools for Claude
Truto dynamically derives MCP tools from Lettr's config.resources and documentation records. Because all tool arguments arrive from the LLM as a single flat object, Truto's MCP router intelligently splits them into query and body parameters based on the underlying JSON schemas.
Here are the highest-leverage Lettr tools you should expose to Claude.
lettr_campaigns_send
Purpose: Immediately dispatches a draft campaign.
Context: The campaign must be in a draft state with a valid subject, sender email, and HTML content. Because sending is asynchronous, the campaign transitions to a preparing state. Claude cannot use this on sandbox keys.
"Dispatch the Black Friday Promo campaign immediately. Grab the campaign ID from my previous prompt and initiate the send."
lettr_audience_contacts_bulk_create
Purpose: Create up to 1000 contacts in a single request.
Context: You can send a contacts array to give each row its own properties, lists, and topics, or use the legacy emails array if the whole batch shares one property map. Claude is excellent at taking a CSV copy-paste and mapping it into this complex JSON payload.
"I just pasted a list of 50 new VIP leads. Bulk create them in Lettr and ensure they are all tagged with the 'Q4_VIP' property map."
create_a_lettr_email
Purpose: Send a highly personalized transactional email.
Context: This bypasses the campaign engine and talks directly to Lettr's transactional router. It requires an Idempotency-Key (which Claude can generate) to ensure retries do not result in duplicate emails being sent via SparkPost.
"Send a transactional welcome email to alex@example.com. Use the 'Onboarding Template' HTML and generate a unique idempotency key so we don't accidentally double-send it if the network hangs."
lettr_audience_contact_lists_bulk_create
Purpose: Bulk attach an array of contacts to an array of lists.
Context: This executes a Cartesian product attachment - every combination of contact_ids × list_ids (up to 1000 contacts × 50 lists). The tool returns an already_attached array for pairs that existed, which Claude must parse to confirm success.
"Take the 15 user IDs I just queried from our database and attach them all to both the 'Weekly Newsletter' and 'Product Updates' lists in Lettr."
list_all_lettr_email_events
Purpose: Retrieve raw email events (deliveries, bounces, opens, clicks).
Context: This endpoint uses cursor-based pagination. Claude must be prompted to read the next_cursor property and loop through the pages if you ask for a full historical analysis.
"Pull the email bounce events for the last 10 days. If there are multiple pages, keep fetching using the next_cursor until you have the complete list, then summarize the top reasons for hard bounces."
For the complete Lettr API tool inventory, including detailed JSON schemas for query parameters, request bodies, and custom methods, consult the Lettr integration page.
Workflows in Action
Connecting tools is only half the battle; orchestrating them into reliable agentic workflows is where MCP shines. Here is how Claude handles complex Lettr operations in the real world.
Workflow 1: End-to-End Campaign Creation and Dispatch
Marketing teams often waste hours moving copy from Google Docs into Lettr, configuring segments, and scheduling the send. Claude can orchestrate this entire lifecycle.
"Create a new Lettr campaign called 'Winter Feature Release'. Write a professional HTML email announcing our new SSO feature. Attach it to the 'Enterprise Admins' audience segment, then immediately dispatch the campaign."
Step-by-Step Execution:
- Retrieve Segments: Claude calls
list_all_lettr_audience_segmentsto find the internal ID for the "Enterprise Admins" segment. - Generate HTML: Claude uses its internal LLM capabilities to draft the HTML content based on the prompt's instructions.
- Draft Campaign: Claude calls
create_a_lettr_campaign, passing thehtml_content, the segment ID, and the required sender information to create the draft. - Dispatch: Claude extracts the newly created
idand passes it tolettr_campaigns_send, transitioning the campaign to thepreparingstate. - Report: Claude informs the user that the campaign is officially queued for delivery.
sequenceDiagram
participant User
participant Claude as Claude Desktop
participant Truto as Truto MCP Server
participant Lettr as Lettr API
User->>Claude: "Create and send Winter Release campaign..."
Claude->>Truto: call list_all_lettr_audience_segments
Truto->>Lettr: GET /api/audience/segments
Lettr-->>Truto: Return segment IDs
Truto-->>Claude: JSON Array of segments
Claude->>Claude: Generate HTML & Map Payload
Claude->>Truto: call create_a_lettr_campaign
Truto->>Lettr: POST /api/campaigns
Lettr-->>Truto: Return draft campaign ID
Truto-->>Claude: { "id": "camp_9982" }
Claude->>Truto: call lettr_campaigns_send(campaign_id: "camp_9982")
Truto->>Lettr: POST /api/campaigns/camp_9982/send
Lettr-->>Truto: 202 Accepted
Truto-->>Claude: Success
Claude-->>User: "Campaign is queued for delivery!"Workflow 2: Transactional Bounces and Remediation
When a critical transactional system fails to deliver emails, support teams need to quickly diagnose the failure and update contact records. Claude can automate this investigative work.
"Check the email events for alex@example.com over the last week. If their transactional emails are bouncing, tell me why, and immediately detach them from the 'Billing Alerts' list so we stop harming our domain reputation."
Step-by-Step Execution:
- Fetch Events: Claude calls
list_all_lettr_email_events, passing the query parameterto=alex@example.com. - Analyze: Claude parses the returned array. It identifies that the recent emails resulted in a
bounceevent due to a550 Mailbox Not Founderror. - Find Contact: Claude calls
list_all_lettr_audience_contactswith the email to retrieve the internal Lettr contact ID. - Find List: Claude calls
list_all_lettr_audience_liststo locate the ID for the "Billing Alerts" list. - Remediate: Claude calls
delete_a_lettr_audience_contact_list_by_id, passing both IDs. It receives a 204 No Content response, confirming the detachment. - Report: Claude summarizes the exact bounce reason and confirms the user has been safely removed from the billing list.
Wrap-up
Managing Lettr integrations involves navigating strict idempotency requirements, dual pagination schemes, and complex bulk matrix responses. Hand-rolling an integration to support AI tool calling forces your engineering team to absorb this complexity, deal with token refreshes, and constantly update schemas as Lettr evolves.
By leveraging Truto's managed MCP architecture, you shift the burden of token lifecycle management, rate limit normalization, and dynamic schema generation off your infrastructure. Whether you are automating campaign dispatches through Claude Desktop or building multi-tenant AI agents for your customers, Truto provides the secure, reliable translation layer required to operate at scale.
FAQ
- How do I handle Lettr API rate limits when using Claude?
- When Lettr returns an HTTP 429, Truto does not retry, throttle, or apply backoff. It normalizes the rate limit info into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) and passes the error directly to Claude. You must instruct your agent to read these headers and retry accordingly.
- Can I test Lettr write operations using a sandbox key via MCP?
- No. Lettr explicitly blocks write operations (like creating campaigns or adding contacts) for sandbox API keys. You must use a production key for these MCP tools to function.
- How does Claude handle Lettr's dual pagination schemes?
- Lettr uses page/per_page for standard endpoints and cursor-based pagination for events. Truto normalizes this by automatically injecting limit and next_cursor properties into the tool schemas, explicitly instructing Claude to pass cursor values back unchanged during consecutive calls.