CognitiveX Docs

MCP connectors

The /api/connectors/mcp surface for attaching external MCP servers to iCog, plus the public /api/providers LLM catalog.

iCog can act as an MCP client: you attach an external MCP server by URL, iCog contacts it to discover its tools, and those tools become available to the chat tool loop. This page is the contract reference for that surface, mounted at /api/connectors/mcp under https://api.cognitivx.io. For a task-oriented walkthrough, see External MCP connectors.

Every connector endpoint authenticates with a key created at developers.cognitivx.io/keys, passed as either Authorization: Bearer <key> or X-API-Key: <key>. The one exception is GET /api/connectors/mcp/oauth/callback, which the OAuth provider's browser redirect hits directly and which validates a CSRF state token instead of a key.

This page covers the iCog-as-MCP-client surface only. The first-party OAuth connectors (Gmail, Google Drive, GitHub) live under a separate /api/connectors prefix and are not documented here.

Endpoints

MethodPathPurpose
GET/api/connectors/mcp/catalogList the curated directory of suggested servers.
GET/api/connectors/mcpList your attached connectors with their tools.
POST/api/connectors/mcpAttach a server and (for non-OAuth) discover its tools.
POST/api/connectors/mcp/{connector_id}/oauth/startBegin the OAuth handshake; returns the URL to open.
GET/api/connectors/mcp/oauth/callbackProvider redirect target. Not called directly.
POST/api/connectors/mcp/{connector_id}/testRe-contact the server and refresh its tool list.
PATCH/api/connectors/mcp/{connector_id}/tools/{tool_name}Enable/disable a tool or change its trust tier.
DELETE/api/connectors/mcp/{connector_id}Remove a connector and its tools.
GET/api/providersPublic, read-only LLM provider catalog.

Error responses are { "detail": "<message>" } with a 4xx/5xx status.

Lifecycle

Create a connector with a server URL and an auth type. For none and bearer connectors iCog contacts the server immediately and discovers its tools. For oauth2 connectors the connector is saved as pending and you start the OAuth flow next.

Authorize (OAuth only). Call POST /{id}/oauth/start, open the returned authorization_url, and let the provider redirect back. iCog exchanges the code, then discovers tools.

Tune which tools are enabled and their trust tier with PATCH /{id}/tools/{tool_name}.

Use the tools. The chat tool loop loads every connected connector's enabled tools automatically for that user. There is no per-request opt-in.

Connector status

A connector's status reflects the last discovery or OAuth attempt:

StatusMeaning
pendingCreated, awaiting OAuth authorization or first discovery.
connectedReachable; tools discovered. Its enabled tools are live in chat.
errorLast contact failed. status_detail carries the reason.

Credentials are never returned by any endpoint. Responses carry a has_credentials boolean only. Each tool has a trust_tier of auto (runs without asking) or confirm (asks first); read-ish tool names default to auto at discovery time.


List the catalog

Return the curated directory of suggested MCP servers shown in the add dialog.

GET /api/connectors/mcp/catalog Auth: Authorization: Bearer <key> or X-API-Key: <key>

The catalog is a static, hardcoded list of seed cards. Adding one just prefills the same create flow a custom URL uses. It does not create anything.

curl https://api.cognitivx.io/api/connectors/mcp/catalog \
  -H "Authorization: Bearer $ICOG_API_KEY"
{
  "items": [
    {
      "key": "deepwiki",
      "name": "DeepWiki",
      "description": "Ask questions about any public GitHub repository's docs.",
      "server_url": "https://mcp.deepwiki.com/mcp",
      "transport": "streamable_http",
      "auth_type": "none",
      "icon": "book-open"
    },
    {
      "key": "context7",
      "name": "Context7",
      "description": "Up-to-date code docs and examples for popular libraries.",
      "server_url": "https://mcp.context7.com/mcp",
      "transport": "streamable_http",
      "auth_type": "bearer",
      "icon": "library"
    },
    {
      "key": "custom",
      "name": "Custom server",
      "description": "Connect any MCP server by URL.",
      "server_url": "",
      "transport": "streamable_http",
      "auth_type": "none",
      "icon": "plug"
    }
  ]
}

Errors: 422 on a malformed request only. The endpoint takes no parameters.


List your connectors

Return all of your attached connectors, each with its discovered tools embedded.

GET /api/connectors/mcp Auth: Authorization: Bearer <key> or X-API-Key: <key>

curl https://api.cognitivx.io/api/connectors/mcp \
  -H "Authorization: Bearer $ICOG_API_KEY"
{
  "connectors": [
    {
      "id": "8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f",
      "slug": "deepwiki",
      "display_name": "DeepWiki",
      "server_url": "https://mcp.deepwiki.com/mcp",
      "transport": "streamable_http",
      "auth_type": "none",
      "status": "connected",
      "status_detail": null,
      "has_credentials": false,
      "last_connected_at": "2026-06-16T18:04:11.220190+00:00",
      "created_at": "2026-06-16T18:04:10.880431+00:00",
      "tools": [
        {
          "tool_name": "ask_question",
          "description": "Ask a question about a GitHub repository's docs.",
          "input_schema": {
            "type": "object",
            "properties": {
              "repo": { "type": "string" },
              "question": { "type": "string" }
            },
            "required": ["repo", "question"]
          },
          "enabled": true,
          "trust_tier": "confirm"
        }
      ]
    }
  ]
}

Errors: 422 on a malformed request only.


Create a connector

Attach an external MCP server. For none and bearer connectors iCog contacts the server immediately and discovers tools; for oauth2 it saves the connector as pending and you start OAuth next.

POST /api/connectors/mcp Auth: Authorization: Bearer <key> or X-API-Key: <key> Returns 201 Created.

FieldTypeRequiredDescription
display_namestringyesHuman label, 1 to 80 chars. Also seeds the connector slug.
server_urlstringyesThe MCP server endpoint, 1 to 2000 chars.
transportstringnoMCP transport. Defaults to streamable_http. Must be a valid transport.
auth_typestringnonone, bearer, or oauth2. Defaults to none.
access_tokenstringnoBearer token. Required when auth_type is bearer.

When auth_type is bearer you must include access_token, or the request fails with 400. When auth_type is oauth2 you leave access_token out and start the OAuth flow afterward.

curl -X POST https://api.cognitivx.io/api/connectors/mcp \
  -H "Authorization: Bearer $ICOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "DeepWiki",
    "server_url": "https://mcp.deepwiki.com/mcp",
    "transport": "streamable_http",
    "auth_type": "none"
  }'

The @cognitivx/sdk namespaces do not include a connectors helper, so call the endpoint with the configured client.

import { configureApiClient, apiClient } from '@cognitivx/sdk';

configureApiClient({ apiKey: process.env.ICOG_API_KEY! });

const { data } = await apiClient.POST('/api/connectors/mcp', {
  body: {
    display_name: 'DeepWiki',
    server_url: 'https://mcp.deepwiki.com/mcp',
    transport: 'streamable_http',
    auth_type: 'none',
  },
});

For a none or bearer connector, the response includes the discovery result:

{
  "connector": {
    "id": "8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f",
    "slug": "deepwiki",
    "display_name": "DeepWiki",
    "server_url": "https://mcp.deepwiki.com/mcp",
    "transport": "streamable_http",
    "auth_type": "none",
    "status": "connected",
    "status_detail": null,
    "has_credentials": false,
    "last_connected_at": "2026-06-16T18:04:11.220190+00:00",
    "created_at": "2026-06-16T18:04:10.880431+00:00",
    "tools": [
      {
        "tool_name": "ask_question",
        "description": "Ask a question about a GitHub repository's docs.",
        "input_schema": { "type": "object", "properties": {} },
        "enabled": true,
        "trust_tier": "confirm"
      }
    ]
  },
  "discovery": {
    "tool_count": 1,
    "tools": ["ask_question"]
  },
  "error": null
}

Discovery failure is not a 4xx. If the server is unreachable or rejects the token, the connector is still saved (so you can fix it and retry with POST /{id}/test) and you still get 201, with status set to error, discovery empty, and the reason in error.

{
  "connector": {
    "id": "8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f",
    "slug": "deepwiki",
    "display_name": "DeepWiki",
    "server_url": "https://mcp.deepwiki.com/mcp",
    "transport": "streamable_http",
    "auth_type": "none",
    "status": "error",
    "status_detail": "connection refused",
    "has_credentials": false,
    "last_connected_at": null,
    "created_at": "2026-06-16T18:04:10.880431+00:00",
    "tools": []
  },
  "discovery": {},
  "error": "connection refused"
}

For an oauth2 connector, no discovery runs yet. The response adds an oauth_required: true flag (absent from the none/bearer shapes):

{
  "connector": {
    "id": "8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f",
    "slug": "linear",
    "display_name": "Linear",
    "server_url": "https://mcp.linear.app/mcp",
    "transport": "streamable_http",
    "auth_type": "oauth2",
    "status": "pending",
    "status_detail": "Authorization required",
    "has_credentials": false,
    "last_connected_at": null,
    "created_at": "2026-06-16T18:04:10.880431+00:00",
    "tools": []
  },
  "discovery": {},
  "error": null,
  "oauth_required": true
}

Errors

StatusWhen
400transport is not a valid transport, auth_type is not none/bearer/oauth2, or auth_type is bearer with no access_token.
422Missing display_name or server_url, or a field violates its length bounds.

Authorize an OAuth connector

Begin the OAuth 2.0 (Authorization Code + PKCE) handshake and get the URL to open. iCog is the OAuth client.

POST /api/connectors/mcp/{connector_id}/oauth/start Auth: Authorization: Bearer <key> or X-API-Key: <key>

FieldTypeRequiredDescription
connector_idstring (path)yesThe connector to authorize. Must be an oauth2 connector you own.

iCog discovers the server's OAuth endpoints, registers a client via Dynamic Client Registration if needed, generates PKCE plus a state token, and returns the authorization URL. Open it in a browser or popup. The redirect URI is fixed to {backend}/api/connectors/mcp/oauth/callback.

curl -X POST \
  https://api.cognitivx.io/api/connectors/mcp/8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f/oauth/start \
  -H "Authorization: Bearer $ICOG_API_KEY"
{
  "authorization_url": "https://mcp.linear.app/oauth/authorize?response_type=code&client_id=icog-...&redirect_uri=https%3A%2F%2Fapi.cognitivx.io%2Fapi%2Fconnectors%2Fmcp%2Foauth%2Fcallback&code_challenge=...&state=..."
}

After the user consents, the provider redirects to the callback below. You do not call the callback yourself.

Errors

StatusWhen
404No connector with that id belongs to you.
400The server has no dynamic registration endpoint and no pre-registered client_id, or another OAuth discovery error. The connector is marked error.

OAuth callback

The provider's browser redirect target. It validates state, exchanges the code for tokens, discovers tools, and 302-redirects the browser back to the frontend connectors page. API consumers do not call this endpoint.

GET /api/connectors/mcp/oauth/callback Auth: none by necessity (the provider redirect carries no iCog key). The state token is the CSRF defense and also locates the connector; it is compared in constant time.

FieldTypeRequiredDescription
codestring (query)noAuthorization code from the provider.
statestring (query)noThe CSRF token issued at oauth/start.
errorstring (query)noSet by the provider if the user denied or the flow failed.
error_descriptionstring (query)noHuman-readable provider error detail.

This endpoint never returns a JSON error to the caller. Every path (success, provider denial, missing or expired state, token exchange failure) 302-redirects the browser:

302  {FRONTEND_URL}/connectors?section=mcp&oauth=success
302  {FRONTEND_URL}/connectors?section=mcp&oauth=error&oauth_error=<reason>

Test (re-discover) a connector

Re-contact the MCP server and refresh its tool list.

POST /api/connectors/mcp/{connector_id}/test Auth: Authorization: Bearer <key> or X-API-Key: <key>

FieldTypeRequiredDescription
connector_idstring (path)yesThe connector to re-discover.

Use this after fixing a URL or token, or to pick up tools the server added. New tools land enabled with a heuristic trust tier; tools that vanished are removed; your enabled/trust choices on surviving tools are preserved.

curl -X POST \
  https://api.cognitivx.io/api/connectors/mcp/8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f/test \
  -H "Authorization: Bearer $ICOG_API_KEY"
{
  "ok": true,
  "tool_count": 2,
  "tools": ["ask_question", "read_wiki_structure"]
}

Errors

StatusWhen
404No connector with that id belongs to you.
502The MCP server could not be reached. The message carries the server's error.

Toggle a tool

Enable or disable a discovered tool and/or change its trust tier. Send only the fields you want to change.

PATCH /api/connectors/mcp/{connector_id}/tools/{tool_name} Auth: Authorization: Bearer <key> or X-API-Key: <key>

FieldTypeRequiredDescription
connector_idstring (path)yesThe owning connector.
tool_namestring (path)yesThe discovered tool to update.
enabledbooleannoWhether the chat tool loop may offer this tool. Omit to leave unchanged.
trust_tierstringnoauto (run without asking) or confirm (ask first). Omit to leave unchanged.

Both body fields are optional, but trust_tier, if present, must be auto or confirm.

curl -X PATCH \
  https://api.cognitivx.io/api/connectors/mcp/8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f/tools/ask_question \
  -H "Authorization: Bearer $ICOG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true, "trust_tier": "auto" }'
{ "ok": true }

Errors

StatusWhen
400trust_tier is present but not auto or confirm.
404The connector or tool was not found for your account.

Remove a connector

Delete a connector and all its discovered tools. Ownership is checked.

DELETE /api/connectors/mcp/{connector_id} Auth: Authorization: Bearer <key> or X-API-Key: <key>

FieldTypeRequiredDescription
connector_idstring (path)yesThe connector to delete.
curl -X DELETE \
  https://api.cognitivx.io/api/connectors/mcp/8f3c2b1a-0d44-4e9a-9c2e-1a2b3c4d5e6f \
  -H "Authorization: Bearer $ICOG_API_KEY"
{ "ok": true }

Errors

StatusWhen
404No connector with that id belongs to you.

LLM providers

List the static catalog of LLM providers and model ids iCog can route to. This is a separate, fully public, read-only endpoint.

GET /api/providers Auth: none (public).

curl https://api.cognitivx.io/api/providers
{
  "providers": [
    {
      "id": "claude",
      "name": "Anthropic Claude",
      "models": [
        { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6" },
        { "id": "claude-haiku-4-5", "name": "Claude Haiku 4.5" }
      ]
    },
    {
      "id": "gemini",
      "name": "Google Gemini",
      "models": [
        { "id": "gemini-2.5-flash", "name": "Gemini 2.5 Flash" },
        { "id": "gemini-2.5-pro", "name": "Gemini 2.5 Pro" }
      ]
    },
    {
      "id": "vertex",
      "name": "Vertex Model Garden",
      "models": [
        { "id": "claude-sonnet-4-6", "name": "Claude Sonnet 4.6 (Vertex)" },
        { "id": "gemini-2.5-flash", "name": "Gemini 2.5 Flash (Vertex)" }
      ]
    }
  ]
}

This catalog is static. It returns 200 with the list above and takes no parameters.