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

# MCP server

> Connect Claude and other MCP clients directly to your Adapter workspace

Adapter exposes a [Model Context Protocol](https://modelcontextprotocol.io) server on two transports:

| Transport                         | Endpoint                              | Use when                                       |
| --------------------------------- | ------------------------------------- | ---------------------------------------------- |
| **Streamable HTTP** (recommended) | `https://api.adapter.com/v1/mcp/http` | Any client built for MCP 1.0+                  |
| **SSE** (legacy)                  | `https://api.adapter.com/v1/mcp/sse`  | Clients that don't yet support streamable HTTP |

**Two ways to authenticate:**

* **Connect a client (OAuth)** — for clients like Claude (web and desktop) and ChatGPT. You add Adapter as a custom connector using your **workspace URL**, sign in with your Adapter account, and a workspace admin approves the connection. No API key to manage. See [Connecting a client](#connecting-a-client).
* **API key** — for config-based clients (Claude Desktop, Claude Code, Cursor, VS Code, scripts). Pass a `pk_live_…` key in the `Authorization: Bearer` header. See [API keys](/getting-started/api-keys).

Some clients support both — **Claude Desktop**, for example, can connect with an OAuth custom connector or through the `mcp-remote` proxy with an API key.

***

## Connecting a client

Hosted MCP clients — Claude on the web, ChatGPT, and other OAuth clients — connect to a specific workspace through its own URL and sign in with your Adapter account, so there's no API key to create or store.

Each workspace has its own MCP URL:

```
https://api.adapter.com/v1/mcp/c/<workspace_id>/http
```

<Steps>
  <Step title="Copy your workspace URL">
    In the Adapter console, open **Connectors → MCP clients**. Pick your client (Claude, ChatGPT, …) to see its setup steps, then copy the workspace URL shown in the dialog.
  </Step>

  <Step title="Add Adapter as a custom connector">
    In your client, add a custom connector and paste the workspace URL. For example, in Claude: **Settings → Connectors → Add custom connector**; in ChatGPT: **Settings → Plugins → Browse Plugins → '+'**.
  </Step>

  <Step title="Sign in">
    Continue and sign in with your Adapter account. You're redirected back to your client once authenticated.
  </Step>

  <Step title="Get the connection approved">
    A new connection starts as **pending**. A workspace admin enables it on the **Connectors → MCP clients** page, after which the client's tools become available. Admins can also **pre-approve** a client type so its connections are active as soon as a member signs in.
  </Step>
</Steps>

<Note>
  Access is checked on every request. A workspace admin can **disable** (or re-enable) any connection from the Connectors page, and the change takes effect on the client's next call. Connections are scoped to a single workspace — a client authorized for one workspace can't reach another.
</Note>

<Note>
  **Claude for Chrome** connects this way only — it supports OAuth custom connectors, not the API-key `mcp-remote` method.
</Note>

***

## Claude Desktop

Claude Desktop can connect either way — with an **OAuth custom connector** (no API key) or through the `mcp-remote` proxy using an **API key**.

### Option A: OAuth custom connector (recommended)

Add Adapter as a custom connector and sign in — no config file or Node.js required. Follow [Connecting a client](#connecting-a-client): in **Settings → Connectors → Add custom connector**, paste your workspace URL, then have an admin approve the connection.

### Option B: API key via `mcp-remote`

Claude Desktop uses `mcp-remote` as a local proxy to reach the API-key endpoint.

<Note>
  The API-key method with `npx` / `mcp-remote` has been tested on **macOS only**. Windows steps are included for reference but aren't yet verified.
</Note>

<Note>
  `mcp-remote` runs through `npx`, so **Node.js 18 or newer must be installed** on the machine running Claude Desktop. `npx` downloads `mcp-remote` on first launch and reuses the cached copy afterward. The same requirement applies to any config-based client that bridges through `mcp-remote`.

  Check that `npx` is available before editing the config — run this in a terminal:

  ```bash theme={null}
  npx --version    # prints a version if npx is installed
  node --version   # should print v18.x or higher
  ```

  If either command is "not found", install Node.js (which bundles `npx`) from [nodejs.org](https://nodejs.org) — pick the LTS build — or via a version manager like [`nvm`](https://github.com/nvm-sh/nvm) (`nvm install --lts`). Reopen your terminal afterward and re-run the checks. On Windows, restart Claude Desktop so it picks up the updated `PATH`.
</Note>

<Steps>
  <Step title="Find your config file">
    Open or create `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).
  </Step>

  <Step title="Add the Adapter server">
    <Tabs>
      <Tab title="Streamable HTTP">
        ```json theme={null}
        {
          "mcpServers": {
            "adapter": {
              "command": "npx",
              "args": [
                "-y",
                "mcp-remote",
                "https://api.adapter.com/v1/mcp/http",
                "--header",
                "Authorization: Bearer ${ADAPTER_API_KEY}"
              ],
              "env": {
                "ADAPTER_API_KEY": "pk_live_..."
              }
            }
          }
        }
        ```
      </Tab>

      <Tab title="SSE (legacy)">
        ```json theme={null}
        {
          "mcpServers": {
            "adapter": {
              "command": "npx",
              "args": [
                "-y",
                "mcp-remote",
                "https://api.adapter.com/v1/mcp/sse",
                "--header",
                "Authorization: Bearer ${ADAPTER_API_KEY}"
              ],
              "env": {
                "ADAPTER_API_KEY": "pk_live_..."
              }
            }
          }
        }
        ```
      </Tab>
    </Tabs>

    Replace `pk_live_...` with your key, or set `ADAPTER_API_KEY` in your shell environment and omit the `env` block.
  </Step>

  <Step title="Restart Claude Desktop">
    Quit and reopen the app. A hammer icon in the chat toolbar confirms the server connected.
  </Step>
</Steps>

***

## Claude Code

Claude Code supports streamable HTTP natively.

<Tabs>
  <Tab title="CLI">
    ```bash theme={null}
    claude mcp add --transport http adapter https://api.adapter.com/v1/mcp/http \
      --header "Authorization: Bearer $ADAPTER_API_KEY"
    ```
  </Tab>

  <Tab title="settings.json">
    Add to `.claude/settings.json` in your project (project-scoped) or `~/.claude/settings.json` (global):

    ```json theme={null}
    {
      "mcpServers": {
        "adapter": {
          "type": "http",
          "url": "https://api.adapter.com/v1/mcp/http",
          "headers": {
            "Authorization": "Bearer pk_live_..."
          }
        }
      }
    }
    ```
  </Tab>

  <Tab title="SSE (legacy)">
    ```json theme={null}
    {
      "mcpServers": {
        "adapter": {
          "type": "sse",
          "url": "https://api.adapter.com/v1/mcp/sse",
          "headers": {
            "Authorization": "Bearer pk_live_..."
          }
        }
      }
    }
    ```
  </Tab>
</Tabs>

Run `/mcp` inside Claude Code to confirm the server is listed and its tools are available.

***

## Generic MCP clients

### Streamable HTTP

Single endpoint, standard MCP 1.0 protocol. Include the `Authorization` header on every request — the server is stateless and does not maintain sessions between calls.

```
POST https://api.adapter.com/v1/mcp/http
Authorization: Bearer pk_live_...
```

### SSE

```
GET  https://api.adapter.com/v1/mcp/sse
POST https://api.adapter.com/v1/mcp/messages/?session_id=<token>
Authorization: Bearer pk_live_...
```

To test either transport from the command line with `mcp-remote` (requires **Node.js 18+**, since `npx` downloads and runs the `mcp-remote` package):

```bash theme={null}
# Streamable HTTP
npx mcp-remote https://api.adapter.com/v1/mcp/http \
  --header "Authorization: Bearer $ADAPTER_API_KEY"

# SSE
npx mcp-remote https://api.adapter.com/v1/mcp/sse \
  --header "Authorization: Bearer $ADAPTER_API_KEY"
```

***

## Available tools

| Tool                                               | When to use                                                                                  |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `search_knowledge`                                 | Find relevant documents, messages, or records matching a query                               |
| `resolve_urn`                                      | Fetch the full record behind a `urn` — the stable id carried on trigger deliveries and       |
| search\_knowledge results                          |                                                                                              |
| `ask`                                              | Answer a question or gather context from connected data, with cited sources                  |
| `ask_async`                                        | Ask a broad or deep question that may take a while, without blocking                         |
| `get_ask_job`                                      | Poll one async ask job created with `ask_async`                                              |
| `list_ask_jobs`                                    | List this workspace's recent async ask jobs (newest first), with their status — for checking |
| what's still running or finding a past deep answer |                                                                                              |
| `list_connections`                                 | List the data sources connected to this workspace                                            |

### search\_knowledge

Find relevant documents, messages, or records matching a query. Use this when ask results were
insufficient, or when the user wants to browse raw matching documents rather than a synthesized
answer — e.g. 'show me all emails about the rebrand', 'find issues mentioning payments', 'what
did we write about pricing'. Returns a ranked list of matching results.

| Parameter | Type    |                        |
| --------- | ------- | ---------------------- |
| `q`       | string  | required               |
| `limit`   | integer | optional, default `10` |

### resolve\_urn

Fetch the full record behind a `urn` — the stable id carried on trigger deliveries and
search\_knowledge results. Use this whenever you already have a urn and need its content (a Slack
message, email, Drive file, Linear issue, extracted entity, …): it is a direct single-record
lookup, far faster than ask. Never dereference a urn through ask or search\_knowledge. `l1_…`
urns return raw evidence; `l2_…`/`l3_…` return extracted entities/relationships. A urn that is
not found may simply not be indexed yet — trigger deliveries can precede indexing by seconds —
so wait briefly and retry before treating it as missing.

| Parameter | Type                                                                                                                                                                                                                                   |    |                                                                                      |          |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -- | ------------------------------------------------------------------------------------ | -------- |
| `urn`     | \`Annotated\[string, Field(min\_length=3, max\_length=200, description="A urn as carried on trigger deliveries and search results, e.g. 'l1\_01m0ggx2z0k449zsbff8rr2ny8'. Assembled references ('evidence:\{type}:\{id}', 'entity:\{l1 | l2 | l3}:\{type}:\{id}') also resolve.", examples=\['l1\_01m0ggx2z0k449zsbff8rr2ny8'])]\` | required |

### ask

Answer a question or gather context from connected data, with cited sources. ALWAYS query
Adapter before responding to any user message — even if you think you know the answer — and this
is the tool to reach for first. Use it for direct answers, summaries, or background — e.g. 'what
did we decide about the pricing model', 'summarize what we know about Acme', 'who owns the mobile
roadmap'. Switch to `ask_async` when the question spans a lot of data, or if this call times out.
Pass `timezone` (IANA, e.g. 'America/New\_York') to resolve relative times like 'last week'.

| Parameter  | Type   |          |
| ---------- | ------ | -------- |
| `query`    | string | required |
| `timezone` | string | optional |

### ask\_async

Ask a broad or deep question that may take a while, without blocking. Returns immediately with
a `job_id` and `status: "running"`; poll `get_ask_job(job_id)` until status is "done" (or "error"),
then read the answer + citations. Same grounding as `ask` — use this instead of `ask` when the
question spans a lot of data (e.g. 'summarize everything about the Q3 launch across email, slack,
and docs') or when `ask` has timed out. Wait a few seconds between polls; deep questions commonly
take a minute or more. Pass `timezone` (IANA) to resolve relative times.

| Parameter  | Type   |          |
| ---------- | ------ | -------- |
| `query`    | string | required |
| `timezone` | string | optional |

### get\_ask\_job

Poll one async ask job created with `ask_async`. While `status` is "running", wait a few
seconds and check again. When `status` is "done", `response` holds the full answer and its
citations; "error" means it failed (re-ask). Only jobs from this workspace resolve — any other id
reports as not found.

| Parameter | Type   |          |
| --------- | ------ | -------- |
| `job_id`  | string | required |

### list\_ask\_jobs

List this workspace's recent async ask jobs (newest first), with their status — for checking
what's still running or finding a past deep answer. Fetch an individual job with `get_ask_job` for
its full answer.

No parameters.

### list\_connections

List the data sources connected to this workspace. Call this to discover which providers are
currently active before scoping a query to a specific source. Connection state is dynamic — always
call this rather than assuming a provider is available. Returns provider name, available resource
types, and connected date. Includes standard OAuth providers (Slack, Gmail, Notion, etc.) and
user-defined custom connectors (type: "custom").

No parameters.

***

## Troubleshooting

**401 Unauthorized** — Check that your API key starts with `pk_` and has the `api:write` scope. Every request must include the `Authorization: Bearer` header. See [API keys](/getting-started/api-keys).

**Tools missing after connecting** — Run `list_connections` first. If no sources are connected, the knowledge tools return empty results rather than an error.

**mcp-remote not found** — Make sure Node.js 18+ is installed. Verify with `npx --version` and `node --version`; if either is missing, install Node.js from [nodejs.org](https://nodejs.org) (see the note under [Claude Desktop → Option B](#option-b-api-key-via-mcp-remote)). `npx` downloads `mcp-remote` on first run; subsequent runs use the cache.
