The Python AI coding agent that works with any model.
Claude, GPT-4o, Gemini, Ollama, DeepSeek — one tool, any brain.
pip install clawpy # or: git clone + uv pip install -e .
clawpy login # use your Claude subscription (or set any API key)
clawpy # start coding with AI
Every AI coding agent locks you into one provider. ClawPy doesn't.
| ClawPy | Claude Code | Cursor | Aider | |
|---|---|---|---|---|
| Pure Python | Yes | TypeScript | Electron | Python |
| Multi-model (5 providers) | Yes | Claude only | OpenAI + Claude | Multi |
| Claude subscription login | Yes | Yes | No | No |
| Runs locally with Ollama | Yes | No | No | Yes |
| Plugin system | Yes | Yes | No | No |
| Background agents | Yes | Yes | No | No |
| Memory consolidation (dream) | Yes | Yes | No | No |
| MCP support | Yes | Yes | No | No |
| Dependencies | 3 | 200+ | Electron | 20+ |
mypy --strict |
Yes | No | No | No |
30 seconds to your first AI-powered code change:
# Install
git clone https://github.com/AIScienceStudio/clawpy.git && cd clawpy
uv venv && uv pip install -e .
# Authenticate (pick one)
clawpy login # Claude Pro/Max/Team subscription
export OPENAI_API_KEY=sk-... # or OpenAI
export GEMINI_API_KEY=AIza... # or Gemini
# Ollama needs no key — just have it running
# Run
clawpyThat's it. You're in.
ClawPy v0.1.0
/home/user/myproject
model: Opus 4.6 via anthropic
> Find the bug in auth.py and fix it
>> Read src/auth.py 3s
>> Grep "password" 4s
>> Edit src/auth.py 6s
Found the issue: the password hash comparison was using == instead
of hmac.compare_digest(), making it vulnerable to timing attacks.
Fixed it.
--- src/auth.py
+++ src/auth.py
@@ -42,1 +42,1 @@
- if stored_hash == computed_hash:
+ if hmac.compare_digest(stored_hash, computed_hash):
1,808in 65out $0.031
clawpy -p openai -m gpt-4o # OpenAI
clawpy -p gemini -m gemini-2.5-pro # Google (1M context!)
clawpy -p ollama -m llama3.1 # Local, free, private
clawpy -p deepseek -m deepseek-chat # DeepSeek V3
clawpy # Claude (default)Or switch mid-conversation:
> /model gemini-2.5-pro
model Gemini 2.5 Pro 1M context, multimodal
9 built-in tools
| Tool | What it does | Permission |
|---|---|---|
| Bash | Execute shell commands | Dynamic (safe commands auto-approved) |
| Read | Read files with line numbers | Read-only |
| Write | Write/create files | Workspace write |
| Edit | Search & replace with diff preview | Workspace write |
| Grep | Search contents (ripgrep) | Read-only |
| Glob | Find files by pattern | Read-only |
| ListFiles | List directory contents | Read-only |
| WebFetch | Fetch URL content | Requires approval |
| Agent | Spawn sub-agents (background OK) | Requires approval |
22 slash commands
| Command | Description |
|---|---|
/model [name] |
Pick a model or list all available |
/tasks [id] |
List running agents or view output |
/bg / /fg / /kill |
Background/foreground/kill agents |
/usage |
Claude subscription rate limits |
/status |
Session info, auth, cost |
/context |
Context window usage with breakdown |
/memory |
View, edit, add persistent memory |
/dream |
LLM-powered memory consolidation |
/plan |
Toggle read-only plan mode |
/resume |
Resume a previous session |
/plugin |
Install/manage plugins |
/agents |
List custom agent definitions |
/mcp |
Show MCP server configuration |
/login / /logout |
Claude subscription auth |
/clear / /compact |
Reset or compress conversation |
/help / /quit |
Help and exit |
Memory system with dream consolidation
Create a CLAWPY.md in your project root — the agent reads it automatically:
# Project: MyApp
- Django project with PostgreSQL
- Run tests with `pytest -x`
- Never modify vendor/ClawPy discovers memory files from your current directory up to root, plus global ~/.clawpy/CLAWPY.md.
Dream (/dream): LLM reviews your conversation and consolidates learnings into organized, persistent memory. Auto-dream triggers after 10+ turns if 24h have passed.
Background agents & parallel tasks
The LLM can spawn background agents that don't block:
> Analyze the codebase and fix the tests
[bg a0001] started: "Explore structure"
[bg a0002] started: "Fix tests"
While those run...
[bg a0001] >> Glob (5s)
[bg a0001] >> Read (8s)
[bg a0001] completed (15s, 4,200 tokens)
[bg a0002] >> Bash (20s)
[bg a0002] completed (23s, 6,100 tokens)
Manage with /tasks, /kill <id>, /fg <id>.
Plugin system
Install plugins from GitHub:
> /plugin install owner/repo-name
Cloning...
Installed my-plugin v1.0.0
Commands: my-plugin:build, my-plugin:deploy
Plugins can add: commands, agents, skills, hooks, MCP servers. Compatible with Claude Code plugin format.
Smart context management
Three layers prevent context overflow:
- Microcompact (70%) — clears old tool results automatically
- Auto-compact (90%) — LLM summarizes old messages, keeps last 10
- Token budget — stops if diminishing returns detected
Plus per-turn cost tracking: 1,808in 65out $0.031
User → CLI → Engine.run_turn()
├── Provider.stream() → SSE → StreamEvents
├── Consume stream → assistant Message
├── ToolCalls → permission → execute (concurrent if read-only)
├── Tool results → append → token budget check
└── Loop until done or compact needed
- 50+ source files, ~6,500 lines of typed Python
- 3 runtime deps: httpx, prompt-toolkit, rich (no SDK bloat)
mypy --strictpasses on all files- 57 tests covering types, config, tools, permissions, engine, SSE, OpenAI conversion
It's ~30 lines. Gemini, Ollama, and DeepSeek all inherit from the OpenAI provider:
class MyProvider(OpenAIProvider):
def __init__(self, cfg):
cfg.base_url = "https://my-api.com/v1"
super().__init__(cfg)
self._provider_name = "my-provider"
register("my-provider", lambda cfg: MyProvider(cfg))uv pip install -e ".[dev]"
uv run pytest tests/ -v # 57 tests
uv run mypy --strict src/ # 0 errors
uv run ruff check src/ # LintMIT