Skip to main content

Introduction

Note: This page is in English. Pages not yet translated are shown in Portuguese.

πŸ‡ΊπŸ‡Έ English Β· πŸ‡§πŸ‡· PortuguΓͺs

GarraIA

The secure, lightweight open-source framework for AI agents β€” written in Rust, born in Brazil.

CI CodeQL Security Audit License: MIT Stars Good First Issues

Rust Crates Channels Providers

Quick Start Β· Why GarraIA? Β· Features Β· Memory Β· Security Β· Architecture Β· Migrate from OpenClaw Β· Contributing


A personal AI assistant that runs on your machine. One self-contained native binary runs your agents on Telegram, Discord, Slack, WhatsApp and iMessage β€” with an AES-256-GCM encrypted credential vault, hot config reload, a full memory system with local embeddings, and a warm Brazilian Portuguese persona as the default voice (fully configurable, including a neutral English mode).

Every performance and comparison number in this README is measured, not asserted: the reproducible harness, the scenario definitions, and the raw evidence live in benches/agent-framework-comparison/. If a number has no committed measurement behind it, it does not appear here.

Local-first. All state β€” conversations, memory, config, credentials β€” is stored on your machine, and there is no telemetry or analytics phone-home. Your prompts go only to the LLM provider you configure; run Ollama for a fully offline setup (set GARRAIA_NO_UPDATE_CHECK=1 to also silence the once-a-day release check against the GitHub API β€” the only other outbound call garra start makes).

🐾 Meet Garra​

Garra is not just an API endpoint β€” it is a personal assistant with a personality. From the first garra start it introduces itself by name and speaks warm, direct, first-person Brazilian Portuguese (no sycophancy). When something breaks, it explains what happened and what to do next instead of dumping raw error codes.

"Oi! πŸ‘‹ Eu sou o Garra, seu assistente pessoal. Pode falar comigo como vocΓͺ falaria com um amigo."

The persona is the default, not a cage: set agent.system_prompt for a custom personality or agent.persona = "neutral" for a fully neutral tone in any language. See ADR 0012.

Quick Start​

# Requires Rust 1.97+ (matches the MSRV declared in Cargo.toml)
cargo build --release -p garraia

# Interactive setup β€” pick your LLM provider; optionally store API keys
# in the encrypted vault (the wizard's default is config.yml, mode 0600)
./target/release/garra init

# Start
./target/release/garra start

# Bare `garra` opens the chat REPL. On a clean install that is OpenRouter
# with `z-ai/glm-5.3-flash` (issue #1180). With no `agent.default_provider`
# in config, autodetect uses the first cloud provider you have a credential
# for (Anthropic > OpenAI > OpenRouter) and only falls back to local Ollama
# when none exists.
./target/release/garra

# Local Ollama is the second option β€” ask for it explicitly by naming a tag.
# A tag that is not pulled yet prompts to download it; `-y` downloads
# without asking.
./target/release/garra --model qwen3.8

# One-shot non-interactive ask β€” great for scripts and CI
./target/release/garra ask --provider openrouter \
--json --timeout-secs 30 "Reply with exactly: OK"

# MCP server over stdio β€” exposes `garra_ask` to Claude Desktop / Claude Code
./target/release/garra mcp-server
Install via script (Linux, macOS) β€” uses published release binaries
curl -fsSL https://garraia.org/install.sh | sh

Mirrors of the same script: GitHub release CDN https://github.com/michelbr84/GarraRUST/releases/latest/download/install.sh (most robust against IP rate limits; a snapshot taken at each release), https://raw.githubusercontent.com/michelbr84/GarraRUST/main/install.sh and https://cdn.jsdelivr.net/gh/michelbr84/GarraRUST@main/install.sh (both track main).

The installer downloads the binary for your platform, verifies it against the release's SHA256SUMS, then chains into init and start. It leaves two names on your PATH: garraia (the release asset) and the alias garra (a relative symlink to it), so the garra … commands used throughout this README and in the CLI's own hints work as written; a cargo build produces garra directly.

Flags (usable through the pipe with sh -s --) and their equivalent env toggles: --skip-setup (GARRAIA_SKIP_INIT=1 + GARRAIA_SKIP_START=1), --skip-init, --skip-start, --no-local (GARRAIA_BOOTSTRAP_LOCAL=0), --version <tag>, --install-dir <dir>, --help. An env var set by the caller wins over the matching flag. For a fully unattended install:

curl -fsSL https://garraia.org/install.sh | sh -s -- --skip-setup
# The project default β€” OpenRouter primary, local Ollama as the backup.
# The key is read from stdin, never from argv.
printf '%s\n' "$OPENROUTER_API_KEY" | garraia config set-routing \
--primary-provider openrouter --primary-model z-ai/glm-5.3-flash \
--backup-provider ollama --backup-model qwen3.8:latest --api-key-stdin
garraia start

In TTY-less contexts (Docker build, CI) the installer prints next steps and exits 0 instead of blocking.

Releases ship 6 prebuilt CLI binaries: Linux x86_64/aarch64, macOS x86_64/aarch64, Windows x86_64/aarch64 (the three aarch64 builds are best-effort) β€” plus, from v0.3.6, an Android aarch64 build for Termux (best-effort; see the Android section below) β€” each also as a .tar.gz (.zip on Windows) containing the binary named plainly garraia, plus LICENSE and README.md. From v0.3.4 they also carry Linux packages β€” garraia-linux-{x86_64,aarch64}.deb/.rpm and a portable garraia-linux-x86_64.AppImage (all best-effort; see docs/installation.md). The bare binaries stay published unchanged because garra update and both installers resolve assets by exact name. The Linux binaries are built against glibc 2.35, so they need Ubuntu 22.04+ / Debian 12+; older distros and musl-based systems (Alpine) have to build from source. The installer checks this before downloading.

Separately from the CLI, the Garra Desktop app (a Tauri tray app with the parrot overlay and the Chat Bar on Ctrl+Space, bundling the CLI as a sidecar) is published best-effort as garraia-desktop-windows-x86_64.msi / -setup.exe (from v0.3.4) and garraia-desktop-linux-x86_64.deb / .AppImage (from v0.3.5). Do not confuse the two AppImages: garraia-linux-x86_64.AppImage is the terminal CLI only. See docs/installation.md Β§"Garra Desktop on Linux".

Once it is installed, garra desktop opens it from the terminal β€” --status reports whether it is installed and where, --no-launch just prints the resolved path for scripts. The CLI only locates and spawns the app: it embeds no GUI and takes no Tauri dependency, so headless installs (Termux, RunPod, Docker) are unaffected (ADR 0021).

Install via script (Windows) β€” irm | iex
irm https://garraia.org/install.ps1 | iex

The Windows sibling of install.sh, at behavioral parity with it: detects the platform, resolves the latest release, verifies the download against SHA256SUMS, installs garraia.exe under %LOCALAPPDATA%\Programs\GarraIA together with a garra.cmd shim (so garra works too), puts the directory on your user PATH, then chains into init and start. No administrator rights needed.

Mirrors (same script, auto-synced): raw.githubusercontent.com, jsDelivr, and the GitHub release CDN https://github.com/michelbr84/GarraRUST/releases/latest/download/install.ps1 β€” the release CDN mirror only resolves from v0.3.4 onward, since install.ps1 landed after the v0.3.3 tag. See docs/installation.md.

irm | iex cannot receive arguments β€” there is no PowerShell equivalent of sh -s --. To pass flags, invoke the downloaded text as a scriptblock:

& ([scriptblock]::Create((irm https://garraia.org/install.ps1))) -SkipSetup

Flags mirror the shell installer (-SkipSetup, -SkipInit, -SkipStart, -NoLocal, -Version <tag>, -InstallDir <dir>, -NoModifyPath, -Help), each paired with a GARRAIA_* environment variable. GARRAIA_VERSION and GARRAIA_INSTALL_DIR set by the caller win over -Version/-InstallDir; for the on/off switches, env var and flag are OR-ed β€” either one enables the behaviour.

On Windows ARM64 the installer picks the native garraia-windows-aarch64.exe (published from v0.3.4, best-effort); pinning GARRAIA_VERSION to anything older on ARM64 fails with a 404, since those releases only served ARM64 via the x86_64 binary under emulation.

The binaries and installers are not code-signed, so SmartScreen shows "Windows protected your PC" on first run of the desktop MSI β€” expected, not tampering. See docs/installation.md for the full Windows section.

Install on Android (Termux) β€” curl | bash inside Termux

From v0.3.6 the installer has a Termux branch: run it inside the Termux app (the F-Droid or GitHub build β€” the Play Store fork is unsupported) and it detects Termux via $TERMUX_VERSION / $PREFIX, skips the glibc preflight, and installs garraia into $PREFIX/bin (on your PATH, no sudo):

pkg install curl
curl -fsSL https://garraia.org/install.sh | bash
garraia doctor # platform, dirs, config, providers, daemon β€” sysexits
garraia doctor whatsapp # the personal-WhatsApp path end to end: link, key, gateway, access, profile, workspace, MCP, provider
garraia chat # cloud provider, or --url http://PC-LAN:8080 for a LAN LLM

The Android binary targets bionic (aarch64-linux-android, API 21+, built with cargo-ndk in the build-android-arm64 release job, best-effort) β€” static musl builds are deliberately not shipped because they break DNS on Android. garra update resolves the garraia-android-aarch64 asset inside Termux. Your LLM can live in the cloud or on your LAN: any OpenAI-compatible server (llama.cpp / LM Studio / vLLM / Ollama) works via --url, and --provider llamacpp talks to a llama-server on localhost:8080. Keep the Termux session in the foreground (or acquire a wakelock) β€” Android's phantom process killer and battery optimization can stop long-running background daemons. Strategy and the Termux β†’ native roadmap live in ADR 0016.

Update an existing install β€” garra update
garra update # interactive
garra update --yes # non-interactive (CI)
garra rollback # restore the previous binary if anything goes wrong

Self-update downloads the platform binary, verifies it against the release's per-asset SHA-256 checksum (aborts on mismatch or missing checksum), and swaps the executable atomically.

Build the desktop app (Tauri)

Prebuilt bundles are on the Releases page (see above); build from source only if you need to. scripts/build-desktop-linux.sh (Linux: .deb + AppImage, prerequisites listed in its header) and scripts/build-installer.ps1 (Windows: MSI + NSIS) wrap these steps:

cargo build --release -p garraia
mkdir -p crates/garraia-desktop/src-tauri/binaries
cp target/release/garra crates/garraia-desktop/src-tauri/binaries/garraia-$(rustc -vV | grep host | cut -d' ' -f2)
cargo tauri build --manifest-path crates/garraia-desktop/src-tauri/Cargo.toml
# `cargo build --release -p garraia-desktop` gives the bare binary, no bundle

Why GarraIA?​

Measured, reproducible numbers​

Measured with the versioned harness in benches/agent-framework-comparison/ (scenarios 001, 002, 003; raw logs committed under results/). Performance was measured on openclaw@2026.7.1-2 (npm latest at run time) and a fresh ZeroClaw master clone (d355e3b); hardware and versions recorded in environment.txt. The security-audit scenarios below use separate commit-pinned inspection checkouts.

MetricGarraIAOpenClaw (Node.js)ZeroClaw (Rust)
Installed footprint47 MiB single binary (LTO, stripped)370 MiB node_modules + Node.js β‰₯ 22.22.3 runtime40 MiB binary (default lean-bundle build)
Peak RSS, --help8.6 MiB (8,756 KiB)49.2 MiB (50,388 KiB)15.3 MiB (15,704 KiB)
Cold start, --help (mean of 20)4.1 ms46.2 ms8.5 ms

Yes, ZeroClaw's default binary is 7 MiB smaller than ours β€” the table reports what the harness measured, including where we lose.

These are CLI-floor measurements, not idle-server memory β€” the harness says exactly what it measures and what it does not. Numbers above are from results/2026-08-28-vm/ (x86_64 Linux container); the dedicated 1 vCPU / 1 GB droplet run is the reference target and lands in a follow-up results directory.

Audited security posture β€” all three frameworks, pinned commits​

Verified by mechanical inspection of pinned checkouts (OpenClaw 343252a, ZeroClaw d5617f1) β€” every row has a reproducible check in scenarios 004 and 005, with per-claim evidence in results/:

GarraIAOpenClawZeroClaw
Credentials at restAES-256-GCM vault (PBKDF2, 600k iters) available; opt-in β€” the init wizard's default is config.yml at mode 0600. MCP secrets auto-move to the vault when a passphrase is setNot encrypted at rest (their docs' own words) β€” POSIX 0600/0700 perms; SecretRefs + 1Password/Vault are opt-inChaCha20-Poly1305 by default β€” the only default-encrypted posture of the three. Caveats: master key sits on the same filesystem; 1Password refs opt-in
Default bind127.0.0.1loopback127.0.0.1
Gateway auth defaultMessaging channels are deny-by-default (pairing codes). Local API is open on loopback; token/session auth is opt-inToken required out of the box; fails closed without onePairing required by default; public bind is warn-only
Dependency tree1,061 crates (Cargo.lock)66 direct prod npm deps; npm install -g resolved 300 packages on the measured run1,265 crates (Cargo.lock)
Plugin isolationWASM sandbox (wasmtime): memory caps + execution deadlines, opt-in featureIn-process, plugins are trusted code (their threat model says so)WASM component model; Ed25519 signing exists but defaults to disabled

Feature comparison​

GarraIAOpenClawZeroClaw
Chat channels11 wired in the default build (Telegram, Discord, Slack, WhatsApp, iMessageΒ·macOS, Google Chat, Teams, LINE, Matrix, IRC, Signal) + web chat + OpenAI-compatible API; the first 5 also have gateway integration tests27 bundled channel plugins~40 adapters (default build bundles 6)
LLM providers15 built-in (Anthropic, OpenAI, Ollama native + 12 OpenAI-compatible presets); 100+ models via OpenRouter; any endpoint via base_urlplugin providersmultiple, feature-gated
MCPclient: stdio (default build) + Streamable HTTP (mcp-http feature); also serves MCP over stdio (garra mcp-server, one garra_ask tool)client: stdio/SSE/Streamable HTTP; also serves MCPclient: stdio/http/sse, per-agent fail-closed scoping
MemorySQLite + local vector search (sqlite-vec) + LLM fact extraction, auto-injected into contextMarkdown files + SQLite FTS5/vectorsqlite/postgres/qdrant backends
Config hot reloadfile watch β€” most settings apply live (channels/providers wire at boot)file watch (hybrid mode)explicit reload endpoint only
Schedulingone-shot heartbeats (up to 30 days ahead) and cron recurrence with IANA timezones, delivered to the originating channel; retries failed runs with backofffull cron + automationscron + SOP engine
Multi-tenant group workspacein active development β€” Postgres 16 + pgvector, 42 tables across 36 migrations, 36 of them under FORCE Row-Level Security (Phase 3)explicit non-goal (single trusted operator)no
Native PT-BR assistant personayes β€” first-class, defaultnono
Prebuilt binaries + self-update6 targets (3 x86_64 required, 3 aarch64 best-effort), SHA-256-verified atomic self-updatenpm package (needs Node runtime)10 targets, SLSA provenance

Where the others win, honestly: OpenClaw has the broadest channel and plugin ecosystem (27 channels, 150+ extensions) plus a mature cron system, and its gateway requires auth out of the box β€” GarraIA's local API auth is still opt-in. ZeroClaw encrypts secrets by default, ships 10 prebuilt targets with SLSA provenance, and has OS-level exec sandboxing. We compare against their strengths on purpose: if this table ever reads like marketing, open an issue with the scenario ID and we will fix the table, not the finding.

Features​

LLM providers​

3 native providers β€” Anthropic Claude (SSE streaming, tool use), OpenAI (GPT-4o, Azure, any compatible endpoint via base_url), Ollama (local models + local embeddings) β€” plus 12 OpenAI-compatible presets: OpenRouter (100+ models), DeepSeek, Mistral, Gemini, Qwen, Yi, Cohere, MiniMax, Moonshot, Falcon, Jais, Sansa. Automatic provider fallback on 429/5xx with exponential backoff and a circuit breaker.

Channels​

Wired end-to-end today: Telegram (streaming, MarkdownV2, bot commands, pairing), Discord (slash commands, sessions), Slack (Socket Mode), WhatsApp (Meta Cloud API webhooks, and β€” since v0.4.3 β€” personal WhatsApp by linked device: garra whatsapp scans a QR code, keeps the session encrypted on disk and runs a Node/Baileys bridge over stdio; needs Node.js 20+ and npm on that path only β€” docs/whatsapp.md, ADR 0023; since v0.4.6, who may talk to it and how far each one goes is Access Policy v2 β€” explicit admission, a declared default for strangers, a per-principal ceiling (chat Β· read Β· full, file writes separate) and a per-group policy, driven by one engine shared by the CLI (garra whatsapp access|level|write|block|unblock|users|remove|owner|unowner), the admin API and the Web Console's WhatsApp Access page; the level is a ceiling that composes with the session mode, so it only ever removes, never grants, and garra doctor whatsapp walks the whole path end to end), iMessage (macOS, chat.db polling + AppleScript). Also: web chat console, an OpenAI-compatible API (/v1/chat/completions) for VS Code (Continue et al.) sharing the same session history, and an Anthropic-compatible POST /v1/messages shim so Claude Code can point at the gateway (ADR 0014). garra agents setup|status|link|rollback|web provisions GarraIA, OpenClaw, Hermes and Claude Code with one provider + model via AgentDeck. Six more channels ship wired in the default build: Google Chat and Teams (RS256-JWT webhooks), LINE (HMAC webhook), and Matrix (federated, E2EE), IRC and Signal (via signal-cli), which connect at boot with backoff retry. They carry unit coverage in garraia-channels but no gateway integration test yet, so the badge counts them as wired, not as CI-guarded.

Agent runtime​

Tool-execution loop (bash, file read/write, web fetch/search, repo search, git diff, scheduling) with per-task tool-call budget; sliding context window plus automatic background summarization for long sessions; execution modes (ask / code / debug / architect / review / orchestrator / custom) with per-mode tool policies, selected via /mode, header, or deterministic auto-routing. Since v0.3.9 those policies are enforced in the executor β€” before that they were only asked for in the system prompt, so a mode advertised as read-only did not actually stop file_write or bash.

Voice​

STT via Whisper (local whisper.cpp or OpenAI API); TTS via Chatterbox (GPU, multilingual), Hibiki, or any OpenAI-compatible /v1/audio/speech endpoint (LM Studio) β€” ElevenLabs and Kokoro adapters exist in garraia-channels::voice_channel but are not wired to the gateway yet; garra start --with-voice; automatic audio replies on Telegram; format conversion via ffmpeg.

MCP (Model Context Protocol)​

Connect any MCP server: stdio for local processes (default build), plus Streamable HTTP for remote ones behind the mcp-http feature (in config.yml/mcp.json use transport: stdio or transport: http; the admin API additionally accepts sse/streamableHttp, all mapped to the Streamable HTTP client; legacy SSE-only servers are not supported, and the prebuilt binaries currently ship stdio-only). Tools appear namespaced (server.tool); MCP prompts become slash commands automatically; marketplace with one-click install via the web console (/api/mcp/marketplace); admin API adds/removes servers without restart; CLI: garra mcp list|inspect|resources|prompts. Config in config.yml or mcp.json, both in the active config directory β€” ~/.config/garraia by default; see Configuration (mcp.json is Claude Desktop-compatible).

Skills & plugins​

Markdown skills (SKILL.md + YAML frontmatter) auto-discovered from <config-dir>/skills/, with a visual editor and full CRUD API. Optional WASM plugin sandbox (wasmtime, --features plugins) with per-plugin memory caps and execution deadlines.

Web console "Garra Glass"​

A no-build-step SPA served at GET / β€” dashboard, chat, providers, channels, sessions, settings, diagnostics, logs. Security invariant: no secret is ever returned by any /api/* endpoint (write-only settings report configured: true|false). Design system in ADR 0009.

Infrastructure​

Hot config reload (watched config.yml), daemonization with PID management, garra restart, runtime provider switching, structured logs (request_id, session_id, JSON via GARRAIA_LOG_FORMAT=json), configurable timeouts per subsystem, per-IP rate limiting, health checks (GET /api/health + boot table + background probes), AI-transparency headers (X-AI-Model, X-AI-Provider) on every response.

Memory and self-learning​

<config-dir>/ # ~/.config/garraia by default (see Configuration)
β”œβ”€β”€ memoria/fatos.json # LLM-extracted facts
β”œβ”€β”€ data/memory.db # SQLite + vector search (sqlite-vec)
β”œβ”€β”€ data/sessions.db # persistent conversation sessions (today under ~/.garraia/data/ unless `data_dir` is set)
└── credentials/vault.json # AES-256-GCM encrypted credentials

After conversations, a dedicated LLM extractor identifies durable facts and stores them with context and date; local embeddings (Ollama β€” nomic-embed-text, mxbai-embed-large, …) power semantic search; relevant facts are injected into the agent's context automatically.

Memory is managed from three places. The CLI covers the most ground β€” garra memory has stats, list, add, search, reindex, backup, pin, ttl, delete and compact. The web console and the gateway API cover the read paths plus a clear: GET /api/memory/recent, GET /api/memory/search and DELETE /api/memory.

memory:
enabled: true
embedding_provider: ollama-embed # key of the `embeddings` entry below
embeddings:
ollama-embed:
provider: ollama
model: nomic-embed-text
base_url: "http://localhost:11434"

Security​

Built for the requirements of always-on agents that touch private data. Wording below matches what the code does β€” audited claim by claim (see the comparison section above for the evidence trail).

  • Encrypted credential vault (opt-in) β€” AES-256-GCM at <config-dir>/credentials/vault.json, key derived via PBKDF2-HMAC-SHA256 (600k iterations) from GARRAIA_VAULT_PASSPHRASE. Stated plainly: the garra init wizard's recommended default stores provider keys in config.yml (mode 0600, plaintext); choose the vault option and export the passphrase on every start to get encryption at rest. Making the vault the default is a roadmap item.
  • MCP secrets vault-protected β€” sensitive env vars of MCP servers are auto-moved to the vault on save; mcp.json keeps only vault:mcp.<server>.<key> references. No passphrase β†’ plaintext with a loud warning, never a broken boot.
  • Channels are deny-by-default β€” per-channel allowlists; unknown users must present a pairing code; unauthorized messages are dropped.
  • Local API binds 127.0.0.1 by default β€” gateway.api_key gates the /ws WebSocket handshake (and only it); the REST surface has no api-key auth today, so protect it with topology (loopback, firewall, reverse proxy). session_tokens_required is NOT implemented and the gateway refuses to start with it set, rather than claim a protection that does not exist. Hardening these defaults is tracked on the roadmap. The HOST env var can override the bind β€” mind your container config.
  • 256-bit session tokens β€” HttpOnly, SameSite=Strict cookie (or Bearer/X-Session-Key), rotated on resume, TTL + idle timeout.
  • Two auth stacks, stated plainly β€” Auth v1 (/v1/auth/*): 15-minute HS256 access tokens + opaque HMAC-signed refresh tokens, Argon2id hashing with PBKDF2 lazy upgrade. Legacy mobile endpoints (/auth/*): 30-day JWTs, Argon2id (legacy PBKDF2 rows upgraded on first login) β€” being migrated to v1.
  • Risky-command confirmation β€” opt-in tool_confirmation_enabled pauses before destructive bash (rm -r, git reset --hard, …).
  • MCP process resource limits β€” optional per-server virtual-memory cap (setrlimit, Unix), startup timeout, auto-restart with exponential backoff. These are resource limits, not a sandbox: MCP processes keep filesystem/network access.
  • MCP child environment isolation β€” a stdio MCP server is spawned with an environment built from scratch: a minimal allowlist (PATH, HOME, locale, temp dir) plus that server's own env map. Gateway secrets (GARRAIA_JWT_SECRET, provider API keys, vault passphrase) never reach a third-party MCP binary. Per-server inherit_env: true restores the old behaviour and warns on every connect.
  • WASM plugin sandbox β€” optional (--features plugins): per-plugin memory caps and execution deadlines via wasmtime.
  • Heuristic input filtering β€” control-character sanitization plus a keyword screen for common prompt-injection phrases on chat channels and the WebSocket. It is a heuristic, not a guarantee β€” treat prompt injection as unsolved, like every framework should.
  • TLS (source builds) β€” compile with cargo build -p garraia --features garraia-gateway/tls (the feature lives on the gateway crate; the garraia binary has no tls passthrough yet) and point tls_cert_path/tls_key_path at your certs (e.g. issued via certbot/Let's Encrypt). No built-in ACME client. Honest caveats: the prebuilt release binaries do not include the TLS feature today, and with certs configured but the feature absent the gateway logs a warning and serves plain HTTP β€” both are open hardening items on the roadmap. For production, a TLS-terminating reverse proxy in front of the loopback bind is the recommended setup.

Execution profiles​

Everything above is the standard profile β€” the posture for a shared machine. For a disposable pod (RunPod, Docker) that exists precisely so the agent can act with full autonomy, declare it β€” the profile is never inferred from container markers, and an invalid value refuses to boot:

execution:
profile: isolated-pod # or GARRAIA_EXECUTION_PROFILE=isolated-pod (wins)
pod_root: /workspace # optional, absolute; MCP filesystem root
channels:
whatsapp_linked:
type: whatsapp_linked
enabled: true
owners: ["5511999998888"] # only declared owners, only in 1:1 chats

Full power inside the isolated pod; no implicit access outside the pod. The WhatsApp owner gets the code floor (bash, file_write, MCP tools); groups and paired-only contacts never inherit it; the bash risky-command gate and file jail stay on; a mounted host filesystem, the Docker socket or host secrets are not isolated by the profile. Guide: docs/execution-profiles.md, ADR 0024.

Migrating from OpenClaw?​

garra migrate openclaw # --dry-run to preview, --source <dir> for custom paths

Imports your skills and channel configurations. Credential files are detected and listed but not copied β€” re-enter API keys via garra init (pick the vault option there to store them encrypted).

Configuration​

GarraIA reads config.yml from its config directory, resolved as $GARRAIA_CONFIG_DIR β†’ ~/.config/garraia (the default on new installs) β†’ ~/.garraia (legacy, only when the XDG dir does not exist). Run garraia config check to see which directory and file are active. Details in docs/installation.md:

# The bind comes from --host/HOST and --port/PORT (default 127.0.0.1:3888);
# gateway.host/gateway.port are deprecated and never bound the socket (#1261).

llm:
claude:
provider: anthropic
model: claude-sonnet-4-5
# api_key resolution: vault > config > ANTHROPIC_API_KEY env var
ollama-local:
provider: ollama
model: qwen3.8:latest
base_url: "http://localhost:11434"

channels:
telegram:
type: telegram
enabled: true
bot_token: "your-bot-token" # or TELEGRAM_BOT_TOKEN

agent:
max_tokens: 4096
fallback_providers: [openrouter, ollama-local]
max_history_messages: 20
summarize_threshold: 40

memory:
enabled: true # embeddings + `embedding_provider`: see "Memory and self-learning"

Run garra config check to validate the effective configuration with precedence reporting. Full reference β€” including Discord, Slack, WhatsApp, iMessage, voice, embeddings, MCP, timeouts, rate limiting and .garraignore β€” in docs/ and the Portuguese README.

Architecture​

A Rust workspace of 22 crates, each with a single responsibility:

crates/
β”œβ”€β”€ garraia-cli/ # CLI, init wizard, daemon management, self-update
β”œβ”€β”€ garraia-gateway/ # WebSocket gateway, HTTP API, web console, REST v1
β”œβ”€β”€ garraia-agents/ # LLM providers, tools, MCP client, agent runtime
β”œβ”€β”€ garraia-channels/ # 11 wired: Telegram, Discord, Slack, WhatsApp, iMessage, Google Chat, Teams, LINE, Matrix, IRC, Signal
β”œβ”€β”€ garraia-auth/ # Auth v1: Argon2id, JWT HS256, RBAC, RLS-backed identity
β”œβ”€β”€ garraia-workspace/ # Postgres 16 + pgvector multi-tenant (42 tables / 36 migrations, 36 under FORCE RLS)
β”œβ”€β”€ garraia-security/ # Credential vault, allowlists, pairing, validation
β”œβ”€β”€ garraia-db/ # SQLite memory, vector search, sessions
β”œβ”€β”€ garraia-config/ # YAML/TOML config, hot reload, `config check`
β”œβ”€β”€ garraia-voice/ # Whisper STT β†’ LLM β†’ Chatterbox/Hibiki TTS
β”œβ”€β”€ garraia-plugins/ # WASM plugin sandbox (wasmtime)
β”œβ”€β”€ garraia-embeddings/ # EmbeddingProvider / VectorStore traits
β”œβ”€β”€ garraia-learning/ # Self-improving skills (mining, safety gate, versioning)
β”œβ”€β”€ garraia-hardware/ # Physical devices: Device trait, R0-R5 risk gate, MQTT/Home Assistant/serial/GPIO adapters
β”œβ”€β”€ garraia-desktop-core/ # Tauri-free core of the Desktop Control Center (state, detect, supervise, locate)
└── ... # telemetry, media, skills, storage, common, glob, desktop
apps/
└── garraia-mobile/ # Flutter client (Riverpod, go_router) β€” Garra Cloud Alpha

Deep dives: runtime flow & voice pipeline, ADRs, wiki.

Documentation site (generated from this repo's markdown): https://michelbr84.github.io/GarraRUST/.

Roadmap​

Development follows a 7-phase plan in ROADMAP.md β€” currently deep in Phase 3: Group Workspace, a multi-tenant family/team space (files, chats, AI memory, Notion-like tasks) on Postgres 16 + pgvector with FORCE Row-Level Security. Recent milestones: auth v1 (Argon2id + 15-min JWTs + refresh tokens), the 37-table RLS schema, tus resumable uploads, object storage (local + S3), OpenTelemetry baseline, the Garra Learning agent, this benchmark harness, and the v0.3.x distribution wave (Aug–Sep 2026): install.sh/install.ps1, Linux .deb/.rpm/AppImage, native Windows ARM64, garra agents setup with the Anthropic-compatible /v1/messages shim, and Garra Desktop for Linux with the Chat Bar.

v0.4.9 (Oct 2026) landed two big fronts and a security sweep. Data-subject rights went live: GET /v1/me/export now returns a user's personal content across every group they belong to (messages, mentions, files, memories, tasks) and declares what it left out, PATCH /v1/me changes an email through a safe out-of-band flow instead of blindly, and DELETE /v1/me queues a 30-day-grace erasure run by a dedicated-credential worker. The gateway also became an MCP server over HTTP with task delegation β€” garra_ask, garra_agent, external orchestrators with their own identity, policy, and per-orchestrator audit, and operator-defined regex redaction β€” all off by default and fail-closed. Alongside: 24 RUSTSEC advisories closed in one pass, verifiable provenance attestation on every release asset, and the request path now rejects unwrap()/expect(). See What's New in v0.4.9.

Contributing​

GarraIA is MIT-licensed open source. Join the Discord, check CONTRIBUTING.md, and filter by good first issue. Support channels are listed in SUPPORT.md; security reports go through SECURITY.md.

License​

MIT