Overview
Canonical source:
README.md. This page is refreshed from the Finch repository when the website builds.
Finch is an experimental terminal agent runtime and coding assistant written in Rust. It provides an interactive REPL, provider-backed chat, code and shell tools with an approval boundary, local persistence, an MCP client, a typed Lisp/Co-Forth runtime, and named shared Brain sessions.
Finch is under active development. This README describes the current main branch, not a promise
that every configured provider, local model, or experimental collaboration path is production
ready. See Current limitations before relying on it.
Direction
Section titled “Direction”Finch aims to bring capabilities that are currently split across terminal coding agents and always-on personal-agent systems under one user-controlled runtime. The intended problem space includes tools built around Codex, Claude, Grok, Muse, and OpenCode, as well as OpenClaw-style assistants that can remain available on a spare computer. Finch is not yet a drop-in replacement for those products.
The long-term design combines:
- provider-independent coding and general agent workflows;
- named, durable Brains that can survive frontend disconnects and machine restarts;
- cloud providers, supported subscription authentication, local models, and explicit fallbacks;
- repository skills and MCP integrations behind the same typed capability boundary;
- semantic, accessible desktop automation instead of coordinate-driven GUI control;
- local or hosted perception for voice, images, documents, and bounded text summaries;
- attached terminal, editor, remote, and lightweight always-on frontends over one auditable event history.
Why Finch
Section titled “Why Finch”| Differentiator | What it is intended to provide | Current status |
|---|---|---|
| Typed Lisp and Co-Forth programs | Agents can express multi-step computation and effects as programs that the runtime can validate and execute, instead of relying only on opaque one-tool-at-a-time calls. | The typed runtimes and direct --lisp, --forth, and --exec interfaces exist; provider wire conformance and broader agent use are still evolving. |
| Durable named Brains | One named conversation, event history, and persistent typed VM can survive frontend disconnects and daemon restarts. | Implemented foundations with experimental reconnect, background-work, and collaboration workflows. |
| One capability boundary | Code tools, MCP tools, future skills, remote peers, and desktop automation are meant to share typed authority, approval, audit, and revocation rules. | Tool approval and MCP client paths exist; skills and wider automation integration remain planned work. |
| Provider and account portability | Use cloud APIs, supported subscriptions, remote Finch nodes, or local models without changing the surrounding workflow or concealing which backend ran it. | Multiple profiles exist; subscription support, model-level conformance, and explicit fallback behavior remain active work. |
| Local models and perception | Keep suitable generation, speech transcription, OCR, image description, and context compression on user-controlled hardware, with explicit cloud fallback when requested. | Daemon chat accepts an explicit GGUF through llama.cpp; frontend memory owns its separate required model defaults and download. Broader media support is not established. |
| Accessibility-native automation | Operate applications through semantic roles, labels, and domain identifiers so automation remains usable and auditable without pixel coordinates. | A design invariant and long-term integration target, not a complete personal-assistant feature today. |
This direction is incremental. Current interfaces are described below; planned work belongs in the issue tracker and the dated development roadmap. Configuration types and design documents are not evidence that an integration works end to end.
Quick start from source
Section titled “Quick start from source”The most reliable way to try the current code is to build a clean checkout. Release artifacts and runtime CI target Apple Silicon macOS and x86-64 Linux. The primary Windows CI contract checks the pinned Rust 1.98.0 rustfmt result; narrowly scoped component probes may compile selected portable sources, but neither constitutes Windows Finch runtime support. Install Rustup, Git, and the Cap’n Proto compiler first; the checkout selects that pinned toolchain.
macOS (Apple Silicon):
xcode-select --installbrew install capnpgit clone https://github.com/darwin-finch/finch.gitcd finchcargo build --release --bin finch./target/release/finch setup./target/release/finch --cloud-onlyUbuntu/Debian Linux (x86-64):
sudo apt-get updatesudo apt-get install -y build-essential capnproto pkg-config libssl-devgit clone https://github.com/darwin-finch/finch.gitcd finchcargo build --release --bin finch./target/release/finch setup./target/release/finch --cloud-onlyfinch setup writes provider profiles and settings to ~/.finch/config.toml. The setup UI
currently offers API-key profiles for Anthropic, OpenAI, xAI, Google Gemini, Mistral, and Groq, as
well as local-model configuration. Use a provider model returned by the setup catalog or enter one
explicitly; model availability changes independently of Finch.
GitHub release assets currently exist for Apple Silicon macOS and x86-64 Linux, but they can lag
behind main. Release and installer reliability are being tracked in
#119 and
#144, so this first truthful refresh does not
recommend the one-line installer as the canonical path.
Current interfaces
Section titled “Current interfaces”These commands are defined by the current CLI:
finch interactive terminal UIfinch attach <name> resume a named Brain by its canonical event streamfinch --raw interactive line-oriented UIfinch --cloud-only skip local-model loading and the daemonfinch query "explain this" run one provider-backed queryfinch setup configure provider profiles and settingsfinch daemon foreground HTTP server on 127.0.0.1:8000 by defaultfinch daemon-start background daemon on 127.0.0.1:11435 by defaultfinch daemon-status report background-daemon statusfinch daemon-stop stop the background daemonfinch --forth "1 2 +" evaluate typed Co-Forth without an LLMfinch --lisp "(+ 1 2)" evaluate typed Finch Lisp without an LLMfinch --exec path/to/file execute a typed Finch scriptfinch brain ls list named Brains (name, turns, size, attached, agents)finch brain ls --json list named Brains as JSON summariesfinch brain rm <name> archive a named Brain (stop the daemon first)Run finch --help and finch <command> --help for the full generated CLI reference. In the REPL,
/help shows the slash commands present in that build. /model overlays a model on the active
Brain (same credentials). /provider <name> binds that Brain to a configured provider entry.
/status inspects the effective identity. --model is one-shot for this invocation and does not
persist; /model does.
Typing @ at a token boundary opens a keyboard-navigable file picker. Selecting a file or
directory inserts a visible @path mention and attaches a snapshot of its contents to the
turn. Email addresses and \@ stay ordinary prompt text. Slash commands remain actions;
@ is not a shell escape.
Shared brains (experimental)
Section titled “Shared brains (experimental)”Tests and live smokes involving Brains must not be invoked directly. Give the process a disposable Finch home with the guarded wrapper (credentials needed by a live smoke should be supplied explicitly through environment variables):
./scripts/test_brains.sh env FINCH_LIVE_TESTS=1 cargo test --test live -- --ignoredThe wrapper deletes the temporary store on success or failure and fails if the
real ~/.finch/brains manifest changes.
A named Brain keeps one ordered conversation and one persistent typed Lisp/Co-Forth VM across
multiple terminals and daemon restarts. Resume it with finch attach <name>.
Tools and approval
Section titled “Tools and approval”Finch can inspect files, search source, propose changes, run commands, and call configured MCP
tools. Approval is policy-dependent: known read-only operations may run without a prompt, while
mutating or otherwise sensitive operations normally require review or are denied. Enabling an
auto-approval setting changes that boundary. The implementation contract is documented in
src/tools/EXECUTION.md; treat generated diffs and commands as untrusted
until reviewed.
Configuration and providers
Section titled “Configuration and providers”The authoritative configuration types live in
src/config/settings.rs and
src/config/provider.rs. A minimal API-key profile looks like:
[[providers]]type = "claude"name = "work"api_key = "sk-ant-..."Provider profiles may have user-defined names and model overrides. The code also contains profile types for Ollama, a remote Finch daemon, and local inference. Configuration support is not the same as end-to-end conformance: provider routing and model selection are still being reconciled in #51, #74, #98, and #104.
ChatGPT consumer subscriptions authenticate through Finch’s device-login flow and a Finch-native
HTTP transport (finch auth login; see
docs/OAUTH.md and
docs/CHATGPT_SUBSCRIPTION_TRANSPORT.md). That flow is a
compatibility boundary, not an OpenAI-supported third-party integration. Legacy Codex app-server
chatgpt_subscription configuration is rejected with migration guidance; subscription
authentication must not be inferred from OpenAI API-key support.
Muse Spark 1.3 can be configured through the direct, origin-bound Meta Model
API profile with a named MODEL_API_KEY; see
docs/META_MODEL_API.md. This is not OpenCode Zen or
the Muse Code harness, and it does not claim local Muse Spark weights.
A hand-written type = "claude_cli_backend" entry drives the official claude
CLI as a subscription subprocess instead of metered API billing. It is never
offered by the setup wizard, it disables the CLI’s own tools so Finch’s
permission system stays the only execution authority, and it carries real
ToS/enforcement risk because Anthropic has enforced account suspensions
against CLI-wrapper usage — the details and the measured wire contract are in
docs/MULTI_PROVIDER_CONFIG.md. Configuring it
is an explicit acceptance of that risk.
Local inference
Section titled “Local inference”Daemon local chat loads either a Finch-managed, pinned Hugging Face GGUF or a user-selected GGUF
file through llama.cpp. Managed downloads are resumed, size/checksum verified, and shown as one
temporary status-bar entry. ONNX and Candle are not chat
providers. Normal startup rejects configurations naming those removed engines without changing
them. finch setup first creates a private adjacent backup, removes only the affected local
[[providers]] block (or legacy [backend] block) and obsolete [coreml] sections, and preserves
unrelated providers, credentials, settings, and comments before opening the editor to add the GGUF
replacement. Local artifacts can be
large. A configured local profile does
not currently guarantee that a query is routed locally; local bootstrap, selection, and provider
parity remain experimental under #74 and
#98. The daemon currently requires at least one
configured cloud provider as a fallback alongside local models. Use --cloud-only when you need to disable
daemon local-chat loading.
The removed ONNX and Candle local-chat implementations were last available in commit
0607ccfad8ba790a236f701aa7d25f77488332d7.
They were retired on 2026-09-22 because neither path provided a reliable supported chat runtime:
ONNX/CoreML repeatedly crashed the daemon during Qwen session construction, while Candle’s Metal
path lacked kernels required by the supported model families and produced wrong, absent, or
impractically slow output. The replacement llama.cpp/GGUF path had completed real buffered,
streamed, and CPU generation on the target MacBook before the cutover. The historical commit is
for source archaeology, not a supported installation recommendation. Frontend memory remains a
separate path: it uses its own fixed managed bge-small-en-v1.5 Q8_0 GGUF through llama.cpp rather
than the user-selected chat GGUF, with a hashed-n-gram fallback while that artifact is unavailable.
HTTP daemon
Section titled “HTTP daemon”finch daemon binds the foreground HTTP server to 127.0.0.1:8000 unless --bind is supplied.
The separately managed background daemon uses 127.0.0.1:11435. The server implements
POST /v1/chat/completions, GET /v1/models, POST /v1/messages, health/metrics endpoints, and
Finch-specific feedback, node, and Brain routes. It does not implement the complete OpenAI API
or the Responses API. Integration conformance is tracked in
#130,
#133, and
#134.
When explicitly enabled, remote Brain collaboration uses a distinct TLS listener whose configured
default is 0.0.0.0:11436. That listener exposes a restricted Brain route set; it is not the
OpenAI-compatible endpoint.
Using the daemon as a local provider proxy
Section titled “Using the daemon as a local provider proxy”POST /v1/chat/completions accepts OpenAI-shaped requests and answers them through whichever
provider Finch is configured to use, so any tool that speaks that shape can reach every provider
Finch can reach, without running a second service.
That translation is not built for the proxy. Finch already converts between provider wire formats because it drives several from one interface; the endpoint is that existing code with a different front door. It is the same job a standalone proxy such as LiteLLM does, and the reason it is nearly free here is that the hard part already had to exist.
Point a client at the daemon’s address — 127.0.0.1:8000 for finch daemon, 127.0.0.1:11435 for
the background daemon, or whatever server.bind_address says.
It is unauthenticated by default. server.auth_enabled is false out of the box, which means
any caller that can reach the port can spend your provider quota. To require a key, set this in
~/.finch/config.toml:
[server]auth_enabled = trueapi_keys = ["your-key-here"]Exactly one non-empty key is accepted; the daemon refuses to start with zero or several. Callers
send it as Authorization: Bearer your-key-here. The key is stored in plaintext in that file, so
its protection is the file’s permissions and nothing more.
The endpoint is a compatible surface, not the complete OpenAI API, and provider coverage through it is exactly Finch’s provider coverage — which is configuration, not conformance evidence.
MCP client
Section titled “MCP client”Finch can start configured stdio MCP servers and import their tools. It does not expose an MCP server. See the MCP client guide for configuration and troubleshooting.
Brains, typed programs, and subagents
Section titled “Brains, typed programs, and subagents”The typed Lisp/Co-Forth runtime and named Brain persistence have extensive implementation and test coverage, but their user workflows are experimental. A Brain is a named, durable conversation and program environment owned by the daemon; local and remote attachment have different transport and authority boundaries. Subagent and remote-collaboration behavior is still evolving under #57, #107, #140, #145, and #146.
Use direct typed-runtime commands for bounded experiments:
./target/release/finch --forth "1 2 +" --json./target/release/finch --lisp "(+ 1 2)" --jsonPersistence and privacy
Section titled “Persistence and privacy”Finch stores configuration and application state under ~/.finch/, including SQLite memory,
sessions, named Brains, feedback, and approval patterns as applicable. Explicit good/bad response
feedback is private durable metadata; it does not authorize or trigger training. Legacy training
queues and adapters may be preserved but are not processed automatically.
Local storage does not make a cloud-backed session offline: prompts, selected context, and tool results sent to a configured cloud provider leave the machine and are governed by that provider. Configured MCP servers and remote Finch peers can also receive data as directed by their tools and capabilities. Finch has no automatic LoRA training path; see #139.
Current limitations
Section titled “Current limitations”- Finch is experimental and is not presented as release-ready or production-ready.
- Provider and local-model behavior is not yet uniform; verify the exact profile and model you use.
- ChatGPT subscription/device auth uses Finch’s device-login flow and its Finch-native transport (docs/OAUTH.md, docs/CHATGPT_SUBSCRIPTION_TRANSPORT.md); it is a compatibility boundary, not an OpenAI-supported third-party integration, and carries no live-model claim for any unreleased or unverified model.
- The server supports a small endpoint subset, not the full OpenAI API and not
/v1/responses. - Image-input/output support is not documented as available.
- Finch does not automatically update itself, train LoRA adapters, or turn feedback into training.
- Brain, remote collaboration, typed-agent, and subagent workflows remain experimental.
The issue tracker is the source for planned work. In particular, do not treat design documents as implemented behavior unless current source or tests say so.
Development
Section titled “Development”After installing the prerequisites from Quick start from source:
Source builds use the repository-pinned Rust 1.98.0 toolchain. See
docs/RUST_TOOLCHAIN.md for the tested-toolchain and MSRV policy.
cargo fmt --all -- --checkcargo check --lib --bins --testscargo testpython3 scripts/check_docs.pySome full builds and tests are memory-intensive. Narrow commands to the module under change when appropriate, then rely on CI for the supported platform matrix. See CONTRIBUTING.md before submitting work and docs/README.md for the documentation map.
Measuring interactive startup
Section titled “Measuring interactive startup”FINCH_STARTUP_TIMINGS publishes a per-phase startup report. It is off by
default and costs nothing when unset.
FINCH_STARTUP_TIMINGS=~/startup.txt finch # write the report to a fileFINCH_STARTUP_TIMINGS=1 finch # write it to stderr (also: stderr)RUST_LOG=finch::startup=debug finch # per-phase tracing events insteadFINCH_STARTUP_SLOW_BUDGET_MS=25 finch # warn about any phase over 25 msA phase over its budget (150 ms by default) is marked SLOW in the report and
warns on the terminal, naming the phase and how long it took.
FINCH_STARTUP_SLOW_BUDGET_MS lowers that budget, which is how the warning
gets exercised without loading the machine; an unparseable value leaves the
default in force.
When the daemon is in use, the daemon_http_connect phase now nests the
GET /health probes (daemon_health_probe, with category=healthy,
unhealthy or unreachable) and the unconditional two-second wait before the
one retry (daemon_retry_backoff) as separate entries — so a slow launch says
whether the daemon was slow or whether a healthy daemon merely missed one
500 ms probe window and cost this launch the flat floor. They need different
fixes.
The report lists each phase and instant mark in start order with its offset
from t0, its duration, and how many phases enclose it (depth — phases nest,
so the ms column does not sum). It ends with accounted_ms,
unaccounted_ms, and time_to_ready_ms.
Two things it is careful about. time_to_ready_ms runs from the first
statement of main’s async body to the first instant a typed key is acted
upon — not to the first painted frame, which happens on a render tick after
it; process spawn and dynamic loading are before t0. And the report carries
phase names, durations, counts and fixed categories only: no Brain name, path,
prompt or credential can appear in it, which is what makes it safe to paste
into a bug report.
scripts/bench_startup_time_to_ready.sh [runs] [brains] runs the same
measurement repeatedly under disposable HOMEs and reports median, p90, min and
max with the machine and commit attached. It is a benchmark, not a gate.
Maintainer and development assistance
Section titled “Maintainer and development assistance”Finch was created and is maintained by Shammah Chancellor. Substantial portions of the project have been developed with assistance from Anthropic Claude and OpenAI Codex. Those products are development tools, not legal authors, maintainers, people, or GitHub identities. Commit authorship should identify the human responsible for the change; optional assistance trailers must be truthful. Existing contributor displays are a consequence of historical commit metadata and cannot be repaired without rewriting history, which this project does not do for attribution cleanup.
See CONTRIBUTING.md for the attribution policy.
License
Section titled “License”Finch is source-available under the PolyForm Noncommercial License 1.0.0. Review the license text for the authoritative terms. Commercial licensing information is available at https://polar.sh/darwin-finch.