# AISend MCP connector: email your AI agent operates and you supervise

- **What it is:** AISend is a paid transactional email API built for AI agents to operate and humans to supervise: an agent sends from your verified domain, checks delivery and validates addresses over MCP or a Resend-compatible API, while you approve, review and can revoke access.
- **Primary user:** An AI agent (ChatGPT, Claude, Cursor, Gemini CLI or any MCP client) operates it: sends email, checks delivery, validates addresses. A human tags the work, approves the connection, reviews what the agent did and can revoke access.
- **Who pays for it:** Product and engineering teams at SaaS companies and agencies that send password resets, receipts and notifications from their own domains, and individuals or small businesses who want an assistant to send and track email from a domain they own.
- **What it does not do:** Cold outreach, purchased lists, bulk marketing or newsletters. No campaigns or automations. No free plan and no free sending: an account needs an active paid plan before it can send. Sending to anyone other than your own account address needs a domain you have verified.
- **Price:** From $14/month (Pro, 50,000 emails/month), billed monthly per account. Business $63/month for 100,000 emails/month; Scale $149/month for 500,000 emails/month (daily cap 5,000, about 150,000 a month today). No per-email overage charges. No free plan.
- **Integrations:** MCP (hosted https://api.aisend.app/mcp and local npx aisend-mcp), Resend-compatible REST API, Node.js SDK (aisend-email), HMAC-SHA256 signed webhooks, delivery through AWS SES.
- **Security and data:** Sends through AWS SES. Data encrypted in transit (TLS); API keys stored hashed. OAuth 2.1 with PKCE for assistants; the key an OAuth sign-in creates works only on the MCP endpoint, expires after 90 days, is limited to 100 emails a day and can be revoked on the API Keys page.
- **Start in minutes:** Create an account (free), add a domain you own and publish its DNS records (propagation time varies), subscribe to a plan, then connect an assistant at https://aisend.app/mcp (about a minute) or create an API key.
- **MCP:** https://api.aisend.app/mcp (Streamable HTTP, OAuth or API key). Official MCP Registry name: app.aisend/aisend.

## Agent quickstart

### 1. Discover
- Plain-text summary: https://aisend.app/llms.txt (full: https://aisend.app/llms-full.txt)
- Markdown pages: https://aisend.app/mcp.md, https://aisend.app/pricing.md, https://aisend.app/index.md
- MCP server card: https://aisend.app/.well-known/mcp/server-card.json
- Official MCP Registry: app.aisend/aisend at registry.modelcontextprotocol.io

### 2. Authenticate
- **OAuth sign-in by the human owner (recommended for assistants).** Connect to https://api.aisend.app/mcp. An unauthenticated request gets HTTP 401 with a WWW-Authenticate header pointing at the protected-resource metadata, so an OAuth-capable client discovers the authorization server, registers itself (RFC 7591) and runs the authorization-code flow with PKCE S256. The owner signs in on aisend.app and presses Approve. The result is an API key named "MCP OAuth: <client>" that works only on the MCP endpoint, expires after 90 days (reconnect after that), is limited to 100 emails a day and can be revoked on the API Keys page.
- **API key as a Bearer header.** Send Authorization: Bearer re_... to the hosted server or the REST API (https://api.aisend.app/api/v1/...). A key the owner created has the account's full API access and does not expire until revoked.
- **Self-serve agent signup (local server or REST).** POST https://api.aisend.app/api/v1/auth/agent-signup with {"name": "<agent name>"} (the local MCP tool agent_signup does the same) returns an API key without a browser. The account cannot send yet: a human must subscribe to a plan and the account needs a verified sending domain. The hosted server does not offer this tool.

### 3. Minimal call sequence
1. See which sender domains are usable

```json
list_domains({})
```
Verified and pending domains. Send only from a verified one.

2. Optionally validate the recipient

```json
validate_email({
  "email": "customer@example.com"
})
```
Format, MX, disposable and role-address checks. Counts against the monthly validation quota.

3. Send

```json
send_email({
  "from": "Acme <hello@acme.com>",
  "to": "customer@example.com",
  "subject": "Your receipt",
  "html": "<p>Thanks for your order.</p>",
  "idempotency_key": "order-1042-receipt"
})
```
The email id. If the content gate holds the message the response is { id, status: "quarantined" } and nothing has been sent yet.

4. Confirm the outcome

```json
get_email_status({
  "email_id": "<id from step 3>"
})
```
Status is one of queued, sending, sent, delivered, failed, bounced, complained or quarantined. Report it as returned; do not claim delivery before status is delivered.

5. Audit recent activity

```json
list_emails({
  "limit": 10
})
```
{ emails: [{ id, from, to, subject, status, createdAt, opened, clicked }], count, offset, nextOffset? } without bodies.

### 4. Limits and quotas
- Recipients per send: up to 50.
- Monthly quota by plan: Pro 50,000 emails/month; Business 100,000 emails/month; Scale 500,000 emails/month (daily cap 5,000, about 150,000 a month today).
- Daily cap by plan (UTC day): Pro 2,500, Business 5,000, Scale 5,000. New accounts ramp up: 50 a day in the first 24 hours, 200 until day 3, 500 until day 7, 1,000 until day 14, then the plan cap. A newly verified domain has its own lower cap for its first week.
- An OAuth-created connection is limited to 100 emails a day, whatever the plan.
- Request rate per API key: 50 requests/second on Pro, 100 on Business and Scale, 10 when the account cannot send. Over the limit: HTTP 429 with Retry-After: 1 and X-RateLimit-Limit / X-RateLimit-Remaining headers.
- Monthly validation quota by plan: Pro 5,000, Business 25,000, Scale 100,000.

### 5. Idempotency
- idempotency_key is required on send_email (up to 255 characters; sent as the Idempotency-Key header).
- Retrying with the same key and the same request returns the first result and sends nothing new.
- Reusing a key for a different request fails with HTTP 409, code IDEMPOTENCY_KEY_REUSED. Use a new key for a different email.
- Use a key derived from the business event (for example order-1042-receipt) so a restarted agent does not send a second copy.

### 6. Errors the agent must handle
| HTTP | Signal | Meaning | Agent should |
|---|---|---|---|
| 402 | code paid_plan_required or subscription_inactive (REST also returns upgradeUrl) | The account has no active paid plan, or the subscription lapsed. | Stop. Do not retry. Hand off to the human owner to subscribe. Nothing was sent. |
| 429 | message about the daily or monthly limit, the connection's daily limit or a new domain's limit | A sending quota is used up. The daily limits reset at the start of the next UTC day. | Do not loop. Tell the human which limit was hit; retry after the reset or let them upgrade. |
| 429 | Rate limit exceeded. Please slow down. (Retry-After: 1) | Too many requests in one second. | Wait one second and retry with the same idempotency_key. |
| 403 | message: domain not verified, account email not verified, account suspended, content refused, or sender change refused | The send is declined, not malformed. Domain and email verification and suspension need the human owner. | Do not retry. Report the message to the human. |
| 422 | Validation failed, invalid or suppressed recipient, bad subject, too many recipients | The request is wrong, or the address previously bounced or complained and is suppressed. | Fix the input or drop that recipient. Do not retry unchanged. |
| 409 | code IDEMPOTENCY_KEY_REUSED | The key was already used for a different request. | Generate a new key for the new email. |
| 202 | response { id, status: "quarantined" } | The content gate held the message for review. It has not been sent and is sent only if it is released. | Tell the human it is held; poll get_email_status rather than sending it again. |
| 401 | Invalid or revoked token (MCP), WWW-Authenticate header | The key was revoked or the OAuth connection expired (90 days). | Ask the human owner to reconnect. |
| 503 | message: sending is paused | AISend has paused sending platform-wide. | Retry later; report to the human if it persists. |

Over MCP a failed call returns an error result whose text is "AISend API request failed (<status>): <message>". The machine-readable code field and upgradeUrl are returned by the REST API; the MCP text carries the status and the message, so match on both. The ChatGPT connector endpoint replaces plan and billing messages with a neutral note that the account cannot do that right now because of its limits.

### 7. Hand off to the human
- Before the first send in a conversation, show the human the sender, recipients, subject and body and wait for a clear yes (most clients also prompt on send_email because it is marked destructive).
- After sending, report the email id and the status exactly as returned, and tell the human where to review it: the Emails page of the AISend dashboard.
- For 402, 403 domain or email verification, and 429 limits: stop and give the human the exact message; these are decisions or actions only the account owner can take.
- Never ask the human to paste an API key into the chat; use the OAuth sign-in or an environment variable.

## Human oversight: what you can see, approve and revoke
| You can | How |
|---|---|
| Approve or refuse a connection | The OAuth consent screen names the client, the account and the redirect host, lists what the assistant will be able to do (send from verified domains under normal limits, read sent emails and delivery status, validate addresses, list domains and API key names) and has Approve and Deny buttons. |
| Approve each send, in clients that ask | send_email is annotated destructive and not read-only, and the reads are annotated read-only, so clients that confirm tool calls ask before a send. That prompt is the client's setting; AISend does not enforce it. |
| Revoke access | Every OAuth connection is an API key on the API Keys page. Revoking it makes the next call fail with 401. Connections also expire after 90 days. |
| See what was created | API Keys page: key names, prefixes and revoked state (the assistant's connection appears as "MCP OAuth: <client>"). Emails page: every sent email with its delivery status. |
| Bound the blast radius | An OAuth-created assistant connection is capped at 100 emails a day; a key the owner creates is not, and has the plan's daily cap instead. Plan quotas, the daily cap, new-account ramp-up, new-domain caps, the verified-domain requirement, suppression of bounced and complained addresses and the content gate apply to every send, from an agent or not. |
| Watch events as they happen | Webhooks deliver sent, delivered, opened, clicked, bounced and complained events, signed with HMAC-SHA256, to an endpoint the human controls. |

## Tools (hosted server: https://api.aisend.app/mcp)
| Tool | What it does | Hints |
|---|---|---|
| `send_email` | Send one email through AISend. This delivers real mail right away and cannot be recalled. Requires an account with an active sending plan. The `from` address must be on a verified sending domain. idempotency_key is required: each distinct key sends one email, and a repeated key returns the first result instead of sending a second copy. Returns the email id. | destructive |
| `get_email_status` | Get one sent email by its ID: delivery status, recipients, subject and body. | read-only, idempotent |
| `list_emails` | List sent emails, newest first, as a compact summary (id, from, to, subject, status, createdAt, opened, clicked). Bodies are left out. Paging uses offset; the response includes nextOffset when more results may remain. | read-only, idempotent |
| `validate_email` | Validate an email address. Checks format, MX records, disposable providers, and role-based addresses. Each call counts against the account's monthly validation quota. | writes, not destructive, idempotent |
| `list_domains` | List all verified and pending sending domains. | read-only, idempotent |
| `list_api_keys` | List the API keys on the current account (name and prefix only; the full key is not included). | read-only, idempotent |

The local server (`npx -y aisend-mcp`) has the same tools plus: `create_api_key`, `agent_signup`.

## Install
- ChatGPT: add https://api.aisend.app/mcp (or https://api.aisend.app/mcp/chatgpt: same tools, plan and billing messages replaced by a neutral note) as a custom MCP connector (developer mode; depends on your plan), sign in, Approve.
- Claude (claude.ai): Settings, Connectors, add custom connector https://api.aisend.app/mcp.
- Claude Code: `claude mcp add --transport http aisend https://api.aisend.app/mcp`, or `/plugin marketplace add airdropfi/aisend-claude-plugin` then `/plugin install aisend@aisend-plugins`.
- Cursor: `url` https://api.aisend.app/mcp plus `Authorization: Bearer re_...` header in mcp.json (https://github.com/airdropfi/aisend-cursor-kit).
- Gemini CLI: `gemini extensions install https://github.com/airdropfi/aisend-gemini-extension`, then `/mcp auth aisend`.
- Local, any client: `npx -y aisend-mcp` with `AISEND_API_KEY`.
- Registry: app.aisend/aisend

## Prompts to copy
### Individual
- Use AISend to list my verified sending domains and tell me which one I should send from. Do not send anything.
- Assign to AISend: email hello@example.com the meeting notes below from my verified domain. Show me the exact message first and send only after I say yes.

### Small business
- Use AISend to validate these 20 customer addresses and list the ones that are disposable or role-based. Show me the list so I can decide.
- Use AISend to show the status of the last 10 emails we sent and flag any that bounced or complained.

### Agency or team
- Assign to AISend: send the approved invoice reminder to billing@client.example from our verified domain with idempotency key invoice-2026-11-reminder. Show me what you did so I can review it.
- Use AISend to list every email to client.example this week with its status, so I can approve what goes in the report.

### Developer
- Use AISend to send a test receipt to me@mycompany.com from our verified domain and then check its delivery status until it is delivered or bounced.
- Use AISend to list my last 50 emails with status failed or bounced and summarise the likely causes. Do not resend anything.

## FAQ
### How do I send email from ChatGPT with AISend?
Add https://api.aisend.app/mcp as a custom MCP connector in ChatGPT (developer mode and custom connectors depend on your ChatGPT plan), sign in to AISend when prompted and approve the connection. Then ask ChatGPT to send or look up email. The alternative endpoint https://api.aisend.app/mcp/chatgpt has the same tools and sign-in but replaces messages about plans and billing with a neutral note; it is the endpoint used for the ChatGPT app submission. You need an AISend account with an active plan and a verified sending domain to send to other people.

### How do I use AISend from Claude?
In claude.ai add https://api.aisend.app/mcp as a custom connector and sign in with OAuth. In Claude Code run "claude mcp add --transport http aisend https://api.aisend.app/mcp", or install the plugin with "/plugin marketplace add airdropfi/aisend-claude-plugin" and "/plugin install aisend@aisend-plugins". Claude Desktop can also run the local server with "npx -y aisend-mcp".

### Does it work with Cursor and Gemini CLI?
Yes. Cursor connects to the hosted server with your AISend API key as a Bearer header (the airdropfi/aisend-cursor-kit repository has the config, rule and skills). Gemini CLI installs the airdropfi/aisend-gemini-extension extension and signs in with OAuth through /mcp auth aisend.

### Is the AISend MCP connector free?
The connector itself costs nothing, but AISend is a paid email service: an account needs an active plan before it can send. Plans start at $14/mo for 50,000 emails. You can create an account, verify a domain and connect the assistant before subscribing; a send without an active plan is rejected with HTTP 402.

### What can the assistant do and not do?
It can send email from your verified domain, check delivery status, list recent emails, validate addresses, and list your domains and API keys. The hosted server cannot create API keys or accounts. Every send goes through the same limits, domain checks and abuse screening as a direct API call, and a send cannot be recalled once delivered.

### What does signing in create, and how do I revoke it?
Approving the OAuth sign-in gives the assistant an API key named after the client (for example "MCP OAuth: Claude"). That key works only on the MCP endpoint, expires after 90 days, sends at most 100 emails a day, and can be revoked on the API Keys page of your AISend dashboard.

### Is AISend listed in the Official MCP Registry?
Yes. The server is published as app.aisend/aisend in the Official MCP Registry (registry.modelcontextprotocol.io), with the npm package aisend-mcp and the hosted Streamable HTTP endpoint https://api.aisend.app/mcp.

### Can an AI agent use AISend without a human?
An agent can operate it, a human has to authorise it. The agent can create an account itself with the agent_signup tool (local server) or POST /api/v1/auth/agent-signup, but the account cannot send until a human subscribes to a plan and a sending domain is verified. With the hosted server the human owner signs in with OAuth and approves the connection.

### How does a human stay in control of what the agent sends?
The owner approves the connection on the OAuth consent screen, can revoke it on the API Keys page and sees every sent email and its status on the Emails page. An OAuth-created connection is capped at 100 emails a day; a key you create yourself has your plan's daily cap. send_email is marked destructive, so clients that confirm tool calls ask before each send; that prompt is the client's setting, not enforced by AISend.

Human page: https://aisend.app/mcp
