Docs
The part where we stop simplifying.
The landing page says Cubby learns how you work. Here's what that actually is: four runtimes, a hash-chained journal, a LoRA trainer pointed at your own GPU, and an agent allowed to patch its own source behind a ratchet it can't widen.
Read top to bottom to get running, or skip to Architecture if you'd rather fork it and judge the code yourself - that's the honest way to evaluate this. Everything here mirrors the repo, which is always the version that gets updated first.
Install
One command detects your OS on Linux and macOS. On Windows, grab the installer from Releases.
Linux & macOS
- Linux with a display → installs the desktop app (.deb / .rpm).
- Linux headless → builds the feral CLI + gateway from source (
-s -- --headless). - macOS → downloads the right .dmg, installs to /Applications, clears quarantine.
Windows 10/11
Download the latest .exe from Releases and run it. SmartScreen may warn on first run (not code-signed yet) - click More info → Run anyway.
Just the CLI (npm)
The terminal agent, any OS. Note: the npm build is a cloud/gateway CLI - it does not bundle the local llama.cpp engine. For local GGUF models, install the desktop app above.
Quick start
- 1Install and open Feral. A short welcome wizard introduces the app - pick a name for yourself and your agent.
- 2Get a model. Local: Models → Browse, pick one, click download - Feral pre-selects the quantization that fits your hardware. Or Cloud (BYOK): Settings → Cloud Keys, paste an API key. Keys are stored locally, never proxied.
- 3Chat - or flip to Agent mode. Agent mode unleashes the sidecar: tool-use, persistent memory, file access, and web research.
Prefer the terminal? feral chat opens a full-screen terminal chat (same sessions, memory and models), feral setup runs the wizard, and feral gateway runs it as a background service.
What's inside
Chat
Persistent conversations with any local or cloud model. Projects keep related chats grouped and sane.
Agent Mode
A full TypeScript sidecar agent with tool-use, 4-layer memory, and an agentic loop.
Memory Layers
Working, episodic (FTS5) and semantic memory, plus Fractal Memory - a RAPTOR embedding-tree that recalls the gist of past work, not just keywords.
Self-forging tools
With tool_forge the agent builds, updates and retires its own tools at runtime - sandboxed, transpile-checked and audited.
Self-Improvement (BRSI)
Feral improves itself in bounded steps - from tuning its own settings up to writing and retiring its own tools and code, each change proven better before it ships. See Self-improvement below.
Connectors
Talk to your agent from WhatsApp (QR pairing), Discord, or Slack - same brain, same memory, on your machine.
Deep Research
Multi-step autonomous web research: searches, reads pages, extracts findings, and synthesizes a cited Markdown report.
Local Models
Load GGUF models from disk. One-click load/unload with live Active status and hardware fitness scoring.
Model Fitness Scoring
Every local model gets a 0-100 score across memory fit, quality, speed, and context window.
Browse HuggingFace
Search and download models inside the app - no terminal, no manual file moves.
SkillHub
Install, discover, and import skills that extend what the AI can do.
Cloud Keys (BYOK)
Bring your own key for OpenAI, Anthropic, Gemini, DeepSeek, Groq, Mistral, OpenRouter, Kimi, GLM, MiniMax, or any custom endpoint.
Privacy Tags
Wrap anything in <private>…</private> and it never touches the memory database.
Tool Health Monitor
Per-tool success rates and latency tracking - the agent can diagnose its own failing tools.
Workspace Scanner
Detects hardcoded secrets and code anti-patterns before you push them to GitHub.
Hardware Monitor
Live GPU / VRAM / RAM readout and Vulkan detection.
Auto-updater
Silent background update checks, signed with minisign. One click to install.
Architecture
One repo, four runtimes, three protocols between them. If you came here to fork it and read the code, this section and the two after it are the map - they mirror ARCHITECTURE.md in the repo, which is the version that gets updated first.
┌───────────────────────────┐ ┌───────────────────────────┐
│ Desktop UI (React/Vite) │ │ TUI (Go + Bubble Tea) │
└─────────────┬─────────────┘ └─────────────┬─────────────┘
│ Tauri IPC │ HTTP
┌─────────────┴───────────────────────────────┴─────────────┐
│ Rust host - crates/feral-core │
│ ├── desktop: src-tauri/ ├── headless: feral-cli/ │
│ ├── llama.cpp inference engine (:11435) │
│ └── OpenAI / Ollama-compatible HTTP API + bearer token │
└─────────────────────────────┬─────────────────────────────┘
│ JSON-lines on stdout
┌─────────────────────────────┴─────────────────────────────┐
│ Sidecar - FeralAgent/ (Bun + TypeScript, one binary) │
│ └── agent loop · BRSI engine · memory · tools · sandbox │
└───────────────────────────────────────────────────────────┘The four runtimes
| Runtime | Stack | Owns |
|---|---|---|
Desktop UIfrontend-react/ | React 18 + Vite + Zustand | Rendering, chat surfaces, the mascot, settings UX. |
Rust host (desktop)src-tauri/ + crates/feral-core/ | Tauri 2 + llama.cpp | IPC, filesystem, GGUF inference, the 127.0.0.1:11435 HTTP API, sidecar supervision. |
Rust host (gateway)crates/feral-cli/ | Rust, no UI | The same feral-core headless. Exposes the feral subcommands and the HTTP API for terminal and automation. |
SidecarFeralAgent/ | Bun + TypeScript, one compiled binary | The agent loop, BRSI engine, memory, tools, sandboxed inference router. |
TUItui/ | Go + Bubble Tea | Terminal chat, onboarding, connectors wizard. API client only. |
Five rows, four runtimes: the desktop shell and the headless gateway are two hosts of the same feral-core crate.
The three protocols
| Protocol | Between | Wire format | Validated by |
|---|---|---|---|
| Tauri IPC | UI ↔ host | invoke() / listen('feral://…') | Command registry in src-tauri/src/commands/ |
| JSON-lines on stdout | host ↔ sidecar | {type:"…", …} one per line | FeralAgent/src/transports/tauri.ts + types.ts |
| OpenAI/Ollama-compat HTTP | any client ↔ host loopback | JSON over HTTP | crates/feral-core/src/api.rs, per-launch bearer token |
API keys never reach React. Tauri commands inject your BYOK keys in Rust before anything is forwarded to the sidecar, so the frontend never holds one. If you are auditing where secrets can leak, start at feral_set_model.
Layer map (L0-L6)
The BRSI stack isn't just conceptual - each layer owns a slice of the tree, with hard contracts between them. The one rule that will get your PR bounced: layers never import sideways. Everything goes through the orchestrators at rsi/sidecar.ts, rsi/engine.ts and rsi/mod.ts. Paths below are relative to FeralAgent/src/ unless they say otherwise.
| Layer | Mandate and limits | Where it lives |
|---|---|---|
| L0Substrate | Git-backed journal, the bounded-ratchet boundary, integrity. | rsi/infra/journal.ts · rsi/infra/hash-chain.ts · feral-core/src/rsi/repo.rs |
| L1Config evolution | Mutates the 7-field GenomeConfig, bounded by schema. May not touch code or weights. | rsi/l1-config/ |
| L2Personal adaptation | LoRA over your own signal. May not mutate base weights. | rsi/l2-adapt/ |
| L3Code RSI | Unified diffs over FeralAgent source, applied through a worktree. May not skip the worktree or touch the host. | rsi/l3-code/ |
| L4Architecture evolution | Subsystem hot-plug behind two v1 seams: retrieval_strategy and planner. May not write into FeralAgent/src/. | rsi/l4-modules/ |
| L5Governance evolution | Tunes parameters inside SandboxBounds. Reversible. May not bypass tier-0. | rsi/l5-gov/ · feral-core/src/rsi/sandbox_bounds.rs |
| L6Meta evolution | Tunes the algorithm that produces those parameters. Never skips the human gate. | rsi/l6-meta/meta-evolution.ts |
| infraCross-layer | Bus events, envelopes, budget, paths, the contract FSM, confidence gate. | rsi/infra/ |
Full per-file breakdown lives at FeralAgent/src/rsi/README.md. The safety contracts are in docs/invariants.md, and the conceptual grounding in docs/brsi-spec.md.
Where do I add X
Every contributor asks at least one of these in the first hour, so here they are up front.
A new inference provider
Four places, in this order: feral-core/src/byok.rs provider_catalog() is the canonical list; FeralAgent/src/egress/inference-providers.ts only if you need a new protocol family; check the auto-seeded vector in brain/capability-registry.ts; the Cloud Keys UI wires itself through useCatalog().
A new built-in tool
One file: FeralAgent/src/tools/builtin/<name>.ts. Declare the manifest (permissions, parameters) in the same file and boot.ts picks it up. Add a smoke test under FeralAgent/tests/.
A new chat connector
Catalog entry in feral-core/src/connectors.rs, desktop IPC in src-tauri/src/connectors.rs, connection owner in FeralAgent/src/egress/mcp-manager.ts. Persistence flows through feral-core so desktop and gateway agree.
A new L4 seam module
modules/<id>/manifest.json + module.ts. The registry at modules/registry.json is the runtime source of truth. Never edit FeralAgent/src/ for a module - that's the L3 trust boundary.
A new memory strategy
Pick the layer first. Same engine, different scoring goes in rsi/l1-config/fitness.ts. A new retriever joins the GenomeConfig.retrievalStrategy pool. A new storage layout belongs in FeralAgent/src/memory/fractal/.
If you add a file under rsi/ update the layer table in ARCHITECTURE.md and rsi/README.md in the same PR. Drift there is treated as a real bug: the next person reading it - human or agent - will believe the wrong thing.
Agent runtime
Flip the composer toggle to Agent mode and your messages go to the Bun/TypeScript sidecar. It recalls relevant memory, streams tokens live, and loops through tool calls until it has an answer - up to 10 iterations per message (50 for complex multi-step tasks like deep research).
user message
│
▼
[Recall] inject relevant past memory (FTS5 + semantic facts)
│
▼
[Inference] → stream tokens live to UI
│
├── tool call? → execute → feed result back → loop
└── no tool call → final answer, persist to memory, doneFailed web/network tools retry with linear backoff and fall back through the web_search → deep_research → read_webpage chain.
Memory layers
Feral layers several kinds of memory that persist across sessions, from a keyword-searchable log up to a semantic tree that understands what you actually talked about.
| Layer | Storage | What it stores |
|---|---|---|
| Working | RAM | The live conversation transcript. Auto-compresses older turns when it runs over the token budget. |
| Episodic | SQLite + FTS5 | Every message, tool result and typed observation, keyword-searchable full-text. |
| Semantic | SQLite | Durable facts pulled from each turn: your name, role, language, preferences, constraints. |
| Fractal Memory | RAPTOR tree | The semantic layer. Events are embedded, k-means-clustered, and each cluster is summarized into a tree; recall embeds your query and walks the tree for related memories across every session. Built offline, and it augments FTS5 instead of replacing it. |
| Recall Engine | - | Unifies all of the above, injecting the most relevant hits before every inference call. |
Fractal Memory is the standout: a RAPTOR-style hierarchy where raw events sit at the leaves, k-means groups related ones, and the model writes a short summary for each cluster all the way up to a single root. Your query is embedded once and traverses that tree, so Feral recalls the gist of past work, not just exact keyword hits. Classic FTS5 + SQLite stay underneath as the always-on fallback, so memory never breaks even before the tree is built.
Privacy tags: wrap sensitive content in <private>…</private> and it's stripped before any episodic write. The model still sees it during the current turn - only the database never does.
Self-improvement (BRSI)
Feral doesn't just run an agent - it improves the agent, and over time the machinery that does the improving. This is BRSI: Bounded Recursive Self-Improvement, a six-layer stack. Each layer answers to the same contract: a change only ships if it measurably beats the current best (the champion), it runs inside a sandbox with an immutable core, every step is written to a hash-chained audit log, and any regression rolls back automatically.
| Layer | What it evolves | How it stays safe |
|---|---|---|
| L1Config Evolution | Its own settings - sampling, memory, retrieval and tool parameters. Runs “dream cycles” while you're away. | A population competes on a fitness score; the champion is only replaced on a measured win. |
| L2Personal Adaptation | A private LoRA adapter trained on how you actually work, on your own GPU. | Gated by an A/B eval, so a worse adapter never ships. |
| L3Self-Code Modification | Its own source code. Feral proposes patches, tests them, and keeps only what passes. | Bounded diff size, an immutable core it can't touch, sandboxed, auto-rollback on regression. |
| L4Tool / Module Evolution | Its own tools. It builds new ones autonomously, improves them over time, and retires the ones that stop earning their keep. | Every module is eval-scored and lifecycle-managed behind a module wall. |
| L5Governance Evolution | The knobs of the improvement policy itself - confidence thresholds, fitness weights, mutation rates, budgets. | Only moves within agent-immutable bounds it cannot widen; every change is reversible. |
| L6Meta Evolution | The algorithm that produces those knobs - how it decides what to try and how it learns. Genuine recursive self-improvement. | Always human-gated. Research preview, behind the strictest promotion gate. |
Bounded by design. The layers switch on progressively, and the deep ones (code, tools, governance, meta) are gated and off by default - Meta Evolution always needs a human. The scorer and the safety bounds are part of the immutable core: the agent can improve almost everything about itself, but never the rules that keep it honest. Nothing is open-ended, and nothing ships that didn't prove it was better.
Built-in tools
A representative slice of the built-in surface (persona and connector builds add more, e.g. capture_lead, schedule_meeting). And with tool_forge the agent writes its own tools too, so the list is never fixed. Every tool declares its permissions at registration; undeclared ones are blocked. Network calls go through an egress proxy (SSRF protection, rate limiting, audit log); file tools honor a hard deny-wall on ~/.feral and ~/.ssh.
| Tool | Permission | Description |
|---|---|---|
| tool_forge | process | Create, update or delete its OWN tools. New tools transpile-check, hot-register instantly, persist in ~/.feral/tools and run sandboxed - the agent extends its own tool surface at runtime. |
| list_tools | - | Discover and enable optional tools on demand, keeping the base set lean (the tool drawer). |
| tool_health | - | Per-tool success rate and latency report; the agent diagnoses its own failing tools. |
| web_search | network | Ranked web results via a self-hosted SearXNG instance. |
| read_webpage | network | Clean Markdown from any URL via Jina Reader. |
| deep_research | network | Iterative plan → search → read → extract → synthesize; returns a cited report. |
| fetch_url | network | Fetch any public HTTPS URL (SSRF-guarded, rate-limited, audited). |
| http_request | network | Full HTTP client for APIs: GET/POST/PUT/PATCH/DELETE with headers and JSON. |
| read_file | fs:read | Read a file from the workspace. |
| write_file | fs:write | Write a file; creates intermediate directories. |
| edit_file | fs:write | Precise find-and-replace edits in place, not just whole-file writes. |
| list_directory | fs:read | List directory contents. |
| file_search | fs:read | Find files by name or glob under an allowed root. |
| grep | fs:read | Regex search across files, ripgrep-style. |
| git_status | process | Run git (status, diff, log) inside the workspace. |
| shell_exec | process | Run shell commands. Gated by FERAL_ENABLE_SHELL_EXEC. |
| scan_workspace | fs:read | Detect hardcoded secrets and code anti-patterns. Never exposes secret values. |
| code_quality | fs:read | Static code-quality analysis on the workspace. |
| recall | - | Search past conversations (episodic + Fractal Memory) for relevant context. |
| remember | - | Write a durable fact into semantic memory on demand. |
| self_describe | - | Introspect its own recent activity, tools and state. |
| delegate_task | - | Hand a self-contained sub-task to a fresh sub-agent (optionally in parallel), depth-guarded. |
| ask_user | - | Pause and ask you when the task genuinely forks - routed to wherever you are. |
| escalate_to_human | - | Hand off to the human owner when it shouldn't act alone. |
| connectors_manage | - | List and configure its own Discord / Slack / WhatsApp connectors (tokens write-only). |
| control_app | process | Drive desktop apps through the OS accessibility tree: read the UI, find elements, click and type. |
| list_skills / read_skill | fs:read | Discover and read installed SkillHub skills. |
| calculator · time_date · todo_write | - | Everyday helpers: exact math, dates and times, and a working to-do list across a task. |
Privacy, honestly
- Local models. Inference, conversations, and memory never leave your machine. No background network requests, no telemetry, no analytics - by design.
- Cloud models (BYOK). Your messages go to the provider you configured, when - and only when - you hit send. Feral talks to their API directly with your key; nothing is routed through our servers, because we don't have any.
- Web tools. Agent tools like web_search and deep_research make outbound requests through an egress proxy with SSRF protection, rate limiting, and an audit log.
- Update check. Once per launch, Feral asks GitHub Releases whether a newer version exists - only the version request, no usage data. Turn it off in Settings → General for a fully offline app.
Environment variables
The agent sidecar reads these - capable by default, restrictable by choice. The full table is in the README.
| Variable | Default | Description |
|---|---|---|
| FERAL_WORKSPACE | cwd + home | Filesystem roots file tools may touch. Set it to RESTRICT. |
| FERAL_FS_DENY | - | Extra paths file tools may never touch (on top of ~/.feral + ~/.ssh). |
| FERAL_BASE_URL | 127.0.0.1:11435 | Inference endpoint - Feral's bundled llama.cpp engine. |
| FERAL_API_KEY | - | Bearer token for the inference endpoint (BYOK / local token). |
| FERAL_MODEL | qwen2.5:7b | Model name (overridden to feral-local by the desktop app). |
| FERAL_ENABLE_SHELL_EXEC | true | Register the shell_exec tool. Set false to disable shell access. |
| FERAL_SEARXNG_URL | - | Origin of a SearXNG instance for web_search. |
| FERAL_FETCH_DOMAINS | - | Domain allowlist for fetch_url. Unset = all public hosts (SSRF guard still applies). |
License
Feral is source-available under the Business Source License 1.1 (BSL).
- ✅ Free forever for you - personal use, small businesses (under $2M annual revenue), education, research, self-hosting, modifying, redistributing.
- 🚫 Not free for big enterprise - organizations above the revenue threshold, or anyone offering Feral as a hosted service, need a commercial license.
- 🕓 Becomes fully open source automatically - each version converts to Apache 2.0 four years after its release.
Ready to try it?
Install in one command, or grab the installer for your OS from GitHub.