Connecting IDEs & AI coding assistants
SadaSend runs a hosted, remote Model Context Protocol (MCP) server at https://mcp.sadasend.com over streamable HTTP. There is nothing to install locally and no background daemon to maintain.
Configure your AI coding environment by adding the server block to your client configuration file. Replace sada_live_sk_… with an API key from your dashboard (or an agent key with approval mode):
// Universal MCP JSON Configuration (Antigravity, Cursor, Cline, Claude Desktop, Windsurf)
{
"mcpServers": {
"sadasend": {
"url": "https://mcp.sadasend.com",
"headers": {
"Authorization": "Bearer sada_live_sk_your_api_key_here"
}
}
}
}| Client / IDE | Configuration File Location | Setup Instructions |
|---|---|---|
| Google Antigravity | ~/.gemini/config/mcp_config.json (global) or .gemini/mcp_config.json | Add remote SSE/HTTP server block under mcpServers.sadasend. Tools register automatically across Antigravity IDE and CLI. |
| Cursor IDE | .cursor/mcp.json (project root) or Cursor Settings → Features → MCP | Add server entry under mcpServers.sadasend. Active tools immediately surface in Cursor Composer and Agent mode. |
| Cline (VS Code) | cline_mcp_settings.json (Click MCP icon in Cline header → Edit) | Add sadasend server entry under mcpServers. Cline connects directly over streamable HTTP. |
| Claude Desktop | ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\... (Win) | Paste the mcpServers configuration into your config file and restart Claude Desktop. |
| Windsurf (Codeium) | ~/.codeium/windsurf/mcp_config.json | Add serverUrl and Authorization header under mcpServers.sadasend for Cascade workflows. |
Connecting Terminal CLIs & LLMs (Claude Code, OpenCode, Codex, cURL)
For command-line agent runners, custom OpenAI Swarm / Codex scripts, or terminal workflows, connect directly using the CLI commands or HTTP JSON-RPC endpoint below:
# 1. Claude Code CLI:
claude mcp add --transport http sadasend https://mcp.sadasend.com \
--header "Authorization: Bearer $SADASEND_API_KEY"
# 2. OpenCode CLI:
opencode mcp add sadasend --url https://mcp.sadasend.com \
--header "Authorization: Bearer $SADASEND_API_KEY"
# 3. Raw HTTP / JSON-RPC 2.0 (cURL, ChatGPT Custom Actions, OpenAI Codex):
curl -s -X POST https://mcp.sadasend.com \
-H "Authorization: Bearer $SADASEND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "preview_email",
"arguments": {
"from": "notifications@yourdomain.com",
"to": "user@example.com",
"subject": "Agent Test Preview",
"text": "Hello from autonomous agent!"
}
}
}'The 11 tools an agent gets
Every tool is dynamically filtered by the scopes on the key you connect with. A read-only key sees strictly read tools and never sees send tools — an agent cannot plan around or retry an action it will always be refused.
| Tool | Scope | Does |
|---|---|---|
| send_email | send | Send transactional email with automatic channel ("mcp") and agent attribution, subject to allowlist, quota, and approval mode |
| preview_email | send | Preflight dry run — renders and validates recipients, never sends |
| get_email_status | read | Delivery state and event timeline without leaking email body |
| search_emails | read | Find messages by recipient, subject, tag, or status |
| list_domains | read | Sending domains on the account and verification state |
| check_domain_setup | domains | Live DNS lookup for SPF, DKIM, and DMARC with remediation advice |
| list_templates | read | Registered templates on the account with versions |
| render_template | read | Render a Liquid template with variables without sending |
| check_suppression | read | Whether an address is suppressed (bounce, complaint, unsubscribe) and why |
| get_stats | read | Bounce and complaint rates over a window up to 90 days |
| build_utm_url | read | Build and normalize standardized UTM campaign URLs with automatic parameter validation |
Automatic agent attribution & provenance
Every email dispatched via MCP is automatically stamped with channel: "mcp" and source: "agent".
The agent can pass an optional agent_name argument (e.g. "Refund Assistant" or "Support Agent"). If omitted, SadaSend auto-resolves the name from the client handshake (claude-code, cursor) or the key’s configured agent persona.
These dimensions are indexed immediately and roll up into GET /account/stats?provenance=true, giving human operators real-time breakdown matrices by channel, source, and top agent across their entire organization.
{
"name": "send_email",
"arguments": {
"from": "support@yourdomain.com",
"to": "customer@example.com",
"subject": "Ticket #4092 resolved",
"html": "<p>Your inquiry has been resolved.</p>",
"agent_name": "Support Agent",
"tags": ["support", "resolution"]
}
}Model reasonability: refusals vs transport faults
When a guardrail blocks an action — an unauthorized recipient, an unverified domain, or a missing scope — SadaSend answers with standard JSON-RPC tool content flagged with isError: true.
Returned as tool text, the model reads "Recipient stranger@external.com is outside this key's allowlist" and can reason about the restriction or self-correct. Returned as a transport fault, the agent treats the server as broken and retries blindly.
Approval mode: human-in-the-loop
A key minted in approval mode (sada_agent_sk_…) accepts sends and marks them pending_approval. The agent receives confirmation that the email was accepted and held in the account queue.
Nothing hits the wire until a person reviews the draft in the dashboard and clicks Approve. This allows autonomous agents to operate with full drafting power and zero public blast radius.
What is deliberately absent
There is no create_api_key, no delete_domain, and no remove_suppression tool. Not scope-gated — completely absent. Any attempt to invoke them returns standard JSON-RPC -32601 METHOD_NOT_FOUND.
An agent that can mint its own credentials has no ceiling, and one that can remove a suppression can burn your domain reputation with mailbox providers. Those actions live strictly in the dashboard with human session authentication.
Transport security
The server sends no unsolicited notifications, so GET requests for SSE are declined with 405 sse_not_offered. Clients fall back to POST without complaint.
Origin headers from untrusted browser domains are refused with 403 origin_not_allowed to protect against DNS rebinding attacks. Native clients (Claude Code, Cursor) send no Origin header and connect cleanly.