Skip to content

MCP Driver: connect kernel to any MCP server (stdio + Streamable HTTP) #41

@dgenio

Description

@dgenio

Milestone: v0.2.0 | Tier: Medium | Effort: Medium

Problem

MCP integration is the repo's #1 value proposition — documented in docs/integrations.md as the primary use case — but no MCPDriver exists. Users cannot connect agent-kernel to any MCP server. Without this, the library's core promise ("secure MCP tool calls") is unrealized.

Proposed Change

Implement MCPDriver in src/agent_kernel/drivers/mcp.py supporting both transports:

1. Driver implementation

class MCPDriver:
    """Driver that connects to an MCP server and executes tool calls."""
    
    async def execute(self, operation: str, params: dict, constraints: dict) -> Any:
        """Map operation → tools/call, apply constraints, return result."""
  • stdio transport: Connect to local MCP servers via mcp.client.stdio.stdio_client.
  • Streamable HTTP transport: Connect to remote MCP servers via mcp.client.streamable_http.streamable_http_client.
  • Factory methods: MCPDriver.from_stdio(command, args) and MCPDriver.from_http(url).

2. Auto-discovery

  • MCPDriver.discover() -> list[Capability]: Call tools/list on the MCP server, convert each MCP tool definition to an agent-kernel Capability with:
    • capability_id = tool name (or namespace.tool_name if namespaced)
    • description from MCP tool description
    • safety_class = READ by default (overridable via mapping config)
    • impl = ImplementationRef(driver_id="mcp:<server_name>", operation=tool_name)
  • Register discovered capabilities via kernel.register_driver() + registry.register_many().

3. Response handling

  • Convert MCP CallToolResult content blocks (TextContent, ImageContent, EmbeddedResource) to dicts that the firewall can process.
  • Handle isError responses by raising DriverError.
  • Support structured output (structuredContent) when available.

4. Connection lifecycle

  • Use async context manager for connection management.
  • Handle reconnection for long-lived HTTP connections.
  • Clean shutdown via async with protocol.

Acceptance Criteria

  • MCPDriver.from_stdio() connects to a local MCP server process
  • MCPDriver.from_http() connects to a Streamable HTTP MCP server
  • discover() converts MCP tools to Capability objects with correct metadata
  • execute() calls MCP tools and returns results through the firewall pipeline
  • Error responses from MCP servers raise DriverError with descriptive message
  • Integration test with a mock MCP server (FastMCP) exercises the full pipeline:
    discover → register → grant → invoke → firewall → response
  • mcp>=1.0 added as optional dependency under [project.optional-dependencies]
  • Graceful error when mcp package not installed (ImportError with helpful message)

Affected Files

  • src/agent_kernel/drivers/mcp.py (new)
  • src/agent_kernel/drivers/__init__.py (export MCPDriver)
  • tests/test_drivers.py (integration tests with mock MCP server)
  • pyproject.toml (optional mcp dependency)
  • docs/integrations.md (update with real usage examples)

References

Metadata

Metadata

Assignees

Labels

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions