> ## Documentation Index
> Fetch the complete documentation index at: https://docs.custral.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Server

> Connect an AI client (Claude, Cursor) to your Custral workspace.

Custral runs a [Model Context Protocol](https://modelcontextprotocol.io) server, so you can add your workspace as a tool source in Claude Desktop, Cursor, or any MCP client and let the model read your data on your behalf.

## Endpoint

```
https://api.custral.com/v1/mcp
```

It speaks MCP over streamable HTTP. There are two ways to authenticate, and for most people the first one means never handling a key at all.

## Connect a client

### Sign in through your browser (recommended)

Point your client at the endpoint and let it walk you through signing in. No key to create, copy, or store.

<CodeGroup>
  ```bash Claude Code theme={null}
  claude mcp add --transport http custral https://api.custral.com/v1/mcp
  ```

  ```json Claude Desktop / Cursor theme={null}
  {
    "mcpServers": {
      "custral": {
        "url": "https://api.custral.com/v1/mcp"
      }
    }
  }
  ```
</CodeGroup>

Notice there's no `Authorization` header. The first time the client calls the server it gets a `401` telling it where to authenticate, and it opens your browser:

<Steps>
  <Step title="Approve the connection">
    Custral shows you which application is asking, **which workspace** it will act on, and a plain-language list of
    exactly what it will be able to do. Pick the workspace and choose **Authorize**.
  </Step>

  <Step title="You're connected">
    The browser hands the client its credential and closes. Nothing is ever displayed for you to copy.
  </Step>
</Steps>

Behind the scenes this is standard OAuth 2.1 with PKCE: the client registers itself, you approve in the browser, and it exchanges the result for a scoped key. What it receives is an ordinary Custral API key, so it appears in **Settings → Applications** alongside any you made by hand, shows when it was last used, and is revoked the same way.

<Note>
  Approving grants access to **one workspace**. The one you pick on the approval screen. To connect a second workspace,
  add the server again under a different name and choose that workspace when you approve.
</Note>

### With an API key

Use a key when the client isn't a browser-capable machine (CI, a server, a container) or when you want to pin an integration to an exact scope set.

The [`custral` CLI](/dev/cli/overview) mints a scoped key and prints a ready-to-paste config for each client:

```bash theme={null}
custral login   # once, if you haven't
custral mcp
```

For **Claude Code**, it prints a command you can run as-is:

```bash theme={null}
claude mcp add --transport http custral https://api.custral.com/v1/mcp \
  --header "Authorization: Bearer sk_live_..."
```

For **Claude Desktop** or **Cursor**, it prints a JSON block to drop into your MCP config:

```json theme={null}
{
  "mcpServers": {
    "custral": {
      "url": "https://api.custral.com/v1/mcp",
      "headers": {"Authorization": "Bearer sk_live_..."}
    }
  }
}
```

You can also create the key yourself in **Settings → Applications**. Either way it needs the **`mcp:read`** scope to connect, plus a resource scope per write action: **`records:write`** to create and update records, **`conversations:write`** to change conversations, **`applications:manage`** to mint keys, **`webhooks:manage`** to register webhooks.

<Warning>
  A secret key (`sk_…`) can read and write your workspace. Keep it out of browsers and out of version control, and
  revoke it in **Settings → Applications** if it leaks.
</Warning>

## Use it

Talk to the agent in natural language. It picks the right tools and stays scoped to the one workspace the connection was granted for. For example:

* *"Summarize my open conversations and tell me which need a reply."*, reads conversations + their transcripts.
* *"Mark conversation conv\_3Ab… as closed and set the outcome to won."*, `set_conversation_status` + `set_conversation_disposition` (needs `conversations:write`).
* *"Find the contact [jane@acme.com](mailto:jane@acme.com) and set their status to customer."*. Searches records, then `update_record` (needs `records:write`).
* *"Create a deal named Globex on the deals object."*, `create_record` (needs `records:write`).

The agent can only do what the connection's scopes allow, with `mcp:read` alone it will find and summarize, but never change anything.

## What's exposed

**Read (`mcp:read`)** is a read-only subset of your workspace tools: searching and reading records, object schemas, conversations, and tasks.

**Write** is a small, curated set of provisioning actions, each gated by its own resource scope so keys stay least-privilege:

| Tool                           | Requires              | Does                                                          |
| ------------------------------ | --------------------- | ------------------------------------------------------------- |
| `create_record`                | `records:write`       | Create a record on any object                                 |
| `update_record`                | `records:write`       | Update a record's fields                                      |
| `set_conversation_status`      | `conversations:write` | Set a conversation's status (`open` / `closed` / `completed`) |
| `set_conversation_disposition` | `conversations:write` | Set a conversation's outcome                                  |
| `create_application`           | `applications:manage` | Create a developer application                                |
| `create_api_key`               | `applications:manage` | Mint a scoped API key (returned once)                         |
| `create_webhook_endpoint`      | `webhooks:manage`     | Register an outbound webhook (signing secret returned once)   |

A tool only appears when the connection holds its scope, so a `webhooks:manage`-only key can register webhooks but cannot mint keys, and vice-versa. Every other write in the assistant's toolbox stays off the MCP surface entirely. The allowlist is explicit, not "all writes."

The scopes **are** the authorization, however you connected: with a key you choose them when you create it, and with browser sign-in you see them listed on the approval screen before you authorize. There is no per-action prompt once a client is connected. MCP clients run headless, so the grant is made once, up front.

## Preview the tools

To see exactly which tools a key exposes (the same list an MCP client receives from `tools/list`, without wiring up a client) call:

```bash theme={null}
curl https://api.custral.com/v1/mcp/tools \
  -H "Authorization: Bearer sk_live_..."
```

It returns `{ endpoint, scopes, count, tools: [{ name, description, inputSchema }] }` and requires the `mcp:read` scope. (This one is a plain HTTP call, so it needs a key. A browser-authorized client reads the same list through `tools/list`.) `scopes` echoes the key's grants, and `tools` includes exactly the write actions those scopes unlock, so it doubles as a quick check that your key is configured the way you expect.

<Note>
  This is Custral acting as an MCP **server** (a client connects *to* your workspace). It is separate from connecting
  Custral's own assistant *to* other people's MCP servers, which is configured in **Settings → Integrations → MCP**.
</Note>

## Related

* [Authentication](/dev/auth/overview): browser sign-in, creating a key by hand, and what each scope grants.
* [API Reference](/dev/api-reference/overview): the equivalent REST surface.


## Related topics

- [MCP Connections](/ai/mcp-connections.md)
- [Authentication](/dev/auth/overview.md)
- [CLI](/dev/cli/overview.md)
- [AI](/ai/overview.md)
- [API Reference](/dev/api-reference/overview.md)
