Skip to main content

MCP Server

The programmatic tools generated by Agent Codemode (from MCP Servers and Skills) can be exposed as an MCP Server for any MCP-compatible client.

This allows you to:

  • Use Agent Codemode's code-first tool composition from any MCP client
  • Build meta-agents that discover and compose tools programmatically
  • Create a unified interface to multiple MCP servers through code execution

Quick Start

Launcher Script

Create a launcher script to configure which MCP servers to compose:

#!/usr/bin/env python3
import sys
from pathlib import Path

from agent_codemode import ToolRegistry, MCPServerConfig, CodeModeConfig
from agent_codemode.server import configure, run

# Create registry and add MCP servers to compose
registry = ToolRegistry()
registry.add_server(MCPServerConfig(
name="my_tools",
command=sys.executable,
args=["/path/to/my_mcp_server.py"]
))

# Configure paths
config = CodeModeConfig(
workspace_path="./workspace",
generated_path="./generated",
skills_path="./skills",
)

configure(config=config, registry=registry)
run()

Then configure your MCP client to run the launcher script.

Exposed Tools

The Codemode MCP Server exposes the following tools:

Tool Discovery

ToolDescription
search_toolsProgressive tool discovery with natural language queries
list_serversList all connected MCP servers
get_tool_detailsGet full schema for a specific tool

Code Execution

ToolDescription
execute_codeExecute Python code that composes tools
call_toolDirect tool invocation (when allow_direct_tool_calls=True)

Skills Management

ToolDescription
list_skillsList available saved skills
save_skillSave a new skill
run_skillExecute a saved skill
delete_skillRemove a skill

Server Management

ToolDescription
add_mcp_serverDynamically add new MCP servers
get_execution_historyView recent execution history

Tool Details

search_tools

Search for available tools from all connected MCP servers:

result = await client.call_tool("search_tools", {
"query": "file operations",
"limit": 10,
"include_deferred": True
})
# Returns: {"tools": [...], "total": 15, "has_more": True}

execute_code

Execute Python code that composes MCP tools:

result = await client.call_tool("execute_code", {
"code": """
import asyncio
from generated.servers.filesystem import read_file, write_file

# Read multiple files in parallel
files = ["/data/a.txt", "/data/b.txt", "/data/c.txt"]
contents = await asyncio.gather(*[read_file({"path": f}) for f in files])

# Process and write results
for i, content in enumerate(contents):
await write_file({
"path": f"/output/processed_{i}.txt",
"content": content.upper()
})

print(f"Processed {len(files)} files")
""",
"timeout": 30.0
})
# Returns: {"success": True, "result": "...", "stdout": "Processed 3 files", ...}

save_skill

Save a reusable skill:

result = await client.call_tool("save_skill", {
"name": "batch_uppercase",
"description": "Convert all files in a directory to uppercase",
"code": '''
async def batch_uppercase(input_dir, output_dir):
from generated.servers.filesystem import list_directory, read_file, write_file

entries = await list_directory({"path": input_dir})
for entry in entries["entries"]:
content = await read_file({"path": f"{input_dir}/{entry}"})
await write_file({"path": f"{output_dir}/{entry}", "content": content.upper()})
return {"processed": len(entries["entries"])}
''',
"tags": ["file", "batch", "text"]
})

run_skill

Execute a saved skill:

result = await client.call_tool("run_skill", {
"name": "batch_uppercase",
"arguments": {
"input_dir": "/data/input",
"output_dir": "/data/output"
}
})

Connecting Clients

Python MCP Client

from mcp import Client

client = Client()
await client.connect("stdio://python -m agent_codemode.server")

# Search for tools
tools = await client.call_tool("search_tools", {"query": "read files"})

# Execute code
result = await client.call_tool("execute_code", {
"code": """
from generated.servers.filesystem import read_file
content = await read_file({"path": "/data/config.json"})
print(content)
"""
})

Claude Desktop Configuration

Add to your Claude Desktop config:

{
"mcpServers": {
"codemode": {
"command": "python",
"args": ["-m", "agent_codemode.server"],
"env": {
"CODEMODE_WORKSPACE": "/workspace"
}
}
}
}

From Another MCP Server

You can chain MCP servers - have one MCP server use Codemode as a client:

from mcp import Client

# In your MCP server, connect to Codemode
codemode = Client()
await codemode.connect("stdio://python -m agent_codemode.server")

# Use Codemode's code execution from your server
result = await codemode.call_tool("execute_code", {"code": "..."})

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│ MCP Client │
│ (Claude, custom agent, another MCP server) │
└────────────────────────────────┬────────────────────────────────────┘
│ MCP Protocol

┌─────────────────────────────────────────────────────────────────────┐
│ Codemode MCP Server │
│ ┌──────────────┐ ┌─────────────┐ ┌────────────────────────────┐ │
│ │ search_tools │ │execute_code │ │ save_skill / run_skill │ │
│ │ list_servers │ │ call_tool │ │ list_skills / delete_skill │ │
│ └──────────────┘ └─────────────┘ └────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────┤
│ Tool Registry │
│ (discovers tools from connected MCP servers) │
├─────────────────────────────────────────────────────────────────────┤
│ Code Executor (Sandbox) │
│ (runs Python code with generated tool bindings) │
└────────────────────────────────┬────────────────────────────────────┘
│ MCP Protocol

┌─────────────────────────────────────────────────────────────────────┐
│ Connected MCP Servers │
│ filesystem, github, slack, database, web, custom servers... │
└─────────────────────────────────────────────────────────────────────┘

Use Cases

1. Meta-Agent for Tool Composition

Build an agent that uses Codemode to intelligently compose tools:

User: "Analyze all Python files in /project and create a summary report"

Agent:
1. Calls search_tools("python file analysis")
2. Discovers filesystem and analysis tools
3. Writes code that reads files, analyzes them, generates report
4. Calls execute_code with the generated code

2. Unified Interface to Multiple Services

Combine multiple MCP servers into one code-first interface:

# Connect multiple specialized MCP servers
registry.add_server(MCPServerConfig(name="filesystem", ...))
registry.add_server(MCPServerConfig(name="github", ...))
registry.add_server(MCPServerConfig(name="slack", ...))
registry.add_server(MCPServerConfig(name="database", ...))

# Execute code that orchestrates all of them
await execute_code("""
# Read config, fetch from GitHub, query DB, notify Slack
config = await filesystem__read_file({"path": "/config.json"})
issues = await github__list_issues({"repo": "myorg/myrepo"})
users = await database__query({"sql": "SELECT * FROM users"})
await slack__send_message({"channel": "#updates", "text": f"Found {len(issues)} issues"})
""")

3. Building Reusable Workflows

Save complex multi-tool workflows as skills:

# Save a workflow as a skill
await save_skill({
"name": "deploy_and_notify",
"description": "Deploy to production and notify team",
"code": '''
async def deploy_and_notify(version):
await github__create_release({"tag": version})
await kubernetes__deploy({"image": f"myapp:{version}"})
await slack__send_message({"text": f"Deployed {version} 🚀"})
'''
})

# Later, run it
await run_skill({"name": "deploy_and_notify", "arguments": {"version": "1.2.3"}})

See Also