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

# Connect an MCP client

> Connect a custom MCP client to Consile over Streamable HTTP: directly, from Claude Code, through an SDK, or via mcp-remote. Includes the protocol notes a client implementer needs.

Any MCP-compatible client can connect to Consile. The client needs to speak
Streamable HTTP and support MCP authorization: RFC 9728 discovery, Dynamic Client
Registration and OAuth with PKCE (see [Authentication](/developers/authentication)).

<Info>
  If you use Claude, ChatGPT or Microsoft 365 Copilot, use the customer guides instead:
  [Connect Claude](/connect/forbind-claude),
  [Connect ChatGPT](/connect/forbind-chatgpt) or
  [Microsoft 365 Copilot](/connect/forbind-microsoft-copilot) (a pilot, e-conomic
  only). This page is for your own clients.
</Info>

## Option 1: an MCP-aware client

Clients that already speak MCP (e.g. desktop AI apps with custom connectors) only
need a connector's URL from the portal. Each connector is its own endpoint, and
`/mcp` is the [Concierge](/developers/concierge). The client discovers the
authorization server itself, takes you through login, and stores your token.

```
https://mcp.consile.ai/gsc/mcp
```

### Claude Code

Add each connector as its own HTTP server. On the connector page in the portal,
**Kopiér Claude Code-kommando** copies the command:

```bash theme={null}
claude mcp add --transport http consile-gsc https://mcp.consile.ai/gsc/mcp
```

Then run `/mcp` in Claude Code to sign in. Use one name per connector, e.g.
`consile-economic` for `https://mcp.consile.ai/economic/mcp`.

## Option 2: mcp-remote (stdio → remote bridge)

Clients that can only run local stdio servers can bridge to Consile with
`mcp-remote`. It opens the browser for OAuth the first time and caches your token.
Add one entry per connector:

```json theme={null}
{
  "mcpServers": {
    "consile-gsc": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.consile.ai/gsc/mcp"]
    },
    "consile-economic": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://mcp.consile.ai/economic/mcp"]
    }
  }
}
```

## Option 3: programmatically via an MCP SDK

Use an official MCP SDK with a Streamable HTTP transport and an OAuth provider.
Once connected, the flow is the standard MCP handshake:

<Steps>
  <Step title="initialize">
    Negotiate protocol version and capabilities. A connector endpoint reports its
    server name as `Consile · <connector name>`. The result can carry `instructions`
    (see [Protocol notes](#protocol-notes)).
  </Step>

  <Step title="tools/list">
    Fetch the tools available to you on this endpoint. On a connector endpoint you get
    that connector's tools when your organization subscribes (otherwise none), plus
    `connect_account` (not on CVR). On e-conomic and Uniconta a read-only access level hides the
    write tools. Calls also require a seat assigned to your user; see
    [Authentication](/developers/authentication#what-decides-access). On `/mcp` you
    always get the seven [Concierge](/developers/concierge) tools.
  </Step>

  <Step title="tools/call">
    Call a tool with its arguments. See the
    [API reference](/developers/tools/gsc).
  </Step>
</Steps>

### Example: raw JSON-RPC

A `tools/call` request over `POST /gsc/mcp` (abbreviated; the
`Authorization: Bearer <token>` header is omitted here). `gsc__top_queries` is a
GSC tool, so it goes to the GSC endpoint, not the aggregate `/mcp`. Tool names on
a connector endpoint are namespaced `<id>__<tool>`:

<CodeGroup>
  ```json Request theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "gsc__top_queries",
      "arguments": {
        "siteUrl": "sc-domain:example.com",
        "startDate": "2026-05-01",
        "endDate": "2026-05-28",
        "limit": 10
      }
    }
  }
  ```

  ```json Result (payload) theme={null}
  {
    "siteUrl": "sc-domain:example.com",
    "startDate": "2026-05-01",
    "endDate": "2026-05-28",
    "queries": [
      { "query": "example keyword", "clicks": 421, "impressions": 9120, "ctr": 0.046, "position": 7.8 }
    ]
  }
  ```
</CodeGroup>

On the wire, the payload arrives inside a standard MCP result. `content` holds one
text block with the payload as JSON, and `structuredContent` holds the same payload as
an object:

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "{\n  \"siteUrl\": \"sc-domain:example.com\", …}" }],
    "structuredContent": { "siteUrl": "sc-domain:example.com", "queries": [ … ] }
  }
}
```

A failed call returns a result with `isError: true` and a text block instead of a
JSON-RPC error; see [Errors & limits](/developers/errors-and-limits).

## The `connect_account` tool

Besides the connector's own tools, `tools/list` on every connector endpoint except
CVR (which needs no connection) includes one extra tool, `connect_account`. The tool
is not namespaced and takes no arguments. It returns
`{ "connect_url": "…", "instructions": "…" }`, a link the user opens in a browser to
connect the provider account for the whole organization. The link expires after
10 minutes. It only works for a connector the organization subscribes to, and it does
not count as usage. On Shopify the tool is listed, but the link fails because Shopify
needs the shop domain first; connect Shopify in the portal instead. On the Concierge
endpoint `/mcp` the same tool takes a required `connector` argument, for example
`"gsc"`; see [Concierge](/developers/concierge).

## Protocol notes

* Headers: send `Content-Type: application/json` and
  `Accept: application/json, text/event-stream` on every POST. Without both Accept
  types the server answers `406`, and with another Content-Type it answers `415`. A
  response may arrive as an SSE stream (`text/event-stream`) whose `data:` line carries
  the JSON-RPC response.
* Stateless: the server does not issue an `Mcp-Session-Id` and sends no
  server-initiated notifications (no `notifications/tools/list_changed`). Call
  `tools/list` again to pick up a new subscription or a changed access level. In chat
  clients that means starting a new conversation.
* Keep-alive: while a tool call is still running on an SSE response stream, the
  server sends an SSE comment line (`: keepalive`) about every 25 seconds. Ignore it.
* `initialize` instructions: on a connector endpoint, the `initialize` result can
  include `instructions` that explain why the signed-in user has no or limited access
  (no subscription, no seat, a read-only access level or a reduced set of tools). Show
  them or pass them to the model.
* Browser clients: requests with an `Origin` header other than
  `https://mcp.consile.ai` are rejected with `403`, and the MCP endpoints send no CORS
  headers. Connect from a server-side process, a desktop app or through `mcp-remote`.
* Limits: request bodies up to 256 KiB (larger bodies get `400`). Requests are rate
  limited per account and connector endpoint. On `429`, wait for the `Retry-After`
  header (1 second) and retry. Current limits are in
  [Errors & limits](/developers/errors-and-limits).

<Note>
  If you call a connector endpoint without a valid token, you get `401` with a
  `WWW-Authenticate` header pointing to the endpoint's metadata document. That's the
  normal starting point for OAuth. See [Authentication](/developers/authentication).
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.