A modular agent runtime extracted from Claude Code, rebuilt in Rust.
English | 简体中文 | 日本語 | 한국어 | Español | Français
- What is This
- Why Rebuild in Rust
- Design Goals
- Architecture
- Crate Overview
- Rust vs TypeScript
- Roadmap
- Project Structure
- Contributing
- References
- License
This project extracts the core runtime ideas from Claude Code and reorganizes them into a set of reusable Rust crates. It's not a line-by-line TypeScript translation — it's a clean-room redesign of the capabilities an agent truly depends on:
- Message Loop — driving multi-turn conversations
- Tool Execution — orchestrating tool calls with schema validation
- Permission Control — authorization before file/shell/network access
- Long-running Tasks — background execution with lifecycle management
- Context Compaction — keeping long sessions stable under token budgets
- Model Providers — unified interface for streaming LLM backends
- MCP Integration — extending capabilities via Model Context Protocol
Think of it as an agent runtime skeleton:
| Layer | Role |
|---|---|
| Top | A thin CLI that assembles all crates |
| Middle | Core runtime: message loop, tool orchestration, permissions, tasks, model abstraction |
| Bottom | Concrete implementations: built-in tools, MCP client, context management |
If the boundaries are clean enough, this can serve not only Claude-style coding agents, but any agent system that needs a solid runtime foundation.
Claude Code has excellent engineering quality, but it's a complete product, not a reusable runtime library. UI, runtime, tool systems, and state management are deeply intertwined. Reading the source teaches a lot, but extracting parts for reuse is nontrivial.
This project aims to:
- Decompose tightly coupled logic into single-responsibility crates
- Replace runtime constraints with trait and enum boundaries
- Transform "only works inside this project" implementations into reusable agent components
- Runtime first, product later. Prioritize solid foundations for Agent loop, Tool, Task, and Permission.
- Each crate should be self-explanatory. Names reveal responsibility, interfaces reveal boundaries.
- Make replacement natural. Tools, model providers, permission policies, and compaction strategies should all be swappable.
- Learn from Claude Code's experience without replicating its UI or internal features.
| Crate | Purpose | Derived From (Claude Code) |
|---|---|---|
agent-core |
Message model, state container, main loop, session | query.ts, QueryEngine.ts, state/store.ts |
agent-tools |
Tool trait, registry, execution orchestration | Tool.ts, tools.ts, tool service layer |
agent-tasks |
Long task lifecycle and notification mechanism | Task.ts, tasks.ts |
agent-permissions |
Tool call authorization and rule matching | types/permissions.ts, utils/permissions/ |
agent-provider |
Unified model interface, streaming, retry | services/api/ |
agent-compact |
Context trimming and token budget control | services/compact/, query/tokenBudget.ts |
agent-mcp |
MCP client, connection, discovery, reconnect | services/mcp/ |
tools-builtin |
Built-in tool implementations | tools/ |
claude-cli |
Executable entry point, assembles all crates | CLI layer |
agent-core — The foundation
Manages how a conversation turn starts, continues, and stops. Defines the unified message model, main loop, and session state. This is the bedrock of the entire system.
agent-tools — Tool definition & dispatch
Defines "what a tool looks like" and "how tools are scheduled." The Rust version avoids stuffing all context into one giant object — instead, tools only receive the parts they actually need.
agent-tasks — Background task runtime
Separating tool calls from runtime tasks is critical for supporting long commands, background agents, and completion notifications fed back into the conversation.
agent-permissions — Authorization layer
Controls what the agent can do, when it must ask the user, and when to refuse outright. Essential whenever agents read files, write files, or execute commands.
agent-provider — Model abstraction
Shields the system from differences between model backends. Unifies streaming output, retry logic, and error recovery.
agent-compact — Context management
Ensures long session stability. Not just "summarization" — applies different compression levels and budget controls based on context to prevent unbounded growth.
agent-mcp — MCP integration
Connects to external MCP services, bringing remote tools, resources, and prompts into the unified capability surface.
tools-builtin — Built-in tools
Implements the most commonly used tools, prioritizing file operations, shell commands, search, and editing — the basic operations any agent needs.
| TypeScript (Claude Code) | Rust Approach |
|---|---|
| Extensive runtime checks | Push checks into the type system |
| Context objects tend to grow unbounded | Smaller context / trait boundaries |
| Scattered callbacks and events | Unified, continuous event streams |
| Runtime feature flags | Compile-time feature gating where possible |
| UI and runtime tightly coupled | Runtime as an independent layer |
This isn't about Rust being "better" — it's about Rust being well-suited for locking down runtime boundaries. For a long-evolving agent system, such constraints are typically valuable.
- Set up
agent-core,agent-tools,agent-provider,agent-permissions - Implement basic
Bash,FileRead,FileWritetools - Deliver a minimal runnable CLI
Goal: A basic version that can chat, call tools, execute commands, and read/write files.
- Add
agent-tasksfor background tasks and notifications - Add
agent-compactfor long sessions and large result handling - Expand
tools-builtinwith editing, search, and sub-agent capabilities
Goal: Sessions that can last longer without becoming fragile due to oversized outputs or long-running tasks.
- Integrate
agent-mcp - Add plugin/skill loading capabilities
- Support SDK / headless usage for embedded scenarios
Goal: Not just a CLI, but a complete agent runtime that can be integrated into other systems.
rust-clw/
├── Cargo.toml # Workspace root — declares all crates and shared deps
├── Cargo.lock
├── crates/
│ ├── claude-cli/ # Binary entry point
│ │ └── src/main.rs # CLI args, REPL loop, provider/tool assembly
│ │
│ ├── agent-core/ # Message model, session state, agent main loop
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── message.rs # Role, ContentBlock, Message
│ │ ├── session.rs # SessionConfig, SessionState
│ │ ├── query.rs # Recursive agent loop (the "beating heart")
│ │ └── error.rs # AgentError enum
│ │
│ ├── agent-tools/ # Tool trait, registry, orchestrator
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── tool.rs # Tool trait, ToolOutput
│ │ ├── registry.rs # ToolRegistry — name → impl lookup
│ │ ├── orchestrator.rs # ToolOrchestrator — batch dispatch & permission
│ │ └── context.rs # ToolContext — minimal deps injected into tools
│ │
│ ├── agent-provider/ # Unified model provider abstraction
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── provider.rs # ModelProvider trait (complete + stream)
│ │ ├── request.rs # ModelRequest, RequestMessage, ToolDefinition
│ │ ├── response.rs # ModelResponse, StreamEvent, StopReason, Usage
│ │ └── anthropic.rs # Anthropic API impl with SSE stream parsing
│ │
│ ├── agent-permissions/ # Authorization layer
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── types.rs # PermissionMode, ResourceKind, PermissionDecision
│ │ ├── policy.rs # PermissionPolicy trait
│ │ └── rules.rs # RuleBasedPolicy — glob/prefix rule matching
│ │
│ ├── agent-tasks/ # Background task lifecycle
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── task.rs # Task trait, TaskState, TaskInfo, TaskNotification
│ │ └── manager.rs # TaskManager — register, track, notify, cancel
│ │
│ ├── agent-compact/ # Context compaction & token budget
│ │ └── src/
│ │ ├── lib.rs
│ │ ├── budget.rs # TokenBudget — window size, thresholds
│ │ └── strategy.rs # CompactStrategy trait, TruncateStrategy
│ │
│ ├── agent-mcp/ # MCP integration (Phase 3 placeholder)
│ │ └── src/
│ │ └── lib.rs # McpServerConfig type stub
│ │
│ └── tools-builtin/ # Built-in tool implementations
│ └── src/
│ ├── lib.rs # register_builtin_tools()
│ ├── bash.rs # BashTool — shell command execution
│ ├── file_read.rs # FileReadTool — read with optional line range
│ └── file_write.rs # FileWriteTool — write with auto mkdir
│
├── docs/
│ ├── assets/
│ │ ├── overview.svg # Project overview diagram
│ │ ├── architecture.svg # Architecture diagram
│ │ └── roadmap.svg # Roadmap diagram
│ └── i18n/
│ ├── README.zh-CN.md # 简体中文
│ ├── README.ja.md # 日本語
│ ├── README.ko.md # 한국어
│ ├── README.es.md # Español
│ └── README.fr.md # Français
│
├── ARCHITECTURE.zh-CN.md # Architecture analysis of Claude Code (TS)
├── CONTRIBUTION.md
├── README.md # English documentation (root)
└── LICENSE
claude-cli
├── agent-core
│ ├── agent-tools
│ │ ├── agent-permissions
│ │ └── agent-provider
│ ├── agent-provider
│ ├── agent-permissions
│ └── agent-compact
├── agent-tasks (independent — no core dependency)
├── agent-compact
├── tools-builtin
│ └── agent-tools
└── agent-mcp (Phase 3, currently standalone)
claude-cliis the only binary crate; everything else is a library. Eachagent-*crate is designed to be usable independently in other agent systems.
Contributions are welcome! This project is in its early design phase, and there are many ways to help:
- Architecture feedback — Review the crate design and suggest improvements
- RFC discussions — Propose new ideas via issues
- Documentation — Help improve or translate documentation
- Implementation — Pick up crate implementation once designs stabilize
Please feel free to open an issue or submit a pull request.
- ARCHITECTURE.zh-CN.md — Detailed teardown of Claude Code's TypeScript architecture
- Claude Code Official Docs
- Model Context Protocol
This project is licensed under the MIT License.
If you find this project useful, please consider giving it a ⭐