Contribute
Contributing to Ancilo
Ancilo is an open-source project by Stefan Grunert. Contributions include code, tests and translations, as well as reproducible bug reports and specific suggestions for improvement. You do not need to be a programmer to take part.
Reporting bugs
Start by checking the existing GitHub issues. If someone has already reported the problem, add your observations there; otherwise, open a new issue. If you do not have a GitHub account, email [email protected]. A short description in your own words is enough to start with.
A useful report includes the Ancilo version, macOS version, chip and memory of your computer. For problems with answers or tasks, include the model name and resource profile as well. Describe the steps leading to the problem, what you expected and what actually happened. The exact error message or a screenshot helps identify the point of failure.
GitHub issues are public. Remove personal information from screenshots and use a small, anonymised sample document where possible. Access keys and complete private conversations are not needed for a bug report.
Suggesting features and improvements
Feature requests can also go into GitHub issues or be sent by email. Describe the task you want to complete and where Ancilo does not yet support it. A specific example explains the need more clearly than a feature name alone.
If you already have a solution in mind, include it as a suggestion. Unclear labels, missing instructions and translation errors are worth reporting too. Discuss larger code changes in an issue first, so the goal and scope are clear before implementation begins.
Tech stack and architecture
- Background serviceRust (edition 2024) with tokio, axum and SQLite (rusqlite) – including the ancilo command line
- Modelsllama.cpp (llama-server) with GGUF models from Hugging Face
- InterfaceReact 19, TypeScript, Vite, TanStack Query
- Desktop appTauri 2, macOS on Apple Silicon
- APIsHTTP API with OpenAPI, MCP, OpenAI- and Anthropic-compatible model API
- Safetysandbox with Seatbelt (macOS) or bubblewrap (Linux)
- Text recognitionSwift with Apple’s Vision
- Tests and buildcargo-nextest, Vitest, Playwright; just collects every command
Ancilo consists of a background service that runs on your own computer, reachable only at 127.0.0.1 and protected by a token. Everything Ancilo can do is an operation in a shared registry. The same operation is reached by the app, the command line, the HTTP API, MCP for Claude Code and Codex, and Ancilo’s built-in assistant. A new feature is built once and is available everywhere. unsafe is forbidden across the Rust workspace.
The model manager plans context size and memory, loads and unloads models and keeps the computer usable; llama.cpp is pinned to one version. A gateway routes requests to the models. Search in documents and code uses a small embedding model and hybrid search over vectors and full text.
The agents for coding and tasks share one loop with tools; their commands run in the sandbox. Documents are read by a separate, sandboxed process. The macOS app starts the service and shows the interface the service itself serves; the interface’s API types are generated from the OpenAPI description.
A scriptable fake model makes behaviour that depends on model output deterministic to test; Hugging Face, Claude Code and Codex are simulated in tests too. The overview shows what lives where in the repository.
crates/core types, errors, events, operation registry
crates/daemon background service – wires everything together
crates/server HTTP API, events (SSE), OpenAPI
crates/cli the ancilo command line
crates/models models: planning, downloads, llama.cpp processes
crates/gateway requests to models: routing, OpenAI/Anthropic APIs
crates/agent agent loop, tools, sandbox
crates/sessions coding and tasks in the app
crates/tasks delegated Coding Tasks, worktrees
crates/mcp MCP server for Claude Code and Codex
crates/connect connecting Claude Code and Codex
crates/docs reading documents, text recognition
crates/index code and knowledge search
crates/web web search
crates/assistant Ancilo’s built-in assistant
crates/compare model comparisons
crates/eval evaluations
crates/storage SQLite and migrations
crates/testkit fake models and test helpers
app/ interface (React, TypeScript, Vite)
app/src-tauri/ macOS app (Tauri 2)
packaging/ packages, signing, DMG, releaseDevelopment environment
Stefan develops on a Mac with Apple Silicon, using tools including Claude Code, Codex and Ancilo. The MCP connection allows bounded tasks such as tests, documentation and small changes to be delegated to a local model. Results are then checked against the code and verified through tests. Contributors do not need to use a particular AI assistant.
Alongside the Ancilo project, Stefan keeps local checkouts of the Codex and OpenCode source repositories in neighbouring directories. They serve as references for him and his coding agent, Claude Code: existing implementations offer ideas for Ancilo and show how other projects solve similar problems. This provides a way to build on existing experience rather than reinvent the wheel.
The documented macOS development workflow requires Git, Rust through rustup, Node.js 22 or later with npm, just and cargo-nextest. The Rust version is pinned in rust-toolchain.toml. You also need Apple’s Command Line Tools with Swift: they build the small text recognition helper; without Swift, Ancilo still builds, just without text recognition. Native app builds also use CMake and Ninja for llama.cpp. Dependencies need to be downloaded during initial setup.
The checks also run on Linux, as in continuous integration; the sandboxed document reader needs bubblewrap there. The desktop app itself is macOS only.
Running Ancilo Dev beside the release
For a code contribution, fork the repository on GitHub, clone your fork locally and create a branch for the change. From the project directory, just app-dev builds and installs the separate “Ancilo Dev” application. The command replaces an existing Dev build while leaving the regular Ancilo app in place.
The Dev app has its own data directory at ~/Library/Application Support/ancilo-dev, uses port 7425 and starts separately at login. Its command-line entry point is ancilo-dev, installed to ~/.local/bin; that directory should be on your PATH. Automatic app updates are disabled in the Dev app. This lets you try changes while keeping the released version available separately.
An Apple Developer certificate is not required for this local build: the script uses an available signing identity or signs ad hoc. Signing and notarising a public release are part of the maintainer’s release process.
git switch -c fix/short-description
just app-devChecking and submitting changes
just verify checks formatting, Clippy, Rust tests, and the interface’s types and tests, installing the interface’s dependencies itself. Deterministic tests replace models and external services with controllable test implementations. Once dependencies have been downloaded, these checks do not need a GPU or a running cloud service. On macOS, the first test run after a build can take noticeably longer because XProtect checks new test programs once.
just app-e2e tests the interface in Chromium and WebKit against a real Ancilo background service with simulated external services. Install the browsers through Playwright once before running it. Changes to models, delegation or the API also call for just test-real, which uses small real models and may need to download them.
If you change operations or responses of the background service, regenerate the interface’s TypeScript types with just app-api; otherwise the interface checks fail.
A pull request should describe the problem, the change and the checks performed, and link to the issue where applicable. Code, comments and commit messages are in English, and the project uses Conventional Commits. AI-generated code also needs your review and appropriate tests. Refer to CONTRIBUTING.md for the current guidelines.
just verify
cd app && npx playwright install chromium webkit && cd ..
just app-e2e