# How MCP Integration with Claude Code Works for Ouroboros Plugin Commands

> Discover how MCP integration with Claude Code empowers Ouroboros plugin commands. Learn how external agents discover and invoke JSON-RPC tools via the ClaudeCodeAdapter and Max-Plan SDK.

- Repository: [Q00/ouroboros](https://github.com/Q00/ouroboros)
- Tags: how-to-guide
- Published: 2026-03-14

---

**MCP integration with Claude Code enables Ouroboros to expose plugin commands as JSON-RPC tools that external agents can discover and invoke, using the ClaudeCodeAdapter to bridge MCP tool requests with the Claude Code Max-Plan SDK for LLM completions.**

The Q00/ouroboros repository implements a Modular Compute Platform (MCP) server that transforms local workflow commands into discoverable remote tools. This architecture allows external MCP clients to execute Ouroboros plugin commands like `ouroboros_execute_seed` while leveraging Claude Code's Max-Plan authentication and model capabilities through a dedicated adapter layer.

## Architecture Overview

The integration follows a layered pipeline that separates transport concerns from LLM execution. When a user invokes `ooo run seed.yaml` or a remote client calls `ouroboros_execute_seed`, the request flows through four distinct stages before reaching the Claude Code LLM.

```

CLI (or remote MCP client)
   │
   ▼
MCPClientManager  ← discovers MCP servers
   │
   ▼
MCPToolProvider  ← builds tool definitions & conflict handling
   │
   ▼
OrchestratorRunner (or MCP server handler)
   │
   ├─ ExecuteSeedHandler ──► ClaudeCodeAdapter (LLM request)
   └─ QAToolHandler      ──► ClaudeCodeAdapter (LLM request)
   │
   ▼
MCPToolResult → JSON-RPC response → CLI / remote client

```

The **MCPClientManager** handles server connections, while the **MCPToolProvider** converts raw MCP tools into agent-callable definitions with timeout and retry policies. Tool handlers like **ExecuteSeedHandler** instantiate a **ClaudeCodeAdapter** to perform the actual LLM request, bridging the JSON-RPC transport layer with Claude Code's Python SDK.

## Core Components

**MCPClientManager** manages persistent connections to one or more MCP servers and enumerates available tools. Located in [`src/ouroboros/mcp/client/manager.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/mcp/client/manager.py), this component provides the `list_all_tools()` method that returns `MCPToolDefinition` objects from all connected servers.

**MCPToolProvider** wraps the client manager's output as agent-callable tools suitable for the Ouroboros orchestrator. Found in [`src/ouroboros/orchestrator/mcp_tools.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/orchestrator/mcp_tools.py), it implements `get_tools()` for conflict resolution and `call_tool()` for execution with automatic retries.

**ClaudeCodeAdapter** implements the LLM-side integration using the Claude Code Max-Plan SDK. Defined in [`src/ouroboros/providers/claude_code_adapter.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/providers/claude_code_adapter.py), this adapter handles authentication automatically and exposes `complete()` methods that translate Ouroboros prompts into Claude Code SDK calls.

**ExecuteSeedHandler** serves as the entry point for the `ouroboros_execute_seed` MCP tool. Located in [`src/ouroboros/mcp/tools/definitions.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/mcp/tools/definitions.py) (lines 61-86 and 119-132), it parses seed YAML and instantiates the orchestrator runner with a fresh `ClaudeCodeAdapter` when no explicit LLM adapter is supplied.

**QAToolHandler** implements the `qa` tool for post-execution quality checks. Found in [`src/ouroboros/mcp/tools/qa.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/mcp/tools/qa.py), it constructs QA-specific system prompts and delegates to `ClaudeCodeAdapter` for evaluation.

**OrchestratorRunner** coordinates the full workflow across interview, execution, and evaluation phases. Defined in [`src/ouroboros/orchestrator/runner.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/orchestrator/runner.py), it receives a `ClaudeAgentAdapter` (which may wrap `ClaudeCodeAdapter`) to process LLM requests within the workflow context.

## The Execution Flow: From MCP Discovery to LLM Completion

### Tool Discovery via MCPClientManager

The process begins when the MCP client manager establishes connections to configured servers. The manager retrieves available tools through the `list_all_tools()` method, which aggregates capabilities from all connected MCP endpoints.

```python

# In MCPClientManager

tools = await self._manager.list_all_tools()

```

This discovery mechanism enables dynamic tool availability without hardcoding command definitions in the client.

### Building Agent-Callable Tools with MCPToolProvider

Once discovered, tools pass through the `MCPToolProvider` class to become compatible with the Ouroboros orchestrator. The `get_tools()` method performs three critical transformations:

- **Conflict detection**: Identifies duplicate tool names between built-in and server-provided tools, logging conflicts via `ToolConflict`
- **Prefixing**: Optionally applies a `tool_prefix` (e.g., `mcp_`) to avoid namespace collisions
- **Schema wrapping**: Converts raw MCP definitions into `MCPToolInfo` objects with JSON-schema parameters

```python
provider = MCPToolProvider(mcp_manager, tool_prefix="mcp_")
available_tools = await provider.get_tools(builtin_tools=["list_sessions"])

```

The provider also configures execution policies including a **30-second default timeout** and exponential backoff retry logic using the `stamina` library.

### Handling Tool Execution: ExecuteSeedHandler

When an MCP client invokes `ouroboros_execute_seed`, the server routes the JSON-RPC request to `ExecuteSeedHandler.handle()`. This handler performs four sequential operations:

1. **Parses the seed YAML** into a `Seed` object
2. **Instantiates a ClaudeCodeAdapter** with `max_turns=1` for fast evaluation if no adapter is provided
3. **Creates an OrchestratorRunner** with `permission_mode="acceptEdits"` and a fresh `EventStore`
4. **Executes the workflow** and returns the result as `MCPToolResult`

```python
from ouroboros.providers.claude_code_adapter import ClaudeCodeAdapter

# Inside ExecuteSeedHandler.handle (lines 119-132)

llm_adapter = ClaudeCodeAdapter(max_turns=1)

runner = OrchestratorRunner(
    adapter=ClaudeAgentAdapter(permission_mode="acceptEdits"),
    event_store=event_store,
    console=Console(stderr=True),
)

```

The handler in [`src/ouroboros/mcp/tools/definitions.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/mcp/tools/definitions.py) automatically bridges the MCP transport layer with the orchestrator's internal execution model.

### LLM Integration via ClaudeCodeAdapter

All LLM-side logic ultimately resolves through `ClaudeCodeAdapter`. When the orchestrator calls the adapter's query method, the adapter constructs `ClaudeAgentOptions` and invokes the Claude Code SDK's `query` function:

```python

# Inside ClaudeCodeAdapter._make_completion

from claude_agent_sdk import ClaudeAgentOptions, query
options = ClaudeAgentOptions(system_prompt=..., max_turns=self.max_turns)
response = query(prompt, options)

```

This design centralizes authentication handling, allowing the Max-Plan SDK to manage credentials while Ouroboros focuses on prompt construction and result parsing.

## Reliability and Error Handling

The MCP integration layer implements robust failure management through the `MCPToolProvider.call_tool()` method in [`src/ouroboros/orchestrator/mcp_tools.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/orchestrator/mcp_tools.py).

**Conflict Resolution**: The `get_tools()` method detects name collisions between built-in tools and MCP-provided tools, recording conflicts in `ToolConflict` objects without crashing the discovery process.

**Retry Policy**: The `_call_with_retry()` method (lines 55-61) decorates the underlying MCP call with `stamina.retry`, configured with:
- **Minimum wait**: 0.5 seconds (`RETRY_WAIT_MIN`)
- **Maximum wait**: 5 seconds (`RETRY_WAIT_MAX`)
- **Maximum attempts**: 3 retries (`MAX_RETRIES`)
- **Retryable exceptions**: `MCPConnectionError` and `asyncio.TimeoutError`

**Error Conversion**: All MCP client errors transform into structured `MCPToolError` objects via `Result.err`, preventing uncaught exceptions from propagating to the orchestrator.

**Timeout Management**: A default 30-second timeout (`DEFAULT_TOOL_TIMEOUT`) applies to all tool invocations unless explicitly overridden in the provider configuration.

## Practical Implementation Example

The following client-side implementation demonstrates connecting to an MCP server, discovering Ouroboros tools, and executing a seed workflow:

```python
import asyncio
from ouroboros.mcp.client.manager import MCPClientManager
from ouroboros.orchestrator.mcp_tools import MCPToolProvider

async def run_seed():
    # Connect to MCP server(s)

    manager = MCPClientManager()
    await manager.add_server({"url": "http://localhost:8000"})
    await manager.connect_all()

    # Wrap tools for the orchestrator

    provider = MCPToolProvider(manager)
    await provider.get_tools()               # discover + conflict-resolve

    # Call the seed-execution tool

    result = await provider.call_tool(
        "ouroboros_execute_seed",
        {
            "seed_content": "name: hello_world\nsteps: []",
            "model_tier": "medium",
            "max_iterations": 5,
        },
    )
    if result.is_ok:
        print("Execution finished:", result.value.output)
    else:
        print("Tool error:", result.error)

asyncio.run(run_seed())

```

On the server side, `ExecuteSeedHandler` automatically instantiates the `ClaudeCodeAdapter` and processes the LLM request upon receiving the tool invocation.

## Summary

- **MCPClientManager** in [`src/ouroboros/mcp/client/manager.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/mcp/client/manager.py) handles server discovery and connection management for MCP servers.
- **MCPToolProvider** converts raw MCP tools into orchestrator-compatible definitions with automatic retry logic and conflict detection.
- **ClaudeCodeAdapter** bridges tool handlers to the Claude Code Max-Plan SDK, managing authentication and completion requests.
- **ExecuteSeedHandler** and **QAToolHandler** serve as the primary entry points for plugin commands, automatically instantiating LLM adapters when needed.
- The integration provides **30-second timeouts**, **exponential backoff retries**, and **structured error handling** via `MCPToolResult` wrappers.

## Frequently Asked Questions

### What is MCP integration in Ouroboros?

MCP integration refers to the Modular Compute Platform implementation that exposes Ouroboros workflows as JSON-RPC tools discoverable by external agents. According to the Q00/ouroboros source code, this allows the `ooo` CLI and remote clients to invoke plugin commands like `ouroboros_execute_seed` through a standardized protocol while maintaining compatibility with the Claude Code LLM backend.

### How does ClaudeCodeAdapter authenticate with Claude Code?

The `ClaudeCodeAdapter` class relies on the Claude Code Max-Plan SDK to handle authentication automatically. As implemented in [`src/ouroboros/providers/claude_code_adapter.py`](https://github.com/Q00/ouroboros/blob/main/src/ouroboros/providers/claude_code_adapter.py), the adapter imports `ClaudeAgentOptions` and `query` from `claude_agent_sdk`, delegating credential management to the underlying SDK rather than handling tokens directly within Ouroboros.

### What happens when MCP tool names conflict?

`MCPToolProvider.get_tools()` detects conflicts between built-in tools and server-provided tools during the discovery phase. Conflicts are recorded in `ToolConflict` objects and logged via `structlog`, while the provider applies optional prefixes (such as `mcp_`) to disambiguate tool names without crashing the discovery process.

### How does Ouroboros handle MCP tool timeouts and failures?

The system implements a multi-layered reliability strategy: `MCPToolProvider.call_tool()` enforces a 30-second default timeout (`DEFAULT_TOOL_TIMEOUT`), while the `_call_with_retry()` method uses the `stamina` library to retry failed connections up to 3 times with exponential backoff between 0.5 and 5 seconds. All failures convert to `MCPToolError` objects wrapped in `Result.err` rather than raising uncaught exceptions.