Unified Python library and CLI for orchestrating coding agents (Claude Code, Codex, etc.) with MCP tool servers and credential management.
Project description
caw
Coding Agent Wrapper — a Python library and CLI for orchestrating coding agents (Claude Code, Codex, opencode) with a unified interface, MCP tool servers, and credential management for Docker containers.
Install
pip install coding-agent-wrapper
Import caw:
import caw
For local development:
pip install -e .
Requires Python 3.10+.
Library: Unified Agent Interface
caw wraps multiple coding agent CLIs behind a single Agent / Session API. Swap providers without changing your code.
Quick start
from caw import Agent
agent = Agent() # defaults to claude_code
traj = agent.completion("Explain what this repository does")
print(traj.result)
print(f"{traj.usage.total_tokens} tokens, ${traj.usage.cost_usd:.4f}")
Multi-turn sessions
from caw import Agent
agent = Agent(provider="claude_code", model="opus", reasoning="high")
agent.set_system_prompt("You are a security reviewer.")
with agent.start_session() as session:
turn1 = session.send("Review src/auth.py for vulnerabilities")
print(turn1.result)
turn2 = session.send("Now check src/api.py")
print(turn2.result)
# session.end() called automatically, returns full Trajectory
Providers
| Provider | CLI | Provider name |
|---|---|---|
| Claude Code | claude |
claude_code |
| Codex | codex |
codex |
| opencode | opencode |
opencode |
Set via constructor, environment variable, or at runtime:
agent = Agent(provider="codex")
# or
os.environ["CAW_PROVIDER"] = "codex"
# or
agent.set_provider("codex")
MCP tool servers
Attach MCP servers so the agent can call external tools:
from caw import Agent, MCPServer
agent = Agent()
agent.add_mcp_server(MCPServer(
name="my_db",
command="python",
args=["-m", "my_mcp_server"],
))
ToolKit: declarative tool servers
Define tools as Python classes. caw spins up an HTTP MCP server automatically:
from caw import Agent, ToolKit, tool
class UserDB(ToolKit, server_name="user_db"):
def __init__(self):
self.users = ["Alice", "Bob"]
@tool(description="List all users")
async def list_users(self) -> str:
return ", ".join(self.users)
@tool(description="Add a user")
async def add_user(self, name: str) -> str:
self.users.append(name)
return f"Added {name}"
db = UserDB()
agent = Agent(system_prompt="You have access to a user database.")
agent.add_tool_server(db.as_server())
traj = agent.completion("Add Eve to the user database, then list all users")
Subagents
Register child agents that the parent can invoke as tools:
from caw import Agent, AgentSpec
reviewer = AgentSpec(
name="security_reviewer",
description="Reviews code for security issues",
system_prompt="You are a security expert. Review the given code.",
)
agent = Agent()
agent.add_subagent(reviewer)
traj = agent.completion("Review the auth module for vulnerabilities")
# Subagent trajectories are captured:
for sub in traj.subagent_trajectories:
print(f" subagent: {sub.agent}, {sub.num_turns} turns")
Data models
Every interaction produces a Trajectory with structured data:
Trajectory
├── agent, model, session_id, created_at
├── turns: list[Turn]
│ ├── input: str
│ ├── output: list[TextBlock | ThinkingBlock | ToolUse]
│ │ └── ToolUse.subagent_trajectory: Trajectory | None
│ ├── usage: UsageStats
│ └── duration_ms: int
├── usage: UsageStats (own)
└── total_usage: UsageStats (own + all nested subagents)
Sessions are persisted to JSONL in caw_data/ by default.
Environment variables
| Variable | Purpose |
|---|---|
CAW_PROVIDER |
Default provider (claude_code, codex) |
CAW_MODEL |
Default model name |
CAW_EFFORT |
Default reasoning effort (high, medium, low) |
CLI: caw auth — Credential Management for Docker Containers
Manages coding agent OAuth credentials so they stay in sync between your host and Docker containers. Supports Claude Code, Codex, and opencode. Host credential files are never modified — they are bind-mounted into the container at run time.
caw auth setup # snapshot configs, write mount manifest
caw auth status # token expiry, last modified, mount flags
docker run $(caw auth docker-flags) -v ./project:/work my-image
caw auth teardown # rm -rf ~/.caw/auth/ (host files untouched)
See caw/auth/README.md for details on how it works, container setup, and supported agents.
License
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 coding_agent_wrapper-0.1.4.tar.gz.
File metadata
- Download URL: coding_agent_wrapper-0.1.4.tar.gz
- Upload date:
- Size: 74.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae1b85ba5d761b7cf19a2c626de4354ce8b50c2ed1630460982f34689ec00121
|
|
| MD5 |
665309be104d7542d2e410b325443cfa
|
|
| BLAKE2b-256 |
e4f96dc32da95ec151fc5f88ef95e5ea6dfb44d9275183cfa9f6052b52d8d7cf
|
Provenance
The following attestation bundles were made for coding_agent_wrapper-0.1.4.tar.gz:
Publisher:
publish.yml on zzjas/caw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coding_agent_wrapper-0.1.4.tar.gz -
Subject digest:
ae1b85ba5d761b7cf19a2c626de4354ce8b50c2ed1630460982f34689ec00121 - Sigstore transparency entry: 1615890322
- Sigstore integration time:
-
Permalink:
zzjas/caw@526e4b8cc4f7b52c1e3f39c902b9b97c0b986e0b -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/zzjas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@526e4b8cc4f7b52c1e3f39c902b9b97c0b986e0b -
Trigger Event:
release
-
Statement type:
File details
Details for the file coding_agent_wrapper-0.1.4-py3-none-any.whl.
File metadata
- Download URL: coding_agent_wrapper-0.1.4-py3-none-any.whl
- Upload date:
- Size: 92.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
33bc635628f74e0f1367a5b67ef3bae856d9e447a20e525d7ecf35c35c6fe3a6
|
|
| MD5 |
e2c686ccba4ac5777d58663634d1e919
|
|
| BLAKE2b-256 |
111c2606d2888a1d7e2047369486c33e34b6a634cf83fc68fafa63d8728f4f0c
|
Provenance
The following attestation bundles were made for coding_agent_wrapper-0.1.4-py3-none-any.whl:
Publisher:
publish.yml on zzjas/caw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
coding_agent_wrapper-0.1.4-py3-none-any.whl -
Subject digest:
33bc635628f74e0f1367a5b67ef3bae856d9e447a20e525d7ecf35c35c6fe3a6 - Sigstore transparency entry: 1615890326
- Sigstore integration time:
-
Permalink:
zzjas/caw@526e4b8cc4f7b52c1e3f39c902b9b97c0b986e0b -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/zzjas
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@526e4b8cc4f7b52c1e3f39c902b9b97c0b986e0b -
Trigger Event:
release
-
Statement type: