---
id: mcp-server
title: MCP server
description: Connect Claude Code, Cursor, or any Model Context Protocol client to the bex platform MCP server at api.bex.co/mcp, sign in with OAuth 2.1 or an API key, and see which tools it exposes.
keywords:
  [bex, mcp, model context protocol, claude code, cursor, ai agents, oauth, api]
last_updated: 2026-09-23
---

bex ships one MCP (Model Context Protocol) server, and it lives with the
platform API rather than with this website:

|                |                                                                                      |
| -------------- | ------------------------------------------------------------------------------------ |
| Endpoint       | `https://api.bex.co/mcp`                                                             |
| Transport      | Streamable HTTP, stateless: any replica answers any request                          |
| Authentication | OAuth 2.1 through `https://oauth.bex.co`, or an API key exchanged for a bearer token |
| Discovery      | `https://api.bex.co/.well-known/oauth-protected-resource` (RFC 9728)                 |
| Scopes         | `bex.read`, `bex.write`, `bex.sensitive`                                             |

`https://bex.co/mcp` is not a server; it redirects to this page. To read this
site's docs and blog from an agent, use the surfaces listed under
[Read the site itself](#read-the-site-itself) instead.

## Connect a client

For a deployment with OAuth discovery configured, add the remote server in
**Claude Code**:

```bash
claude mcp add --transport http bex-api https://api.bex.co/mcp
```

Open `/mcp` inside a session, select the server, and complete the available
sign-in flow. Client registration and browser authorization depend on the
issuer's configuration; use the API-key path below when interactive connection
is unavailable.

**Cursor** can use its remote OAuth flow or a bearer token. For the token path,
add to `.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "bex-api": {
      "url": "https://api.bex.co/mcp",
      "headers": { "Authorization": "Bearer ${env:BEX_TOKEN}" }
    }
  }
}
```

**Headless clients and CI** use an API key. Mint one in the dashboard under
Settings → API Keys, then exchange it for a short-lived bearer token. The
platform creates these OAuth clients with `client_secret_post`: send the ID
and secret as form fields. This example requires `curl` and `jq`; set
`BEX_KEY_ID` and `BEX_KEY_SECRET` from your secret store first:

```bash
BEX_TOKEN=$(curl --fail-with-body --silent --show-error \
  https://oauth.bex.co/oauth2/token \
  --data-urlencode 'grant_type=client_credentials' \
  --data-urlencode "client_id=$BEX_KEY_ID" \
  --data-urlencode "client_secret=$BEX_KEY_SECRET" \
  | jq -er '.access_token')
export BEX_TOKEN
```

Stop if the exchange fails, and keep shell tracing off around credentials.
Send the returned token as `Authorization: Bearer $BEX_TOKEN` on every request
to `/mcp`. The client process must inherit `BEX_TOKEN` for the Cursor example.
The step-by-step walkthrough, including deploying from chat once connected, is in
[Connect an agent](platform/connect-an-agent.md).

## How authentication works

1. A request to `https://api.bex.co/mcp` without a token gets `401` with
   `WWW-Authenticate: Bearer resource_metadata="https://api.bex.co/.well-known/oauth-protected-resource"`.
2. The client fetches that document, learns that the authorization server is
   `https://oauth.bex.co` and which scopes exist. Client registration follows
   the issuer's configuration. Bex's reference Hydra configuration enables
   dynamic client registration; self-hosted deployments can configure it
   differently. If the issuer advertises no registration endpoint, use a
   registered client or the API-key flow rather than guessing an endpoint.
3. Authorization code with PKCE, a login, and a consent screen produce a
   bearer token. The reference Hydra configuration uses 15-minute access
   tokens. Use the returned expiry and refresh credentials rather than
   hardcoding a lifetime for every installation.
4. API keys are OAuth client credentials: the token endpoint is
   `https://oauth.bex.co/oauth2/token`.

Every call is then authorized per workspace on the server; a tool that needs
a workspace takes `workspaceId` and the server checks the caller's access.

## What the server exposes

Some tool names follow Render's MCP vocabulary; arguments, permissions, and
available operations are defined by Bex. Call `tools/list` for the current
schemas before constructing a request. The
families:

| Area                                         | Examples                                                                                                                                                     |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Services                                     | `list_services`, `get_service`, `create_web_service`, `update_service`, `scale_service`, `restart_service`, `suspend_service`, `add_custom_domain`, `deploy` |
| Deploys                                      | `list_deploys`, `get_deploy`, `trigger_deploy`, `cancel_deploy`, `rollback_deploy`                                                                           |
| Logs and metrics                             | `list_logs`, `list_log_label_values`, `get_metrics`, `get_datastore_metrics`                                                                                 |
| Postgres                                     | `list_postgres_instances`, `create_postgres`, `query_render_postgres` (read-only SQL), `get_postgres_logs`, `failover_postgres`, exports and users           |
| Key Value                                    | `list_key_value`, `create_key_value`, `update_key_value`, `get_key_value_logs`                                                                               |
| Environment and secrets                      | `list_env_vars`, `set_env_var`, `update_env_vars`, secret files, environment groups                                                                          |
| Projects and environments                    | create, list, update, delete                                                                                                                                 |
| Jobs and cron                                | `create_job`, `list_jobs`, `create_cron_job`, `run_cron_job`, `list_cron_job_runs`                                                                           |
| Agent sessions and sandboxes                 | `spawn_agent_session`, `attach_agent_session`, `steer_agent_session`, `spawn_sandbox`, `sandbox_exec`                                                        |
| Workspaces, members, API keys                | `list_workspaces`, `get_workspace_limits`, member invites and roles, `create_api_key`, `revoke_api_key`                                                      |
| Billing, webhooks, notifications, blueprints | `get_usage`, webhook endpoints and deliveries, notification settings, `generate_blueprint`, `sync_blueprint`                                                 |

An advertised tool can still reject the caller. In particular, durable API-key
creation requires an authorized direct human caller; a machine key or
third-party agent cannot use `create_api_key` to mint another credential.

For the operations available through other interfaces, see the
[platform API overview](platform/api.md) and the [official platform CLI](cli.md).
The website's `/graphql` endpoint only queries blog content.

## Discovery documents

| URL                                                           | What it is                                                                                                         |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `https://api.bex.co/.well-known/oauth-protected-resource`     | Resource metadata for the MCP server: the resource identifier, its authorization servers, and the supported scopes |
| `https://oauth.bex.co/.well-known/oauth-authorization-server` | Authorization server metadata (RFC 8414). `https://bex.co/.well-known/oauth-authorization-server` redirects here   |
| `https://oauth.bex.co/.well-known/openid-configuration`       | OpenID Connect discovery. `https://bex.co/.well-known/openid-configuration` redirects here                         |
| `https://bex.co/.well-known/mcp.json`                         | A manifest that points at the server above and lists this site's content surfaces                                  |

## Read the site itself

This website runs no MCP server. An agent that needs bex documentation reads
it directly:

- `https://bex.co/llms.txt` is the index and `https://bex.co/llms-full.txt`
  the full dump (llmstxt.org).
- Append `.md` to an English docs page URL or a dated blog post URL for raw
  markdown. Docs use the canonical English source. Blog posts support locale
  prefixes and fall back to English when a translation is missing. Listing,
  tag, and author pages have no raw markdown representation.
- `https://bex.co/content/openapi.json` is the **Bex Website Content API**
  specification; `https://bex.co/graphql` serves read-only blog queries.
  These public endpoints need no platform token and cannot manage services,
  deployments, or databases. Use the platform MCP server above for those tasks.
  The platform project owns its API contract separately.
- Existing `/openapi.json` and `/api/openapi.yaml` links redirect to the website
  content specification, preserving their original purpose.

## Troubleshooting

- **The client never shows a sign-in.** Check the deployment's OAuth discovery,
  client registration, and the client's supported authentication flow. A
  missing registration endpoint is an issuer configuration issue. Use the
  API-key path above when browser authorization is unavailable.
- **`401` after a while.** Check the token's expiry and whether it was revoked.
  Browser OAuth clients can use their refresh token; client-credentials tokens
  require another API-key exchange.
- **`403` on a tool call.** The token lacks the scope the tool needs
  (`bex.write` for mutations, `bex.sensitive` for secrets) or the caller has no
  access to that workspace.
