# Connect an AI agent over MCP

> Connect Claude Code, Cursor, VS Code, Codex, ChatGPT, Claude.ai, Lovable, Windsurf or any stdio client to Belvador's MCP server with OAuth or a read-only token.

Belvador's MCP server lets the AI agent you already use — in your editor, your terminal or a chat app — read this workspace's issues, events, traces, logs and monitors, and search these docs. It speaks the [Model Context Protocol](https://modelcontextprotocol.io) (versions 2026-07-28, 2025-11-25).

## Remote or local

| | Remote | Local |
|---|---|---|
| Address | `https://api.belvador.dev/mcp` | `npx -y @belvador/mcp@0.4.0` (Node.js 20.10 or newer) |
| Sign-in | OAuth, or a token | A token from `BELVADOR_TOKEN` or the OS keychain |
| Your node's data | Read through the edge for each call; api.belvador.dev does not store or log it | Read straight from edge.belvador.dev with a short-lived ticket; it never passes through api.belvador.dev |

Both offer the same tools with the same descriptions and answers.

## The quickest way: Settings → AI agents

In Belvador, open **Settings → AI agents** in your workspace:

1. Pick your tool.
2. Choose how it signs in. OAuth is best where the tool supports it: you approve on belvador.dev and no token is copied anywhere.
3. Choose toolsets, then copy the configuration shown for your tool.
4. For a token, press **Create read-only token** (it asks for your authenticator code), put the token in `BELVADOR_TOKEN`, and press **Check connection**. The page asks the MCP server for its tool list and shows how many tools the token sees. For OAuth, the connection appears on the same page once you approve it.

## Supported tools

| Tool | OAuth | API token | Local (stdio) | Source |
|---|---|---|---|---|
| Claude Code | Yes | Yes | Yes | [code.claude.com](https://code.claude.com/docs/en/mcp) |
| Cursor | Yes | Yes | Yes | [cursor.com](https://cursor.com/docs/mcp) |
| VS Code | Yes | Yes | Yes | [code.visualstudio.com](https://code.visualstudio.com/docs/agents/reference/mcp-configuration) |
| Codex | Yes | Yes | Yes | [developers.openai.com](https://developers.openai.com/codex/mcp) |
| ChatGPT | Yes | — | — | [developers.openai.com](https://developers.openai.com/api/docs/guides/custom-mcp-server) |
| Claude.ai | Yes | — | — | [claude.com](https://claude.com/docs/connectors/custom/remote-mcp) |
| Lovable | Yes | Yes | — | [docs.lovable.dev](https://docs.lovable.dev/integrations/custom-mcp) |
| Windsurf | Yes | Yes | Yes | [docs.devin.ai](https://docs.devin.ai/windsurf/plugins/cascade/mcp) |
| stdio / other | — | — | Yes | [modelcontextprotocol.io](https://modelcontextprotocol.io/docs/concepts/transports) |

Configuration formats were checked against each vendor's documentation on 2026-10-26. If a menu has moved, use the tool's "add a remote MCP server" option with `https://api.belvador.dev/mcp`.

## Set up by tool

### Claude Code

With OAuth:

```bash
claude mcp add --transport http --scope user belvador https://api.belvador.dev/mcp
```

Start Claude Code, run `/mcp`, choose `belvador` and pick Authenticate.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

```bash
claude mcp add --transport http --scope project belvador https://api.belvador.dev/mcp \
  --header 'Authorization: Bearer ${BELVADOR_TOKEN}'
```

Keep the single quotes: Claude Code saves `${BELVADOR_TOKEN}` in `.mcp.json` and reads the variable when it starts, so the token itself is never written to the file.

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

Local:

```bash
claude mcp add --scope project --transport stdio \
  --env 'BELVADOR_TOKEN=${BELVADOR_TOKEN}' \
  belvador -- npx -y @belvador/mcp@0.4.0
```

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

### Cursor

With OAuth:

```json title="~/.cursor/mcp.json"
{
  "mcpServers": {
    "belvador": {
      "url": "https://api.belvador.dev/mcp"
    }
  }
}
```

Use `~/.cursor/mcp.json` for every project or `.cursor/mcp.json` inside one project.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

```json title="~/.cursor/mcp.json"
{
  "mcpServers": {
    "belvador": {
      "url": "https://api.belvador.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Use `~/.cursor/mcp.json` for every project or `.cursor/mcp.json` inside one project.

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

Local:

```json title="~/.cursor/mcp.json"
{
  "mcpServers": {
    "belvador": {
      "command": "npx",
      "args": [
        "-y",
        "@belvador/mcp@0.4.0"
      ],
      "env": {
        "BELVADOR_TOKEN": "${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Use `~/.cursor/mcp.json` for every project or `.cursor/mcp.json` inside one project.

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

### VS Code (GitHub Copilot)

With OAuth:

```json title=".vscode/mcp.json"
{
  "servers": {
    "belvador": {
      "type": "http",
      "url": "https://api.belvador.dev/mcp"
    }
  }
}
```

Start the server from the file (Start above `belvador`) and approve in the browser when VS Code asks.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

```json title=".vscode/mcp.json"
{
  "servers": {
    "belvador": {
      "type": "http",
      "url": "https://api.belvador.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

Local:

```json title=".vscode/mcp.json"
{
  "servers": {
    "belvador": {
      "type": "stdio",
      "command": "npx",
      "args": [
        "-y",
        "@belvador/mcp@0.4.0"
      ],
      "env": {
        "BELVADOR_TOKEN": "${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

### Codex

With OAuth:

```bash
codex mcp add belvador --url https://api.belvador.dev/mcp
codex mcp login belvador
```

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

```toml title="~/.codex/config.toml"
[mcp_servers.belvador]
url = "https://api.belvador.dev/mcp"
bearer_token_env_var = "BELVADOR_TOKEN"
```

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

Local:

```toml title="~/.codex/config.toml"
[mcp_servers.belvador]
command = "npx"
args = ["-y", "@belvador/mcp@0.4.0"]
env_vars = ["BELVADOR_TOKEN"]
```

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

### ChatGPT

In ChatGPT open Plugins → + → Add custom MCP server (developer mode must be allowed for your account or workspace).

```text
https://api.belvador.dev/mcp
```

Paste the URL above as Server URL, choose OAuth as authentication, accept the warning and create it.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

### Claude.ai

In Claude open Customize → Connectors → Add custom connector (organization owners: Organization settings → Connectors → Add → Custom → Web).

```text
https://api.belvador.dev/mcp
```

Paste the URL above, add it, then press Connect. Leave the OAuth client fields empty — Belvador registers the client by itself.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

### Lovable

With OAuth:

In Lovable open Connectors → Add custom → MCP server, name it Belvador and keep Direct connection.

```text
https://api.belvador.dev/mcp
```

Paste the URL above, keep OAuth and press Add & authorize.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

In Lovable open Connectors → Add custom → MCP server, name it Belvador and keep Direct connection.

```text
https://api.belvador.dev/mcp
```

Paste the URL above, choose Bearer token or API key, paste the token there (only there) and press Add server.

### Windsurf

With OAuth:

```json title="mcp_config.json"
{
  "mcpServers": {
    "belvador": {
      "serverUrl": "https://api.belvador.dev/mcp"
    }
  }
}
```

Open it from Cascade → MCP → Open MCP config file, then refresh the server list.

The client opens belvador.dev in your browser: choose the workspace and what the agent may do, then approve. The connection then appears under Account → Connected apps.

With a token:

```json title="mcp_config.json"
{
  "mcpServers": {
    "belvador": {
      "serverUrl": "https://api.belvador.dev/mcp",
      "headers": {
        "Authorization": "Bearer ${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Open it from Cascade → MCP → Open MCP config file, then refresh the server list.

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

Local:

```json title="mcp_config.json"
{
  "mcpServers": {
    "belvador": {
      "command": "npx",
      "args": [
        "-y",
        "@belvador/mcp@0.4.0"
      ],
      "env": {
        "BELVADOR_TOKEN": "${env:BELVADOR_TOKEN}"
      }
    }
  }
}
```

Open it from Cascade → MCP → Open MCP config file, then refresh the server list.

Put the token in the environment variable `BELVADOR_TOKEN` of the program that starts the agent (your shell profile or a secret manager). The config file only names the variable — never paste the token into it or into a chat.

### Any other stdio client

```bash
npx -y @belvador/mcp@0.4.0
```

```json
{
  "mcpServers": {
    "belvador": {
      "command": "npx",
      "args": [
        "-y",
        "@belvador/mcp@0.4.0"
      ],
      "env": {
        "BELVADOR_TOKEN": "<from your secret store>"
      }
    }
  }
}
```

Any MCP client that starts a local command works. Without `BELVADOR_TOKEN` the package reads the OS keychain entry service `belvador.dev`, account `mcp`.

```bash
# macOS
security add-generic-password -s belvador.dev -a mcp -w
# Linux (libsecret)
secret-tool store --label=Belvador service belvador.dev account mcp
```

## Toolsets and tools

Three toolsets are on by default: `investigate` (issues, events, traces, logs), `reliability` (monitors) and `docs`. Pick fewer with `?toolsets=investigate,docs` on the URL, or `--toolsets=investigate,docs` for the local package. The token narrows them further: a tool is listed only when the token holds the scope it needs, so an agent never sees a tool that would refuse it.

| Tool | Toolset | Needs scope | Read-only |
|---|---|---|---|
| `get_workspace` | investigate | `org:read` | Yes |
| `list_projects` | investigate | `projects:read` | Yes |
| `search_issues` | investigate | `issues:read` | Yes |
| `get_issue` | investigate | `issues:read` | Yes |
| `list_events` | investigate | `events:read` | Yes |
| `get_event` | investigate | `events:read` | Yes |
| `get_trace` | investigate | `traces:read` | Yes |
| `search_spans` | investigate | `traces:read` | Yes |
| `query_logs` | investigate | `logs:read` | Yes |
| `query_metrics` | investigate | `metrics:read` | Yes |
| `correlate` | investigate | `traces:read` | Yes |
| `list_monitors` | reliability | `monitors:read` | Yes |
| `get_monitor_status` | reliability | `monitors:read` | Yes |
| `list_alerts` | reliability | `alerts:read` | Yes |
| `list_incidents` | reliability | `incidents:read` | Yes |
| `get_incident` | reliability | `incidents:read` | Yes |
| `get_coverage` | reliability | `coverage:read` | Yes |
| `verify_integration` | reliability | `projects:write` | No — sends one test event |
| `search_operations` | configure | The operation's scope | Yes |
| `describe_operation` | configure | The operation's scope | Yes |
| `plan_change` | configure | The operation's scope | Yes |
| `apply_change` | configure | The operation's scope | No — changes settings; sensitive ones wait for a person |
| `get_operation` | configure | The operation's scope | Yes |
| `search_docs` | docs | — | Yes |
| `get_doc` | docs | — | Yes |

## Changing settings: `configure`

The `configure` toolset is off by default. Add it with `?toolsets=investigate,reliability,docs,configure` on the URL, or `--toolsets=…` for the local package. It is listed only when the token or OAuth connection holds at least one write scope, and it covers every operation of the [REST API](https://belvador.dev/en/docs/reference/api) that changes settings:

1. `search_operations` finds the operation ("rotate the DSN key", "add a monitor"); `describe_operation` shows its fields, the scope it needs and whether a person must approve it.
2. `plan_change` checks the fields without changing anything: errors, a missing scope, whether approval is needed and, for edits, the current values, what would change and the `etag`.
3. `apply_change` makes the change with an `idempotency_key` — the same key never applies twice — and, for edits, `if_match` with that etag.
4. Sensitive changes (keys, members, tokens, alert destinations, node changes) answer `approval_required` with a link to belvador.dev. Clients on MCP 2026-07-28 that support it open the link for you; otherwise the agent shows it. A person approves with their authenticator code within 15 minutes, then `get_operation` — or `apply_change` again with the same key — reports the outcome. New keys and tokens appear only on that page, never to the agent. See [Approvals](https://belvador.dev/en/docs/reference/api#approvals).

What a person must type — the name that confirms a deletion, a bot token, webhook URL or mail password — is not part of any tool's input; the approval page asks for it.

## Tokens

- **Read-only token from Settings → AI agents.** Every read scope except the audit log, this workspace only, valid for 90 days unless the workspace sets a shorter limit. For other scopes, projects or lifetimes, create one under **Account → API tokens** — see [DSN, ingest keys, ping URLs, tokens and node tickets](https://belvador.dev/en/docs/security/credentials).
- **Where it goes.** In the `BELVADOR_TOKEN` environment variable of the program that starts the agent, or your OS keychain for the local package. Never in a config file, a repository or a chat.
- **OAuth.** Access tokens last 60 minutes and are renewed by the tool; the connection ends after 30 days without use.
- **Revoke** a token under **Account → API tokens** and an OAuth connection under **Account → Connected apps**; it stops working within a minute.

## What the agent receives

- Text from your applications — error messages, stack traces, log lines, breadcrumbs — is placed in `untrusted` fields with where it came from. The server tells the model not to follow instructions found there and not to open links from it. Invisible characters are shown as visible markers.
- One tool answer is at most 64 KB; longer lists are paged.
- Trace and log queries need a time window of at most 168 hours.
- Calls count toward the same limit as the [REST API](https://belvador.dev/en/docs/reference/api): 300 a minute per token.
- When the node is offline, data tools answer `NODE_OFFLINE`; control-plane tools and docs keep working.

## Privacy

What the agent reads is sent to the AI model provider you chose. Belvador cannot see or control what that provider keeps. Connect only the projects and environments the agent needs — a token can be limited to some projects and environments under **Account → API tokens**.

## Troubleshooting

| What you see | What to do |
|---|---|
| 401, or "the token is wrong, expired or revoked" | Create a new token, or connect again with OAuth |
| 403 `insufficient_scope` | The tool needs the scope named in the answer; create a token that has it or approve the OAuth connection again |
| `approval_required` | Open the link, check the change and approve with your authenticator code within 15 minutes; then ask the agent to check again |
| The tool list is empty | The token has no read scopes for this workspace's data |
| Local: `no token` | Set `BELVADOR_TOKEN` for the program that starts the agent, or add the keychain entry |
| Local: `the API did not answer` behind a company proxy | Give Node.js the proxy's certificate with `NODE_EXTRA_CA_CERTS` |
