Files
cleveragents-core/docs/reference/mcp_adapter.md
T
aditya ee82d6101e feat(skill): add MCP adapter for external tools
Implement MCPToolAdapter to connect to external MCP servers, enumerate
tools, and register them in ToolRegistry with source="mcp". Includes
connect/reconnect/disconnect lifecycle with timeout enforcement, input
validation on invoke, capability inference, Behave/Robot/ASV tests, and
docs/reference/mcp_adapter.md.

ISSUES CLOSED: #159
2026-02-25 13:17:26 +00:00

5.6 KiB

MCP Tool Adapter

This document covers the MCP (Model Context Protocol) adapter introduced in M2.3.mcp-runtime: connecting to external MCP servers, discovering tools, invoking them with schema validation, and registering them in the ToolRegistry.

Overview

The MCPToolAdapter bridges any MCP-compatible tool server into the CleverAgents runtime. It manages the full lifecycle:

Operation Method Description
Connect connect(timeout?) Start the server process or HTTP session, perform handshake
Disconnect disconnect() Clean shutdown of the server connection
Reconnect reconnect(timeout?) Disconnect and re-connect; clears cached tool list
Discover discover_tools(filter?) Enumerate available tools from the server
Invoke invoke(name, args) Call a tool with automatic input validation
Register register_tools(registry, namespace) Bulk-register into a ToolRegistry

Server Configuration

MCPServerConfig Fields

Field Type Required Description
name string Yes Server identifier
transport string Yes stdio, sse, or streamable-http
command string stdio only Command to spawn the server process
args list[string] No Command-line arguments
env dict No Environment variables for the server process
url string sse/http only Server URL for remote connections
headers dict No HTTP headers for remote connections

Validation Rules

  • stdio transport requires command
  • sse / streamable-http transport requires url

Tool Discovery

After connecting, call discover_tools() to enumerate all tools exposed by the MCP server. Each returned MCPToolDescriptor includes the tool name, description, and JSON Schema for inputs.

Filtering

Use MCPToolFilter with include or exclude lists to control which tools are exposed.

MCPToolDescriptor Fields

Field Type Description
name string Tool name as exposed by the server
description string Human-readable description
input_schema dict JSON Schema for tool inputs

Tool Invocation

Call invoke(name, arguments) to execute a discovered tool. Input arguments are validated against the tool's JSON Schema before the call is made. If validation fails, the result is returned immediately with success=False.

MCPToolResult Fields

Field Type Description
success bool Whether the invocation succeeded
data dict Result payload from the server
error string or null Error message on failure
duration_ms float Wall-clock execution time in milliseconds

Reconnect

Use reconnect(timeout?) to recover from a dropped connection or after a server restart. It performs a clean disconnect() followed by a fresh connect() and clears the cached tool list. Call discover_tools() again after reconnecting.

try:
    adapter.invoke("create_issue", {"title": "Bug"})
except RuntimeError:
    # Connection dropped — attempt recovery
    adapter.reconnect(timeout=10.0)
    adapter.discover_tools()

If the new connection attempt fails or times out, reconnect() raises ConnectionError.

ToolRegistry Integration

Discovered MCP tools can be bulk-registered into any ToolRegistry via register_tools(registry, namespace). Each tool is registered with the name {namespace}/{tool_name}. Re-registration after tool list changes replaces stale entries automatically.

Registered tools always carry source="mcp" and source_metadata={"server": "<server-name>"} for provenance tracking. checkpointable is always False for MCP tools — external server calls cannot be rolled back transactionally.

Capability Inference

MCP tools expose limited metadata (name, description, inputSchema). The adapter automatically infers extended ToolCapability metadata using name-based heuristics:

Tool name keywords Inferred capability
read, get, list, search, find read_only: true
write, create, update, delete, set writes: true
Both read and write keywords writes: true (write takes precedence)
Neither read_only: false, writes: false

Inferences are applied automatically when registering tools via register_tools(). They can be overridden via the overrides block in tool or skill YAML.

Use MCPToolAdapter.infer_capabilities(tool_name) directly to check what would be inferred for a given tool name.

Error Classification

Error Type When Exception / Field
Connection failure connect() with unreachable server ConnectionError
Not connected invoke() / discover_tools() before connect() RuntimeError
Tool not found invoke() with unknown tool name result.error contains "not found"
Validation failure invoke() with invalid input result.error contains "validation"
Timeout Server call exceeds deadline result.error contains "timeout"
Server error Server returns isError: true result.error contains "server error"

Transport Layer

The MCPTransport base class defines the abstract interface. Concrete implementations handle stdio (child process) and HTTP (SSE / streamable-http) protocols. For testing, provide a mock transport to the adapter constructor.

Thread Safety

MCPToolAdapter uses threading.RLock internally. All public methods are safe to call from multiple threads concurrently.