# supersendtx-mcp

MCP server for [SuperSend TX](https://ranla.ai) — send email and manage domains, webhooks, suppressions, and templates from Cursor, Claude Code, and other MCP clients, and talk to Ranla, the agent in the same account.

**Install:** `npx -y supersendtx-mcp` · **Docs:** https://docs.ranla.ai/ai/mcp

## Transports

| Mode | Command / URL | Auth |
|------|---------------|------|
| **stdio** (default) | `npx -y supersendtx-mcp` | `SUPERSENDTX_API_KEY=stx_…` or `rnl_…` |
| **HTTP** (local) | `npx -y supersendtx-mcp --http --port 3000` | `Authorization: Bearer stx_…` or `rnl_…` on each request |
| **HTTP** (hosted) | `https://mcp.ranla.ai/mcp` | **OAuth** (default) or `Authorization: Bearer stx_…` or `rnl_…` |

Create API keys on the dashboard **API keys** page. `RANLA_API_KEY` works in place of `SUPERSENDTX_API_KEY`. Optional: `SUPERSENDTX_API_URL` sets the mail API base URL (default `https://api.supersendtx.com`). Over HTTP the server reads only the `Authorization` header.

Local HTTP endpoint: `http://127.0.0.1:3000/mcp` · health: `GET /health`  
Hosted health: `GET https://mcp.ranla.ai/health`

Hosted OAuth: add only `"url": "https://mcp.ranla.ai/mcp"`. The client opens a browser to sign in on `app.ranla.ai`; click **Allow access**. `https://mcp.supersendtx.com/mcp` is the same server, and existing configs keep working. A Bearer key still works for advanced setups.

---

## Cursor (stdio)

`.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "supersendtx": {
      "command": "npx",
      "args": ["-y", "supersendtx-mcp"],
      "env": {
        "SUPERSENDTX_API_KEY": "stx_your_key_here"
      }
    }
  }
}
```

### Cursor (local HTTP)

```bash
npx -y supersendtx-mcp --http --port 3000
```

```json
{
  "mcpServers": {
    "supersendtx": {
      "url": "http://127.0.0.1:3000/mcp",
      "headers": {
        "Authorization": "Bearer stx_your_key_here"
      }
    }
  }
}
```

### Cursor (hosted)

OAuth (default) — no key in config:

```json
{
  "mcpServers": {
    "supersendtx": {
      "url": "https://mcp.ranla.ai/mcp"
    }
  }
}
```

Bearer (advanced):

```json
{
  "mcpServers": {
    "supersendtx": {
      "url": "https://mcp.ranla.ai/mcp",
      "headers": {
        "Authorization": "Bearer stx_your_key_here"
      }
    }
  }
}
```

---

## Claude Code

```bash
# HTTP (hosted, OAuth — run /mcp in Claude Code to sign in)
claude mcp add --transport http supersendtx https://mcp.ranla.ai/mcp

# stdio
claude mcp add --transport stdio supersendtx -- npx -y supersendtx-mcp

# HTTP (local — after starting --http server)
claude mcp add --transport http supersendtx http://127.0.0.1:3000/mcp --header "Authorization: Bearer stx_your_key_here"
```

Export `SUPERSENDTX_API_KEY` for stdio.

---

## Tools

### Mail tools

These call the public API through the `supersendtx` SDK.

| Tool | Purpose |
|------|---------|
| `send_email` | Send now, or later with `scheduled_at` |
| `list_emails` / `get_email` | List or fetch sends |
| `cancel_email` | Cancel a scheduled send |
| `list_received_emails` / `get_received_email` | Inbound mail |
| `list_domains` / `get_domain` / `create_domain` | Domains; `get_domain` returns DNS records |
| `apply_domain_dns` / `verify_domain` | Apply DNS (`cloudflare`, `godaddy`, `vercel`) and verify |
| `list_webhooks` / `create_webhook` / `delete_webhook` | Webhook endpoints |
| `list_suppressions` / `add_suppression` / `remove_suppression` | Suppression list |
| `list_templates` / `get_template` / `create_template` / `publish_template` | Templates |
| `send_test_webhook_event` | Test webhook event (outbound email events) |
| `get_deliverability` | Best-effort metrics (`7d` / `30d`) |

`send_email` takes `from`, `to`, and either `subject` with `html` / `text` or `template_id` / `template_alias` with `variables`. Optional: `cc`, `bcc`, `reply_to`, `scheduled_at`, `category` (`transactional`, `product`, `newsletter`), `tags`, `headers`, `idempotency_key`, `unsubscribe`. Recipient fields take one address, several separated by commas, or an array.

### Ranla agent tools

These call the app host and need a full-access key (OAuth sign-in and dashboard keys have one; a `sending`-scope key gets a 403).

| Tool | Purpose |
|------|---------|
| `arc_ensure_thread` / `arc_list_threads` | Durable thread for this client; list threads a page at a time |
| `arc_get_thread` | Read a thread's messages, artifacts and waiting approvals |
| `arc_message` | Send text to Ranla and wait for the turn — returns `text`, `artifacts`, and `pendingApproval` |
| `arc_list_approvals` / `arc_approve` / `arc_reject` | Answer approvals |
| `arc_request_connection` | Connect link for a missing integration |
| `arc_<tool>` | Read-only Ranla tools, listed from the account with input schemas. Results say in `forCaller` when a step needs `arc_message` |

Flow: `arc_ensure_thread` → `arc_message` → if a step needs approval, `arc_list_approvals` → `arc_approve` or `arc_reject`.

An SEO page approval also carries `actionId`: pass it to `arc_seo_page_package` to read the draft, for example to build the page in your own repo.

Every tool has a `title` and `readOnlyHint` / `destructiveHint` annotations, so clients can run reads without asking and confirm writes.

Full reference: https://docs.ranla.ai/ai/mcp

## License

MIT
