Transactional and broadcast email at cost. Your agent signs up, tests and sends; no API key.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Bearer <connection token>. Mint one with `npx sendforai sandbox` then `npx sendforai token`.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Returns a checkout_url for your human operator to add prepaid credit (minimum $10). Use it when a send returns balance_required. $5 is taken only in months you send to anyone outside your own domains (10,000 emails included), then $0.11/1k at cost. Pass auto_topup: true to let their saved card refill the balance automatically, always within the budget they set. Never pay it yourself; hand the link over. account.topped_up appears in list_events when they finish.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http mcp https://sendforai.com/mcp \ --header 'Authorization: Bearer YOUR_TOKEN'
Headers
Authorization (required): Bearer <connection token>. Mint one with `npx sendforai sandbox` then `npx sendforai token`.Returns a checkout_url for your human operator to add prepaid credit (minimum $10). Use it when a send returns balance_required. $5 is taken only in months you send to anyone outside your own domains (10,000 emails included), then $0.11/1k at cost. Pass auto_topup: true to let their saved card refill the balance automatically, always within the budget they set. Never pay it yourself; hand the link over. account.topped_up appears in list_events when they finish.
| Argument | Type | Description |
|---|---|---|
| amount_usd | number | |
| auto_topup | boolean |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"amount_usd": {
"type": "number",
"minimum": 10
},
"auto_topup": {
"type": "boolean"
}
}
}Let this account send from another domain with the same key. First publish DNS TXT _sendforai.<domain> = "v=sfa1; delegate=<identity domain>" (if you have DNS access) or hand that record to your operator, then call this. If the record is not visible yet the response says exactly what to publish. Up to 50 domains, no fee; each keeps its own reputation and warmup.
| Argument | Type | Description |
|---|---|---|
| domain* | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"domain"
],
"properties": {
"domain": {
"type": "string"
}
}
}A Stripe billing portal link for your operator: update the saved card and download receipts.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Cancel a broadcast before or during sending. Emails already sent stay sent; the unsent remainder is cancelled.
| Argument | Type | Description |
|---|---|---|
| id* | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
}Create a broadcast to subscribed contacts (optionally filtered by contact data). By default it waits for a human: the response includes approval_url. Hand that link to your operator; clicking it sends. Use dry_run to see recipients, cost, and lint first.
| Argument | Type | Description |
|---|---|---|
| from* | string | |
| html | string | |
| text | string | |
| filter | object | Match contacts whose data contains these keys, e.g. { plan: 'pro' } |
| dry_run | boolean | |
| subject* | string | |
| markdown | string | |
| max_cost_usd | number | |
| require_approval | boolean | Default true. Set false only if your operator has already approved. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from",
"subject"
],
"properties": {
"from": {
"type": "string"
},
"html": {
"type": "string"
},
"text": {
"type": "string"
},
"filter": {
"type": "object",
"description": "Match contacts whose data contains these keys, e.g. { plan: 'pro' }",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"number",
"boolean"
]
}
},
"dry_run": {
"type": "boolean"
},
"subject": {
"type": "string"
},
"markdown": {
"type": "string"
},
"max_cost_usd": {
"type": "number"
},
"require_approval": {
"type": "boolean",
"description": "Default true. Set false only if your operator has already approved."
}
}
}Balance, whether this month's $5 sending fee is paid, auto top-up, the monthly usage budget (used and remaining), emails used and included remaining, and every sending domain. Check this before a large send.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Status, cost, approval_url (while awaiting approval), and progress (sent, queued, failed, cancelled, resumes_at) once sending starts.
| Argument | Type | Description |
|---|---|---|
| id* | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
}How many emails can be sent right now: daily cap, sent today, remaining, warmup stage, and when the window resets.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Identity, SES verification status, DNS records still needed, and current sending capacity for the configured domain.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Public, machine-readable pricing. Use it to compute cost before committing to a send.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Emails sent this period, SES cost, what has been billed, included allowance remaining, and a projection to period end.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Bulk import up to 10,000 contacts per call, deduplicated by email. Available in a sending month; on the free build tier the error explains what to do.
| Argument | Type | Description |
|---|---|---|
| contacts* | array |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"contacts"
],
"properties": {
"contacts": {
"type": "array",
"items": {
"type": "object",
"required": [
"email"
],
"properties": {
"data": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"email": {
"type": "string"
},
"subscribed": {
"type": "boolean"
}
}
},
"maxItems": 10000,
"minItems": 1
}
}
}Page through contacts.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| cursor | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"limit": {
"type": "integer",
"maximum": 1000,
"minimum": 1
},
"cursor": {
"type": "string"
}
}
}Every domain this account can send from, with role (identity or delegated), status, SES status, warmup stage and daily cap.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}Pull delivery, bounce, complaint, broadcast, and unsubscribe events by cursor. No webhook endpoint needed. Keep next_cursor between calls.
| Argument | Type | Description |
|---|---|---|
| type | string | |
| limit | integer | |
| cursor | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"type": {
"type": "string"
},
"limit": {
"type": "integer",
"maximum": 1000,
"minimum": 1
},
"cursor": {
"type": "string"
}
}
}Everything send_email does except sending. Returns cost, capacity after send, suppression hits, and lint warnings with fixes. Call this before send_email when cost or deliverability matters.
| Argument | Type | Description |
|---|---|---|
| to* | any | Recipient address or list (max 50) |
| from* | string | Sender address on the configured domain, e.g. [email protected] or 'Name <[email protected]>' |
| html | string | |
| text | string | |
| stream | string | |
| subject* | string | |
| markdown | string | Markdown body. Rendered to responsive HTML plus a text part. Preferred. |
| reply_to | string | |
| max_cost_usd | number | Refuse if the billed cost would exceed this |
| idempotency_key | string | Safe retries: same key returns the original result |
Starts sending an approved broadcast in the background (status: sending). Poll get_broadcast for progress. Large Member broadcasts continue after the daily cap resets. Returns a 409 with the approval_url if a human has not approved it yet.
| Argument | Type | Description |
|---|---|---|
| id* | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"id"
],
"properties": {
"id": {
"type": "string"
}
}
}Send a transactional email from the configured domain. Response includes id, cost, capacity, lint, and a signed receipt.
| Argument | Type | Description |
|---|---|---|
| to* | any | Recipient address or list (max 50) |
| from* | string | Sender address on the configured domain, e.g. [email protected] or 'Name <[email protected]>' |
| html | string | |
| text | string | |
| stream | string | |
| subject* | string | |
| markdown | string | Markdown body. Rendered to responsive HTML plus a text part. Preferred. |
| reply_to | string | |
| max_cost_usd | number | Refuse if the billed cost would exceed this |
| idempotency_key | string | Safe retries: same key returns the original result |
Turn auto top-up off, or change its amount. Turning it on requires a saved card from a human-completed add_credit.
| Argument | Type | Description |
|---|---|---|
| enabled* | boolean | |
| amount_usd | number |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean"
},
"amount_usd": {
"type": "number",
"minimum": 10
}
}
}Lowering the budget applies immediately. Raising it returns an approval_url that only your human operator can approve; hand it over. Use when a send returns budget_exceeded.
| Argument | Type | Description |
|---|---|---|
| monthly_usd* | number |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"monthly_usd"
],
"properties": {
"monthly_usd": {
"type": "number",
"minimum": 0
}
}
}Store a contact for broadcasts. Contacts are unlimited on every plan. Data is arbitrary JSON you can filter on later.
| Argument | Type | Description |
|---|---|---|
| data | object | |
| email* | string | |
| subscribed | boolean |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"email"
],
"properties": {
"data": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"email": {
"type": "string"
},
"subscribed": {
"type": "boolean"
}
}
}Create the SES identity for a domain on this account (default: the configured identity domain) and return the DKIM and MAIL FROM records to publish. Idempotent; call again to re-check.
| Argument | Type | Description |
|---|---|---|
| domain | string |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"domain": {
"type": "string"
}
}
}The identity this server acts as, how it authenticates, and whether it is a sandbox.
No arguments.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {}
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 13, 2026.
No readOnlyHint / destructiveHint annotations, so clients can't tell a read from a write without asking.
Fix: Add annotations to each tool, e.g. { readOnlyHint: true } for tools that only read.
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from",
"to",
"subject"
],
"properties": {
"to": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"maxItems": 50
}
],
"description": "Recipient address or list (max 50)"
},
"from": {
"type": "string",
"description": "Sender address on the configured domain, e.g. [email protected] or 'Name <[email protected]>'"
},
"html": {
"type": "string"
},
"text": {
"type": "string"
},
"stream": {
"enum": [
"transactional",
"broadcast"
],
"type": "string"
},
"subject": {
"type": "string"
},
"markdown": {
"type": "string",
"description": "Markdown body. Rendered to responsive HTML plus a text part. Preferred."
},
"reply_to": {
"type": "string"
},
"max_cost_usd": {
"type": "number",
"description": "Refuse if the billed cost would exceed this"
},
"idempotency_key": {
"type": "string",
"description": "Safe retries: same key returns the original result"
}
}
}{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"from",
"to",
"subject"
],
"properties": {
"to": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"maxItems": 50
}
],
"description": "Recipient address or list (max 50)"
},
"from": {
"type": "string",
"description": "Sender address on the configured domain, e.g. [email protected] or 'Name <[email protected]>'"
},
"html": {
"type": "string"
},
"text": {
"type": "string"
},
"stream": {
"enum": [
"transactional",
"broadcast"
],
"type": "string"
},
"subject": {
"type": "string"
},
"markdown": {
"type": "string",
"description": "Markdown body. Rendered to responsive HTML plus a text part. Preferred."
},
"reply_to": {
"type": "string"
},
"max_cost_usd": {
"type": "number",
"description": "Refuse if the billed cost would exceed this"
},
"idempotency_key": {
"type": "string",
"description": "Safe retries: same key returns the original result"
}
}
}