Architecture
A technical overview of how Gumm is designed and how the components interact.
High-level diagram
┌──────────────────────────────────────────────────────┐
│ Frontend │
│ Chat · Modules · Brain · History │
│ (Nuxt 4 + TailwindCSS) │
└─────────────────────────┬────────────────────────────┘
│ HTTP / SSE
┌─────────────────────────▼────────────────────────────┐
│ Backend (Nitro + Hono) │
│ │
│ ┌───────────┐ ┌────────────────┐ ┌──────────────┐ │
│ │ Brain │ │ Module Registry│ │Context Window│ │
│ │ (identity │ │ (hot-swap │ │ (system │ │
│ │ memory) │ │ file watcher)│ │ prompt) │ │
│ └─────┬─────┘ └───────┬────────┘ └──────┬───────┘ │
│ │ │ │ │
│ ┌─────▼────────────────▼───────────────────▼──────┐ │
│ │ SQLite (LibSQL) │ │
│ │ conversations · messages · memory · modules │ │
│ │ events · brain_config · api_connections │ │
│ └──────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ Redis │ │ Rate Limiter / Cache │ │
│ │ (rate limits, │ │ (in-memory fallback │ │
│ │ auto-memory) │ │ when Redis is down) │ │
│ └─────────────────┘ └─────────────────────────┘ │
└─────────────────────────┬────────────────────────────┘
│ HTTPS
┌──────────▼──────────┐
│ OpenRouter │
│ (LLM Gateway) │
│ GPT-4 · Claude │
│ Mistral · Llama │
└─────────────────────┘
Technology stack
| Component | Technology |
|---|---|
| Runtime | Bun v1.1+ |
| Framework | Nuxt 4 (SSR/SPA hybrid) |
| Server engine | Nitro with Hono router |
| Frontend style | TailwindCSS |
| Database | SQLite via LibSQL + Drizzle ORM |
| Cache / State | Redis (redis-stack-server) |
| Auth | nuxt-auth-utils (encrypted session cookie) |
| LLM gateway | OpenRouter |
| Container | Docker (oven/bun:alpine) |
Request flow (chat message)
- User sends a message via the web UI or CLI
- Guardrail check — sensitive data patterns (credit cards, API keys, etc.) are detected and stripped before proceeding
- Context window is assembled: system prompt (identity + memory + knowledge) + conversation history
- Module tools — all active module tool definitions are appended to the payload
- Request is sent to OpenRouter
- OpenRouter response is streamed back
- If the response contains tool calls, they are executed:
- The tool name is matched to the owning module in the registry
- The module’s
handler(toolName, args, ctx)function is called - The result is fed back into the conversation
- The final assistant message is stored in SQLite and returned to the user
- Auto-memory runs in the background — a lightweight LLM call extracts personal facts from the exchange and stores them in memory
Module system
The Module Registry is a singleton that:
- Watches
modules/official/(bundled, read-only) - Watches
modules/user/(Docker volume, hot-reloaded) - Validates each module’s
manifest.jsonagainst a Zod schema - Uses
await import('path?t=' + Date.now())for cache-busted dynamic imports - Checks the database for the module’s enabled/disabled status before importing
When a module file changes on disk, the registry detects it and reloads the module without restarting the server.
If a module throws during load, the error is caught and the module is marked with status error — the rest of the system continues running.
Database schema (key tables)
| Table | Purpose |
|---|---|
conversations | Chat conversation metadata (id, title, timestamps) |
messages | Individual messages — role, content, tool calls |
memory | Persistent key-value facts (namespaced, typed) |
modules | Module registry — metadata, status, source |
brain_config | All configuration entries (key/value JSON) |
api_connections | OAuth connection metadata (tokens stored encrypted) |
events | Event log for inter-module communication |
user_secrets | User-facing secret vault (salted hash for passwords) |
schedules | Registered CRON jobs from modules |
Security layers
See the full Security document. In brief:
- VPN Guard middleware — rejects non-VPN IPs when network mode is active
- Session auth — bcrypt password + encrypted cookie for all API routes
- Rate limiter — Redis-backed sliding window on chat and auth endpoints
- Guardrail — DLP pattern matching strips secrets before they reach the LLM
- Module isolation — failed modules don’t crash the server
- Telegram whitelist — only allowed chat IDs can send messages
Networking
Gumm has Tailscale and NetBird built into the Docker image. The VPN daemon starts automatically when auth credentials are configured via the dashboard. The entire configuration is done through the UI — no host-level setup is required.
Port binding is controlled by VPN_BIND_IP in .env. When set to a VPN IP, the GUmm port is only reachable from VPN peers.