Python implementation of Cloudflare's Code Mode using Claude AI, pydantic-ai, and Anthropic Agent SDK
Project description
Claude Codemode ๐
A Python implementation of Cloudflare's Code Mode, enabling AI agents to write code that calls tools instead of directly invoking them. Built on pydantic-ai and Claude AI.
What is Claude Code Mode
Traditional Tool Calling Agents:
Input โ LLM โ loop(Tool Call โ Execute Tool โ Result โ LLM) โ output
Claude Code Mode Agent:
Input โ loop(Claude Codes w/ access to your tools) โ Execute Code โ output
Why it's better
Each time tool output is passed to the LLM, and output is introduced, it leaves some possibility of mistake. As the number of iterations your agent does n increases, the better Code Mode gets compared to traditional iterative tool calling agents.
LLMs are better at generating code files & verifying & running that code they generate than calling tools to create output.
How It Works
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Your Application โ
โ โ
โ agent = Agent('claude-sonnet-4-5-20250929') โ
โ โ
โ @agent.tool โ
โ def search_docs(query: str) -> list[database_rows]: ... โ
โ โ
โ @agent.tool โ
โ def analyze_blueprints(file_location: str) -> dict: ... โ
โ โ
โ @agent.tool โ
โ def report_blueprint(pdf_location: str) -> None: ... โ
โ โ
โ result = agent.codemode("verify structural integrity") โ
โ โ โ
โโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โ 1. Extract tools from agent
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Claude Codemode โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ 2. Generate agentRunner.py with tool definitions โ โ
โ โ โ โ
โ โ def search_docs(query: str) -> list[database_rows]: โ โ
โ โ """Search documentation, returns database rows.""" โ โ
โ โ "... implementation ..." โ โ
โ โ โ โ
โ โ def analyze_blueprints(file_location: str) -> dict: โ โ
โ โ """Analyze blueprints for issues.""" โ โ
โ โ "... implementation ..." โ โ
โ โ โ โ
โ โ def report_blueprint(pdf_location: str) -> None: โ โ
โ โ """Report a blueprint for failing standards.""" โ โ
โ โ "... implementation ..." โ โ
โ โ โ โ
โ โ def main(params: str = "verify structural integrity") โ โ
โ โ "TODO: Implement task using above tools" โ โ
โ โ pass โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Spawn Claude Code
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Claude Code โ
โ โ
โ Instructions: โ
โ "Implement the main() function to accomplish the task. โ
โ Use the provided tools by writing Python code." โ
โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Claude reads agentRunner.py โ โ
โ โ Claude writes implementation: โ โ
โ โ โ โ
โ โ def find_database_files_on_disk(database_row): โ โ
โ โ "Claude wrote this helper function!" โ โ
โ โ return database_row['file'].download().path โ โ
โ โ โ โ
โ โ def main(): โ โ
โ โ "Search docs - returns database rows" โ โ
โ โ database_rows = search_docs("structural integrity")โ โ
โ โ โ โ
โ โ "Analyze each blueprint and report failures" โ โ
โ โ analyses = [] โ โ
โ โ for row in database_rows: โ โ
โ โ file_path = find_database_files_on_disk(row) โ โ
โ โ result = analyze_blueprints(file_path) โ โ
โ โ analyses.append(result) โ โ
โ โ if not result.passes: โ โ
โ โ report_blueprint(file_path) โ โ
โ โ โ โ
โ โ return {"analyses": analyses} โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ 4. Execute agentRunner.py โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ python agentRunner.py โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Return result
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CodeModeResult โ
โ โ
โ { โ
โ "output": {...}, โ
โ "success": true, โ
โ "execution_log": "..." โ
โ } โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
More Specifically Why It's Better
This problem has a lot of elements of what an agent excels at: some ambiguity, needing to integrate pieces together, formatting a nice output.
I tried to also exemplify claude code's ability to figure out how to piece any two pieces of software together on the fly, it figures out here how to grab database_row['file'].download().path and puts that in a function. This is something that I feel like is more likely to be figured out by claude code rather than any other way to make a tool that would try to do the same.
As the amount of functions needed to be called by the agents becomes very large, then the amount of advantage that the Code Mode Agent has keeps increasing. The best LLM agents today can call tools in parallel, but it's difficult for them to call > 10 tools in parallel. They can call tools in serially, but after 20 iterations, they lose track of where they are even with a todo list.
With Code Mode Agent, you can call an essentially unlimited amount of functions provided to you by the original agent definition, without waiting for a ridiculous number of agent iterations because of for serial or parallel limitations of agents.
Installation
Install with support for your preferred agent framework:
# For pydantic-ai support
pip install claude-codemode[pydantic-ai]
# For Claude Agent SDK support
pip install claude-codemode[anthropic-sdk]
# For both
pip install claude-codemode[all]
Or install from source:
git clone https://github.com/ryx2/claude-codemode.git
cd claude-codemode
# Using pip
pip install -e ".[all]"
# Or using poetry (recommended for development)
poetry install --extras pydantic-ai
# Then run examples with: poetry run python examples/basic_example.py
Prerequisites
- Python 3.10+
- Claude Code CLI installed
- Anthropic API key set up for Claude Code
- Either
pydantic-aiorclaude-agent-sdk(installed via extras above)
Quick Start
Basic Usage
from pydantic_ai import Agent
from claude_codemode import codemode
# Create an agent with tools
agent = Agent('claude-sonnet-4-5-20250929')
@agent.tool
def get_weather(city: str) -> str:
"""Get weather for a city."""
return f"Weather in {city}: Sunny, 72ยฐF"
@agent.tool
def calculate_temp_diff(temp1: str, temp2: str) -> str:
"""Calculate temperature difference."""
import re
t1 = int(re.search(r'(\d+)', temp1).group(1))
t2 = int(re.search(r'(\d+)', temp2).group(1))
return f"{abs(t1 - t2)}ยฐF"
# Use codemode instead of run
result = codemode(
agent,
"Compare weather between San Francisco and New York"
)
print(result.output)
Using the Monkey-Patched Method
from pydantic_ai import Agent
import claude_codemode # This adds .codemode() to Agent
agent = Agent('claude-sonnet-4-5-20250929')
@agent.tool
def search_docs(query: str) -> str:
"""Search documentation."""
return f"Results for: {query}"
# Call codemode directly on the agent
result = agent.codemode("Search for authentication docs")
print(result.output)
Using Claude Agent SDK
import asyncio
from claude_agent_sdk import ClaudeSDKClient
import claude_codemode # This adds .codemode() to ClaudeSDKClient
async def main():
async with ClaudeSDKClient() as client:
# Register tools using the codemode extension
@client.register_codemode_tool
def search_docs(query: str) -> str:
"""Search documentation."""
return f"Results for: {query}"
@client.register_codemode_tool
def analyze_code(code: str) -> dict:
"""Analyze code for issues."""
return {"issues": [], "quality": "good"}
# Use codemode
result = await client.codemode(
"Search for authentication docs and analyze the examples"
)
print(result.output)
asyncio.run(main())
With Configuration
from claude_codemode import codemode, CodeModeConfig
config = CodeModeConfig(
verbose=True, # Print detailed logs
preserve_workspace=True, # Keep workspace for inspection
timeout=300, # 5 minute timeout
workspace_dir="/tmp/my-workspace" # Custom workspace location
)
result = codemode(agent, "Your complex task here", config=config)
Architecture
Components
claude_codemode/
โโโ core.py # Main CodeMode class and codemode() function
โโโ converter.py # Extracts and converts pydantic-ai tools
โโโ template.py # Generates agentRunner.py templates
โโโ runner.py # Manages Claude Code subprocess
โโโ types.py # Type definitions
Flow Diagram
User Code โ Extract Tools โ Generate Template โ Spawn Claude Code โ Execute โ Return Result
โ โ โ โ โ โ
Agent ToolConverter TemplateGenerator ClaudeCodeRunner agentRunner.py CodeModeResult
Advanced Examples
With Dependencies
from dataclasses import dataclass
from pydantic_ai import Agent, RunContext
@dataclass
class DatabaseContext:
connection_string: str
agent = Agent('claude-sonnet-4-5-20250929', deps_type=DatabaseContext)
@agent.tool
def query_db(ctx: RunContext[DatabaseContext], sql: str) -> list:
"""Execute database query."""
# Use ctx.deps.connection_string
return [{"id": 1, "name": "Alice"}]
deps = DatabaseContext("postgresql://localhost/mydb")
result = codemode(agent, "Get all users from database", deps=deps)
Complex Multi-Step Tasks
agent = Agent('claude-sonnet-4-5-20250929')
@agent.tool
def fetch_data(source: str) -> dict:
"""Fetch data from source."""
pass
@agent.tool
def transform_data(data: dict, rules: list) -> dict:
"""Transform data according to rules."""
pass
@agent.tool
def validate_data(data: dict) -> bool:
"""Validate transformed data."""
pass
@agent.tool
def store_data(data: dict, destination: str) -> bool:
"""Store data to destination."""
pass
# Code Mode handles the complex orchestration
result = codemode(
agent,
"""
Create an ETL pipeline:
1. Fetch data from 'api_source'
2. Transform using rules: ['normalize', 'deduplicate']
3. Validate the transformed data
4. If valid, store to 'warehouse'
5. Return success status and record count
"""
)
API Reference
codemode(agent, prompt, deps=None, config=None)
Execute an agent in code mode.
Parameters:
agent(Agent): The pydantic-ai agent with toolsprompt(str): Task description for Claudedeps(Any, optional): Dependencies for the agentconfig(CodeModeConfig, optional): Configuration options
Returns:
CodeModeResult: Result object with output, success status, and logs
CodeModeConfig
Configuration for codemode execution.
@dataclass
class CodeModeConfig:
workspace_dir: Optional[str] = None # Custom workspace directory
claude_code_path: str = "claude" # Path to Claude Code CLI
timeout: int = 300 # Execution timeout in seconds
verbose: bool = False # Enable detailed logging
preserve_workspace: bool = False # Keep workspace after execution
CodeModeResult
Result from codemode execution.
@dataclass
class CodeModeResult:
output: Any # The result from the agent
execution_log: str # Complete execution logs
success: bool # Whether execution succeeded
error: Optional[str] = None # Error message if failed
Comparison: Traditional vs Code Mode
Traditional Tool Calling
# Agent directly calls tools
result = agent.run("Compare weather in SF and NY")
# Behind the scenes:
# 1. LLM decides to call get_weather("San Francisco")
# 2. LLM decides to call get_weather("New York")
# 3. LLM decides to call calculate_difference(...)
# Limited by tool calling training data
Code Mode
# Agent writes code that calls tools
result = agent.codemode("Compare weather in SF and NY")
# Behind the scenes:
# 1. Claude sees available tools as Python functions
# 2. Claude writes: sf_weather = get_weather("San Francisco")
# 3. Claude writes: ny_weather = get_weather("New York")
# 4. Claude writes: diff = calculate_difference(sf_weather, ny_weather)
# Leverages extensive Python training data
Benefits
๐ฏ Better Tool Usage
Claude is trained on millions of Python examples and knows how to compose functions naturally.
๐ Complex Workflows
Multi-step tasks with conditionals, loops, and error handling become trivial.
๐ Easier Debugging
Generated Python code can be inspected, modified, and tested independently.
๐ More Reliable
Reduces errors from unfamiliar tool-calling formats.
๐ก Flexible
Claude can use Python's full capabilities (data structures, libraries, etc.)
Examples
See the examples/ directory for complete examples:
basic_example.py- Simple weather comparison with pydantic-aiadvanced_example.py- Complex ETL with dependenciesmonkey_patch_example.py- Usingagent.codemode()methodclaude_sdk_example.py- Using Claude Agent SDK with codemode
Run an example:
cd examples
python basic_example.py
# or for Claude SDK
python claude_sdk_example.py
Limitations
- Requires Claude Code CLI to be installed
- Spawns a subprocess for each codemode execution
- Tools must be serializable to Python source code
- Currently only supports Python tools (not TypeScript like Cloudflare's version)
Contributing
Contributions welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
MIT License - see LICENSE file for details.
Inspirations
- Cloudflare's blog post introducing the code mode concept
- Theo's t3 chat video for making me aware of this approach
- Early MCP implementation by jx-codes
Acknowledgments
- Inspired by Cloudflare's Code Mode
- Built on pydantic-ai
- Powered by Claude AI
Related Projects
- pydantic-ai - Data validation using Python type hints
- Claude Code - Official Claude CLI
- Anthropic Agent SDK - Agent development framework
Made with โค๏ธ by the Claude Codemode Contributors
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_codemode-0.1.4.tar.gz.
File metadata
- Download URL: claude_codemode-0.1.4.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
01ac7bfd7df29901390cf1b04cf0e4bcb691e17d93e11ae1625c3fdccb4e4c47
|
|
| MD5 |
23896795827c4111120ceec8524e9afe
|
|
| BLAKE2b-256 |
be9dd03a95babe32ff8067913d96d61001b5c4e6f6424bc2f3ccaef09d5b679a
|
File details
Details for the file claude_codemode-0.1.4-py3-none-any.whl.
File metadata
- Download URL: claude_codemode-0.1.4-py3-none-any.whl
- Upload date:
- Size: 16.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6092709255181c44d925d7b038659b087990dd8b6494a66bc45958dde219d879
|
|
| MD5 |
170028a455cb78c9c6271410d0ac9a74
|
|
| BLAKE2b-256 |
2f07ff1622e6de83f51c934e63c2cdaa71f89d54357c1fc21c67302a9f09bd85
|