Skip to main content
codemode

Code Mode enables AI agents to interact with MCP tools through code execution instead of direct tool calls. Based on research from Anthropic and Cloudflare, this approach reduces context consumption by up to 98.7% for complex workflows.

Quick Start

from mcp_use import MCPClient

client = MCPClient(config="config.json", code_mode=True)
await client.create_all_sessions()

result = await client.execute_code("""
# Discover tools
tools = await search_tools("github")

# Call tools as functions
pr = await github.get_pull_request(owner="facebook", repo="react", number=12345)

return {"title": pr["title"]}
""")

Why Code Mode?

Traditional MCP clients load all tool definitions upfront and pass intermediate results through the model context. This creates two problems:
  1. Tool definitions overload context - 150+ tools = 150,000+ tokens before processing any request
  2. Intermediate results consume tokens - Each tool result flows through the model, even when just passing data between tools
Code Mode solves both by having agents write code that executes in a separate environment.

Key Advantages

1. Progressive Disclosure

Agents load only the tools they need, when they need them:
result = await client.execute_code("""
# Search for relevant tools instead of loading all upfront
github_tools = await search_tools("github pull request")

# Only the 3 PR-related tools are loaded, not all 150+ tools
pr = await github.get_pull_request(...)
""")
Benefit: 2,000 tokens instead of 150,000 tokens (98.7% reduction)

2. Context-Efficient Tool Results

Large datasets are processed in the execution environment before returning to the agent:
result = await client.execute_code("""
# Fetch 10,000 rows
all_issues = await github.list_issues(owner="microsoft", repo="vscode")
print(f"Processing {len(all_issues)} issues")

# Filter locally (doesn't consume agent context)
critical = [i for i in all_issues if 'critical' in str(i.get('labels'))]

# Return only summary, not 10,000 rows
return {
    "total": len(all_issues),
    "critical": len(critical),
    "top_5": critical[:5]
}
""")
Benefit: Agent sees 5 issues instead of 10,000

3. More Powerful Control Flow

Loops, conditionals, and error handling use familiar code patterns instead of chaining individual tool calls:
result = await client.execute_code("""
# Poll for deployment notification
found = False
attempts = 0

while not found and attempts < 10:
    messages = await slack.get_channel_history(channel='C123456')
    found = any('deployment complete' in m.text for m in messages)

    if not found:
        await asyncio.sleep(5)
        attempts += 1
        print(f"Attempt {attempts}: waiting...")

return {"found": found, "attempts": attempts}
""")
Benefit: More efficient than alternating between tool calls and sleep commands through the agent loop

4. Privacy-Preserving Operations

Intermediate results stay in the execution environment by default:
result = await client.execute_code("""
# Fetch customer data with PII
customers = await crm.get_customer_list()

# Process PII locally - never enters model context
for customer in customers:
    await salesforce.update_record(
        objectType='Lead',
        recordId=customer['id'],
        data={'Email': customer['email'], 'Phone': customer['phone']}
    )
    print(f"Updated customer {customer['id']}")

# Return only count, not PII data
return {"updated": len(customers)}
""")
Benefit: Sensitive data flows through the workflow without entering the model’s context

Real-World Example: File System Exploration

This example demonstrates how Code Mode dramatically simplifies complex workflows. An agent tasked with “list files and rename them” performs the entire operation efficiently.
Code Mode in Action

Discovery: Finding the Right Tools

The agent starts by searching for filesystem tools:
# Agent calls search_tools
tools = await search_tools('filesystem list')
Result (16 filesystem tools found)
[
  {"name": "list_directory", "server": "filesystem"},
  {"name": "list_directory_with_sizes", "server": "filesystem"},
  {"name": "move_file", "server": "filesystem"},
  {"name": "read_file", "server": "filesystem"},
  ...
]
Code Mode Advantage: The agent discovered 16 tools using ~200 tokens, compared to ~8,000+ tokens if all filesystem tool definitions were pre-loaded into the system prompt.

Execution: Processing Files Efficiently

The agent writes a single Python script to complete the task:
# Agent-generated code
# 1. List files
files_str = await filesystem.list_directory_with_sizes(path="/path/to/folder")

# 2. Parse and filter locally (doesn't consume LLM context)
lines = files_str.strip().split('\n')
file_list = [line for line in lines if line.startswith('[FILE]')]

# 3. Rename files using move_file
for file_line in file_list:
    filename = file_line.split()[1]  # Extract filename
    if '_example' not in filename:
        source = f"/path/to/folder/{filename}"
        # Split extension
        name, ext = filename.rsplit('.', 1)
        dest = f"/path/to/folder/{name}_example.{ext}"
        await filesystem.move_file(source=source, destination=dest)

# 4. Return summary, not raw data
return {"renamed": len(file_list), "total_files": len(lines)}

Efficiency Comparison

MetricWithout Code ModeWith Code ModeImprovement
Tool Calls18 (1 list + 1 move × 17 files)1 (execute_code)94% fewer
Context Tokens~25,000 (tool defs + results)~1,500 (meta tools)94% reduction
Latency18 round trips1 execution17x faster
By writing code instead of chaining tool calls, the agent processed the file list locally and only returned the summary. This avoided passing the raw directory listing (and each rename confirmation) through the LLM context.

API Reference

MCPClient

__init__(code_mode=True)

client = MCPClient(
    config="config.json",
    code_mode=True  # Enable code execution mode
)

execute_code(code: str, timeout: float = 30.0)

Execute Python code with MCP tool access. Returns:
{
    "result": Any,           # Return value
    "logs": list[str],       # Captured print()
    "error": str | None,     # Error if failed
    "execution_time": float  # Seconds
}

search_tools(query: str = "", detail_level: str = "full")

Search available tools across all servers. Detail levels: "names", "descriptions", "full"

What’s Available in Code

Functions

  • search_tools(query, detail_level) - Discover tools
  • server.tool_name(**kwargs) - Call any MCP tool
  • __tool_namespaces - List of server names
Note: Tool names are automatically sanitized to be valid Python identifiers. For example, a tool named list-files becomes list_files.

Builtins

# Data: list, dict, set, tuple, str, int, float, bool
# Iteration: range, enumerate, zip, map, filter
# Aggregation: len, sum, min, max, sorted, any, all
# Async: asyncio
# Exceptions: Exception, ValueError, TypeError, etc.
Restricted: import, open, eval, file I/O

Performance

From Anthropic’s research:
TraditionalCode ModeImprovement
150,000+ tokens (tool defs)2,000 tokens98.7% reduction
16 API iterations1 execution88% fewer calls
All results in contextOnly summary68% fewer tokens

Examples

Tool Chaining

result = await client.execute_code("""
pr = await github.get_pull_request(owner="facebook", repo="react", number=12345)

if pr['state'] == 'open':
    await slack.post_message(
        channel="#dev",
        text=f"PR needs review: {pr['title']}"
    )
    return {"notified": True}

return {"notified": False}
""")

Data Processing

result = await client.execute_code("""
files = await filesystem.list_directory(path="/private/tmp")
lines = files.strip().split('\\n')

dirs = [l for l in lines if l.startswith('[DIR]')]
files_only = [l for l in lines if l.startswith('[FILE]')]

return {
    "total": len(lines),
    "directories": len(dirs),
    "files": len(files_only)
}
""")

Error Handling

result = await client.execute_code("""
try:
    data = await api.fetch_data(id="123")
    return {"success": True, "data": data}
except Exception as e:
    print(f"Failed: {e}")
    return {"success": False, "error": str(e)}
""")

Agent Integration

Agents only see 2 tools when code_mode=True:
  • execute_code - Execute Python code with tool access
  • search_tools - Discover available tools
All other MCP tools are accessible within code execution.
from mcp_use import CODE_MODE_AGENT_PROMPT

system_prompt = f"""
{CODE_MODE_AGENT_PROMPT}

Additional instructions...
"""

References

See Also