feat(mcp): add MCP (Model Context Protocol) tool integration

Allows CowAgent to dynamically load tools from any MCP server at startup,
extending the agent from a fixed toolset to an open, extensible tool ecosystem.

## What's added

- `agent/tools/mcp/mcp_client.py`: lightweight JSON-RPC client supporting both
  stdio (subprocess) and SSE (HTTP) transports — zero extra dependencies
- `agent/tools/mcp/mcp_tool.py`: `McpTool` wraps a single MCP tool as a
  `BaseTool`, with dynamic name/description/params set at instance level
- `agent/tools/tool_manager.py`: new `_load_mcp_tools()` loads MCP servers at
  startup via `McpClientRegistry`; falls back gracefully on any error; no-op
  when `mcp_servers` is not configured
- `config.py`: registers `mcp_servers` in `available_setting` with inline docs

## Design

- No new dependencies — JSON-RPC implemented from scratch using stdlib only
- MCP clients are long-lived (initialized once, shared across tool calls)
- `McpClientRegistry` holds all subprocess handles and shuts them down cleanly
- Server init failures are non-fatal: logged as warnings, agent continues normally
- Zero overhead when `mcp_servers` is absent from config

## Config example

```json
"mcp_servers": [
  {
    "name": "filesystem",
    "type": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
  }
]
```

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ooaaooaa123
2026-05-06 20:16:04 +08:00
parent 55aaf60a57
commit b2429ec30c
6 changed files with 469 additions and 1 deletions

View File

@@ -219,6 +219,19 @@ available_setting = {
# using the rule: skill[<name>][<key>] -> SKILL_<NAME>_<KEY>
# (e.g. skill["image-generation"].model -> SKILL_IMAGE_GENERATION_MODEL).
"skill": {},
# MCP (Model Context Protocol) server list.
# Each entry describes one MCP server to connect at startup.
# Supported types:
# stdio — launch a local process and communicate over stdin/stdout
# sse — connect to a remote server via HTTP + Server-Sent Events
#
# Example:
# "mcp_servers": [
# {"name": "filesystem", "type": "stdio", "command": "npx",
# "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]},
# {"name": "my-api", "type": "sse", "url": "http://localhost:8000/sse"}
# ]
"mcp_servers": [],
}