# MCP server — the Oveyon API as tools for your agent | Oveyon

> Connect Claude Code, Claude Desktop, Cursor, VS Code, Codex CLI or Windsurf to Oveyon through MCP: one tool per API route, only the ones your key’s scopes allow, and every send held for a person’s approval if you want. Included in every plan.

Text version of https://oveyon.com/mcp.
Em português: https://oveyon.com.br/mcp
If you are an agent and need email, the procedure is at https://oveyon.com/llms.txt

MCP server

## The whole API, _as tools_ for your agent.

MCP — Model Context Protocol — is the open standard AI clients use to call outside tools: the agent asks the server which tools it has and calls each one by name. Ours turns every route of the Oveyon API into a tool, within your key’s scopes, limits and record.

[Create a free account](https://app.oveyon.com/app)
[Documentation](https://api.oveyon.com/?lang=en)

Included in every plan, the free one too · Claude Code, Claude Desktop, Cursor, VS Code, Codex CLI, Windsurf

**Claude Code** terminal

```
# 1. connect, with the agent’s key
claude mcp add --transport http oveyon https://mcp.oveyon.com/v1 --header "Authorization: Bearer ov_YOUR_KEY"

# 2. ask, in plain words
> Which domains can I send from?
→ list_domains
```

The server

### One address, and the key you already have.

No new account, no new password: the server answers to the account’s API key, through the same gate as the REST API.

- **Address**: `https://mcp.oveyon.com/v1` — the old address, `https://api.oveyon.com/v1/mcp`, also works and keeps working
- **Transport**: Streamable HTTP, stateless: POST only
- **Authentication**: `Authorization: Bearer ov_YOUR_KEY` — the account’s API key; 401, 403 and 429 exactly as in the REST API
- **Tools**: One per route of the REST API — 76 — and the server lists only those the key’s scopes allow; `whoami` and `check_disposable` work with every key
- **whoami**: The account, the key, and which tools are available or not, with the scope each one needs
- **Guide**: The resource `oveyon://guide` holds the procedure for the agent
- **Same rules**: Every tool call is an API call with the same key: scopes, quotas, policies, idempotency and the call log apply unchanged — in the API logs, the calls show up as the family `oveyon-mcp`
- **Errors**: They reach the model whole: the error code, the message and `Retry-After`
- **Price**: Included in every plan, Free too; what the agent sends counts against the plan quota as usual

Four steps

### Connected in four steps.

#### 1. Pick your client

Claude Code, Claude Desktop, Cursor, VS Code, Codex CLI or Windsurf — or any client that can send a header. Each one keeps its configuration in a different place.

#### 2. Create a key for the agent

From the panel’s MCP screen (Sending → MCP): the suggested scopes come ticked, and so does «Require human approval for this key’s sends». The key is shown once.

#### 3. Paste the configuration

Sending → MCP prints it for your client, and it is below too. Replace `ov_YOUR_KEY` with the key — in the client, never in a repository.

#### 4. Ask your agent

In plain words. It picks and calls the tools; with the lock on, what it sends waits for a person under Messages → Approvals.

Configuration

### Paste this into your client.

The same text the panel prints under Sending → MCP. Replace `ov_YOUR_KEY` with the agent’s key.

#### Claude Code

In the terminal:

**terminal**

```
claude mcp add --transport http oveyon https://mcp.oveyon.com/v1 --header "Authorization: Bearer ov_YOUR_KEY"
```

#### Claude Desktop

Under Settings → Developer → Edit Config. The mcp-remote bridge sends the header for Claude Desktop.

**claude_desktop_config.json**

```
{
  "mcpServers": {
    "oveyon": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@0.14.3",
        "https://mcp.oveyon.com/v1",
        "--transport",
        "http-only",
        "--header",
        "Authorization:${OVEYON_AUTH}"
      ],
      "env": {
        "OVEYON_AUTH": "Bearer ov_YOUR_KEY"
      }
    }
  }
}
```

#### Cursor

In `~/.cursor/mcp.json` — not the project’s `.cursor/mcp.json`, which usually goes into the repository.

**~/.cursor/mcp.json**

```
{
  "mcpServers": {
    "oveyon": {
      "url": "https://mcp.oveyon.com/v1",
      "headers": {
        "Authorization": "Bearer ov_YOUR_KEY"
      }
    }
  }
}
```

#### VS Code

In `.vscode/mcp.json`. VS Code asks for the key once and stores it as a secret — it never sits in the file.

**.vscode/mcp.json**

```
{
  "servers": {
    "oveyon": {
      "type": "http",
      "url": "https://mcp.oveyon.com/v1",
      "headers": {
        "Authorization": "Bearer ${input:oveyon-key}"
      }
    }
  },
  "inputs": [
    {
      "type": "promptString",
      "id": "oveyon-key",
      "description": "Oveyon API key",
      "password": true
    }
  ]
}
```

#### Codex CLI

In `~/.codex/config.toml`. Export `OVEYON_API_KEY` in the environment first.

**~/.codex/config.toml**

```
[mcp_servers.oveyon]
url = "https://mcp.oveyon.com/v1"
bearer_token_env_var = "OVEYON_API_KEY"
```

#### Windsurf

In `mcp_config.json`, opened from the editor: Cascade → MCP.

**mcp_config.json**

```
{
  "mcpServers": {
    "oveyon": {
      "serverUrl": "https://mcp.oveyon.com/v1",
      "headers": {
        "Authorization": "Bearer ov_YOUR_KEY"
      }
    }
  }
}
```

#### Any other client

The URL and the `Authorization` header, over Streamable HTTP. To check by hand — the answer arrives as an event, on the `data:` line:

**terminal** tools/list

```
curl -X POST https://mcp.oveyon.com/v1 \
  -H "Authorization: Bearer ov_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
```

Examples

### What you type, and what the agent does.

No API to learn: the agent picks the tool and the arguments. A few requests, and the tools behind them.

| You type | The agent calls | What happens |
| --- | --- | --- |
| «Which domains can I send from?» | list_domains | It lists the account’s domains. |
| «Send the welcome email to ana@example.com from hello@yourdomain.com — hold it for my approval.» | send_email | With `hold: true` and an `idempotencyKey`: the email becomes a draft a person approves under Messages → Approvals, and a repeat never sends twice. |
| «What arrived in support@ today? Flag anything the safety verdict marks dangerous.» | list_inbound get_inbound | `list_inbound` with the `agent_safety` filter, then `get_inbound` on what it opens: every message carries the verdict — clean, suspicious or dangerous — with the score and the signals. |
| «Reply to the last message from joao@example.com saying we received it.» | reply_inbound | A plain-text reply from the mailbox that received the message. With the lock on, it waits for approval like any send. |
| «Which Oveyon account and key am I using, and what can it do?» | whoami | The account, the key, the tools it can call and the scope each of the others needs. |

Safety

### The agent works inside the key, not around it.

A received email can carry hidden orders. The brakes live in the key and in the platform — not in the prompt.

#### Scopes decide the tools

The server lists only what the key’s scopes allow: a read-only key only reads. The suggested key has no `approve:holds` — the key that sends is not the one that approves.

#### Human approval on every send

Created from the MCP screen, the key comes with «Require human approval for this key’s sends» ticked: a sending policy turns every email and every reply the agent sends into a draft a person approves under Messages → Approvals.

#### The verdict on every message

Every received message carries `agentSafety`: clean, suspicious or dangerous, a 0–100 score and the signals. An email can give the agent orders; approval is what stops it from obeying them.

#### The key stays out of the repository

The panel never prints the key: it is shown once, at creation. Keep it in the client’s configuration or in an environment variable — never in a repository.

#### 403 stops, 429 waits

Errors reach the model whole — code, message, `Retry-After`: on a 429 the agent waits; on a 403 it stops and tells you.

#### Every call in the log

Each tool call is an API call with the same key — scopes, quotas, policies and idempotency apply — and shows up in the API logs as the family `oveyon-mcp`.

The tools

### The tools, by scope.

Each tool is one route of the API and needs that route’s scope. The server lists only what the key allows.

| Scope | Tools |
| --- | --- |
| send | `send_email` |
| read:messages | `list_messages`, `get_message` |
| read:stats | `get_stats` |
| read:suppressions | `list_suppressions` |
| write:suppressions | `add_suppression`, `remove_suppression` |
| read:domains | `list_domains` |
| write:domains | `add_domain`, `verify_domain` |
| manage:webhooks | `list_webhooks`, `create_webhook`, `update_webhook`, `delete_webhook` |
| read:inbound | `list_inbound`, `get_inbound`, `get_inbound_content`, `list_threads`, `get_thread`, `get_inbound_stats` |
| reply:inbound | `reply_inbound` |
| write:inbound | `release_inbound`, `list_mailboxes`, `create_mailbox`, `get_mailbox`, `update_mailbox`, `delete_mailbox`, `detach_mailbox_channel` |
| approve:holds | `list_holds`, `approve_hold`, `reject_hold` |
| read:templates | `list_templates`, `get_template` |
| write:templates | `create_template`, `update_template`, `publish_template`, `delete_template` |
| read:send-policies | `list_send_policies`, `get_send_policy`, `list_send_policy_decisions` |
| write:send-policies | `create_send_policy`, `update_send_policy`, `pause_send_policy`, `unpause_send_policy`, `reorder_send_policies`, `delete_send_policy` |
| read:inbound-policies | `list_inbound_policies`, `get_inbound_policy`, `list_inbound_policy_decisions`, `simulate_inbound_policy` |
| write:inbound-policies | `create_inbound_policy`, `update_inbound_policy`, `pause_inbound_policy`, `unpause_inbound_policy`, `reorder_inbound_policies`, `delete_inbound_policy` |
| read:policies | `list_allow_block`, `list_ip_rules` |
| write:policies | `add_allow_block`, `remove_allow_block`, `add_ip_rule`, `remove_ip_rule`, `pause_ip_fence`, `unpause_ip_fence` |
| read:surveys | `list_surveys`, `get_survey`, `list_survey_responses` |
| write:surveys | `create_survey`, `update_survey`, `delete_survey` |
| send:surveys | `send_survey` |
| read:logs | `list_api_logs`, `get_api_log` |
| no scope (public) | `check_disposable` |
| every key | `whoami` |

Suggested for an agent’s key, and ticked in the panel: `send`, `read:messages`, `read:stats`, `read:suppressions`, `read:domains`, `read:inbound`, `reply:inbound`, `read:templates`, `read:inbound-policies` — without `approve:holds` (the key that sends is not the one that approves) and without `read:logs`.

Questions

### Short answers.

#### Does it cost extra?

No. The MCP server is included in every plan, Free included. It uses your API key, and what the agent sends counts against the plan quota as usual.

#### Which clients can connect?

Claude Code, Cursor, VS Code, Codex CLI and Windsurf connect directly; Claude Desktop connects through the mcp-remote bridge. Any other client that speaks Streamable HTTP and sends an `Authorization` header works too.

#### My client has no field for a header. Can it connect?

The connection on this page is by API key, sent in the `Authorization: Bearer` header. Claude Desktop connects through the mcp-remote bridge, which sends the header for it — the same works for any client that can start a local command.

#### Can the agent send without a person seeing it?

Only if you let it. With «Require human approval for this key’s sends» — ticked when the key is created from the MCP screen — every email and every reply becomes a draft a person approves under Messages → Approvals. Without `approve:holds`, the agent cannot approve its own drafts.

#### Can it read attachments and reply with files?

The agent reads the message with `get_inbound_content`; the raw .eml and the attachment bytes are not tools. `reply_inbound` sends a plain-text reply, without attachments, from the mailbox that received the message. `send_email` accepts attachments (base64) and templates.

#### Where do I see what the agent did?

In the API logs: every tool call is an API call made with the agent’s key, and shows up there as the family `oveyon-mcp`.

#### I already use https://api.oveyon.com/v1/mcp. Do I need to change it?

No. The old address also works and keeps working.

### Connect your agent today. The approval lock comes with it.

MCP included in every plan, the free one too.

[Create a free account](https://app.oveyon.com/app)
[Documentation](https://api.oveyon.com/?lang=en)

---

First email today. No card. — https://app.oveyon.com/app
