Self-hosted AI agent · one static binary · MIT
The agent that can't slip its leash.
gcrab is a self-hosted AI agent with an exec policy it can't turn off and approvals it can't answer — enforced outside the model, so a compromised or confused agent can't delete its own leash. One ~6 MB static binary on a 512 MB VPS. Zero dependencies, nothing to expose. Every message, tool call, and policy decision lands in an append-only log you can replay.
Talks to you on Telegram or the terminal. Anthropic API or any local model (Ollama, llama.cpp, vLLM).
Sound familiar?
Built against the failure modes, not the feature lists.
The big self-hosted agents are impressive — and heavy. Every gcrab design decision started from a failure report filed against one of them.
They eat your VPS.
Heavyweight agents want 2 GB+ of RAM, hundreds of packages, and still get OOM-killed after days of uptime.
gcrab: ~6 MB binary, ~20 MB idle, runs on 512 MB. systemd unit ships with MemoryMax=256M.
They burn tokens on nothing.
Workspace dumps, skill files, and memory injected on every request — a fortune on API models, unusable on local ones.
gcrab: hard context budget, enforced before every call. A trivial message costs tens of tokens.
They quietly rewrite history.
Silent compaction, poisoned summaries, cross-session leaks — a mutable session store you can't trust.
gcrab: history is derived from an append-only event log. Trims are logged. Nothing is silent.
Their safety can be talked around.
In-band approvals a model can echo past, dangerous-command checks that some backends skip entirely.
gcrab: approvals are out-of-band operator prompts. The deny backstop applies in every mode, always.
Their channels drop and misroute.
Reconnect storms that get accounts banned, replies routed to the wrong person, listeners that die until manual restart.
gcrab: jittered-backoff circuit breaker; sessions structurally bound to one chat. Empty allowlist = refuses to start.
Their setup is a weekend.
Node versions, plugin repair loops, gateway config, docs longer than the codebase.
gcrab: init → doctor → chat. Three commands. doctor tells you exactly what's wrong.
On paper
gcrab vs. the heavyweight agents
| gcrab | Typical heavyweight agent | |
|---|---|---|
| Install | One ~6 MB static binary. No runtime, no packages. | Node or Python runtime + hundreds of dependencies; 2 GB+ RAM recommended. |
| Idle footprint | ~20 MB RAM. Happy on a 512 MB VPS. | 400–800 MB idle; OOM kills reported on small hosts. |
| Context per message | Tens of tokens, hard 8K budget re-checked before every call incl. tool loops, trims logged. | 12–20K tokens injected per request; local models crawl. |
| Cost control | A spend cap that halts. Set a daily $/token ceiling and gcrab stops before the call that would cross it. A meter rides every reply. | Watch the bill climb. No hard cap; the leading one closed the request as “not planned.” |
| Session history | Append-only, replayable event log. gcrab replay shows everything. |
Mutable store with silent auto-compaction and summary bleed-through. |
| Approvals | Out-of-band operator prompt, nonce-correlated. Model output can't satisfy it; neither can a stale or cross-chat reply. | In-band mechanisms — bypasses via echoed text reported. |
| Dangerous commands | Deny backstop in every mode, on every backend. Config is additive — it cannot shrink the list. | Checks skipped in some backends by design. |
| Unconfigured chat bot | Refuses to start. Deny-by-default allowlist. | Misconfiguration can leave instances open to the internet. |
| Local models | First-class. Any OpenAI-compatible endpoint; budget sized for 8B models on CPU. | Supported in name; context bloat makes them impractical. |
"Typical heavyweight agent" figures reflect published documentation, release notes, CVE advisories, and community bug reports for the popular open-source agent platforms as of mid-2026. Your mileage—and their next release—may vary. gcrab does less than they do, on purpose.
Install
One command. Then three.
The installer downloads to disk first, verifies the checksum, and installs to ~/.local/bin. It refuses to install if it can't verify. For an independent, off-server anchor, cross-check SHA256SUMS against the GitHub release.
curl -fsSLO https://gcrab.com/install.sh && sh install.sh
gcrab init # write config (~/.gcrab/config.json, chmod 600)
export GCRAB_ANTHROPIC_API_KEY=sk-ant-… # your key — or edit the config, or point at a local model
gcrab doctor # checks keys, permissions, connectivity, memory pressure
gcrab chat # talk to it — or `gcrab run` under systemd for Telegram
macOS / Windows: the binary is unsigned, so on first run allow it past Gatekeeper (xattr -d com.apple.quarantine ~/.local/bin/gcrab) or SmartScreen. Linux runs as-is.
Design principles
Boring is the feature.
Hard context budget
A token ceiling enforced before every provider call — including every round inside a tool loop, where heavier agents let context grow unbounded. Every trim is visible in the log.
Replayable event log
History is derived from an append-only log — no separate mutable store to poison, no hidden summarization. Sequence-numbered, so a missing record shows up as a GAP instead of passing as continuity.
Policy outside the tools
Every exec is checked, in every mode, on every backend. The destructive-command backstop cannot be switched off.
Plaintext memory
One human-editable MEMORY.md with a byte cap. Symlink it into a git repo. No database, no embeddings, no magic.
Workspace jail
File tools cannot reach outside the workspace. Traversal and absolute paths resolve back inside, no path component may be a symlink, and opens use O_NOFOLLOW. The workspace lives outside the data dir, so even a jail failure can't reach your keys.
Deliberately small
Four native tools. Two channels. No plugin marketplace, no browser automation in core, no self-modifying skills. MCP arrives in v0.5 for everything else.