Guardrails

The safety model behind the MCP tools — why an agent can operate email infrastructure without torching a domain.

The MCP tools are safe by construction, so an agent can operate real email infrastructure without a human watching every call. The guarantees are enforced in the shared cores — not the tool layer — so they hold no matter who calls them.

No blasts

email_send_email is single-recipient by design — there is no list parameter. Broad sending happens only through automations, which enroll contacts one at a time (each send still flows through the suppression check, kill switch, and daily cap). An agent cannot email a whole list in one call.

Kill switch + send caps

Every project has a sendsPaused kill switch (set via email_set_sends_paused) plus daily and monthly send caps. The ceiling comes from the provider plan; dailySendCap is an optional operator tightening on top of it (unset = rely on the plan, 0 = unlimited). All of them are re-checked on the worker path, so scheduled and automation sends respect them too.

Suppression matrix

Bounces and complaints auto-suppress from provider webhooks. Bounce/complaint/manual suppressions block all sends; an unsubscribe blocks lifecycle mail only (transactional receipts/resets still deliver). Complaint suppressions are never removable — not even by an agent.

Automations are created paused

email_create_automation always creates a paused automation. Enabling it (email_set_automation_status) is a separate call that requires confirm: true and validates every step's template is published — a deliberate human decision point.

Credentials never travel over MCP

No tool takes or returns a secret. Connecting a provider (platform sending, or a Resend/SendGrid key), connecting the platform a company is migrating off, and minting API keys all happen on the dashboard's sending settings page, whose URL email_get_connection_status returns as settingsUrl. Keys are stored AES-256-GCM-encrypted; no tool can read or set them.

Confirm literals

Destructive tools (delete, un-suppress, pause) carry a confirm: z.literal(true) gate — a call that omits it is refused, so a destructive action is never one hallucinated argument away.

Every guarantee above is enforced in the cores rather than by withholding tools, so it holds for every credential: an OAuth session is workspace-scoped with write access, and an aem_ key, however it is scoped, is still bound by the same cores — narrower, never wider.

On this page