An AI-powered coding agent platform built in Rust. Connects to LLM providers (Anthropic, OpenAI, Google, and more) and exposes a TUI and HTTP API for autonomous code editing, shell execution, file management, and language server integration.
Alpha software — not production ready. quickcode is under active development. APIs, config formats, and storage schemas may change without notice between versions. We welcome early adopters and contributors — see Contributing below.
- Multi-turn AI conversations with full message history and per-session context
- ReAct-style agent loop — Reason → Act (tool calls) → Observe → repeat, up to 50 steps per message
- Session compaction — automatically summarises old messages when context window fills up
- Session forking, revert, and abort — branch conversations, undo agent steps, cancel in-flight runs
- Snapshot tracking — per-step git-based change tracking with diff/patch storage
| Tool | Description |
|---|---|
read |
Read files with optional line ranges |
write |
Write files with LSP diagnostics feedback |
edit |
In-place find-and-replace editing |
bash |
Shell command execution via PTY (real terminal emulation) |
glob |
File pattern matching (capped at 100 results) |
grep |
Ripgrep-powered content search (capped at 100 results) |
web_fetch |
Fetch a URL (5 MB cap, HTML-to-text extraction) |
web_search |
Web search via configured search provider |
apply_patch |
Apply unified diffs to files |
ask_user |
Request clarification from the user |
subtask |
Spawn a sub-agent session for parallel workloads |
todo_read / todo_write |
Manage a per-session task list |
lsp |
Language server operations (hover, go-to-definition, diagnostics) |
memory_write |
Store a key-value pair in session, project, or global memory |
memory_read |
Retrieve a stored memory entry |
memory_delete |
Delete a memory entry |
memory_list |
List memory entries, with optional wildcard key filter |
- Short-term (session) — key-value pairs tied to the current conversation, cleaned up automatically
- Long-term (project) — persist across all sessions for a project; injected into every session's system prompt
- Global — available in all projects; useful for user preferences and cross-project conventions
POST /project/init— scans your project, calls the LLM, and writes aQUICKCODE.mdto the project root; this file is automatically included in every future session's context
- Anthropic — Claude 3.5 / Claude 3 family (most complete support)
- OpenAI — GPT-4o, GPT-4, o-series reasoning models
- Google — Gemini 1.5 / 2.0 family
- OpenRouter — unified access to 200+ models
- Azure OpenAI — Azure-hosted deployments
- Model catalog auto-fetched from models.dev and cached locally
- Model variant selection — picks the largest context window available for a given model
- Rule-based allow / deny / ask per tool and file-path pattern (wildcard)
- Global config → session-level → agent-level rule merging
- Doom-loop detection — stops an agent repeating the same tool call 3+ times in a row
- SQLite database at
~/.local/share/quickcode/quickcode.db - Tables:
project,session,message,part,todo,permission,memory - Per-session token/cost tracking
- HTTP API (axum) with SSE event streaming and optional WebSocket
- Basic auth — password-protected server via
QUICKCODE_SERVER_PASSWORD - Workspace support — multi-tenant isolation via
?workspace=orX-quickcode-Workspaceheader - MCP server — exposes quickcode tools over the Model Context Protocol (stdio)
- OpenAPI doc endpoint at
GET /doc
- TUI — ratatui-based terminal UI with chat, welcome screen, markdown rendering
- LSP client — JSON-RPC language server integration with push-diagnostics (
textDocument/publishDiagnostics) - Config — JSONC (comments + trailing commas),
{env:VAR}and{file:path}substitutions - Session sharing — stable share URLs via
POST /session/:id/share - VCS — git diff and status endpoints
quickcode is alpha software. Here is what that means in practice:
- The core agent loop, tool execution, and session persistence work reliably.
- Incoming breaking changes: we are actively redesigning several subsystems (MCP client integration, LSP wiring, plugin API, config schema). Breaking changes will happen without a deprecation period until we reach v1.0.
- The HTTP API is not yet considered stable; field names and response shapes may change.
- The TUI is functional but minimal — UI polish is planned.
- Windows support is untested. macOS and Linux are the primary targets.
We tag releases with 0.x.y and document breaking changes in the commit log.
- Rust 1.75+ (
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh) git(for VCS and snapshot features)- An API key for at least one LLM provider
git clone https://github.com/your-org/quickcode
cd quickcode
cargo build --releaseThe binary will be at target/release/quickcode.
Optionally add it to your PATH:
cp target/release/quickcode ~/.local/bin/quickcodeSet your API key in the environment (or in the config file):
export ANTHROPIC_API_KEY=sk-ant-... # Claude
export OPENAI_API_KEY=sk-... # GPT-4o
export GOOGLE_API_KEY=... # GeminiOptionally create a config file at ~/.config/quickcode/config.jsonc:
Run this once to generate a QUICKCODE.md file in your project root. It will be automatically included in every future agent session as project context:
curl -X POST "http://localhost:4096/project/init?directory=$(pwd)"Or from the TUI, type /init (if the command is wired to a slash command).
# In your project directory:
quickcode
# Or specify a directory:
quickcode --dir /path/to/projectquickcode serve --port 4096The API will be available at http://localhost:4096.
quickcode [OPTIONS] [COMMAND]
Commands:
run Start in TUI mode (default)
serve Start HTTP server only
Options:
-d, --dir <DIR> Working directory [default: current dir]
-p, --port <PORT> HTTP server port [default: 4096]
--log-level <LEVEL> Log level [default: info]
-h, --help Print help
-V, --version Print version
The server exposes a REST API on port 4096 (configurable). All events are also available via SSE on GET /event.
| Method | Path | Description |
|---|---|---|
GET |
/session |
List sessions (filter by ?projectId=, ?workspace=, ?archived=) |
POST |
/session |
Create a session |
GET |
/session/:id |
Get a session |
DELETE |
/session/:id |
Delete a session |
PATCH |
/session/:id |
Update title or permission rules |
POST |
/session/:id/chat |
Send a message — returns SSE stream |
POST |
/session/:id/compact |
Trigger manual compaction |
POST |
/session/:id/abort |
Abort the running agent |
POST |
/session/:id/fork |
Fork a session |
POST |
/session/:id/revert |
Revert to a previous message |
POST |
/session/:id/share |
Generate a stable share URL |
GET |
/session/:id/message |
List messages (with cursor pagination) |
GET |
/session/:id/stats |
Token and cost summary |
| Method | Path | Description |
|---|---|---|
GET |
/project |
List all projects |
GET |
/project/current |
Get/create project for a directory |
PATCH |
/project/:id |
Update project metadata |
POST |
/project/init |
Analyse project and write QUICKCODE.md |
POST |
/project/git/init |
Initialise a git repository |
GET /provider List all providers and auth status
GET /provider/:id/models List models (from cache)
POST /provider/:id/validate Validate credentials
PUT /auth/:provider_id Set provider API key
GET /permission List project permission rules
POST /permission Add a rule
DELETE /permission/:id Delete a rule
GET /permission/request List pending permission prompts
POST /permission/request/:id Respond to a prompt (allow/deny)
GET /event → SSE stream of all bus events (no auth required)
GET /ws → WebSocket alternative
src/
├── main.rs # CLI entry point (clap)
├── lib.rs # Module declarations
├── errors.rs # Unified error types (thiserror)
├── bus.rs # In-process pub/sub event bus (tokio broadcast)
├── instance.rs # Per-directory instance management
├── vcs.rs # Git integration (worktree, diff, init)
├── mcp.rs # MCP server (tools over stdio)
├── agents/ # Built-in agent definitions and system prompts
├── config/ # JSONC config loading, merging, substitutions
├── lsp/ # JSON-RPC LSP client with push-diagnostics
├── models/ # All data model structs (serde)
├── permission/ # Rule-based permission system, doom-loop detection
├── provider/ # LLM provider abstraction
│ ├── anthropic.rs # Claude streaming
│ ├── openai.rs # GPT / o-series streaming
│ ├── google.rs # Gemini streaming
│ ├── models_cache.rs # models.dev catalog cache
│ └── message_convert.rs
├── server/ # axum HTTP API
│ └── routes/ # session, project, provider, permission, event, ws, …
├── session/ # Session lifecycle, ReAct agent loop, compaction
├── snapshot/ # Git-based change snapshots and patch generation
├── storage/ # SQLite CRUD (sqlx) — project, session, message, memory, …
├── tools/ # Tool implementations
│ ├── read.rs write.rs edit.rs bash.rs
│ ├── glob_tool.rs grep_tool.rs
│ ├── web_fetch.rs web_search.rs
│ ├── apply_patch.rs ask_user.rs
│ ├── subtask.rs lsp_tool.rs
│ ├── todo_tool.rs memory.rs
│ └── mod.rs # ToolRegistry, ToolContext
└── tui/ # ratatui terminal UI
The SQLite database is stored at:
~/.local/share/quickcode/quickcode.db(default)$QUICKCODE_HOME/quickcode.db(if env var is set)
Tables: project, session, message, part, todo, permission, memory
Config files (JSONC) are loaded in priority order — later overrides earlier:
~/.config/quickcode/config.jsonc(global)~/.quickcode/quickcode.jsonc(home-level override).quickcode/quickcode.jsonc(project-local, walks up to git root)$QUICKCODE_CONFIG_DIR/quickcode.jsonc(env override)
| Variable | Default | Description |
|---|---|---|
ANTHROPIC_API_KEY |
— | Anthropic API key |
OPENAI_API_KEY |
— | OpenAI API key |
GOOGLE_API_KEY |
— | Google Gemini API key |
QUICKCODE_HOME |
~/.local/share/quickcode |
Data directory |
QUICKCODE_SERVER_PASSWORD |
— | Enable HTTP Basic Auth |
QUICKCODE_SERVER_USERNAME |
quickcode |
Basic Auth username |
QUICKCODE_MODELS_URL |
https://models.dev |
Model catalog URL |
QUICKCODE_MODELS_PATH |
— | Override catalog with a local JSON file |
QUICKCODE_DISABLE_MODELS_FETCH |
— | Skip model catalog fetch |
QUICKCODE_CONFIG_DIR |
— | Extra config directory |
RUST_LOG |
info |
Log level (debug, info, warn, error) |
# Run all tests
cargo test
# Check for compile errors without building
cargo check
# Run with debug logging
RUST_LOG=debug cargo run -- serve
# Run a specific test
cargo test memory_write_and_readThere are currently 90 integration tests covering tool execution, permission enforcement, storage CRUD, session lifecycle, and memory scoping.
quickcode is an open project and we actively welcome contributions. Here is how to get started:
- MCP client — consuming external MCP servers (not just exposing our own)
- Plugin API stability — formalising the plugin lifecycle
- TUI improvements — syntax highlighting, diff viewer, better keybindings
- Config schema v2 — cleaner separation of global vs. project config
- Windows support — PTY and path handling for Windows
- More provider coverage — Mistral, Cohere, local Ollama
If you want to work on any of these, open an issue first so we can coordinate.
-
Fork the repository and create a feature branch:
git checkout -b feat/your-feature
-
Make your changes. Keep commits focused — one logical change per commit.
-
Add or update tests. All new behaviour should be covered by tests in the relevant
mod testsblock. Runcargo testbefore submitting. -
Check for warnings:
cargo clippy -- -D warnings cargo fmt --check
-
Open a pull request against
main. Describe what you changed and why. Link any related issues.
- Keep PRs small. A focused 200-line PR is much easier to review than a 2000-line one.
- No
unsafewithout discussion. Open an issue first if you thinkunsafeis the right tool. - Match the existing code style. We use
rustfmtdefaults. Runcargo fmtbefore pushing. - Test coverage matters. Bug fixes should include a regression test. New tools/features should include integration tests.
- Breaking changes need a note. If your PR changes the HTTP API, config schema, or storage format, say so explicitly in the PR description.
Open a GitHub issue with:
- quickcode version (
quickcode --version) - OS and Rust version (
rustc --version) - Steps to reproduce
- Expected vs. actual behaviour
- Relevant log output (
RUST_LOG=debug quickcode serve 2>&1)
Open a GitHub Discussion or an issue tagged question. We are happy to help.
MIT — see LICENSE for details.
{ // Default model ("provider/model_id") "model": "anthropic/claude-3-5-sonnet-20241022", // Permission rules — last-match-wins "permission": [ { "permission": "bash", "pattern": "*", "action": "allow" } ], // Agent-specific overrides "agent": { "build": { "model": "openai/gpt-4o", "temperature": 0.5 } } }