MCP Server

Connect SMTPfast to an AI assistant (Claude Code, Claude Desktop, Cursor, and other MCP clients) and let it send email, check domain verification, and inspect deliverability through your account.

Connect without an API key (OAuth)

Clients that support MCP authorization (Claude, Cursor and others) can connect with a click instead of a pasted key. Add https://smtpfa.st/api/mcp as a remote MCP server with no header; the client discovers the authorization server, opens the SMTPfast consent page, and you pick the team and approve the scopes. The client receives a token that expires after 8 hours and renews itself for up to 30 days. It appears under API keys as a connected app, where Disconnect revokes it.

  • Discovery: /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server.
  • Standards: OAuth 2.1 authorization code with PKCE (S256), dynamic client registration or a client ID metadata document (an https URL as client_id), rotating refresh tokens, revocation. Public clients only; no client secret.
  • Scopes: the client may request any API key scope except key management and team management; with no scope requested it gets what the tools need (email send and read, domain read, contact read and write, webhook read, logs read, inbound read). Templates are created and published with the email send scope.
  • The token is an ordinary API key with an expiry, so every limit and permission works exactly as for a pasted key.

Endpoint

The MCP server is hosted at a single URL. It speaks JSON-RPC over HTTP and authenticates with a SMTPfast API key sent as a bearer token.

http
POST https://smtpfa.st/api/mcp
Authorization: Bearer sf_your_api_key

Create a key under API Keys in the dashboard. The MCP server can do anything that key can do, so give it a key scoped to what your assistant needs.

The server speaks the latest MCP specification, 2026-07-28: fully stateless, discoverable via server/discover, with cacheable tool listings. Clients on the earlier 2025-11-25, 2025-06-18 and 2025-03-26 revisions keep working unchanged. Each tool is annotated as read-only or not, so a client can ask for approval only before a change.

Connect your client

# OAuth: no key, sign in when Claude Code asks
claude mcp add --scope user --transport http smtpfast https://smtpfa.st/api/mcp

# Or with an API key
claude mcp add --scope user --transport http smtpfast https://smtpfa.st/api/mcp \
  --header "Authorization: Bearer sf_your_api_key"
  • For Cursor, put the JSON in .cursor/mcp.json. For Claude Desktop, put it in claude_desktop_config.json. Both files are plain JSON, so do not add comments to them.
  • In Claude Code, --scope user makes the server available in every project. Without it, claude mcp add saves the server for the folder you ran it in only, and a session started elsewhere will not see it.
  • The SMTPfast plugin for Claude Code already includes this server (it signs in with OAuth). Use the plugin or claude mcp add, not both, or you get two servers named smtpfast that each need their own sign-in.

Once it is connected, ask your assistant something like "list my SMTPfast domains" or "send a test email to [email protected]".

Tools

ToolWhat it does
get_capabilitiesWhat this key can do: scopes, plan tier, rate limit, and which send-time checks apply. Call it first instead of discovering scopes through 403s.
explain_emailWhat happened to one email: status, timeline, bounce or complaint detail, suppression state, next step.
deliverability_reportOne domain over the last N days: counts, bounce and complaint rates, top bounce reasons, DNS health, receiving status.
find_problem_recipientsAddresses that bounced or complained recently, grouped, with whether they are already suppressed and what to do.
check_before_sendSender domain, display name, spam patterns, client compatibility and link reputation in one pass-or-fix list.
send_emailSend an email. Marketing by default; set category to transactional for receipts and resets. Requires a verified sender domain.
send_email_batchSend up to 100 different emails in one call.
list_emailsList sent emails with their delivery status. Filter by status, recipient, or a cursor. Use status=scheduled to see what has not gone out yet.
get_emailGet one email's status and full event history, including why it bounced.
share_emailCreate a read-only link to a sent email that expires.
cancel_scheduled_emailStop an email that has not been sent yet.
reschedule_emailMove a scheduled email to a new time.
list_domainsList sending domains and their DKIM, SPF, and DMARC status.
get_domainOne domain with every DNS record to publish and its status.
add_domainAdd a sending domain and get its DNS records.
claim_domainTake over a domain another account added but never verified.
delete_domainDelete a sending domain. Owners and admins only.
connect_domain_dnsGet a one-click link that adds the DNS records on Cloudflare.
verify_domainTrigger a fresh verification check for a domain.
list_link_domainsList custom link domains with their status and DNS records, or get one.
add_link_domainAdd a link domain such as links.example.com for tracking and unsubscribe links.
refresh_link_domainAsk Cloudflare for a link domain's current status now.
delete_link_domainDelete a link domain. Owners and admins only.
list_suppressionsList suppressed recipients (bounces, complaints, unsubscribes), or get one.
add_suppressionStop sending to one address or up to 100. This is the step explain_email and find_problem_recipients recommend.
remove_suppressionAllow sending to one or up to 100 suppressed addresses again. Owners and admins only.
get_analyticsSending and deliverability stats, optionally scoped to a window and one domain.
get_email_metricsCounts and rates over any range, by period, domain, email or broadcast.
list_clicked_linksTop clicked links across all email, or one link in detail.
get_usageThis month's sends against the plan limit.
list_team_membersWho is on the team and with which role. Needs team:read; inviting and removing people stay with people.
list_contactsList audience contacts, with search so you can find one without paging the list.
list_logsThe event log: every lifecycle event of every sent email, filterable by type, time, recipient, domain or tag. Needs the logs:read scope.
list_received_emailsList emails received on your inbound domains, with filters and the unread count.
get_received_emailRead one received email: bodies, headers, attachments, raw download link (metadata only when quarantined).
list_received_attachmentsGet download links for a received email's attachments (none for quarantined mail).
mark_received_emailsMark received emails read or unread.
get_received_attachmentOne attachment of a received email with a fresh download link.
reply_to_received_emailReply in the same thread to a received email.
delete_received_emailDelete a received email. Needs the inbound:delete scope.
set_domain_receivingTurn inbound receiving on or off for a domain and get the MX record.
list_inboxesList inboxes with their unread thread and draft counts, or get one by id or address.
manage_inboxCreate, rename or delete an inbox on one of your domains. Owners and admins only.
list_inbox_threadsConversations in an inbox folder, with search and label filters, or one thread.
get_inbox_thread_emailsThe messages of a thread, received and sent, with authentication verdicts on received mail.
update_inbox_threadMark a thread read or unread, archive it, move it to spam, or label it.
delete_inbox_threadMove a thread to trash; it is removed after 30 days. Needs the inbound:delete scope.
reply_to_inbox_emailSend a reply from the inbox address now. Prefer save_inbox_draft unless asked to send.
forward_inbox_emailForward a message from the inbox address now.
inbox_labelsList, create, rename, recolor or delete an inbox's labels.
list_inbox_draftsThe drafts waiting for review, or one draft in full.
save_inbox_draftCreate a draft for a person to review and send, or edit one. Sends nothing.
delete_inbox_draftDiscard a draft.
send_inbox_draftSend a reviewed draft. Needs the email:send scope.
list_broadcastsList broadcasts with status and recipient counts. Filter by status or search.
get_broadcastGet one broadcast: content, audience, schedule and delivery counts.
create_broadcastCreate a broadcast as a draft, for all contacts or one segment. Nothing is sent.
send_broadcast_testSend one test copy of a broadcast to a single address.
send_broadcastSend a broadcast to its audience now or at a scheduled time.
cancel_broadcastCancel a scheduled or sending broadcast.
update_broadcastEdit a draft or scheduled broadcast.
delete_broadcastDelete a broadcast that was never sent.
duplicate_broadcastCopy a broadcast into a new draft.
list_broadcast_clicked_linksThe links in a sent broadcast, ranked by clicks.
list_broadcast_recipientsWho received a broadcast, filtered by what happened.
preview_broadcast_audienceHow many contacts a broadcast would reach.
list_templatesList email templates with their status, alias and subject.
get_templateOne template: subject, sender, body and its variables.
save_templateCreate a template or edit its draft. Sends are not affected until it is published.
publish_templatePublish a template's draft so sends use it.
duplicate_templateCopy a template into a new unpublished draft.
delete_templateDelete a template.
send_template_emailSend a published template with variables filled in.
list_segmentsList contact segments with their ids and contact counts.
get_segmentOne segment, and optionally its members.
save_segmentCreate or rename a segment.
delete_segmentDelete a segment. Its contacts stay.
get_contactGet one contact by id or email address.
create_contactAdd a contact, optionally to segments.
update_contactChange a contact's name, properties, subscription state or segments.
delete_contactDelete a contact. Their sent-email history stays.
delete_contactsDelete up to 500 contacts by id.
contact_segmentsList a contact's segments, or add or remove one.
import_contactsAdd up to 500 contacts in one call.
list_contact_propertiesThe custom contact properties broadcasts can merge.
save_contact_propertyDeclare a property or change its fallback value.
delete_contact_propertyDelete a declared contact property.
list_webhooksList webhook endpoints and the events each one receives, or get one.
create_webhookAdd a webhook endpoint. The signing secret is shown once.
delete_webhookDelete a webhook endpoint.
list_webhook_deliveriesRecent delivery attempts for one webhook, or one delivery in full, to see why events are not arriving.
update_webhookChange a webhook's URL or events, or pause it.
test_webhookSend a sample event to a webhook now.
retry_webhook_deliverySend one failed delivery again.
list_webhook_eventsEvents sent to a webhook in Resend's format, one event with its payload, or its delivery attempts.
replay_webhook_eventSend one webhook event again.
rotate_webhook_secretReplace a webhook's signing secret. The new one is shown once.
list_formsSignup forms, or one form with its settings.
preview_form_welcome_emailRender a form's welcome email without sending it.
save_formCreate or edit a signup form.
delete_formDelete a signup form.
manage_pending_signupsList, approve or remove signups waiting on double opt-in.

Try it with curl

List the available tools:

bash
curl -sS https://smtpfa.st/api/mcp \
  -X POST \
  -H "Authorization: Bearer sf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Call a tool to send an email:

bash
curl -sS https://smtpfa.st/api/mcp \
  -X POST \
  -H "Authorization: Bearer sf_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 2,
    "method": "tools/call",
    "params": {
      "name": "send_email",
      "arguments": {
        "from": "[email protected]",
        "to": "[email protected]",
        "subject": "Hello from MCP",
        "text": "Sent by an AI assistant through SMTPfast."
      }
    }
  }'

Inboxes: let an agent draft and a person send

The inbox tools let an assistant work through a support or sales address: read threads, check the SPF, DKIM and DMARC verdicts before trusting a message, label and archive, and write replies. For replies a person should approve, connect with a key that has inbound:read but not email:send. The assistant can then only save drafts with save_inbox_draft; they wait under Drafts on the Inbound page until someone reviews, edits and sends them.

See Inboxes for the API behind these tools.

How it works

Every tool call runs against the same v1 REST API, so the same rules apply: sending requires a verified sender domain, rate limits and plan quotas are enforced, and suppressed recipients are skipped. Your API key is validated on each request.

Most MCP clients show each tool call for your approval before running it, so you stay in control of what your assistant sends.

The endpoint is stateless (JSON-RPC request and response, no streaming session). It takes a bearer API key, or OAuth if your client supports it, as described above. If your client needs a streaming connection, let us know.