Codumentor logo Codumentor

MCP (Model Context Protocol) Plugin

The MCP Plugin enables Codumentor to integrate with Model Context Protocol (MCP) servers, exposing their tools as native Codumentor tools. You can configure which agents (main agent, subagents, or both) receive these tools.

Overview

The MCP plugin:

  1. Connects to MCP servers over stdio (local processes) or HTTP/SSE (remote servers)
  2. Discovers available tools from MCP servers
  3. Wraps MCP tools as Codumentor tools
  4. Makes tools available to configured agents (main agent, subagents, or both)
  5. Shares MCP client connections across all agent instances to avoid redundant processes

Installation

The MCP plugin is included with Codumentor. No additional installation is required.

Testing

The MCP plugin tests are optional and skipped by default to keep the test suite fast. They spawn actual processes and take ~8-12 seconds to run.

Run all tests except MCP tests (default)

python -m unittest discover -s tests

Run only MCP tests

RUN_MCP_TESTS=1 python -m pytest tests/test_mcp_plugin.py -v

Run all tests including MCP tests

RUN_MCP_TESTS=1 python -m unittest discover -s tests

Configuration

Add the MCP plugin to your Codumentor configuration file. You can configure either a local stdio server or a remote HTTP/SSE server.

Local stdio Server Configuration

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      executable: "path/to/mcp-server"  # Required: MCP server executable
      args: []                          # Optional: Command-line arguments
      env: {}                           # Optional: Environment variables
      enabled: true                     # Optional: Enable/disable the plugin (default: true)
      target_agents: "all"              # Optional: Which agents receive tools (default: "all")
      disabled_tools: []                # Optional: Tools to disable (single string or list)

Remote HTTP/SSE Server Configuration

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      url: "https://mcp-server.example.com"  # Required: Remote MCP server URL
      headers:                               # Optional: HTTP headers for authentication
        Authorization: "Bearer your-token"
        X-API-Key: "your-api-key"
      enabled: true                          # Optional: Enable/disable the plugin (default: true)
      target_agents: "all"                    # Optional: Which agents receive tools (default: "all")
      disabled_tools: []                     # Optional: Tools to disable (single string or list)

Configuration Parameters

For Local stdio Servers

For Remote HTTP/SSE Servers

Common Parameters (Both Types)

Per-user secrets in headers / env

Rather than hard-coding a shared token in config, you can reference a per-user secret with a ${secret:<name>} placeholder in headers (remote) or env/args (stdio). It is resolved from the calling user's secret registry at request time — so a single server config authenticates each user with their own key, and the token never appears in config or the agent transcript.

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      url: "https://api.example.com/mcp"
      headers:
        Authorization: "Bearer ${secret:my_service_token}"   # per-user

The MCP plugin scans its configured headers/env/args for these placeholders and declares them to the User Secrets pane, which shows the user exactly which secrets to create ("Needed by plugins", set/unset). Requires the user_secrets plugin to be loaded — it is what resolves the placeholder and surfaces the requirement. This indirection is also why a Codumentor-native plugin is preferable to MCP when you need per-user identity for a local tool: a stdio MCP server's environment is fixed at spawn and shared across all sessions, so it cannot carry per-user identity the way a placeholder-in-headers remote server (or a native plugin like redmine) can.

Examples

Local stdio Server - Basic Configuration

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      executable: "mcp-filesystem"

Local stdio Server - With Arguments

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      executable: "mcp-server"
      args: ["--workspace", "/path/to/workspace"]
      env:
        API_KEY: "your-api-key"
        LOG_LEVEL: "info"
      response_truncate_length: 50000  # Truncate responses longer than 50K characters

Remote HTTP/SSE Server - Basic Configuration

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      url: "https://mcp-server.example.com"

Remote HTTP/SSE Server - With Authentication

plugins:
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      url: "https://api.example.com/mcp"
      headers:
        Authorization: "Bearer your-oauth-token"
        X-API-Key: "your-api-key"

Multiple MCP Servers (Local and Remote)

You can configure multiple MCP plugins to connect to different servers:

plugins:
  # Local stdio server
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      executable: "mcp-filesystem"
      
  # Another local stdio server
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      executable: "mcp-github"
      env:
        GITHUB_TOKEN: "your-github-token"
  
  # Remote HTTP/SSE server
  - module: codumentor.plugins.mcp
    class: MCPPlugin
    args:
      url: "https://remote-mcp.example.com"
      headers:
        Authorization: "Bearer your-token"

How It Works

MCP Protocol

The plugin implements the Model Context Protocol, which is a JSON-RPC protocol. The protocol supports two transports:

  1. stdio Transport: For local MCP server processes (JSON-RPC over stdin/stdout)
  2. HTTP/SSE Transport: For remote MCP servers (JSON-RPC over HTTP with Server-Sent Events)

The protocol includes:

  1. Initialization: Handshake with the MCP server to establish protocol version and capabilities
  2. Tool Discovery: Listing available tools and their schemas
  3. Tool Execution: Calling tools with arguments and receiving results

Tool Integration

MCP tools are automatically integrated into Codumentor's tool system:

  1. Tool Wrapping: Each MCP tool is wrapped as a Codumentor Tool instance
  2. Schema Translation: MCP's JSON schemas are translated to Codumentor's tool parameter schemas
  3. Result Translation: MCP tool results are converted to Codumentor's ToolResult format

Shared Client Architecture

The plugin uses a shared client architecture to optimize resource usage:

Hook-Based Registration

Tools are registered dynamically via the onPromptAssemble hook:

Tool Naming

MCP tools are exposed with their original names from the MCP server. They appear in logs with the [MCP] prefix for easy identification:

[MCP] read_file(path='/path/to/file')

Error Handling

The plugin handles various error scenarios:

Troubleshooting

Plugin Not Loading

Check the logs for plugin loading errors:

grep "MCPPlugin" logs/codumentor.log

Common issues:

Tools Not Appearing

If MCP tools don't appear in the agent:

  1. Verify the MCP server is starting correctly
  2. Check that the server returns tools in the tools/list response
  3. Look for errors in the MCP server's stderr (logged by the plugin)

Communication Issues

For JSON-RPC communication problems:

  1. Enable debug logging in your configuration
  2. Check the MCP protocol version compatibility
  3. Verify the server implements the expected MCP protocol

Advanced Usage

Custom MCP Server

You can implement your own MCP server in any language. The server must:

  1. Read JSON-RPC messages from stdin (one per line)
  2. Write JSON-RPC responses to stdout (one per line)
  3. Implement the MCP protocol methods: - initialize: Handshake and capability negotiation - tools/list: Return available tools and their schemas - tools/call: Execute tool calls

Example minimal MCP server (Python):

#!/usr/bin/env python3
import json
import sys

def handle_request(request):
    method = request["method"]
    
    if method == "initialize":
        return {
            "protocolVersion": "2024-11-05",
            "capabilities": {"tools": {}},
            "serverInfo": {"name": "my-server", "version": "1.0.0"}
        }
    
    elif method == "tools/list":
        return {
            "tools": [
                {
                    "name": "example_tool",
                    "description": "An example tool",
                    "inputSchema": {
                        "type": "object",
                        "properties": {
                            "message": {"type": "string"}
                        },
                        "required": ["message"]
                    }
                }
            ]
        }
    
    elif method == "tools/call":
        tool_name = request["params"]["name"]
        args = request["params"]["arguments"]
        
        # Implement your tool logic here
        result = {"content": [{"type": "text", "text": f"Processed: {args}"}]}
        return result

# Main loop
for line in sys.stdin:
    request = json.loads(line)
    response = {
        "jsonrpc": "2.0",
        "id": request.get("id")
    }
    
    try:
        response["result"] = handle_request(request)
    except Exception as e:
        response["error"] = {"message": str(e)}
    
    print(json.dumps(response), flush=True)

Programmatic Access

You can also use the MCP client programmatically:

from codumentor.plugins.mcp.mcp_client import MCPClient

# Create and start a client
client = MCPClient(executable="mcp-server", args=["--config", "config.json"])
await client.start()

# List tools
print(f"Available tools: {[t.name for t in client.tools]}")

# Call a tool
result = await client.call_tool("example_tool", {"message": "Hello"})
print(result)

# Stop the client
await client.stop()

Performance Considerations

Security Considerations

Remote Server Support

The MCP plugin supports connecting to remote MCP servers over HTTP/SSE. This enables:

Remote Server Requirements

Remote MCP servers should:

Transport Details

Future Enhancements

Potential improvements for the MCP plugin:

References