- Hooks ([[hooks]]): pre_tool, post_tool, user_prompt, stop; sandboxed, exit 2 blocks - @file mentions with autocomplete; mentioned files/folders are attached to the prompt - Session full-text search in the sidebar, fork into a copy, export as Markdown/JSON - Chat follows the newest message until the user scrolls up; jump-to-latest button - SVG activity spark and thinking icon instead of Unicode/emoji glyphs - File search ranks name matches first and returns relative paths Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CodeCraft
A self-hosted coding agent for your browser: any model, your tools, your rules.
Run Claude, Gemini, opencode Go, fal.ai or your own models as coding agents with files, shell, MCP and subagents,
approve what they do from any device, and see exactly what every request costs.
How it works · Modes · Models · Users · Statistics · Get started · Configuration · Themes · Development · Status
A session: the agent works through its task list, shows diffs, and asks before anything outside the rules.
🧠 Any modelAnthropic natively, plus everything that speaks the OpenAI API: Gemini, opencode Go, fal.ai, OpenRouter, Ollama, vLLM, llama.cpp. Mix them in one chat. |
🛠️ Real toolsRead, write, edit, glob, grep, shell, web fetch, task lists, subagents, skills – and every tool of your MCP servers. |
🙋 You decidePermission requests with diffs, questions from agents and MCP servers, per-tool rules. On your phone, with notifications. |
📊 Every token countedTokens, cache hits, prefill and output speed, and cost per request – per chat and in a dashboard. |
How it works
CodeCraft runs on your server, next to your projects. You talk to it from a browser or the installed app; the agent keeps working when you close the tab.
- Pick a folder and a mode. Every user has their own folder; admins can share more.
- Say what you want. The agent plans with a task list, reads the code and makes changes.
- Approve or answer. Anything outside your rules shows up as a card: allow once, allow for the session, or reject with feedback. Questions from agents and MCP servers too.
- Delegate. The agent hands work to subagents – in parallel or in the background, on other models and hosts – and continues while they run.
![]() Mobile: answer questions and approve changes from your phone. |
![]() Settings: providers, models, prices, MCP, permissions and users – all in the UI. |
Modes
| Mode | What it does |
|---|---|
| build | Full access: implement, edit, run. |
| plan | Read-only: investigate, ask, and propose a step-by-step plan. One click switches to build. |
| craft | Study a target, build your own version, check it visually, refine. Websites are captured at several screen widths in a headless browser and compared with the build (similarity per page and width). Clean room uses only what a visitor sees; deep mode may read the page source. |
| custom | Your own modes and subagents – in the UI, the config file or as Markdown in .codecraft/agents / .claude/agents. |
Projects keep working the way they do in Claude Code and opencode: AGENTS.md, CLAUDE.md,
slash commands in .claude/commands and skills in .claude/skills are picked up automatically.
Models
Every provider is an endpoint with a list of models. Each model can have a context size, output limit, reasoning effort, extra request options and prices per million tokens.
- Several models per chat: switch the model at any time, give modes a fixed model, and run subagents on other models – e.g. a coding model on one GPU host and a small model that writes documentation and translations in the background on another.
- Concurrency limits:
max_concurrencyper host or model queues requests for servers that can only process one at a time;max_parallellimits instances of a subagent. Waiting time is shown in the chat and never counted as model latency. - Background subagents: the agent starts them with
background = true, keeps working, and receives their result as a message when they finish.
Users
- Local accounts (Argon2 passwords) and single sign-on via OpenID Connect (Authentik, Authelia, Keycloak, …) with optional admin and access groups.
- Admins manage providers, MCP, permissions, users and shared folders and see all statistics. Users see their own sessions and statistics.
- Every user works in
<workspace>/<username>; admins can share additional folders with selected users. Sessions are private and can be shared read-only.
Note
File tools are confined to a user's folders. Shell commands run in the shared container and are not sandboxed per user – only give accounts to people you trust with that container.
Statistics
Every model request is stored with input, output and cache tokens, time to first token, prefill and output speed, and its cost at the price configured at that moment. The dashboard shows totals, cost per day by model, tokens per day, a weekday × hour heatmap, and tables per model, provider, mode, user and session – each chart also as a table.
Get started
git clone <this repository> codecraft && cd codecraft
cp .env.example .env # workspace path, provider keys, optional first admin
docker compose up -d --build
docker compose logs codecraft # shows the one-time setup code for the first admin
All state – configuration, database, the agent's home directory – lives in the Docker volume
codecraft-data; rebuilding or recreating the container keeps it. Your projects are mounted
from WORKSPACE.
The port is bound to 127.0.0.1 by default. Put a TLS reverse proxy in front of it (enable
WebSocket support) and set auth.public_url – installing the PWA requires HTTPS.
Configuration
One commented TOML file, /data/config.toml in the volume, created from
config.example.toml on first start. The settings page edits it in
place and keeps your comments. Secrets belong in the environment and are referenced as
${NAME}.
| Section | Purpose |
|---|---|
[server] |
workspace, default and small model, currency, auto-compaction, subagent limit |
[providers.<name>] |
kind = "anthropic" | "openai", base_url, api_key, max_concurrency, models |
[mcp.<name>] |
type = "stdio" (command, args, env) or "http" (url, headers) |
[permissions] |
allow / ask / deny per tool (globs like mcp__*); bash_rules for commands |
[agents.<name>] |
modes and subagents: model, tools, max_parallel, prompt |
[auth], [auth.oidc] |
sign-in, public URL, single sign-on |
[craft] |
headless browser, screen widths, clean room |
Compound shell commands (&&, ;, |) are only auto-allowed when every part is allowed.
Themes
Pick a base theme in Settings → Interface and switch light / dark / auto there or with
the ◐ button in the sidebar (auto follows the system preference). Every base theme has a dark and
a light variant. The palettes come from zink/trilium-themes
(MIT, see web/src/themes/LICENSE-trilium-themes), which
in turn are based on:
| Theme | Variants | Palette source | License |
|---|---|---|---|
| Gruvbox | Dark, Light | morhetz/gruvbox | MIT |
| Ash | Dark, Light | original, Gruvbox-derived (zink/trilium-themes) | MIT |
| Harbor | Dark, Light | HANCORE-linux/omarchy-harbordark-theme | MIT |
| Coffee | Dark, Latte | megabyte0x/omarchy-coffee-theme | MIT |
| Solarized | Dark, Light | Solarized by Ethan Schoonover | MIT |
| Tokyo Night | Night, Day | folke/tokyonight.nvim | Apache-2.0 |
Further standard themes (palettes re-created from the published colour specifications):
| Theme | Variants | Palette source | License |
|---|---|---|---|
| Nord | Dark, Light (Snow Storm background) | nordtheme/nord | MIT |
| VS Code | Dark Modern, Light Modern | microsoft/vscode | MIT |
| GitHub | Dark, Light | primer/github-vscode-theme | MIT |
| Catppuccin | Mocha, Latte | catppuccin/catppuccin | MIT |
| One | One Dark, One Light | atom/atom | MIT |
| Dracula | Dracula, Alucard | dracula/dracula-theme | MIT |
| Rosé Pine | Main, Dawn | rose-pine/rose-pine-theme | MIT |
| Everforest | Dark, Light | sainnhe/everforest | MIT |
| Kanagawa | Wave, Lotus | rebelot/kanagawa.nvim | MIT |
Colours, syntax highlighting and chart palettes come from CSS variables, one file per variant in
web/src/themes. To add a base theme <id>:
- Copy
gruvbox-dark.css/gruvbox-light.cssto<id>-dark.css/<id>-light.cssand change the values on:root[data-theme="<id>-dark"]/"<id>-light"; note source and license in the header. - Import both in
themes/index.tsand add the base theme toTHEMESinweb/src/theme.ts.
The variables cover surfaces (--bg0–--bg3), text (--fg0–--fg3, --muted), accents,
diffs, syntax (--syntax-*) and the browser bar colour (--theme-color). The chart palettes
(--series-1–8 categorical, --seq-1–6 sequential) live in themes/base.css per light/dark
mode and are validated for colour-vision deficiencies.
Development
Requirements: Rust (edition 2024) and Node ≥ 20.19.
# backend – writes ./data/config.toml on first start
cd server && CODECRAFT_CONFIG=../data/config.toml cargo run
# frontend with hot reload, proxies /api to 127.0.0.1:8787
cd web && npm install && npm run dev
Tests: cd server && cargo test · type check: cd web && npx tsc --noEmit.
server/ Rust (axum, tokio)
runner.rs agent loop: streaming, tools, permissions, subagents, compaction
provider/ Anthropic and OpenAI-compatible streaming clients, concurrency slots
tools/ built-in tools (files, shell, web, agent, craft)
mcp.rs MCP client (stdio, Streamable HTTP, elicitation)
auth.rs users, sessions, OpenID Connect
prompts.rs modes, system prompt, AGENTS.md, commands, skills
web/ React + Vite PWA
src/components chat, composer, cards, settings, statistics
src/themes CSS themes
src/i18n English (reference) and German
Translations: copy web/src/i18n/en.ts, translate the values and register the language in
web/src/i18n/index.ts – the type checker reports missing keys.
Status
Early alpha. Planned next:
- Per-user sandboxes for shell commands
- File checkpoints and undo, background shells,
@filementions - MCP OAuth, resources and prompts
- Hooks before/after tool calls
- Image generation tools (fal.ai) and the OpenAI Responses API


