A home for your agents.
Self-hosted AI agent runtime — personal assistants, autonomous workers, and everything in between.
Setup Guide · Architecture · Configuration · Worker Guide · API Reference
Nerve is a self-hosted runtime for AI agents, built around the Claude Agent SDK. It gives agents everything they need to be useful long-term: persistent memory, scheduled execution, task management, learnable skills, and channels to reach you through — web UI, Telegram, Slack, or autonomous cron jobs.
Ship a personal assistant that develops a personality, remembers your preferences, and manages your inbox. Or deploy a worker agent that monitors your CI, reviews PRs, and fixes flaky tests — all plan-driven with human approval. Same engine, different mission.
curl -fsSL https://raw.githubusercontent.com/ClickHouse/nerve/main/install.sh | bashThe installer puts the dependencies in place (Python, Node.js, uv), clones the repo and runs nerve init. That asks three questions in the terminal — server or Docker, where the files live, which port and address — then starts Nerve and prints the address of the setup page with a one-time setup token. Everything else (your account, personal assistant or worker, the model provider, channels, memory, scheduled jobs) is decided in the browser. See the Setup Guide.
Manual install
Prerequisites: Git, Python 3.13+, uv, Node.js 22.12+
git clone https://github.com/ClickHouse/nerve.git && cd nerve
uv sync # creates .venv from uv.lock
source .venv/bin/activate
nerve init # builds the web UI, starts Nerve, prints the setup page + tokenPrefer to answer everything in the terminal? nerve init --terminal is the full
wizard; it does not start Nerve, so follow it with nerve start. For hosts with
no terminal at all, see unattended installation.
nerve upgrade
nerve restartRuns git pull, reinstalls Python deps, and rebuilds the web UI in one shot. Use --no-pull, --no-deps, or --no-frontend to skip steps. For Docker deployments, rebuild the image instead: git pull && docker compose build && docker compose up -d.
No API key? Use your Claude subscription instead
A full-featured assistant for one human. Syncs your email, remembers your preferences, develops personality over time. Comes with a web UI, Telegram bot, memory, cron jobs, and notifications out of the box.
"You assist one person over the long run." — from the Personal SOUL template
- Workspace files define personality (
SOUL.md), identity (IDENTITY.md), and user context (USER.md) - Memory categories are life-oriented: relationships, finances, travel, health, work
- Default crons: inbox processor, task planner, memory maintenance
- The agent develops opinions, follows up on past conversations, and gets better the longer you use it
A task-focused autonomous agent for teams or programmatic deployment. Monitors something, proposes fixes, implements after approval. Plan-driven with a full audit trail.
"You are a specialist with one mission, set out in
TASK.md, and an explicit quality bar." — from the Worker SOUL template
- Self-configuring: give it a plain-English task description and it researches, writes its own
TASK.md, creates skills, sets up cron jobs, and starts working - Memory categories are operational: patterns, procedures, decisions, approvals, infrastructure
- No
IDENTITY.mdorUSER.md— workers execute a mission, not build a relationship - Built for reliability: plan before acting, verify after executing, log everything
The mode is chosen on the setup page: run nerve init, open the page it
prints, and pick Worker on the Mode step — it asks for a plain-English task
description and the agent onboards itself on first boot. The same choice in a
terminal is nerve init --terminal; unattended installs set NERVE_MODE=worker
(and NERVE_TASK):
# Spin up a worker that monitors CI and fixes flaky tests, with no browser
NERVE_MODE=worker NERVE_TASK="Monitor CI for flaky tests and propose fixes" \
ANTHROPIC_API_KEY=sk-ant-REPLACE NERVE_PASSWORD=REPLACE \
nerve init --non-interactive && nerve start| 🧠 Memory that persists | Dual-layer memory: curated hot memory loaded every session + semantic search over your entire history. Agents remember context, preferences, and lessons learned — permanently. |
| 🔧 Self-evolving skills | Agents watch for repeated workflows and propose reusable skills automatically. Skills are plain Markdown — agents read, create, and improve their own procedures over time. |
| 📋 Autonomous task planning | A background planner explores open tasks, researches codebases, and proposes implementation plans — without being asked. You review and approve; the agent executes. |
| 📡 Multi-source awareness | Gmail, GitHub, and Telegram flow into a unified inbox with Kafka-style cursors. Multiple consumers process the same data independently — inbox triage, digest generation, task extraction. |
| ⚡ Single process, zero ops | No Docker required, no message queues, no service mesh. FastAPI + uvicorn + asyncio. Runs on a Raspberry Pi. |
| 🔑 No API key required | Optional OAuth proxy routes through your Claude Max/Pro subscription. Zero API costs. |
| 🔄 Session persistence | Sessions survive server restarts. Fork conversations, resume from any point, run up to 4 concurrent agent sessions. |
| 🛡️ Human-in-the-loop | Agents can pause mid-turn to ask questions via any channel. Plans require approval before execution. Destructive actions need explicit consent. |
Every channel shares the same agent engine, memory, and tools.
Full React + Vite + TailwindCSS frontend served by FastAPI. Real-time streaming over WebSocket.
- Chat with session history, branching, and resume
- Setup wizard: claim the instance, choose a mode, connect a model, configure channels, sources and jobs — re-enterable from the Setup entry
- Inline diff viewer for file changes (no git required)
- Task manager, memory browser, skill editor
- Source inbox, notification center, cron logs
- Plan review with approval/decline/revision workflow
- JWT auth, self-signed HTTPS via mkcert
Powered by python-telegram-bot v21+.
- Streaming responses via edit-in-place
- Inline keyboard buttons for interactive tool questions
/replycommand for free-text answers- Configurable DM policy (
openorpairing)
Reach your agent where your team already works — a direct message, or a channel you have invited it to. Nothing to expose: it connects outwards, so it runs behind NAT with no public URL.
- Answers appear as they are written, and stay in the thread you started
- Each thread is its own conversation, so several people can work in one channel
- In a channel it stays quiet until you
@mentionit - Reply to its questions by pressing a button, or send it a file to read
- You decide who may talk to it and where — by person, by channel, or both
Scheduled AI sessions via APScheduler. Three session modes:
| Mode | Behavior |
|---|---|
| Isolated | Fresh session per run. No prior context. Best for briefings, cleanup, reports. |
| Persistent | Accumulates context across runs. Optional rotation to manage token usage. Reminder mode for lightweight follow-ups. |
| Main | Runs inside the user's primary conversation — full context access. |
Built-in crons (personal mode): skill-extractor (12h), skill-reviser (weekly), inbox-processor (30min), task-planner (4h). Worker mode ships with skill-reviser and skill-extractor on and task-planner off; the onboarding session enables task-planner when the worker should plan through the approval loop, and configures the worker's own crons.
Cursor-based data ingestion pipeline. Each source runs as an independent APScheduler job.
- Telegram — Telethon user-account API (
updates.getDifference) - Gmail —
gogCLI with 2-step fetch and LLM condensation - GitHub Notifications —
gh apienriched with PR/issue content - GitHub Events — Pushes, PRs, reviews, comments
Multiple independent consumers read the same inbox at their own pace. Content is prefixed with untrusted-data warnings to prevent prompt injection.
Two layers, one seamless experience.
L1 — Hot Memory (MEMORY.md) Curated facts injected into every system prompt. Active projects, current deadlines, operational lessons. Tagged with dates, automatically evicted when stale.
L2 — Deep Memory (memU) Semantic search over everything — conversations, facts, preferences, events. SQLite-persisted. Uses vector embeddings when an OpenAI key is configured, or LLM-based ranking with Anthropic models only.
- Four memory types:
profile,event,knowledge,behavior - Automatic conversation indexing on session close
- Pre-recall: relevant memories delivered with the first message when sessions start (kept out of the system prompt so it stays cacheable across sessions)
- 3-level quality filtering prevents generic facts from polluting memory
- Semantic deduplication (cosine similarity 0.85 threshold)
- Full audit log of all mutations
Memory categories adapt to mode — personal agents track relationships, health, and finances; workers track patterns, procedures, and approvals.
Markdown files backed by SQLite FTS5 full-text search.
- Statuses:
pending→in_progress→done/deferred - Duplicate detection: exact URL match + fuzzy FTS fallback
- Escalation reminders: deadline → +30min follow-up → +2h URGENT (respects quiet hours)
- Full markdown editor in the web UI
The agent's procedural knowledge. Pure Markdown files that agents read, create, and update themselves.
workspace/skills/
└── my-skill/
├── SKILL.md # Instructions (YAML frontmatter + markdown)
├── references/ # On-demand documentation
├── scripts/ # Executable code (30s timeout)
└── assets/ # Supporting files
- Progressive disclosure: only name + description in system prompt; full content loaded on demand
skill-extractorcron proposes new skills from repeated workflowsskill-revisercron reviews existing skills for accuracy- Usage statistics tracked per skill
Proactive task planning with human-in-the-loop approval.
- Planner cron picks open tasks autonomously
- Agent explores codebase, researches approaches, proposes implementation plan
- User reviews → approves / declines / requests revision
- Approved plans spawn implementation sessions automatically
Revisions happen in the same persistent planner session — full context preserved.
Async communication between agent and human, delivered to the web UI, Telegram,
and Slack. notifications.channels chooses which of them; all three are on by
default and a transport that is off is skipped.
notify— Fire-and-forget alerts (status updates, completions, reminders)ask_user— Questions with predefined options, rendered as buttons- Priority levels:
urgent,high,normal,low
nerve (single Python process)
│
├── Gateway (FastAPI)
│ ├── REST API — sessions, tasks, memory, plans, sources, diagnostics
│ ├── WebSocket — real-time streaming, answer routing
│ └── Static files — serves the React web UI
│
├── Agent Engine (Claude Agent SDK)
│ ├── ~30 custom MCP tools (tasks, memory, skills, sources, notifications)
│ ├── Interactive mid-turn pausing (AskUserQuestion, plan approval)
│ ├── File snapshot hooks → session-scoped diffs without git
│ ├── Session lifecycle: created → active → idle → stopped → archived
│ └── Up to 4 concurrent sessions (configurable)
│
├── Channels
│ ├── Web — passive WebSocket channel
│ ├── Telegram — bot with streaming + inline keyboards
│ └── Slack — bot with streaming + buttons, per-thread sessions
│
├── Cron (APScheduler)
│ ├── AI jobs (isolated / persistent / main session modes)
│ └── Source sync jobs (Telegram, Gmail, GitHub)
│
├── Memory
│ ├── File-based hot memory (L1)
│ └── memU semantic index (L2, SQLite + embeddings)
│
├── Tasks — Markdown + SQLite FTS5
├── Skills — Filesystem + DB index + usage tracking
├── Plans — SQLite with approval workflow
├── Notifications — Multi-channel delivery
└── Proxy (optional) — Claude OAuth, no API key needed
Three layers, lowest precedence first:
<workspace>/config/settings.yaml— shareable settings, git-tracked with the workspace (this is the layer you review in a PR and sync between machines)config.yaml— machine-local settings (gitignored)config.local.yaml— secrets and personal overrides (gitignored)
See docs/config.md for all options.
- Python 3.13+
- uv (recommended package manager)
- Node.js 22.12+ (for web UI build)
- Claude Code CLI (bundled with
claude-agent-sdk) - Anthropic API key or Claude subscription via CLIProxyAPI proxy
- Optional: OpenAI API key (for vector-based memory search — without it, LLM-based recall is used), Telegram bot token, gog CLI, gh CLI
| Doc | Description |
|---|---|
| Architecture | System overview, modes, deployment, data flow |
| Setup | Installation, the browser setup wizard, the setup token, Docker, HTTPS, systemd |
| Config | All config options with descriptions and defaults |
| Accounts | Local accounts, actor identity, the first-start bootstrap and the signing secret |
| Worker Guide | Worker mode setup, onboarding, plan-approve loop |
| Personal Best Practices | Running a personal assistant well: brain files, memory tiers, approval classes, turn shape, safety hygiene |
| Worker Best Practices | Running an autonomous worker well: TASK.md anatomy, plan-approve-execute, task state machine, CI results comments, escalation |
| API Reference | REST API and WebSocket protocol |
| SDK Sessions | Session lifecycle, resume, forking |
| Sources | Sync engine, cursors, consumer model |
| Tasks | Task file format, escalation rules |
| Memory | Memory file conventions, memU integration |
| Cron | Job format, session modes, built-in crons |
| Plans | Plan proposal, approval, and implementation workflow |
| Web UI | Frontend architecture, building, development |
pytest tests/ -v