> Documentation index: [/llms.txt](/llms.txt). Every page as one file: [/llms-full.txt](/llms-full.txt).

# Connect MCP servers

Connect MCP servers [#connect-mcp-servers]

Register a remote Model Context Protocol (MCP) server, call its tools over the API, and add it to an agent.

Central Hub stores the server's credentials encrypted and calls the server itself, so a client calls tools without holding the server's secret.

Endpoints [#endpoints]

Every route selects the workspace with `X-Space-Slug`.

| Method   | URL                                                                          | Does                                                                                         | Requires | Auth          |
| -------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | -------- | ------------- |
| `GET`    | `/api/v1/mcp-connections/`                                                   | List the MCP connections you can see                                                         | Read     | Key or bearer |
| `GET`    | `/api/v1/mcp-connections/catalog/`                                           | List the ready-made servers the Connectors page offers                                       | Read     | Key or bearer |
| `POST`   | `/api/v1/mcp-connections/`                                                   | Register a server; lists its tools                                                           | Create   | Key or bearer |
| `POST`   | `/api/v1/mcp-connections/test/`                                              | List an unsaved config's tools; saves nothing                                                | Create   | Key or bearer |
| `GET`    | `/api/v1/mcp-connections/{connection_id}/`                                   | Read one, with `discovered_tools`; secrets are `[REDACTED]` unless `?mask_credentials=false` | Read     | Key or bearer |
| `PATCH`  | `/api/v1/mcp-connections/{connection_id}/`                                   | Edit or rotate credentials                                                                   | Edit     | Key or bearer |
| `DELETE` | `/api/v1/mcp-connections/{connection_id}/`                                   | Delete it; `204`                                                                             | Delete   | Key or bearer |
| `POST`   | `/api/v1/mcp-connections/{connection_id}/refresh-tools/`                     | List the server's tools again                                                                | Edit     | Key or bearer |
| `POST`   | `/api/v1/mcp-connections/{connection_id}/call/`                              | Call one tool                                                                                | Read     | Key or bearer |
| `GET`    | `/api/v1/mcp-connections/{connection_id}/auth-status/`                       | Whether you can use it now                                                                   | Read     | Key or bearer |
| `POST`   | `/api/v1/mcp-connections/{connection_id}/authenticate/init/` · `…/callback/` | Connect your own account to an `oauth2` server                                               | Read     | Key or bearer |
| `DELETE` | `/api/v1/mcp-connections/{connection_id}/authenticate/`                      | Disconnect your own account; `204`                                                           | Read     | Key or bearer |

Requires names the MCP connections permission (`mcp_connection:read`, `create`, `edit`, `delete`).

Request fields [#request-fields]

| Field              | Type                                                                              | Notes                                                                                          |
| ------------------ | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `name`             | string, required                                                                  |                                                                                                |
| `url`              | string, required                                                                  | The server's MCP endpoint; outside local deployments it must be `https` and not a private host |
| `transport`        | `streamable_http` or `sse`, default `streamable_http`                             |                                                                                                |
| `auth_type`        | `none`, `bearer_token`, `custom_header`, `basic_auth` or `oauth2`, default `none` |                                                                                                |
| `credentials`      | object, default `{}`                                                              | Keys per `auth_type`, below                                                                    |
| `scope_visibility` | `private` or `space`, default `private`                                           | `space` needs a second workspace member                                                        |
| `connector_key`    | string, optional                                                                  | A catalog entry's `key`; the web app shows that vendor's logo for the connection               |

| `auth_type`     | `credentials`                                                                                             |
| --------------- | --------------------------------------------------------------------------------------------------------- |
| `none`          | `{}`                                                                                                      |
| `bearer_token`  | `token`; sent as `Authorization: Bearer <token>`                                                          |
| `custom_header` | `header_name`, `header_value`                                                                             |
| `basic_auth`    | `username`, `password`                                                                                    |
| `oauth2`        | Optional `client_id`, `client_secret` for servers without dynamic client registration; each user signs in |

Register an MCP server [#register-an-mcp-server]

1. Optional: check the config first with `POST /api/v1/mcp-connections/test/` and the same body. The response is `{"ok": true, "tools": [...], "server_instructions": null}`.

2. Register it. Central Hub connects, lists the tools and stores them in `discovered_tools`:

   ```bash
   curl -X POST "$CENTRAL_HUB_URL/api/v1/mcp-connections/" \
     -H "X-API-Key: $ALO_API_KEY" \
     -H "X-Space-Slug: $WORKSPACE_SLUG" \
     -H "Content-Type: application/json" \
     -d '{
       "name": "Issues MCP",
       "url": "https://mcp.example.com/mcp",
       "auth_type": "bearer_token",
       "credentials": {"token": "…"}
     }'
   ```

3. Keep the `id` from the `201` response (abridged):

   ```json
   {
     "id": 62,
     "name": "Issues MCP",
     "url": "https://mcp.example.com/mcp",
     "transport": "streamable_http",
     "auth_type": "bearer_token",
     "credentials": {"token": "[REDACTED]"},
     "scope_visibility": "private",
     "discovered_tools": [
       {
         "name": "search_issues",
         "title": null,
         "description": "Search issues by text.",
         "input_schema": {
           "type": "object",
           "required": ["query"],
           "properties": {"query": {"type": "string"}, "limit": {"type": "integer", "default": 5}}
         }
       }
     ],
     "last_error": null,
     "user_authenticated": true
   }
   ```

If the server cannot be reached or refuses the credentials, nothing is saved and the response is `422` with the reason.

Connect an OAuth server [#connect-an-oauth-server]

An `oauth2` server is saved without tools; each user then signs in with their own account.

1. Register it with `"auth_type": "oauth2"`. `discovered_tools` is `[]` and `user_authenticated` is `false`.

2. Start your sign-in:

   ```bash
   curl -X POST "$CENTRAL_HUB_URL/api/v1/mcp-connections/63/authenticate/init/" \
     -H "X-API-Key: $ALO_API_KEY" \
     -H "X-Space-Slug: $WORKSPACE_SLUG" \
     -H "Content-Type: application/json" \
     -d '{"redirect_uri": "https://your-app.example.com/oauth/callback"}'
   ```

3. Send the user to the returned `auth_url`. When the server redirects back, send its `code` and `state` to `POST …/mcp-connections/63/authenticate/callback/`; the response is the auth status with `authenticated: true`.

4. Fill `discovered_tools` with `POST …/mcp-connections/63/refresh-tools/`.

To sign in before the connection exists, send `{url, redirect_uri}` to `POST /api/v1/mcp-connections/authenticate/init/`, then `{code, state}` to `POST /api/v1/mcp-connections/authenticate/callback/`; pass the returned `handle` as `oauth_handle` when you register the server.

Connect a server from the catalog [#connect-a-server-from-the-catalog]

`GET /api/v1/mcp-connections/catalog/` lists the ready-made servers the **Connectors** page offers:

```json
[
  {
    "key": "intercom_eu",
    "name": "Intercom (EU)",
    "description": "Search conversations, contacts and Help Center articles.",
    "url": "https://mcp.eu.intercom.com/mcp",
    "auth_type": "bearer_token",
    "logo_url": "/images/mcp-catalog/intercom_eu.png",
    "docs_url": "https://developers.intercom.com/docs/guides/mcp"
  }
]
```

| Field              | Notes                                                                             |
| ------------------ | --------------------------------------------------------------------------------- |
| `key`              | Never changes; send it as `connector_key`                                         |
| `url`, `auth_type` | What to register; `auth_type` is `oauth2`, `none`, `bearer_token` or `basic_auth` |
| `logo_url`         | A path on the web app                                                             |
| `docs_url`         | Where the vendor issues the key; `null` when there is none                        |

To connect one, [register it](#register-an-mcp-server) with its `name`, `url` and `auth_type`, `connector_key` set to its `key`, and the `credentials` that `auth_type` needs. For `oauth2`, [sign in](#connect-an-oauth-server) first and pass `oauth_handle`.

Call a tool [#call-a-tool]

1. Read the connection and pick a tool:

   ```bash
   curl "$CENTRAL_HUB_URL/api/v1/mcp-connections/62/" \
     -H "X-API-Key: $ALO_API_KEY" \
     -H "X-Space-Slug: $WORKSPACE_SLUG"
   ```

   Each `discovered_tools[].input_schema` is what `arguments` must satisfy. If the list is empty or stale, send `POST …/mcp-connections/62/refresh-tools/`.

2. Call it. `arguments` is optional and defaults to `{}`:

   ```bash
   curl -X POST "$CENTRAL_HUB_URL/api/v1/mcp-connections/62/call/" \
     -H "X-API-Key: $ALO_API_KEY" \
     -H "X-Space-Slug: $WORKSPACE_SLUG" \
     -H "Content-Type: application/json" \
     -d '{"tool_name": "search_issues", "arguments": {"query": "renewal"}}'
   ```

3. Read `result`, the tool's output:

   ```json
   {"result": {"issues": [{"id": "ISS-1", "title": "Renewal overdue (renewal)"}]}}
   ```

Rotate credentials [#rotate-credentials]

1. Send the new credentials to `PATCH /api/v1/mcp-connections/{connection_id}/`. They merge into the stored ones:

   ```bash
   curl -X PATCH "$CENTRAL_HUB_URL/api/v1/mcp-connections/62/" \
     -H "X-API-Key: $ALO_API_KEY" \
     -H "X-Space-Slug: $WORKSPACE_SLUG" \
     -H "Content-Type: application/json" \
     -d '{"credentials": {"token": "…"}}'
   ```

2. A change to `url`, `transport`, `auth_type` or `credentials` reconnects and refreshes `discovered_tools`; if that fails, the response is `422` and nothing changes.

Add an MCP server to an agent [#add-an-mcp-server-to-an-agent]

* On every run: add the connection ID to the agent's `enabled_mcp_connection_ids`, with `PATCH /api/v1/agents-v2/agents/{agent_id}/` or in a bundle's `agent.yaml`, as in [Create and configure an agent](../configurable-agents/create-and-configure).
* For one run: pass it in `forwardedProps.runtimeConfig.mcp_connection_ids`; see [Run an agent and stream its events](../configurable-agents/run-and-stream).

Troubleshooting [#troubleshooting]

| Response                                                                                                              | Cause                                                                                         | Fix                                                       |
| --------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `404` `MCP connection not found`                                                                                      | The ID does not exist, or it is another user's private connection                             | Check the ID with `GET /api/v1/mcp-connections/`          |
| `502` `MCP tool 'nope' call failed: Unknown tool: nope`                                                               | `tool_name` is not one of the server's tools                                                  | Use a name from `discovered_tools`; refresh them if stale |
| `502` `MCP tool 'search_issues' call failed: Error executing tool search_issues: 1 validation error …`                | `arguments` do not satisfy the tool's `input_schema`                                          | Fix `arguments`                                           |
| `422` `tool_name is required`                                                                                         | Empty `tool_name`                                                                             | Send a tool name                                          |
| `428` `{"code": "PER_USER_AUTH_REQUIRED", "reason": "not_connected", "connector_key": "mcp", "connection_id": 63, …}` | An `oauth2` server you have not connected; `reason` is `needs_reauth` when your token expired | [Connect your account](#connect-an-oauth-server)          |
| `422` `Couldn't reach 127.0.0.1:1. Check the server is running and the address is right.`                             | Create, test or edit could not list the server's tools                                        | Fix the URL or credentials                                |
| `422` `Missing MCP credential field: token`                                                                           | A required credential for the `auth_type` is empty                                            | Add it                                                    |
| `422` `This MCP connection does not use OAuth.`                                                                       | `authenticate/` on a server whose `auth_type` is not `oauth2`                                 | Rotate its credentials with `PATCH` instead               |
| `409` `Workspace sharing is available after a second member joins`                                                    | `scope_visibility: "space"` in a one-member workspace                                         | Keep `private` or invite a member                         |
