MCP server
Give an agent the ability to send, inspect, explain, and remediate email — with evidence attached and approval gates on anything consequential.
The OutSend MCP server exposes sending and observability to agents over the Model Context Protocol. The design rule is simple: every tool returns the evidence behind its answer, and nothing consequential happens without a human.
Connect
npx -y @outsend/mcp
Most MCP clients take a config block like this:
{
"mcpServers": {
"outsend": {
"command": "npx",
"args": ["-y", "@outsend/mcp"],
"env": { "OUTSEND_API_KEY": "..." }
}
}
}
Scope the key to a single domain when the agent only needs one. The server cannot widen its own scope.
Tools
Sending
| Tool | What it does |
|---|---|
send_email | Sends a message. Accepts an idempotency key, and requires one for anything the agent might retry. |
schedule_email | Same, with a scheduled_at. |
cancel_scheduled | Cancels a queued message before it goes. |
Inspection
| Tool | What it does |
|---|---|
get_trace | Full lifecycle of one message, every event with the provider’s raw response. |
search_events | Filter by type, recipient, domain, and time range. |
get_message | The message itself: headers, bodies, stream, source. |
webhook_deliveries | Attempts, response codes, and bodies for a webhook endpoint. |
Diagnosis
| Tool | What it does |
|---|---|
explain_failures | Takes a set of failures and returns provider concentration, the likely signal, the evidence supporting it, and explicit uncertainty. |
check_reputation | Current reputation state per domain and workspace, with the events that moved it. |
check_domain | DNS record state, propagation, and SPF duplication. |
Remediation — approval-gated
| Tool | What it does |
|---|---|
propose_remediation | Returns a plan with an id: what it would change, why, and what evidence supports it. Changes nothing. |
apply_remediation | Executes a plan. Requires human approval, and the approval is recorded with the plan id. |
Why the gate
An agent that can change routing, edit DNS, or alter account state without a
human in the loop is a liability, not a feature. propose_remediation is designed
to be the terminal step of an autonomous run: it produces something a person can
read, check against the evidence, and approve in one action.
The split is deliberate. Reading and diagnosing are safe and unbounded. Changing things is bounded and logged.
What a run looks like
› inspect failed password-reset deliveries since 09:00
search_events → matched 17 messages
explain_failures→ provider concentration: Outlook
signal: temporary reputation deferral
evidence: event trace + provider response
uncertainty: 2 of 17 lack a provider response
› what should we do about it
propose_remediation → plan_7d3a
slow route to Outlook for 6h
verify DKIM alignment on alerts@yourdomain.com
approval required
› verify recovery
check_reputation → Gmail healthy · Outlook recovering · Yahoo healthy
aggregate-only verdict: rejected
That last line is the point. The server will not return a single aggregate health verdict, because an aggregate is exactly the thing an agent cannot reason about.
Uncertainty is a field, not a footnote
Every diagnostic tool returns what it could not determine alongside what it could. If two of seventeen failures have no provider response stored, that is in the response — not rounded away to make the answer look cleaner.
Self-hosted instances
{ "env": { "OUTSEND_API_KEY": "...", "OUTSEND_BASE_URL": "https://mail.yourcompany.com/api/v1" } }
The MCP server is part of the open core. Point it at your own instance and it behaves identically.