# Tool integrations API

> Attach managed MCP servers, app integrations, and your own MCP servers to an agent over the REST API, and complete their OAuth sign-in.

Source: https://docs.runbear.io/api/tool-integrations

Last updated: 2026-09-30

The **Tool integrations API** gives an agent its tools from your own code: the same managed MCP servers, app integrations, and [Custom MCP](/agents/tools/custom-mcp.md) servers you would otherwise add on the agent's **Tools** tab. Use it to provision agents from a script, keep several agents' tools in step, or connect an internal MCP server as part of a deployment.

## What you need

- An [API key](/api/api-keys.md). Reading needs no particular capability; creating, changing, and deleting integrations needs the [`manageAgents` capability](/api/api-keys.md#capabilities).
- An **Anthropic**, **OpenAI Responses**, or **Claude Agent SDK** agent. Other agent types don't take tool integrations through the API: writes to them answer `400` with `provider_does_not_support_tool_integrations`. Claude Agent SDK agents also need API access to be enabled for your organization, or requests answer `400` with `claude_agent_sdk_not_permitted`.

## Endpoints

| Endpoint                                                               | Purpose                                                           |
| ---------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `GET /v1/agents/{agentId}/tool-integrations`                           | List the agent's integrations, as `{ "toolIntegrations": [...] }` |
| `POST /v1/agents/{agentId}/tool-integrations`                          | Attach an integration. Answers `201` with the new integration     |
| `GET /v1/agents/{agentId}/tool-integrations/{integrationId}`           | Read one integration                                              |
| `PATCH /v1/agents/{agentId}/tool-integrations/{integrationId}`         | Replace an integration's settings                                 |
| `DELETE /v1/agents/{agentId}/tool-integrations/{integrationId}`        | Detach an integration and delete the secrets it stored            |
| `POST /v1/agents/{agentId}/tool-integrations/{integrationId}/auth-url` | Get a sign-in URL for an integration that needs OAuth             |
| `GET /v1/tool-integrations/managed-mcps`                               | List the managed MCP catalog                                      |

Every request and response field is in the [OpenAPI reference](https://api.runbear.io/v1/docs).

## Integration types

The `type` field decides which other fields an integration has.

### `managed-mcp`

A managed MCP server from Runbear's catalog, such as Notion or HubSpot. Find its slug with `GET /v1/tool-integrations/managed-mcps`, which also lists each server's transport, whether it uses OAuth, and its tools.

```json
{
  "type": "managed-mcp",
  "app": "notion"
}
```

Runbear fills in the server's connection details from the catalog. A catalog server that runs as a local process may need environment variables, such as an API key. Pass them in `secrets.envMap`; they're stored in your organization's vault. Remote (OAuth) catalog servers take no `secrets`, and sending them answers `400` with `secrets_not_supported_for_remote_managed_mcp`.

### `pipedream`

An app integration, identified by its app slug.

```json
{
  "type": "pipedream",
  "nameSlug": "firecrawl",
  "authType": "keys"
}
```

`authType` is how the app authenticates: `keys`, `oauth`, or `none`.

### `custom-mcp`

Your own MCP server.

```json
{
  "type": "custom-mcp",
  "app": "context-server",
  "url": "https://mcp.example.com/mcp",
  "transportType": "streamableHttp",
  "auth": { "type": "static", "headerKey": "Authorization" },
  "httpHeaders": {
    "Authorization": { "type": "secret", "value": "Bearer sk-..." },
    "X-Team": { "type": "plain_text", "value": "support" }
  }
}
```

| Field           | Meaning                                                                                                                                                                     |
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `app`           | The server's name, the same value as **Server Name** in the dashboard. [Hooks](/api/hooks.md) refer to the server by it                                                     |
| `url`           | The server's URL                                                                                                                                                            |
| `transportType` | `streamableHttp` or `sse`                                                                                                                                                   |
| `auth`          | `{ "type": "oauth" }`, `{ "type": "none" }`, or `{ "type": "static", "headerKey": "..." }`, where `headerKey` names the header in `httpHeaders` that carries the credential |
| `httpHeaders`   | Headers sent with every request. Each value is `{ "type": "plain_text", "value": ... }` or, for a credential, `{ "type": "secret", "value": ... }`                          |

A `secret` header is stored in your organization's vault and never returned. When you read the integration back, it appears as `{ "type": "vault", "keyName": "..." }`.

Some names are reserved for Runbear's own integrations, and a `custom-mcp` with one of them answers `400` with `tool_integration_identity_reserved`. A few vendors' MCP servers can only be connected from the dashboard; pointing a `custom-mcp` at one answers `400` with `tool_integration_preset_not_supported_via_public_api`.

### Fields every type has

- `excludedTools` — tool names to hide from the agent, for a server that offers more tools than the agent should use.
- `status` — read-only. `ready` means the integration is authorized and its tools are usable; `pending_auth` means someone has to finish signing in first.

`pipedream` and `custom-mcp` integrations created through the API use one shared connection for everyone who talks to the agent, rather than asking each person to connect their own account. Per-user connections are set up in the dashboard.

## Changing and removing an integration

`PATCH` replaces the integration's settings with the body you send, which has the same shape as the one for `POST`. The `type` and the integration's identity (`app` for `managed-mcp` and `custom-mcp`, `nameSlug` for `pipedream`) can't change; a request that changes them answers `400` with `tool_integration_identity_immutable`. To switch to a different app or server, delete the integration and create a new one. A `secret` header you send replaces the stored value.

Integrations set up with a per-user connection, or with a vendor preset, can be edited only in the dashboard; `PATCH` answers `400` with `tool_integration_not_editable_via_public_api`.

`DELETE` detaches the integration and deletes the secrets it stored in the vault.

## Completing OAuth

An integration that uses OAuth starts as `pending_auth`. To finish it:

1. Call `POST /v1/agents/{agentId}/tool-integrations/{integrationId}/auth-url`.
2. Open the returned `authUrl` in a browser and approve access. Runbear completes the sign-in on its side.
3. Read the integration again. Its `status` is now `ready`.

`authUrl` is `null` when the integration is already authorized. An integration that has no browser sign-in (a `pipedream` app with `authType` `none`, a managed MCP server that runs as a local process, or a `custom-mcp` with `auth` `none` or `static`) answers `400` with `auth_url_not_applicable`.

## Errors

These endpoints answer with a route-specific body, `{ "error": "<cause>", "message": "..." }`, rather than the [standard envelope](/api/errors-and-limits.md#other-shapes). Branch on `error`:

| Status | `error`                                                | When                                                                                                                                                                                                  |
| ------ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | `provider_does_not_support_tool_integrations`          | The agent's type doesn't take tool integrations through the API. Until a pending fix ships, the `message` names only Anthropic and OpenAI Responses, though Claude Agent SDK agents are supported too |
| `400`  | `claude_agent_sdk_not_permitted`                       | API access to Claude Agent SDK agents isn't enabled for your organization                                                                                                                             |
| `400`  | `unknown_managed_mcp_app`                              | `app` isn't a slug in the managed MCP catalog                                                                                                                                                         |
| `400`  | `secrets_not_supported_for_remote_managed_mcp`         | `secrets` was sent for a remote managed MCP server                                                                                                                                                    |
| `400`  | `tool_integration_identity_immutable`                  | A `PATCH` tried to change `type`, `app`, or `nameSlug`                                                                                                                                                |
| `400`  | `tool_integration_not_editable_via_public_api`         | The integration can be edited only in the dashboard                                                                                                                                                   |
| `400`  | `tool_integration_identity_reserved`                   | The `custom-mcp` name is reserved for Runbear                                                                                                                                                         |
| `400`  | `tool_integration_preset_not_supported_via_public_api` | That server can be connected only from the dashboard                                                                                                                                                  |
| `400`  | `auth_url_not_applicable`                              | The integration has no browser sign-in                                                                                                                                                                |
| `404`  | `agent_not_found` or `not_found`                       | The agent or the integration doesn't exist in your organization                                                                                                                                       |
| `409`  | `tool_integration_already_exists`                      | The agent already has an integration for that app or server. Update or delete it instead                                                                                                              |

## Integration suggestions

When someone asks an agent to do something with an app it isn't connected to, the agent can answer with an "Integration Required" message that links to Runbear's setup page. For agents whose users never see Runbear, such as one behind your own product, you can turn those suggestions off for the whole organization. There is no dashboard control for this; it is set through the API only.

| Endpoint                          | Purpose                                                                                                                                         |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /v1/integration-suggestions` | Read the setting, as `{ "disabled": false }`                                                                                                    |
| `PUT /v1/integration-suggestions` | Change it. Send `{ "disabled": true }` to stop the suggestions, `{ "disabled": false }` to restore them. Requires the `manageAgents` capability |

Suggestions are on (`disabled: false`) by default.

## Related

- [Custom MCP](/agents/tools/custom-mcp.md) — the same servers, set up from the dashboard
- [Tool catalog](/agents/tools/catalog.md) — the managed servers and apps you can attach
- [Managing agents via API](/api/agents.md) — create and configure the agents these integrations attach to
- [Hooks API](/api/hooks.md) — call a Custom MCP tool at fixed points in a conversation
- [MCP server](/api/mcp-server.md) — attach integrations from an AI client instead
