Model Context Protocol (MCP)

Connect Clew to external tools, data sources, and services via the Model Context Protocol — the open standard for AI-tool integration.

MCP support lives in src/services/mcp/. Clew discovers MCP servers from settings.json, CLI flags, and plugin manifests, then merges their tools into the runtime at startup and via /mcp at runtime.

Architecture

 ┌──────────────────────────────────────────────────────────────────────────┐
 │                         MCP — MODEL CONTEXT PROTOCOL                    │
 └──────────────────────────────────────────────────────────────────────────┘

                         ┌──────────────────────────┐
                         │   Settings / CLI Config   │
                         │  src/services/mcp/config  │
                         │   (servers.json schema)   │
                         └────────────┬─────────────┘
                                      │
                                      ▼
                     ┌──────────────────────────┐
                     │   MCPConnectionManager   │
                     │   src/services/mcp/       │
                     │   MCPConnectionManager.tsx │
                     └────────────┬─────────────┘
                                  │
              ┌───────────────────┼───────────────────┐
              ▼                   ▼                   ▼
      ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
      │  Stdio MCP   │   │   SSE MCP    │   │Direct Connect│
      │ (subprocess) │   │  (remote)    │   │ (in-process) │
      │ npx/node/etc │   │  WebSocket   │   │              │
      └──────┬───────┘   └──────┬───────┘   └──────┬───────┘
             │                  │                   │
             └──────────────────┼───────────────────┘
                                │
                                ▼
                     ┌──────────────────────┐
                     │   Client (JSON-RPC)  │
                     │  tools/list          │
                     │  resources/list      │
                     │  prompts/list        │
                     │  tools/call          │
                     │  resources/read      │
                     └──────────┬───────────┘
                                │
                                ▼
                     ┌──────────────────────┐
                     │   assembleToolPool   │
                     │  (MCP tools + built- │
                     │   in tools merged)   │
                     └──────────┬───────────┘
                                │
                                ▼
                     ┌──────────────────────┐
                     │    Query Engine      │
                     │  Model sees all tools│
                     │  Tool calls routed   │
                     │  to correct server   │
                     └──────────────────────┘


 ═══ MCP SERVER TYPES ═══

 ┌─────────────────────────────────────────────────────────────────────┐
 │ Type        │ Transport   │ Auth        │ Use Case                  │
 ├─────────────┼─────────────┼─────────────┼───────────────────────────┤
 │ Stdio       │ stdin/stdout│ None        │ Local tools (npx, node)   │
 │ SSE         │ HTTP+SSE    │ OAuth/Token │ Remote services           │
 │ Direct      │ In-process  │ Internal    │ Plugin-bundled servers    │
 └─────────────────────────────────────────────────────────────────────┘

How It Works

Server Discovery

MCP servers are found from three sources at startup:

  1. settings.jsonmcpServers key with server definitions (command, args, env)
  2. CLI --mcp-config — JSON file or inline JSON with server definitions
  3. Plugins — plugin manifests can declare MCP servers; started when plugin loads, stopped when unloaded

At runtime, /mcp command can add, remove, or reconnect servers dynamically.

Server Connection Types

TypeProtocolHow It Works
Stdio JSON-RPC over stdin/stdout Clew spawns a subprocess (e.g. npx @modelcontextprotocol/server-filesystem) and communicates via its stdin/stdout streams. The subprocess advertises its capabilities via tools/list and handles tools/call requests.
SSE HTTP + Server-Sent Events Connects to remote MCP servers over HTTP. Uses SSE for server-to-client messages (tool results, resource updates) and HTTP POST for client-to-server requests. Supports OAuth authentication.
Direct Connect In-process Runs an MCP server in the same process via an in-process transport pair. Used by internal subsystems and plugin-bundled servers. No network overhead, no subprocess spawning.

Tool Lifecycle

  ┌─────────────────────────────────────────────────────────────────┐
  │                    MCP TOOL LIFECYCLE                           │
  └─────────────────────────────────────────────────────────────────┘

  1. CONNECT     ──► MCPConnectionManager connects to server
                       │
                       ▼
  2. DISCOVER    ──► Clew calls tools/list (paginated)
                       │
                       ▼
  3. MERGE       ──► assembleToolPool() merges MCP tools with
                       built-in tools (sorted by name, deduplicated)
                       │
                       ▼
  4. PRESENT     ──► Model sees MCP tools as native tools
                       │  (with permission gating, hooks, logging)
                       ▼
  5. EXECUTE     ──► Model calls tool → toolExecution.ts
                       │  routes to correct MCP server
                       │  mapToolResultToToolResultBlockParam
                       ▼
  6. RESPOND     ──► Result returned to model

Authentication

MCP supports multiple auth flows defined in src/services/mcp/auth.ts and src/services/mcp/oauthPort.ts:

  • OAuth 2.0 — redirect-based flow for remote MCP servers. Opens a local HTTP port to receive the callback.
  • Bearer token — static API token in the Authorization header
  • XAA token — Claude-specific auth provider token, handled in src/services/mcp/xaa.ts
  • Credential vault — stored credentials injected via credential_item_ids

MCP Commands

CommandDescription
/mcpOpen interactive MCP management menu — list servers, add, remove, reconnect
/mcp listList all connected MCP servers with their tools, resources, and prompts
/mcp add <name> <command> [args...]Add a new stdio MCP server
/mcp remove <name>Remove a connected MCP server
/mcp reconnect <name>Reconnect a disconnected MCP server

Server Config Format (settings.json)

json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"],
      "env": {}
    },
    "database": {
      "command": "node",
      "args": ["./mcp/db-server.js"],
      "env": {
        "DB_URL": "postgresql://localhost:5432/mydb"
      }
    },
    "remote-api": {
      "url": "https://mcp.example.com",
      "headers": {
        "Authorization": "Bearer sk-..."
      }
    }
  }
}

Plugin-Bundled MCP Servers

Plugins can declare MCP servers in their manifest. When a plugin loads, Clew creates a DirectConnect session internally — no subprocess, no network. The MCP server's tools become available as soon as the plugin registers. When the plugin is unloaded, the server is stopped.

See Plugins for details on plugin development.

Tool Pool Integration

MCP tools are merged with built-in tools via assembleToolPool() in src/tools.ts:

  • Both lists are sorted alphabetically, then concatenated, then deduplicated by name (uniqBy('name'))
  • Built-in tools take precedence when names collide
  • MCP tools go through the same permission gating and hook pipeline
  • Results are formatted via mapToolResultToToolResultBlockParam just like built-in tools

Integration with Built-in Tools

Several built-in tools use MCP under the hood:

ToolMCP Used For
ListMcpResourcesLists resources from all connected MCP servers (resources/list)
ReadMcpResourceReads a specific resource by URI from an MCP server (resources/read)

Architecture Files

PathRole
src/services/mcp/MCPConnectionManager.tsxServer lifecycle manager — connect, reconnect, disconnect, list servers
src/services/mcp/config.tsMCP server config loading from settings.json and CLI flags
src/services/mcp/client.tsJSON-RPC client — sends requests, receives responses and notifications
src/services/mcp/auth.tsOAuth and bearer token authentication flow
src/services/mcp/oauthPort.tsLocal HTTP server for OAuth callback handling
src/services/mcp/types.tsMCP type definitions and protocol constants
src/services/mcp/InProcessTransport.tsIn-process linked transport pair for DirectConnect mode
src/services/mcp/SdkControlTransport.tsSDK-level transport for programmatic control
src/services/mcp/normalization.tsTool name normalization between MCP and internal formats
src/services/mcp/envExpansion.tsEnvironment variable expansion in server config
src/services/mcp/officialRegistry.tsOfficial MCP server registry lookup
src/services/mcp/xaa.tsXAA auth token integration for Claude-specific servers
src/tools.tsTool registry — assembleToolPool merges MCP tools