- User management: local accounts (Argon2) and OpenID Connect, admin/user roles, per-user folders plus admin-shared folders, read-only session sharing, event filtering per user - File manager with CodeMirror editor and git client (status, diff, stage, commit, branches, fetch/pull/push, log, clone/init) - Image generation via fal.ai: generate_image tool and image page - Budgets: monthly limits per provider, provider balances/costs (OpenRouter, Anthropic admin cost report, fal.ai), price discovery - Subagents on other models, background tasks, concurrency limits per host/model/subagent - MCP tools loaded on demand (mcp_search/mcp_call), read-only hints - Permission mode "auto", safe read-only commands always allowed - Persistent message queue with attachments, deletable - Live reasoning incl. <think> tags, activity animations, CSS themes, mobile layout, statistics per user, upload size handling - Docker: named volume for state, localhost-bound port Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
227 lines
10 KiB
Markdown
227 lines
10 KiB
Markdown
<p align="center">
|
||
<img src="web/public/icon.svg" width="112" height="112" alt="CodeCraft icon: angle brackets with a slash on a dark tile">
|
||
</p>
|
||
|
||
<h1 align="center">CodeCraft</h1>
|
||
|
||
<p align="center">
|
||
<b>A self-hosted coding agent for your browser: any model, your tools, your rules.</b><br>
|
||
Run Claude, Gemini, opencode Go, fal.ai or your own models as coding agents with files, shell, MCP and subagents,<br>
|
||
approve what they do from any device, and see exactly what every request costs.
|
||
</p>
|
||
|
||
<p align="center">
|
||
<img alt="Rust backend" src="https://img.shields.io/badge/backend-Rust-b7410e?style=flat-square&logo=rust">
|
||
<img alt="React PWA" src="https://img.shields.io/badge/frontend-React%20PWA-2d81ff?style=flat-square&logo=react">
|
||
<img alt="Docker" src="https://img.shields.io/badge/deploy-Docker-1d63ed?style=flat-square&logo=docker&logoColor=white">
|
||
<img alt="Status: early alpha" src="https://img.shields.io/badge/status-early%20alpha-d69e2e?style=flat-square">
|
||
</p>
|
||
|
||
<p align="center">
|
||
<a href="#how-it-works">How it works</a> ·
|
||
<a href="#modes">Modes</a> ·
|
||
<a href="#models">Models</a> ·
|
||
<a href="#users">Users</a> ·
|
||
<a href="#statistics">Statistics</a> ·
|
||
<a href="#get-started">Get started</a> ·
|
||
<a href="#configuration">Configuration</a> ·
|
||
<a href="#themes">Themes</a> ·
|
||
<a href="#development">Development</a> ·
|
||
<a href="#status">Status</a>
|
||
</p>
|
||
|
||
<br>
|
||
|
||
<p align="center">
|
||
<img src="docs/images/chat.png" alt="A CodeCraft session: the agent edits a file, a permission card shows the diff and asks before running a command, the task list shows what is left" width="100%">
|
||
<br>
|
||
<sub>A session: the agent works through its task list, shows diffs, and asks before anything outside the rules.</sub>
|
||
</p>
|
||
|
||
<table>
|
||
<tr>
|
||
<td width="25%" valign="top">
|
||
<h3>🧠 Any model</h3>
|
||
Anthropic natively, plus everything that speaks the OpenAI API: Gemini, opencode Go, fal.ai, OpenRouter, Ollama, vLLM, llama.cpp. Mix them in one chat.
|
||
</td>
|
||
<td width="25%" valign="top">
|
||
<h3>🛠️ Real tools</h3>
|
||
Read, write, edit, glob, grep, shell, web fetch, task lists, subagents, skills – and every tool of your MCP servers.
|
||
</td>
|
||
<td width="25%" valign="top">
|
||
<h3>🙋 You decide</h3>
|
||
Permission requests with diffs, questions from agents and MCP servers, per-tool rules. On your phone, with notifications.
|
||
</td>
|
||
<td width="25%" valign="top">
|
||
<h3>📊 Every token counted</h3>
|
||
Tokens, cache hits, prefill and output speed, and cost per request – per chat and in a dashboard.
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
<br>
|
||
|
||
## 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.
|
||
|
||
1. **Pick a folder and a mode.** Every user has their own folder; admins can share more.
|
||
2. **Say what you want.** The agent plans with a task list, reads the code and makes changes.
|
||
3. **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.
|
||
4. **Delegate.** The agent hands work to subagents – in parallel or in the background, on
|
||
other models and hosts – and continues while they run.
|
||
|
||
<table>
|
||
<tr>
|
||
<td width="50%" valign="top">
|
||
<img src="docs/images/mobile.png" alt="CodeCraft on a phone: a session with a question card offering three options" width="100%"><br>
|
||
<sub><b>Mobile:</b> answer questions and approve changes from your phone.</sub>
|
||
</td>
|
||
<td width="50%" valign="top">
|
||
<img src="docs/images/settings.png" alt="Settings: providers with models, context sizes and prices per million tokens" width="100%"><br>
|
||
<sub><b>Settings:</b> providers, models, prices, MCP, permissions and users – all in the UI.</sub>
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
|
||
## 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_concurrency` per host or model queues requests for servers that
|
||
can only process one at a time; `max_parallel` limits 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
|
||
|
||
<p align="center">
|
||
<img src="docs/images/stats.png" alt="The statistics dashboard: cost and token tiles, cost per day stacked by model, tokens per day, and an activity heatmap by weekday and hour" width="100%">
|
||
</p>
|
||
|
||
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
|
||
|
||
```sh
|
||
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`](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
|
||
|
||
Colours, syntax highlighting and chart palettes come from CSS variables. Each theme is one
|
||
file in [`web/src/themes`](web/src/themes) (Gruvbox Dark and Light ship by default):
|
||
|
||
1. Copy `gruvbox-dark.css` to `<id>.css`, change the values on `:root[data-theme="<id>"]`.
|
||
2. Import it in `themes/index.ts` and add it to `THEMES` in `web/src/theme.ts`.
|
||
|
||
The variables cover surfaces (`--bg0`–`--bg3`), text (`--fg0`–`--fg3`, `--muted`), accents,
|
||
diffs, syntax (`--syntax-*`), charts (`--series-1`–`8` categorical, `--seq-0`–`6` sequential)
|
||
and the browser bar colour (`--theme-color`). The chart colours are validated for colour-vision
|
||
deficiencies against the background – re-check them when the background changes a lot.
|
||
|
||
## Development
|
||
|
||
Requirements: Rust (edition 2024) and Node ≥ 20.19.
|
||
|
||
```sh
|
||
# 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, `@file` mentions
|
||
- MCP OAuth, resources and prompts
|
||
- Hooks before/after tool calls
|
||
- Image generation tools (fal.ai) and the OpenAI Responses API
|