Skip to main content
This guide covers how to give an AI agent access to Lettr over MCP with no more reach than its job needs. The controls are the key’s permission level, a sandbox key for rehearsal, IP restrictions and idempotency keys for retries. The last section combines them into one setup.

What Can Go Wrong

A script sends exactly what its code says, while an agent decides what to send from instructions and data that nobody fully controls. That opens risks a script does not have: A better prompt does not remove any of these. The controls below are limits Lettr enforces, so they hold whatever the agent decides.

How Agents Reach Lettr

Lettr hosts a remote MCP server at https://app.lettr.com/mcp. It accepts either a Lettr sign-in (OAuth) or a lttr_ API key sent as Authorization: Bearer lttr_.... Each tool maps to the same operation as a REST endpoint. The two ways of connecting give you very different control: For an agent you want to restrict, use a key. OAuth gives the assistant everything you can do in the dashboard, so it suits supervised, personal use rather than an autonomous agent.

Give the Agent the Least Access It Needs

Choose a Permission Level

Every key is one of two permission levels, picked when you create it under API Keys: A Sending only key that calls any other endpoint gets 403 with error_code: insufficient_scope. The level is a preset of scopes, and you cannot pick scopes one by one. See Permissions for the full scope list. For an agent whose job is to send, such as a support assistant that emails order updates or a workflow that sends a template, use Sending only.

What the Agent Sees through MCP

The server checks the key on every request and hides tools the key has no scope for, so an agent never offers an action it cannot perform. Each tool needs the same scope as its REST endpoint. Two details matter for safety:
  • A tool that declares no scope is unavailable to every key. A new tool cannot reach key-authenticated agents by accident.
  • list_api_keys and browse_api_logs are never available to a key. An agent holding a key cannot list your other keys.
After a key’s permission level changes, the agent loses the affected tools on its next call, even if its client still has the old tool list cached.
A Full access key lets an agent call send_campaign, which sends to a campaign’s whole audience, and delete tools such as delete_template. If an agent does not need these, do not give it a Full access key.

Rehearse With a Sandbox Key

Before an agent touches real recipients, run it on a sandbox key. Create one under API Keys by setting Type to Sandbox. Sandbox keys start with lttr_sandbox_. A sandbox key behaves like a live key with its email sends contained:
  • Recipients are replaced. Every to, cc and bcc address becomes the email address of the user who created the key, whatever the agent asked for.
  • The sender domain is replaced. The from domain becomes dev.uselettr.com, so no verified sending domain is needed.
  • Most writes are blocked. On REST, a sandbox key can send email and read, but creating, updating or deleting templates, domains, webhooks and similar resources is refused, and so are SMS and WhatsApp sends. On MCP, any tool that needs a :write scope is unavailable to a sandbox key.
  • Email sends are isolated. Sandbox email sends use a separate subaccount, do not count toward your sending quota, and do not trigger your webhooks.
Because every email goes to the key owner, an agent whose prompt is still being tuned can loop or hallucinate an address without a real recipient receiving anything. One difference between REST and MCP matters here. Over REST, a sandbox key cannot call POST /events. Over MCP, send_event stays available to a Full access sandbox key, and the event it sends is not redirected, so it can start automations that email real recipients. A Sending only sandbox key does not hold the events:send scope, so send_event is not available to it. For that reason, rehearse on a sandbox key with Sending only permissions. It holds only the sending scopes, so the agent has the send and schedule tools and nothing that acts on your audience or automations. To see what the agent sent, open the Events page in the dashboard and turn on the Sandbox toggle. Sandbox events are not shown without it.
Sandbox keys have their own rate limits, separate from your team’s live traffic. See Sandbox API Keys for the figures.

Restrict Where the Key Can Be Used

A key can be limited to specific source addresses. In the Allowed IPs field, enter comma-separated IP addresses or CIDR ranges, for example 10.20.30.40, 10.20.30.0/24. Leave it blank to allow any address. Requests from other addresses are refused with 403 and the message Access denied. Your IP address is not allowed. The same check applies to key-authenticated MCP connections. This limits the value of a leaked key: for an agent that always runs from a known server or CI runner, a copy of the key does not work from any other address.
Cloud CI runners often have changing addresses. If you cannot pin a range, rely on a Sending only key and keep the key out of logs instead.

Make Retries Safe

When a tool call times out, the model often cannot tell whether the email went out, so agents tend to retry the send. Both send_email and send_template_email accept an idempotency_key. Reuse the same value on a retry and Lettr does not send the email a second time. Without it, a retry after a timeout can send the email twice. The key must be 1 to 255 characters, using letters, digits, periods, underscores and hyphens. Instruct the agent to derive it from the business event, not to generate a fresh one on each attempt:
The REST API has the same protection for code that calls it directly. See Idempotency.

Keep a Human in the Loop for Risky Actions

Tools that send email, overwrite data or delete it carry the MCP destructive annotation, including send_email, send_template_email, cancel_scheduled_email and send_campaign. Clients that support the annotation, such as Claude, can ask you to approve each call before it runs. Check the recipients, the template and the audience in each prompt before approving it. For an unattended agent there is no prompt, so the key’s permission level and a sandbox rehearsal are the controls that count. If the agent works across several teams through OAuth, pin the team in the connection URL (https://app.lettr.com/mcp?team=41) so it cannot act on another one. A key is already bound to a single team.

Protect the Key

A key in a client config file is a plain-text password.
  • Use a separate key per agent, named for its job, so you can revoke one without affecting others.
  • Keep config files that hold keys out of version control.
  • Revoke a key by deleting it.
  • Key-authenticated MCP calls appear in your API logs with the key’s id. Filter by key name under Logs to see what an agent has done.

A Safe Setup, End to End

For an agent that sends order updates:
1

Rehearse on a sandbox key

Create a sandbox key with Sending only permissions, named order-agent-test. Connect the agent, run the real task several times and read the emails in your own inbox (subject, body, merge data, tone). Check the Events page with the Sandbox toggle for anything unexpected.
2

Create the live key

Create a Sending only live key named order-agent-prod, with Allowed IPs set to the server that runs the agent.
3

Connect the agent

In Claude Code:
4

Set the sending rules

Tell the agent to use saved templates and to set an idempotency_key on every send.
5

Watch the first live runs

Start with a small, low-stakes workflow and follow it in Logs and Events.

Connect with an API Key

Set up key-based MCP access and see what each key can reach

API Key Permissions

Permission levels, scopes and IP restrictions

Sandbox API Keys

Test email sends without reaching real recipients

Security Best Practices

Protect your API keys, webhooks, and account