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

# Integrations

> Connect agents to external services via OAuth 2.0, MCP servers, and the official MCP registry.

# Integrations

<Note>
  **The managed Composio UI is now the default.** The `/integrations` page is the
  full managed integration platform (Composio) — a KPI header plus tabs for
  Catalog, Connected accounts, Agent access, Tools, Triggers, and MCP endpoints —
  so you can connect apps via OAuth without standing up and maintaining your own
  MCP servers.

  The legacy self-hosted MCP connector management UI is restorable by building the
  dashboard with `NEXT_PUBLIC_LEGACY_MCP_INTEGRATIONS=true`. No legacy code or API
  has been removed — the MCP endpoints documented below still work, and
  **credentials are unaffected**. The sections below describe the legacy mechanism.
</Note>

Crewship supports two integration mechanisms: **OAuth 2.0 connections** for service authentication and **MCP (Model Context Protocol) servers** for extending agent tool capabilities.

## Managed Integrations (Composio)

Crewship's managed integration path uses [Composio](https://composio.dev) so you connect apps once instead of hosting MCP servers yourself.

**Object model**

| Concept               | What it is                                                                                                    |
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Auth config**       | Per-app OAuth blueprint (GitHub, Slack, Gmail, …). One per app, shared by all users. The "connector catalog". |
| **User (`user_id`)**  | An end-user identity — the isolation boundary. A user owns a set of connected accounts.                       |
| **Connected account** | One user's authorised connection to an app (OAuth tokens).                                                    |

**How isolation works.** An agent is bound to exactly **one `user_id`** and therefore sees only that user's connected accounts — never anyone else's. To give 30 mailboxes to 30 agents, create 30 users (one per mailbox) and bind each agent to its user; the per-agent MCP URL is scoped server-side, so an agent cannot reach another user's accounts even in principle. Use Composio **projects** only for coarse isolation (per environment, or per customer/workspace) — not per agent.

**Enabling.** Add a Composio **project API key** either per-workspace from the app (Integrations → **API key**, or `crewship integration composio key set`) — validated and stored encrypted — or server-wide via the `COMPOSIO_API_KEY` env. The effective key resolves workspace-first, then env. Billing is by tool calls (Composio free tier = 20K/mo), not by number of users or connected accounts.

<Warning>
  **Multi-tenant isolation.** A Composio API key maps to a single Composio
  **project**, which is the isolation boundary — every connected account, user,
  and trigger under that key is visible to anyone with access to a workspace
  using it. The server-wide `COMPOSIO_API_KEY` env therefore puts **all**
  workspaces in **one shared project**: do not back multiple independent tenant
  workspaces with it. For true per-tenant isolation, give each workspace its own
  key (Integrations → API key) so it maps to a separate Composio project.
</Warning>

**Inspecting the inventory.** The operator view of the catalog and connected accounts (grouped by user):

```bash theme={null}
crewship integration composio inventory
```

returns the same data as `GET /api/v1/integrations/composio/inventory`. This is an operator/admin view — agents are never handed the full list.

### Connecting an account & binding an agent

The end-to-end flow from a fresh project key to an agent that can drive an app:

```bash theme={null}
# 1. Set the project API key (per-workspace, validated + stored encrypted):
crewship integration composio key set --key ak_… [--label "My project"]

# 2. Browse the app catalog:
crewship integration composio toolkits --search gmail

# 3. Connect an account — open the printed redirect_url to authorize:
crewship integration composio connect gmail --user user-42

# 4. Verify the connected account (and its user_id) landed:
crewship integration composio inventory

# 5. Bind the connected user to an agent with per-app tool scope:
crewship integration composio bind <agent> --user user-42 \
  --app gmail:read --app github:full

# 6. Inspect / remove the agent's bindings:
crewship integration composio bindings <agent>
crewship integration composio unbind <agent> [--app gmail]
```

**Account lifecycle.** Refresh, revoke, or permanently remove a connected
account at the provider:

```bash theme={null}
crewship integration composio account {refresh,revoke,remove} <account-id>
```

### Default connector (`COMPOSIO_DEFAULT_CONNECTOR`)

By default an agent only reaches Composio tools an operator explicitly **bound**
to it (`crewship integration composio bind`). The server flag
`COMPOSIO_DEFAULT_CONNECTOR` flips this to a **default-on** model so agents never
lack a tool they should obviously have (e.g. calendar):

* **ON** — every agent **without** an explicit per-agent Composio binding
  automatically gets a workspace-wide **default connector**: a Composio MCP
  server with **full access to all the workspace's connected apps**, scoped to
  the workspace's default Composio user. No manual bind needed.
* A **per-agent binding always overrides** the default for that agent — the
  bound (tool-scoped) server resolves and the default is **not** added, so you
  can still restrict specific agents.
* **Legacy (non-Composio) MCP servers are turned OFF** at resolve time while the
  flag is on (they are **not deleted** — flip the flag back off to restore
  them). This makes Composio the single managed connector surface.
* **OFF** (default) — today's behaviour, unchanged: agents get only what's
  explicitly bound.

The flag is a behaviour switch layered on an already-configured Composio — it
**never** auto-enables the provider (you still need a project API key). It is
`false` unless `COMPOSIO_DEFAULT_CONNECTOR=true` (or `1`) is set on the server.

**Provisioning the default.** The default connector needs a Composio
**`user_id`** (whose connected accounts back it) and a provisioned MCP server.
Both are set with one operator call:

```bash theme={null}
# Auto-derive the user when exactly one Composio user has connected accounts:
crewship integration composio default enable

# Or pin a specific user explicitly:
crewship integration composio default set <user_id>

# Inspect the current state (flag, default user/server, connected-user count):
crewship integration composio default show
```

`enable` errors if **zero** users have connected accounts ("connect an account
first") or if **multiple** users exist (pin one with `default set`). Re-running
is idempotent and refreshes the connector's app set, so apps you connect later
show up in the default automatically. These map to
`GET`/`PUT /api/v1/integrations/composio/default`.

### Agent awareness of connected integrations

An agent is told **up front**, in its system prompt, which integrations it can
already drive. Every MCP server that resolves for the agent — Composio apps as
well as plain MCP servers — is listed in a `[CONNECTED INTEGRATIONS]` block,
including the access mode encoded in the display name (e.g.
`Composio: youtube · Full`).

This exists so an agent never reflexively answers *"I don't have access to your
YouTube account"* when the YouTube tools are in fact wired in. The block
instructs the agent to use the matching tools directly and to only report that
something isn't possible **after** checking the tools available for that app —
so the user never has to tell it to "go look at the MCP server" first.

Nothing to configure: the block appears automatically whenever the agent
resolves at least one integration, and is omitted entirely when it has none.

## OAuth 2.0 Integrations

Crewship includes pre-configured OAuth providers for popular services. The implementation uses PKCE (Proof Key for Code Exchange) per RFC 7636 for secure authorization.

### Supported OAuth Providers

| Provider       | Auth URL                                  | Default Scopes            |
| -------------- | ----------------------------------------- | ------------------------- |
| **Google**     | `accounts.google.com/o/oauth2/v2/auth`    | Gmail, Calendar, Drive    |
| **Slack**      | `slack.com/oauth/v2/authorize`            | channels:read, chat:write |
| **GitHub**     | `github.com/login/oauth/authorize`        | repo, user                |
| **Microsoft**  | `login.microsoftonline.com/.../authorize` | Mail, Calendars           |
| **Linear**     | `linear.app/oauth/authorize`              | read, write               |
| **GitLab**     | `gitlab.com/oauth/authorize`              | api, read\_user           |
| **Cloudflare** | `dash.cloudflare.com/oauth2/authorize`    | (custom)                  |
| **Stripe**     | `connect.stripe.com/oauth/authorize`      | read\_write               |
| **Notion**     | `api.notion.com/v1/oauth/authorize`       | (custom)                  |

### OAuth Flow

<Steps>
  <Step title="Create OAuth credential">
    In Settings -> Credentials, create an OAuth2 credential with the client ID, client secret, and selected provider.
  </Step>

  <Step title="Authorize the connection">
    Click "Connect" to start the PKCE authorization flow:

    1. Crewship generates a `code_verifier` (32 random bytes, base64url-encoded)
    2. Computes `code_challenge` = SHA256(code\_verifier), base64url-encoded
    3. Redirects user to provider's authorization URL
  </Step>

  <Step title="Token exchange">
    After the user authorizes, the provider redirects back with an authorization code. Crewship exchanges it for access and refresh tokens using the code\_verifier.
  </Step>

  <Step title="Token storage">
    Tokens are encrypted with AES-256-GCM and stored in the credentials table. Refresh tokens are used automatically to maintain access.
  </Step>
</Steps>

### Auto-Bind

When OAuth credentials are created, the `oauth_autobind` system can automatically configure MCP servers or other integrations that use the credential. This eliminates manual setup for common provider-integration pairs.

## MCP Server Integration

Crewship integrates with the [Model Context Protocol](https://modelcontextprotocol.io/) ecosystem, allowing agents to use tools from external MCP servers.

### MCP Architecture

```
Agent (Claude Code)
    |
    | Reads .mcp.json config
    v
Sidecar MCP Gateway (internal/sidecar/mcp_gateway.go)
    |
    | Connects to MCP servers
    v
MCP Server (stdio or HTTP transport)
    |
    v
External Service (GitHub, Slack, etc.)
```

### Transport Types

| Transport         | Description                 | Use Case                    |
| ----------------- | --------------------------- | --------------------------- |
| `stdio`           | Server runs as a subprocess | Local tools, custom scripts |
| `streamable-http` | HTTP-based communication    | Remote/cloud MCP servers    |
| `sse`             | Server-Sent Events          | Legacy MCP servers          |

### MCP Server Configuration

MCP servers are configured per-crew or per-agent via the `.mcp.json` file:

```json theme={null}
{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_TOKEN": "${GH_TOKEN}"
      }
    }
  }
}
```

The sidecar merges crew-level and agent-level MCP configurations at runtime. The merged config is written to `/crew/agents/{slug}/.mcp.json` inside the container.

### MCP Gateway

The `MCPGateway` (`internal/sidecar/mcp_gateway.go`) manages MCP server connections:

1. **Connect:** Establishes connections to all configured MCP servers at sidecar startup (15-second timeout)
2. **Discover tools:** Queries each server for available tools
3. **Route calls:** Proxies tool calls from agents to the correct MCP server

### Sidecar MCP Endpoints

| Endpoint      | Method | Description                                         |
| ------------- | ------ | --------------------------------------------------- |
| `/mcp/tools`  | GET    | List all available tools from connected MCP servers |
| `/mcp/call`   | POST   | Call a specific tool on an MCP server               |
| `/mcp/status` | GET    | Check connection status of all MCP servers          |

### MCP Credential Injection

MCP servers can have credentials associated with them:

```go theme={null}
type MCPCredInput struct {
    Token  string `json:"token"`   // Decrypted credential value
    Type   string `json:"type"`    // "bearer", "api_key", "basic"
    Header string `json:"header"`  // Custom header name (for api_key type)
}
```

The sidecar handles credential injection for MCP server authentication, keeping raw tokens out of the agent's environment.

## MCP Registry

Crewship syncs with the official MCP registry at `registry.modelcontextprotocol.io/v0/servers`. The `SyncMCPRegistry` function (`internal/api/mcp_registry.go`) fetches and caches all registered servers locally. This allows users to browse and install MCP servers from the registry without manual configuration.

<Accordion title="What registry entries include">
  * Server name and display name
  * Description and category
  * Package information (runtime, environment variables)
  * Remote transport configuration
  * Verification status
</Accordion>

## Crew Connections

Crews can be connected to share context and enable cross-crew operations:

### Connection Endpoints (via Sidecar)

| Endpoint                     | Method | Description                      |
| ---------------------------- | ------ | -------------------------------- |
| `/crew-connections`          | GET    | List crew connections            |
| `/crew-connections`          | POST   | Create a crew connection         |
| `/connections`               | GET    | List active connections          |
| `/connections/{id}/message`  | POST   | Send a message to connected crew |
| `/connections/{id}/messages` | GET    | Read messages from connection    |
| `/connections/{id}/files`    | GET    | Read shared files                |
| `/connections/{id}/files`    | POST   | Write shared files               |

## Integration Testing

The `integration_test_connection.go` handler provides a test endpoint for verifying that integrations are properly configured and credentials are working before deploying to production.

<Tip>
  When configuring OAuth integrations, always test the connection after setup. OAuth tokens can expire, scopes can be insufficient, and client secrets can be rotated.
</Tip>
