A local-first agent in a single Rust binary: your Markdown vault as memory, grammar-enforced tool calls on llama.cpp, and nothing leaves your machine unless you say so.
Eris runs a local LLM as a personal agent over a plain-Markdown vault (Obsidian-compatible). It reads and writes your notes, remembers across sessions through tiered semantic memory, manages reminders and alarms, and calls its tools through a JSON protocol that is structurally enforced by a GBNF grammar β no function-calling API required, and no cloud in the loop.
Named for Eris β the Greek goddess of strife and the golden apple of discord. The name is mythological, not an acronym: a local agent meant to productively disturb your vault (read, write, remember, remind).
Sovereign by architecture, not by promise. No telemetry leaves the machine. Every outbound integration (web fetch, mail, calendar, Discord) is opt-in and enumerable. The vault is plain text you own; the semantic index is derived data that can always be rebuilt from it.Reliability engineering for small models. Local 8β26B models are sloppy with JSON. Eris compiles a GBNF grammar per session β and a narrowed per-turn subset grammar β so the model's output is constrained at the token level. Bounded generation (n_predict_max
) guards against context-window truncation.One brain, three faces. The same orchestrator and tool registry serve a full-screen terminal UI (ratatui), a localhost web UI (eris chat --web
), and an optional Discord sidecar sharing the live session.
Eris is not smarter than hosted frontier models β its intelligence ceiling is the GGUF you run. It is smarter about your data than anything hosted: it lives where your notes live, and it works when your network doesn't.
| Core (supported) | Extras (best-effort) |
|---|---|
| Chat (TUI + web), Markdown vault read/write/search | Discord sidecar |
| Tiered memory: staged (ephemeral) + committed (vault) + semantic recall (Qdrant) | Vision (vision:see , multimodal GGUF + mmproj) |
| Tool protocol with gatekeeper + GBNF enforcement (llama.cpp) | Voice ingress (STT via ffmpeg) |
| Agenda: reminders, alarms, self-driven follow-ups | Google Workspace mail/calendar tools |
| Web fetch/search with allowlist, consent, and session budget | Moltbook client |
Full tool roster (by family): ** docs/TOOLS.md**.
Prerequisites: Rust (stable, edition 2024), llama.cpp (llama-server
), a chat GGUF + an embedding GGUF (e.g. nomic-embed-text
), and Qdrant for semantic memory:
docker run -d -p 6333:6333 -p 6334:6334 -v eris-qdrant-data:/qdrant/storage qdrant/qdrant
Build and run:
cargo build --release
./target/release/eris chat # first run launches the ignition wizard
./target/release/eris chat --web # same session, localhost web UI
The first-run wizard writes .fcp/config.toml
(backend, model paths, GPU layers) and seals the vault directory. Full setup β including the Ollama alternative backend, vision, and voice β is in ** docs/REFERENCE.md** and
.
docs/HOW_TO/| Setup | Works |
|---|---|
| Apple Silicon, 16 GB+ | Good: 7β12B GGUF chat + embed model, Metal offload |
| Apple Silicon, 32 GB+ | Comfortable: 26B-class models, vision mmproj |
| Linux + NVIDIA (8 GB+ VRAM) | Good with --n-gpu-layers tuning |
| CPU-only | Runs, but slow; small quantized models only |
llama.cpp is the canonical production backend β it is the only one with GBNF grammar enforcement, vision, and voice. Ollama is supported as an easier-to-install alternative with weaker JSON discipline (soft format: json
instead of grammar); expect more recovery turns on long sessions.
Alpha. Single-user, single-process. Dogfooded on macOS (Apple Silicon / unified memory, Metal) and Linux (ideally NVIDIA GPU). Windows should run; it is less exercised and packaging is not a priority yet. Honest known limitations:
- Long-context sessions can still degrade JSON discipline on the Ollama backend (grammar-less path).
- Installation is manual (build from source + fetch models); installers and prebuilt binaries are planned.
- The architecture docs in docs/updated_architecture/include a frankself-reviewof the codebase's debt β read it before contributing to the orchestrator.
Everything under docs/ is
my working notesβ design diaries, reviews, how-tos, and TODOs I keep in-repo so the thinking stays visible and I can sync across machines. I curate them when I can; they are
not a guarantee of being fully up to date with
main
. Prefer the code, this README, , and
SECURITY.md
CONTRIBUTING.md
| Doc | Contents |
|---|---|
docs/REFERENCE.mddocs/HOW_TO/docs/updated_architecture/Contributions are welcome under inbound = outbound terms: your contributions are licensed under Apache 2.0, confirmed by a DCO Signed-off-by
line (git commit -s
). See CONTRIBUTING.md β including the project's non-negotiable engineering rules (zero panics, no unsafe
, actor-model concurrency).
Copyright 2026 Jan Dahlke. Licensed under the Apache License, Version 2.0.