Integrations connect agents to external tools through MCP (Model Context Protocol) servers. Crewship uses a three-tier model: workspace-level MCP servers cascade down to crews, which cascade down to agent bindings, and each level can override or extend the configuration. Servers can be defined directly, discovered from the MCP registry, and authenticated with stored credentials or a full OAuth 2.0 flow.
All integration endpoints require authentication and workspace context (except where a step explicitly states otherwise, such as the OAuth callback).
Endpoints
Managed Integrations (Composio)
Read-only inventory of the Composio managed-integration provider. See the
Integrations guide for the
object model. Requires COMPOSIO_API_KEY on the server; when unset the endpoint
returns enabled: false with empty lists rather than an error.
Composio Inventory
GET /api/v1/integrations/composio/inventory?workspace_id={workspaceId}
Returns the connector catalog (auth configs) and every connected account
grouped by Composio user_id. Gated on workspace read. This is an operator
view; agents are scoped to a single user_id and never receive the full list.
Response: 200 OK
{
"enabled": true,
"auth_configs": [
{
"id": "ac_JE6J7fDSsneA",
"name": "gmail-i6p1sb",
"status": "ENABLED",
"toolkit": { "slug": "gmail", "logo": "https://logos.composio.dev/api/gmail" }
}
],
"users": [
{
"user_id": "pg-test-8acca167",
"connected_accounts": [
{
"id": "ca_2pjydr0oHqiI",
"user_id": "pg-test-8acca167",
"status": "ACTIVE",
"toolkit": { "slug": "gmail" },
"auth_config": { "id": "ac_JE6J7fDSsneA", "auth_scheme": "OAUTH2", "is_composio_managed": true, "is_disabled": false }
}
]
}
]
}
| Field | Type | Description |
|---|
enabled | boolean | Whether the provider is configured (COMPOSIO_API_KEY set) |
auth_configs | array | Connector catalog — one entry per configured app |
users | array | Connected accounts grouped by Composio user_id, sorted by user_id |
CLI: crewship integration composio inventory.
GET /api/v1/integrations/composio/toolkits?workspace_id={workspaceId}&search={q}&category={cat}&limit={n}
Proxies the Composio app catalog (1000+ connectable apps). search, category,
and limit (max 100, default 40) are optional server-side filters. Read-gated;
returns enabled: false when the provider is unconfigured.
Response: 200 OK
{
"enabled": true,
"total": 1047,
"toolkits": [
{
"slug": "github",
"name": "GitHub",
"no_auth": false,
"meta": {
"description": "Code hosting platform…",
"logo": "https://logos.composio.dev/api/github",
"tools_count": 846,
"categories": [{ "id": "developer-tools", "name": "developer tools" }]
}
}
]
}
| Field | Type | Description |
|---|
enabled | boolean | Whether the provider is configured |
total | integer | Total apps matching the filter in the Composio catalog |
toolkits | array | The current page of apps (slug, name, meta) |
CLI: crewship integration composio toolkits [--search] [--category] [--limit].
GET /api/v1/integrations/composio/tools?workspace_id={workspaceId}&toolkit={slug}&search={q}&limit={n}
Lists the tools a single toolkit exposes (e.g. github has 846, gmail 61).
toolkit is required (400 otherwise). search and limit (max 100,
default 40) are optional server-side filters. Read-gated; returns
enabled: false when the provider is unconfigured.
Response: 200 OK
{
"enabled": true,
"total": 846,
"tools": [
{
"slug": "GITHUB_CREATE_AN_ISSUE",
"name": "Create an issue",
"description": "Create a new issue in a repository",
"toolkit": { "slug": "github" }
}
]
}
| Field | Type | Description |
|---|
enabled | boolean | Whether the provider is configured |
total | integer | Total tools matching the filter for the toolkit |
tools | array | The current page of tools (slug, name, description, toolkit) |
CLI: crewship integration composio tools <toolkit> [--search] [--limit].
Composio Triggers
GET /api/v1/integrations/composio/triggers?workspace_id={workspaceId}&toolkit={slug}&search={q}&limit={n}
Lists the available trigger types — event subscriptions a toolkit exposes
(e.g. GMAIL_NEW_MESSAGE, GITHUB_PR_OPENED). toolkit, search, and
limit (max 100, default 40) are optional server-side filters. Read-gated;
returns enabled: false when the provider is unconfigured.
Response: 200 OK
{
"enabled": true,
"total": 12,
"triggers": [
{
"slug": "GMAIL_NEW_GMAIL_MESSAGE",
"name": "New Gmail message",
"description": "Triggers when a new email arrives",
"type": "poll",
"toolkit": { "slug": "gmail" }
}
]
}
| Field | Type | Description |
|---|
enabled | boolean | Whether the provider is configured |
total | integer | Total trigger types matching the filter |
triggers | array | The current page of trigger types (slug, name, description, type, toolkit) |
CLI: crewship integration composio triggers types [--toolkit] [--search] [--limit].
Composio Active Triggers
GET /api/v1/integrations/composio/triggers/active?workspace_id={workspaceId}
Lists the live trigger instances in the project across all users. Read-gated;
returns enabled: false when the provider is unconfigured.
Response: 200 OK
{
"enabled": true,
"triggers": [
{
"id": "ti_abc123",
"trigger_name": "GMAIL_NEW_GMAIL_MESSAGE",
"user_id": "user-1",
"connected_account_id": "ca_1",
"trigger_config": { "interval": 60 }
}
]
}
| Field | Type | Description |
|---|
enabled | boolean | Whether the provider is configured |
triggers | array | The active trigger instances (id, trigger_name, user_id, connected_account_id, trigger_config, disabled_at) |
CLI: crewship integration composio triggers active.
Composio Create Trigger
POST /api/v1/integrations/composio/triggers?workspace_id={workspaceId}
Creates (or re-enables) a trigger instance for a Composio user. OWNER/ADMIN
only. Returns 400 if slug or user_id is empty, or if the provider is
unconfigured.
Request body:
{
"slug": "GMAIL_NEW_GMAIL_MESSAGE",
"user_id": "user-1",
"config": { "interval": 60 }
}
| Field | Type | Description |
|---|
slug | string | Trigger-type slug to enable (required) |
user_id | string | Composio user the trigger fires for (required) |
config | object | Trigger-type-specific configuration (optional) |
Response: 200 OK
{
"enabled": true,
"trigger": {
"id": "ti_new",
"trigger_name": "GMAIL_NEW_GMAIL_MESSAGE",
"user_id": "user-1",
"trigger_config": { "interval": 60 }
}
}
CLI: crewship integration composio triggers enable <slug> --user <id>.
Composio Connect
POST /api/v1/integrations/composio/connect?workspace_id={workspaceId}
Starts an OAuth Connect Link for an app and user. Requires workspace manage
(OWNER/ADMIN). Finds the toolkit’s auth config (creating a managed one on demand
if none exists), then creates a Composio Connect Link for the given user.
Request body:
{ "toolkit": "gmail", "user_id": "user-42" }
| Field | Type | Description |
|---|
toolkit | string | App slug to authorize (required) |
user_id | string | Composio user to connect the account under (required) |
Returns 400 if either field is empty, or if Composio is unconfigured.
Response: 200 OK
{
"redirect_url": "https://…",
"connected_account_id": "ca_…",
"user_id": "user-42"
}
The end-user opens redirect_url to authorize. Returns 502 on an upstream
Composio failure. CLI: crewship integration composio connect <toolkit> --user <id>.
Composio Settings
Manage the per-workspace Composio API key from the app instead of the
server env. The key is validated against Composio before being stored
encrypted (AES-GCM). The effective key is resolved per request: the
workspace key first, then the server COMPOSIO_API_KEY env fallback. The key
is never returned by any endpoint.
GET /api/v1/integrations/composio/settings?workspace_id={workspaceId}
PUT /api/v1/integrations/composio/settings?workspace_id={workspaceId}
DELETE /api/v1/integrations/composio/settings?workspace_id={workspaceId}
GET (read) returns the status; PUT/DELETE require workspace manage
(OWNER/ADMIN). PUT body: { "api_key": "ak_…", "label": "" }.
The Composio host is server-controlled via the COMPOSIO_BASE_URL env var, not
via this API.
Response (GET / PUT / DELETE): 200 OK
{ "configured": true, "source": "workspace", "label": "Crewship_dev_1" }
| Field | Type | Description |
|---|
configured | boolean | Whether a usable key exists (workspace or env) |
source | string | workspace, env, or none |
label | string | Optional project label (workspace source only) |
A PUT with an invalid key returns 400 (Composio rejected it). CLI:
crewship integration composio key {show,set,remove}.
Composio Default Connector
Inspect / provision the workspace-wide default connector. When the server
flag COMPOSIO_DEFAULT_CONNECTOR is ON, every agent without an explicit
per-agent binding inherits this connector (full access to all the workspace’s
connected apps), and legacy non-Composio MCP servers are turned off at
resolve time (not deleted). See the
Integrations guide.
GET /api/v1/integrations/composio/default?workspace_id={workspaceId}
PUT /api/v1/integrations/composio/default?workspace_id={workspaceId}
GET (read) reports state; PUT requires workspace manage (OWNER/ADMIN).
PUT body is optional: { "user_id": "<id>" } pins the default Composio user;
omit it to auto-derive the user when exactly one is connected. PUT errors
400 when zero users are connected (“connect an account first”) or when
multiple users exist (pin one). Re-running is idempotent and refreshes the
connector’s app set.
Response (GET / PUT): 200 OK
{ "enabled_flag": true, "default_user_id": "user-a", "default_mcp_server_id": "mcp_srv_1", "connected_user_count": 1 }
| Field | Type | Description |
|---|
enabled_flag | boolean | Whether COMPOSIO_DEFAULT_CONNECTOR is armed on the server |
default_user_id | string | The Composio user the default is scoped to ("" if unset) |
default_mcp_server_id | string | The provisioned Composio MCP server id ("" if not provisioned) |
connected_user_count | integer | Live count of Composio users with connected accounts |
CLI: crewship integration composio default {show,set,enable}.
Composio Agent Binding
Grant an agent per-app, tool-scoped access to a Composio user’s
connected apps. For each granted app the binding provisions one
tool-scoped Composio MCP server and persists the rows the runtime resolver
reads — a per-(agent, app) workspace MCP server pointing at the per-user
Composio MCP URL, a workspace credential holding the Composio API key, and an
agent MCP binding joining them (cred_type: api_key, cred_header: x-api-key).
No resolver change is needed: the sidecar injects the x-api-key header on the
streamable-http request.
Each app carries a mode that maps to the MCP server’s allowed_tools:
| Mode | allowed_tools | Effect |
|---|
full | (empty) | Every tool the app exposes (no enumeration). |
read | the app’s read-ish tools | Server-resolved: tools whose slug carries a read verb (GET, LIST, FETCH, SEARCH, READ, …). Conservative — unknown verbs are treated as not-read. |
custom | the picked tool slugs | The request’s tools, intersected with the app’s real tools (bogus slugs are dropped). |
GET /api/v1/integrations/composio/agents/{agentId}/bind?workspace_id={workspaceId}
POST /api/v1/integrations/composio/agents/{agentId}/bind?workspace_id={workspaceId}
DELETE /api/v1/integrations/composio/agents/{agentId}/bind?workspace_id={workspaceId}[&toolkit={slug}]
GET (read) lists the agent’s per-app Composio bindings; POST/DELETE
require workspace manage (OWNER/ADMIN). POST body:
{
"user_id": "user-42",
"apps": [
{ "toolkit": "gmail", "mode": "read" },
{ "toolkit": "github", "mode": "full" },
{ "toolkit": "gmail", "mode": "custom", "tools": ["GMAIL_FETCH_EMAILS", "GMAIL_LIST_THREADS"] }
]
}
user_id is required (the Composio user the agent is scoped to). The legacy
shape { "user_id": "…", "toolkits": ["gmail"] } is still accepted — each
toolkit becomes an app at full. When neither apps nor toolkits is given,
every connected app is bound at full. Re-binding replaces the agent’s app
set: apps no longer present are removed (their server row + binding deleted).
read/custom with an empty resolved tool set returns 400. DELETE with
?toolkit=<slug> removes one app; without it, removes all the agent’s Composio
apps.
Response (POST): 200 OK
{
"agent_id": "clx…",
"user_id": "user-42",
"apps": [
{ "toolkit": "gmail", "mode": "read", "endpoint": "https://mcp.composio.dev/server/…?user_id=user-42" },
{ "toolkit": "github", "mode": "full", "endpoint": "https://mcp.composio.dev/server/…?user_id=user-42" }
]
}
Response (GET): 200 OK
{ "agent_id": "clx…", "bindings": [ { "toolkit": "gmail", "mode": "read", "user_id": "user-42", "endpoint": "https://mcp.composio.dev/server/…?user_id=user-42" } ] }
POST returns 404 for an unknown/foreign agent and 400 when Composio is
unconfigured or no apps resolve. CLI:
crewship integration composio {bind,unbind,bindings} <agent> --user <id> [--app toolkit[:mode[:t1,t2]]]….
Composio Connected-Account Management
Lifecycle operations on an existing connected account. The accountId is the
Composio account id surfaced by the inventory endpoint.
All three require workspace manage (OWNER/ADMIN) and return 400 when
Composio is unconfigured.
POST /api/v1/integrations/composio/accounts/{accountId}/revoke?workspace_id={workspaceId}
POST /api/v1/integrations/composio/accounts/{accountId}/refresh?workspace_id={workspaceId}
DELETE /api/v1/integrations/composio/accounts/{accountId}?workspace_id={workspaceId}
- revoke — de-authorizes the account at the provider. Its credentials are
invalidated upstream; the user must re-connect before it can be used again.
- refresh — refreshes the account’s credentials (e.g. exchanging a refresh
token for a new access token).
- delete — permanently removes the connected account at the provider.
Response: 204 No Content on success; 502 when Composio returns an error.
CLI: crewship integration composio account {revoke,refresh,remove} <account-id>.
Workspace Integrations
Workspace-level MCP server definitions available to all crews and agents.
List Workspace Integrations
GET /api/v1/integrations?workspace_id={workspaceId}
Response: 200 OK
[
{
"id": "int_abc",
"workspace_id": "ws_123",
"name": "github-mcp",
"display_name": "GitHub MCP Server",
"transport": "stdio",
"endpoint": null,
"command": "npx",
"args_json": "[\"-y\", \"@modelcontextprotocol/server-github\"]",
"env_json": "{\"GITHUB_TOKEN\": \"{{credential:github-token}}\"}",
"config_json": null,
"icon": "github",
"enabled": true,
"created_at": "2024-01-15T10:00:00Z",
"updated_at": "2024-01-15T10:00:00Z",
"agent_binding_count": 5,
"crew_server_count": 2
}
]
Response Fields
| Field | Type | Description |
|---|
id | string | Integration ID |
workspace_id | string | Workspace ID |
name | string | Internal name |
display_name | string | Human-readable name |
transport | string | Transport type (validated set: streamable-http or stdio) |
endpoint | string? | Server endpoint URL (required when transport is streamable-http) |
command | string? | Command to execute (required when transport is stdio) |
args_json | string? | JSON array of command arguments |
env_json | string? | JSON object of environment variables |
config_json | string? | Additional configuration JSON |
icon | string? | Display icon name |
enabled | boolean | Whether the integration is active |
agent_binding_count | integer | Number of agent bindings |
crew_server_count | integer | Number of crew-level servers |
Create Workspace Integration
POST /api/v1/integrations?workspace_id={workspaceId}
Auth: OWNER or ADMIN role
Request Body:
| Field | Type | Required | Default | Description |
|---|
name | string | Yes | — | Internal name |
display_name | string | No | name | Display name (defaults to name when omitted) |
transport | string | No | "streamable-http" | streamable-http or stdio |
endpoint | string | Conditional | null | Required when transport is streamable-http |
command | string | Conditional | null | Required when transport is stdio |
args_json | string | No | null | JSON array of arguments |
env_json | string | No | null | JSON object of env vars |
config_json | string | No | null | Additional config JSON |
icon | string | No | null | Display icon |
{
"name": "github-mcp",
"display_name": "GitHub MCP Server",
"transport": "stdio",
"command": "npx",
"args_json": "[\"-y\", \"@modelcontextprotocol/server-github\"]",
"env_json": "{\"GITHUB_TOKEN\": \"{{credential:github-token}}\"}"
}
Response: 201 Created — integration object (enabled defaults to true).
| Status | Condition |
|---|
400 | Missing name, invalid transport, or endpoint/command missing for the chosen transport |
403 | Insufficient role |
409 | Integration with this name already exists |
Get Workspace Integration
GET /api/v1/integrations/{integrationId}?workspace_id={workspaceId}
Response: 200 OK
Update Workspace Integration
PATCH /api/v1/integrations/{integrationId}?workspace_id={workspaceId}
Auth: OWNER or ADMIN role
All fields optional: display_name, transport, endpoint, command, args_json, env_json, config_json, icon, enabled.
Response: 200 OK
Delete Workspace Integration
DELETE /api/v1/integrations/{integrationId}?workspace_id={workspaceId}
Cascade-deletes agent bindings, crew-level overrides, and finally the workspace server, all in one transaction.
This cascades: every agent binding and crew-level override of the integration is removed alongside the workspace server, in a single transaction.
Auth: OWNER or ADMIN role
Response: 200 OK
| Status | Condition |
|---|
404 | Integration not found |
Test Workspace Integration
POST /api/v1/integrations/{integrationId}/test?workspace_id={workspaceId}
Tests the MCP server connection. For stdio transport the server is not actually launched (that only happens inside a container at runtime) — instead the config is statically validated (command must be a bare executable with no embedded whitespace, args_json must be a valid JSON string array), returning status: "ok" when well-formed or status: "error" otherwise. For streamable-http (also http/sse) an MCP initialize handshake is attempted via an SSRF-safe HTTP client (private/loopback IPs blocked).
Response: 200 OK
{
"status": "ok",
"message": "Connected to MCP server",
"server_info": { "name": "github-mcp", "version": "1.2.3" }
}
| Field | Description |
|---|
status | ok, error, or auth_required (the struct also defines skipped, but the current handlers never emit it) |
message | Optional human-readable description (omitted when empty) |
server_info | Optional raw initialize result from the server (omitted when empty) |
| Status | Condition |
|---|
404 | Integration not found |
Crew Integrations
Crew-level MCP bindings — either standalone servers or overrides linked to a workspace integration. This tier also carries per-tool enable/disable state.
All Crew Integrations
GET /api/v1/integrations/crews?workspace_id={workspaceId}
Cross-crew overview of all crew-level integration bindings.
Response: 200 OK — array of crew integration objects.
List Crew Integrations
GET /api/v1/crews/{crewId}/integrations?workspace_id={workspaceId}
Response: 200 OK — array of crew MCP server bindings.
Create Crew Integration
POST /api/v1/crews/{crewId}/integrations?workspace_id={workspaceId}
Auth: OWNER, ADMIN, or MANAGER role
Request Body:
| Field | Type | Required | Default | Description |
|---|
workspace_mcp_server_id | string | No | null | Link to an existing workspace integration (must be in same workspace) |
name | string | Yes | — | Internal name |
display_name | string | No | name | Display name |
transport | string | No | "streamable-http" | streamable-http or stdio |
endpoint | string | Conditional | null | Required when transport is streamable-http |
command | string | Conditional | null | Required when transport is stdio |
args_json | string | No | null | JSON array of arguments |
env_json | string | No | null | JSON object of env vars |
config_json | string | No | null | Additional config JSON |
icon | string | No | null | Display icon |
Response: 201 Created — crew MCP server object.
| Status | Condition |
|---|
400 | Missing name, invalid transport, missing endpoint/command for transport, or referenced workspace integration not in same workspace |
404 | Crew not found |
409 | Integration with this name already exists in this crew |
Update Crew Integration
PATCH /api/v1/crews/{crewId}/integrations/{integrationId}?workspace_id={workspaceId}
Auth: OWNER or ADMIN role
All fields optional: display_name, transport, endpoint, command, args_json, env_json, config_json, icon, enabled. Changing transport re-validates against the merged final endpoint/command.
Response: 200 OK — updated crew integration object.
| Status | Condition |
|---|
400 | Invalid transport, or endpoint/command missing for new transport |
404 | Crew integration not found |
Delete Crew Integration
DELETE /api/v1/crews/{crewId}/integrations/{integrationId}?workspace_id={workspaceId}
Cascade-deletes agent bindings and any OAuth credentials that were auto-created for this integration (only when no other binding still references them).
This cascades: agent bindings are removed, and OAuth credentials auto-created for this integration are deleted too — but only when no other binding still references them.
Auth: OWNER or ADMIN role
Response: 200 OK
| Status | Condition |
|---|
404 | Crew integration not found |
Test Crew Integration
POST /api/v1/crews/{crewId}/integrations/{integrationId}/test?workspace_id={workspaceId}
Same probe semantics as the workspace test endpoint.
Response: 200 OK — { status, message?, server_info? } (see Test Workspace Integration).
| Status | Condition |
|---|
404 | Crew or integration not found |
GET /api/v1/crews/{crewId}/integrations/{integrationId}/tools?workspace_id={workspaceId}
Returns the recorded per-tool enable/disable bindings for the crew’s
MCP server (mcp_tool_bindings). Only tools that have been toggled or
seen via Refresh have a row; a tool
with no row is treated as enabled by default. This endpoint does
not contact the MCP server.
Response: 200 OK — a JSON array of tool-binding objects (no wrapper).
[
{ "id": "tb_abc", "tool_name": "search", "description": "...", "enabled": true, "created_at": "2026-05-14T09:12:44Z", "updated_at": "2026-05-14T09:12:44Z" },
{ "id": "tb_def", "tool_name": "create_issue", "description": null, "enabled": false, "created_at": "2026-05-14T09:12:44Z", "updated_at": "2026-05-14T09:12:44Z" }
]
| Field | Type | Description |
|---|
id | string | Tool-binding row ID |
tool_name | string | MCP tool name |
description | string? | Tool description (nullable) |
enabled | boolean | Per-crew enabled state |
created_at | string | ISO 8601 timestamp |
updated_at | string | ISO 8601 timestamp |
| Status | Condition |
|---|
404 | Crew or integration not found |
500 | Database error (a real DB failure is not collapsed to 404) |
PATCH /api/v1/crews/{crewId}/integrations/{integrationId}/tools/{toolName}?workspace_id={workspaceId}
Content-Type: application/json
Upsert a single tool’s binding for this crew. If no row exists for the
tool it is materialised (a fresh row defaults to enabled = true).
Wraps the crewship integration tool enable/disable CLI subcommands.
Auth: OWNER or ADMIN role (canRole(role, "manage"))
Request Body: provide at least one of the following fields.
| Field | Type | Description |
|---|
enabled | boolean | New enabled state (omit to leave unchanged) |
description | string | Tool description to store (omit to leave unchanged) |
Response: 200 OK — the upserted tool-binding object (same shape as the List entries).
| Status | Condition |
|---|
400 | Empty toolName, invalid JSON, or neither enabled nor description supplied |
403 | Insufficient role |
404 | Crew or integration not found |
POST /api/v1/crews/{crewId}/integrations/{integrationId}/tools/refresh?workspace_id={workspaceId}
Reconcile the mcp_tool_bindings rows for this crew server against a
tool list supplied in the request body (typically posted by the
frontend after a successful test-connection round-trip). The server
does not contact the MCP server itself: new tools are inserted
enabled = true, existing tools have their description refreshed but
their enabled state left untouched, and tools absent from the payload
are left in place (never auto-revoked). An empty list is a no-op.
Auth: OWNER or ADMIN role (canRole(role, "manage"))
Request Body:
{
"tools": [
{ "name": "search", "description": "Search issues" },
{ "name": "create_issue", "description": null }
]
}
Response: 200 OK
{ "created": 1, "updated": 1, "total": 2 }
total is the number of entries in the request tools array.
| Status | Condition |
|---|
400 | Invalid JSON body |
403 | Insufficient role |
404 | Crew or integration not found |
Agent MCP Bindings
Agent bindings link MCP servers (workspace or crew level) to specific agents, optionally with credential overrides.
List Agent Bindings
GET /api/v1/agents/{agentId}/integrations?workspace_id={workspaceId}
Response: 200 OK — array of agent MCP binding objects.
Create Agent Binding
POST /api/v1/agents/{agentId}/integrations?workspace_id={workspaceId}
Auth: OWNER, ADMIN, or MANAGER role
Request Body:
| Field | Type | Required | Default | Description |
|---|
mcp_server_id | string | Yes | — | ID of the MCP server to bind |
mcp_server_scope | string | Yes | — | workspace or crew |
credential_id | string | No | null | Workspace credential to attach for auth |
cred_type | string | No | "bearer" | bearer, api_key, or basic |
cred_header | string | No | null | Custom header name (used when cred_type is api_key) |
env_var_name | string | No | null | Env var name for stdio credential injection |
enabled | boolean | No | true | Whether the binding is active |
config_override_json | string | No | null | Per-binding config override JSON |
Response: 201 Created — binding object.
| Status | Condition |
|---|
400 | Missing/invalid mcp_server_id, mcp_server_scope, cred_type, or referenced integration/credential not in this workspace |
404 | Agent not found |
409 | Agent already has a binding for this integration |
Update Agent Binding
PATCH /api/v1/agents/{agentId}/integrations/{integrationId}?workspace_id={workspaceId}
Auth: OWNER, ADMIN, or MANAGER role
All fields optional: credential_id (empty string clears), cred_type, cred_header, env_var_name (empty string clears), enabled, config_override_json.
Response: 200 OK
| Status | Condition |
|---|
400 | Invalid cred_type, credential not in this workspace, or no fields to update |
404 | Agent binding not found |
Delete Agent Binding
DELETE /api/v1/agents/{agentId}/integrations/{integrationId}?workspace_id={workspaceId}
Auth: OWNER, ADMIN, or MANAGER role
Response: 200 OK
| Status | Condition |
|---|
404 | Agent binding not found |
Resolve Agent Integrations
GET /api/v1/agents/{agentId}/integrations/resolved?workspace_id={workspaceId}
Returns the effective set of MCP servers for an agent after cascading workspace, crew, and agent-level configurations. Includes resolved credentials.
Response: 200 OK — array of resolved integration objects.
OAuth Flow
OAuth 2.0 flow for connecting external services (GitHub, Slack, Google, etc.) and storing tokens as credentials.
List OAuth Providers
GET /api/v1/oauth/providers
Returns available OAuth provider configurations.
Auth: Session or CLI token (no workspace context needed)
Response: 200 OK
Initiate OAuth Flow
POST /api/v1/oauth/initiate?workspace_id={workspaceId}
Starts the OAuth authorization flow by generating an authorization URL.
Auth: Session or CLI token + workspace membership
Response: 200 OK — includes the authorization URL to redirect the user to.
OAuth Callback
GET /api/v1/oauth/callback?code={code}&state={state}
Handles the OAuth callback from the provider.
No authentication required — this endpoint uses the state token for validation instead.
Exchange Token
POST /api/v1/oauth/exchange?workspace_id={workspaceId}
Exchanges an authorization code for access and refresh tokens.
Response: 200 OK
Loopback
POST /api/v1/oauth/loopback?workspace_id={workspaceId}
Handles loopback redirect for local OAuth flows.
Response: 200 OK
Discover OAuth Endpoints
POST /api/v1/oauth/discover
Discovers OAuth endpoints from an OpenID Connect discovery document or well-known URL.
Auth: Session or CLI token (no workspace context needed)
Response: 200 OK — discovered endpoints.
Auto-Connect Integration
POST /api/v1/oauth/auto-connect?workspace_id={workspaceId}
Automatically creates an integration from an OAuth connection.
Response: 200 OK
MCP Registry
Public registry of MCP server definitions for easy discovery and installation.
List Registry Entries
Auth: Session or CLI token (no workspace context needed)
Response: 200 OK — array of registry entries.
Search Registry
GET /api/v1/mcp-registry/search?q={query}
Auth: Session or CLI token
Response: 200 OK — matching registry entries.
Sync Registry
POST /api/v1/mcp-registry/sync?workspace_id={workspaceId}
Triggers a manual sync of the MCP registry.
Auth: Session or CLI token + workspace membership
Response: 200 OK