MCP Client Support — connect to external MCP servers as tool providers #86

Open
opened 2026-02-23 11:20:02 +00:00 by nazim · 0 comments
Contributor

Summary

Add MCP (Model Context Protocol) client support to cobot, allowing it to connect to external MCP servers and expose their tools to the agent. This is the standard way AI agents integrate with external tool ecosystems.

Why

MCP is becoming the universal protocol for AI tool integration (backed by Anthropic, adopted by VS Code, Claude Desktop, Codex CLI, Cursor, etc.). Adding client support means cobot can instantly access:

  • Code indexing (code-index-mcp, #85)
  • Databases, filesystems, browsers
  • Any of the 100+ public MCP servers
  • Custom internal tools

Without MCP support, every tool integration requires a custom plugin. With it, we get ecosystem compatibility for free.

MCP Protocol Essentials

Architecture: Host (cobot) → Client (one per server) → Server (external process)

Transports:

  • stdio — launch server as subprocess, communicate via stdin/stdout (local servers)
  • Streamable HTTP — connect to remote servers over HTTP+SSE (remote servers)
  • SSE (legacy) — server-sent events transport

Protocol: JSON-RPC 2.0 over the transport. Key methods:

  • initialize — capability negotiation
  • tools/list — discover available tools (returns name, description, JSON Schema params)
  • tools/call — invoke a tool with arguments, get results back

Data flow:

  1. Cobot spawns/connects to MCP server
  2. Calls tools/list → gets tool definitions
  3. Converts MCP tool schemas to cobot's TOOL_DEFINITIONS format
  4. When agent calls an MCP tool → routes to session.call_tool(name, args)
  5. Returns result to agent

Python SDK

Official library: mcp (maintained by Anthropic/MCP team)

  • pip install mcp (or uv add mcp)
  • Provides ClientSession, StdioServerParameters, stdio_client
  • Async-native (asyncio), fits cobot's async architecture
  • Handles protocol negotiation, transport, JSON-RPC framing

Client code is ~30 lines:

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

params = StdioServerParameters(command="uvx", args=["code-index-mcp"])
async with stdio_client(params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        tools = await session.list_tools()  # discover tools
        result = await session.call_tool("search_code", {"query": "def main"})  # invoke

Integration Plan

Phase 1: MCP plugin (core client) — ~2-3 days

New plugin: cobot/plugins/mcp/plugin.py

  1. Configuration in cobot.yaml:
mcp:
  servers:
    code-index:
      command: uvx
      args: ["code-index-mcp", "--project-path", "/path/to/repo"]
      transport: stdio
    # remote example:
    # sentry:
    #   url: https://mcp.sentry.io
    #   transport: streamable-http
  1. Implements ToolProvider interface — the existing pattern in tools/plugin.py already aggregates tools from all ToolProvider plugins. The MCP plugin just needs to:

    • get_definitions() → convert MCP tool schemas to cobot format
    • execute(tool_name, args) → route to session.call_tool()
  2. Lifecycle:

    • start() → spawn configured MCP servers, run initialize(), cache tool lists
    • stop() → graceful shutdown of subprocesses
    • Handle server crashes with auto-restart
  3. Tool namespacing: Prefix tools to avoid collisions: mcp_code-index_search_code

Phase 2: Dynamic server management — ~1-2 days

  1. CLI commands:

    • cobot mcp list — show connected servers and their tools
    • cobot mcp add <name> <command> — add a server at runtime
    • cobot mcp remove <name> — disconnect a server
  2. Web panel (depends on #43): show connected servers, tool counts, health status

Phase 3: Remote transport — ~1 day

  1. Add Streamable HTTP transport support for connecting to remote MCP servers
  2. Auth support (OAuth, API keys) for authenticated remote servers

Effort Estimate

Phase Effort Dependencies
Phase 1: Core client 2-3 days mcp pip package
Phase 2: CLI/management 1-2 days Phase 1
Phase 3: Remote transport 1 day Phase 1
Total 4-6 days

Phase 1 alone gives us a working MCP client. Phases 2-3 are nice-to-haves.

Dependencies

  • mcp package (adds: httpx, pydantic, anyio — cobot may already have some of these)
  • Python 3.10+ (already required)

References

## Summary Add MCP (Model Context Protocol) client support to cobot, allowing it to connect to external MCP servers and expose their tools to the agent. This is the standard way AI agents integrate with external tool ecosystems. ## Why MCP is becoming the universal protocol for AI tool integration (backed by Anthropic, adopted by VS Code, Claude Desktop, Codex CLI, Cursor, etc.). Adding client support means cobot can instantly access: - Code indexing (code-index-mcp, #85) - Databases, filesystems, browsers - Any of the 100+ public MCP servers - Custom internal tools Without MCP support, every tool integration requires a custom plugin. With it, we get ecosystem compatibility for free. ## MCP Protocol Essentials **Architecture:** Host (cobot) → Client (one per server) → Server (external process) **Transports:** - **stdio** — launch server as subprocess, communicate via stdin/stdout (local servers) - **Streamable HTTP** — connect to remote servers over HTTP+SSE (remote servers) - **SSE** (legacy) — server-sent events transport **Protocol:** JSON-RPC 2.0 over the transport. Key methods: - `initialize` — capability negotiation - `tools/list` — discover available tools (returns name, description, JSON Schema params) - `tools/call` — invoke a tool with arguments, get results back **Data flow:** 1. Cobot spawns/connects to MCP server 2. Calls `tools/list` → gets tool definitions 3. Converts MCP tool schemas to cobot's `TOOL_DEFINITIONS` format 4. When agent calls an MCP tool → routes to `session.call_tool(name, args)` 5. Returns result to agent ## Python SDK **Official library:** [`mcp`](https://pypi.org/project/mcp/) (maintained by Anthropic/MCP team) - `pip install mcp` (or `uv add mcp`) - Provides `ClientSession`, `StdioServerParameters`, `stdio_client` - Async-native (asyncio), fits cobot's async architecture - Handles protocol negotiation, transport, JSON-RPC framing **Client code is ~30 lines:** ```python from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client params = StdioServerParameters(command="uvx", args=["code-index-mcp"]) async with stdio_client(params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools = await session.list_tools() # discover tools result = await session.call_tool("search_code", {"query": "def main"}) # invoke ``` ## Integration Plan ### Phase 1: MCP plugin (core client) — ~2-3 days New plugin: `cobot/plugins/mcp/plugin.py` 1. **Configuration** in `cobot.yaml`: ```yaml mcp: servers: code-index: command: uvx args: ["code-index-mcp", "--project-path", "/path/to/repo"] transport: stdio # remote example: # sentry: # url: https://mcp.sentry.io # transport: streamable-http ``` 2. **Implements `ToolProvider` interface** — the existing pattern in `tools/plugin.py` already aggregates tools from all `ToolProvider` plugins. The MCP plugin just needs to: - `get_definitions()` → convert MCP tool schemas to cobot format - `execute(tool_name, args)` → route to `session.call_tool()` 3. **Lifecycle:** - `start()` → spawn configured MCP servers, run `initialize()`, cache tool lists - `stop()` → graceful shutdown of subprocesses - Handle server crashes with auto-restart 4. **Tool namespacing:** Prefix tools to avoid collisions: `mcp_code-index_search_code` ### Phase 2: Dynamic server management — ~1-2 days 5. **CLI commands:** - `cobot mcp list` — show connected servers and their tools - `cobot mcp add <name> <command>` — add a server at runtime - `cobot mcp remove <name>` — disconnect a server 6. **Web panel** (depends on #43): show connected servers, tool counts, health status ### Phase 3: Remote transport — ~1 day 7. Add Streamable HTTP transport support for connecting to remote MCP servers 8. Auth support (OAuth, API keys) for authenticated remote servers ## Effort Estimate | Phase | Effort | Dependencies | |-------|--------|--------------| | Phase 1: Core client | 2-3 days | `mcp` pip package | | Phase 2: CLI/management | 1-2 days | Phase 1 | | Phase 3: Remote transport | 1 day | Phase 1 | | **Total** | **4-6 days** | | Phase 1 alone gives us a working MCP client. Phases 2-3 are nice-to-haves. ## Dependencies - `mcp` package (adds: `httpx`, `pydantic`, `anyio` — cobot may already have some of these) - Python 3.10+ (already required) ## References - [MCP Spec](https://modelcontextprotocol.io/docs/learn/architecture) - [MCP Python SDK](https://pypi.org/project/mcp/) — official client/server library - [Build an MCP Client tutorial](https://modelcontextprotocol.io/docs/develop/build-client) - [MCP server registry](https://github.com/modelcontextprotocol/servers) - #85 — code-index-mcp integration (first consumer of this feature) - Cobot `ToolProvider` interface in `plugins/interfaces.py` - `tools/plugin.py` already aggregates from all `ToolProvider` plugins (lines 153-175)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
ultanio/cobot#86
No description provided.