Rapa — Self-Hosted AI Agent Platform
A full-stack AI agent platform you run on your own machine. Chat with any OpenAI-compatible LLM in three modes — Chat (direct conversation), Agent (an autonomous tool-using loop), and Plan (read-only analysis) — while the agent reads and writes files, runs shell commands, searches the web, drives a headless browser, manages Git, and talks to MCP servers, all bounded to a workspace directory you choose.
SQLite by default — no daemon, no cloud, no Docker required. The same code runs hosted with MySQL/PostgreSQL by switching the Prisma provider.
Highlights
- Three modes, one UI — Chat, Agent, and a read-only Plan mode with a hard tool allowlist.
- 58 tools, 11 categories — filesystem, code editing, shell, web, browser automation (Playwright), Git, image generation, document generation, scheduling, notifications/email, and MCP passthrough.
- Workspace-scoped by design — every file and shell action is bounded to your workspace; symlink escapes are rejected, secrets are stripped from child processes, and write/shell tools require your approval by default.
- A real agent harness — parallel read-only batches, sequential writes, context compaction with file restoration, loop/stall detection, run limits (tokens / cost / duration), circuit breakers, and tracing with optional Langfuse export.
- Isolated sub-agents —
spawn_agentruns a fresh-context, read-only child agent that investigates and reports back, keeping the parent's context clean. - Verify-before-done — when the agent edits code, the harness runs the workspace's tests and typecheck; a failing suite bounces the "done" answer back for one fix round.
- AGENTS.md support — your workspace's
AGENTS.md/CLAUDE.md/.cursorrulesis injected at run start, wrapped injection-safe. - Key rotation — register multiple API keys per provider; Rapa auto-rotates when one hits a rate limit.
- Scheduling — cron / interval / one-shot agent runs with history.
- Built-in IDE surface — file tree with context menu, Go-to-file (Ctrl+P), Find-in-files, and an embedded terminal (xterm.js).
Quick start
Prerequisites: Node.js 20+ and Git. That's it.
git clone https://github.com/rafael-fu2025/rapa-agent.git
cd rapa-agent
npm install
cd server && npm install && cd ..
cp server/.env.example server/.env
# Optional: edit server/.env — the defaults work out of the box.
# Generate an APP_SECRET (already set in .env.example for local dev):
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
cd server
npx prisma generate
npx prisma migrate dev --name init
cd ..
# Terminal 1 — backend (Fastify on 127.0.0.1:8787)
cd server && npm run dev
# Terminal 2 — frontend (Vite on http://localhost:5173)
npm run dev
Then:
- Add a provider — Settings → pick a provider (Gemini recommended) → paste your API key. Keys are encrypted (AES-256-GCM) before storage.
- Add a workspace — sidebar → Add Workspace → pick a project folder. The agent can now read and write inside it; each conversation pins its workspace.
Configuration
Everything lives in server/.env (see server/.env.example).
The agent loop
User prompt
→ seed history (conversation memory, rules, specialists, AGENTS.md)
→ iterate up to maxIterations:
call LLM → parse tool calls → execute
read-only tools in parallel (identical re-reads stubbed)
write/shell tools sequentially, with approval gates
checkpoint validation: lint + throttled tests/typecheck
ask_user? → return question to the user
context >65%? → compact + re-attach recently-read files
→ tool-free answer → verify-before-done gate (tests + typecheck)
→ done event (carries verification status)
Events stream to the browser over SSE (WebSocket only for the terminal PTY). Full architecture, module map, and conventions: AGENTS.md.
Tools at a glance
58 tools across 11 categories:
Development
npm test # frontend (66 tests)
cd server && npm test # backend (571 tests)
npm run typecheck && cd server && npm run typecheck
npm run lint && npm run lint:server # zero warnings allowed
cd server && npm run test:coverage # per-area coverage gate
637 tests total, all passing. All four gates (type-check, lint, tests, coverage) run green before every commit. See CONTRIBUTING.md for the full workflow.
Deployment
Personal machine (default) — two terminals as in Quick Start.
Docker — SQLite on a volume, works out of the box:
export APP_SECRET=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")
docker compose up --build
APP_SECRET is required — compose refuses to start without it. MySQL is an
opt-in for hosted setups (instructions in docker-compose.yml).
Hosted (multi-user) — switch the Prisma provider to mysql or
postgresql, point DATABASE_URL at your database, set HOST=0.0.0.0 and
CORS_ORIGINS, then npx prisma migrate deploy && npm run build && npm start.
Security model
- Workspace boundary — absolute paths and
..rejected;realpathresolves symlinks and re-checks, so links pointing outside the workspace are refused. - Sanitized shell env —
APP_SECRET,DATABASE_URL, and every*_API_KEY/*_SECRET/*_PRIVATE_KEYare stripped before any child process runs. - Encrypted at rest — provider API keys are AES-256-GCM encrypted with
APP_SECRET. - Approval gates — write/shell/destructive tools require explicit
approval; a dangerous-pattern overlay (e.g.
rm -rf /) is checked even for auto-approved commands. - Injection defense — untrusted tool output and workspace instruction files are scanned and wrapped as data, never executed as instructions.
- JWT auth — every route except health/auth sits behind token auth, with per-IP rate limiting.
Common issues
- "No agent tools were registered" — a tool import failed; check backend logs for the missing dependency.
- "Missing API key" — Settings → provider → add key → confirm it's active.
- PTY not starting on Windows —
node-ptyneeds VS Build Tools (C++ workload); the shell falls back tochild_process.execwithout it. - SQLite "database is locked" — a stray node process holds the file; stop it and restart.
Acknowledgements
The harness design draws on the best of the open agent ecosystem — Claude Code's compaction and sub-agent patterns, QoderWork's tool catalog, Odysseus's stall detection, and the Model Context Protocol spec.