n3rv
Invisible engineering infrastructure for opencode agents.
The harness that contains, restrains, and orchestrates LLMs — A2A hub, persistent semantic memory, code graph, and structured SDD workflows. The daemon runs beneath your workspace. You never see it.
Maintained by Juan Manuel Daza · n3rv.daza.ar · Apache-2.0 · Python ≥3.11
What This Is
n3rv is a runtime library and config generator for opencode. It scaffolds any repo (python/node/go/generic) into an agent-native workspace: skills, MCP servers, daemon, and provider abstraction. Satellites and standalone projects use it at runtime for provider resolution and task routing.
your-project/
├── AGENTS.md ← coding standards for every agent
├── opencode.json ← 4 MCP servers + env wiring
├── .opencode/ ← skills, agents, commands, plugins
├── .n3rv/ ← Geofront: memory, code_graph, hub-state, logs
│ ├── memory/chroma/ ← ChromaDB vectors (Melchior)
│ ├── memory/relations.db ← SQLite relations (Balthasar)
│ ├── code_graph.db ← AST index (symbols/imports/calls)
│ ├── exec.db ← lint/test cache (XXH3)
│ ├── hub-state/ ← persisted A2A tasks
│ └── a2a-config.yaml ← hub host/port + project name
└── .githooks/pre-push ← SDD verification gate
Features
| Subsystem | What it does |
|---|---|
| 4 MCP Servers | n3rv-memory (12 tools), n3rv-hub (5), n3rv-exec (8, universal 20+ langs), n3rv-code-graph (6) |
| A2A Hub | Cross-process task delegation over 127.0.0.1:19820 — delegate_task → check_pending_tasks → complete_task, JSON-RPC + SSE, file-persisted |
| MAGI Memory | ChromaDB (vectors, ONNX/hash fallback) + SQLite (relations/judgments) + SessionManager. SDD artifacts, conflict detection (BM25), TTL pruning |
| Code Graph | AST index (Python) — symbols, imports, call sites, blast-radius affected, FTS5 search, surgical explore (nodes+code+call_paths+blast_radius) with watcher debounce + staleness banner |
| Universal Exec | One toolchain for 20+ langs: ruff→eslint→golangci→clippy→…, pytest→npm→go→cargo, mypy→tsc→vet — XXH3 inputHash=fileHashes:configHash:toolHash (70× cache) + exec_affected via code graph (50–75% prune) |
| Provider Abstraction | ModelProvider Protocol + `get_provider("qwen" |
| Input Validation | n3rv.limits — validate_text_input, validate_image_input, validate_audio_*, estimate_tokens for satellite payloads |
| Config Generation | Jinja2-templated scaffold of AGENTS.md, opencode.json, skills (18), agents (7), commands (8), plugins, hooks — stack-aware (python/node/go/generic) |
| Org Mode | Multi-satellite workspace: `n3rv org init |
| SDD Workflow | 8-phase explore → propose → spec → design → tasks → apply → verify → archive + converge + lighter Spec-Kit path (spec/plan/tasks under .specify/) |
| Daemon | systemd --user unit (`n3rv daemon install |
Quick Start
# install
pip install git+https://github.com/juanmanueldaza/n3rv.git
# or for development
pip install -e ".[dev]"
# scaffold your project
cd your-project
n3rv init # auto-detects stack
n3rv init --stack python --force # explicit
# start the hub (daemon recommended)
n3rv daemon install
n3rv daemon enable --now
n3rv daemon status
# or foreground for dev
n3rv hub start
# verify
n3rv --help
n3rv-memory --help # 12 tools
n3rv-hub --help # 5 tools
n3rv-exec --help # 8 tools (via MCP)
n3rv-code-graph --help
Generated opencode.json wires all 4 MCP servers with N3RV_AGENT_SOURCE=opencode so every agent gets memory + hub + exec + code-graph without extra config.
CLI Reference
n3rv init [--root PATH] [--project-name NAME] [--stack python|node|go|generic] [--force]
n3rv update [--dry-run] [--diff] [--force-commands] [--only marker-merge|json-merge|overwrite|skip-default] [--root PATH]
n3rv converge <change_id> [--root PATH] [--issue N] # close spec↔impl gap → sdd-*-tasks
n3rv hub start
n3rv daemon install|start|stop|status|enable [--now]|logs [--root PATH]
n3rv memory list [--type TYPE] [--scope SCOPE] [--limit N]
n3rv memory search <query> [--type TYPE] [--keyword KW] [--limit N]
n3rv memory prune --scope session|personal|project [--older-than DAYS] [--type TYPES] [--hard-delete]
n3rv memory stats
n3rv memory-list # alias for memory list
n3rv memory-search # alias for memory search
n3rv org init [--root PATH] [--org-name The-Replacement] [--force]
n3rv org add-satellite <name> [--root PATH] [--description TEXT] [--type satellite|tool]
n3rv org sync [--root PATH] [--dry-run] [--only CATEGORY]
n3rv org protect [project] [--root PATH] [--dry-run]
n3rv code-graph init [--root PATH] [--force]
n3rv code-graph index [--root PATH] [--force]
n3rv code-graph sync [--root PATH]
n3rv code-graph status [--root PATH] [--json]
n3rv code-graph query <query> [--root PATH] [--kind KIND] [--limit N] [--json]
n3rv code-graph explore <query> [--root PATH] [--max-nodes N] [--json]
n3rv code-graph node <symbol|file> [--root PATH] [--json]
n3rv code-graph files [--root PATH] [--json]
n3rv code-graph callers <symbol> [--root PATH] [--limit N]
n3rv code-graph callees <symbol> [--root PATH] [--limit N]
n3rv code-graph impact <symbol> [--root PATH] [--depth N]
n3rv code-graph affected <files...> [--root PATH] [--depth N] [--json]
MCP Servers
All four are stdio servers launched by opencode via opencode.json. See docs/MCP-TOOLS.md for the full 31-tool reference.
| Server | Command | Tools | Purpose |
|---|---|---|---|
n3rv-memory |
n3rv-memory |
12 | memory_save/search/recall/context/timeline/stats/judge/prune/delete/session_* |
n3rv-hub |
n3rv-hub |
5 | delegate_task/list_pending_tasks/check_pending_tasks/complete_task/get_task |
n3rv-exec |
n3rv-exec |
8 | exec_lint/typecheck/test/history/diff/timeline/cache_stats/affected — universal + cache + staleness |
n3rv-code-graph |
n3rv-code-graph |
6 | code_graph_index/symbols/references/imports/affected/explore — AST + FTS5 + blast radius |
Code graph and exec are twins: both use SQLite WAL + file watcher + pending set + _inject_staleness banner (⚠️ Stale: file pending sync — Read it directly).
Providers
from n3rv.providers.factory import get_provider, get_tts_provider
llm = get_provider() # N3RV_PROVIDER env, default "qwen"
llm = get_provider("openai:gpt-4o") # model override via colon
llm = get_provider("fallback") # N3RV_FALLBACK_PROVIDERS="qwen,openai,local"
tts = get_tts_provider() # DASHSCOPE_API_KEY + N3RV_TTS_* env
Implementations: QwenProvider (DashScope compat), OpenAIProvider, LocalProvider (Ollama/vLLM compat), FallbackProvider, TTSProvider / TTSFallbackProvider. All share ProviderDefaults from n3rv.config.
Environment Variables
| Variable | Default | Purpose |
|---|---|---|
N3RV_PROVIDER |
qwen |
Active LLM provider: qwen · openai · local · fallback |
N3RV_DEFAULT_MODEL |
qwen3-coder-plus |
Global default model ID |
N3RV_DEFAULT_BASE_URL |
https://dashscope-intl.aliyuncs.com/compatible-mode/v1 |
Global default base URL |
N3RV_FALLBACK_PROVIDERS |
— | Comma-separated fallback chain (e.g. qwen,openai) |
N3RV_TTS_FALLBACK_MODELS |
— | Comma-separated TTS models for TTSFallbackProvider |
N3RV_FALLBACK_MODELS |
— | Legacy alias, same as above |
DASHSCOPE_API_KEY |
— | Qwen/DashScope API key |
OPENAI_API_KEY |
— | OpenAI API key |
N3RV_LOG_LEVEL |
INFO |
DEBUG·INFO·WARNING·ERROR |
N3RV_AGENT_SOURCE |
opencode |
Agent identity for memory attribution + hub routing |
N3RV_HUB_URL |
http://127.0.0.1:19820 |
Hub URL for MCP delegation |
N3RV_MEMORY_PROFILE |
full |
full (all tools) or safe (read-only, no delete/prune) |
N3RV_EXEC_DEBOUNCE_MS |
300 |
Exec watcher debounce |
N3RV_CODE_GRAPH_NO_WATCH |
unset | Set 1/true to disable code-graph watcher |
N3RV_EXEC_NO_WATCH |
unset | Set 1/true to disable exec watcher |
OPENCODE_EXPERIMENTAL_BACKGROUND_SUBAGENTS |
unset | Process env only — true enables background:true subagents (n3rv-scout/n3rv-sensor parallel dispatch) |
Hub host/port can also be set in .n3rv/a2a-config.yaml:
hub:
host: 127.0.0.1
port: 19820
project: my-project
SDD Workflow
/sdd-new <change> → explore → propose → spec → design → tasks → apply → verify → archive
Each phase is an opencode skill (sdd-*) that saves to memory under sdd-<change_id>-<phase>. The hub tracks phase on the The-Replacement Roadmap when --issue N is passed.
n3rv converge <change_id> [--issue N]— re-runs verify in converge mode and emits remediation tasks for anyFAIL/PARTIALacceptance criteria.- Spec-Kit path (lighter, 3 artifacts) —
sdd-spec-kit-{spec,plan,tasks}with templates under.specify/templates/(byte-identical to GitHub Spec Kit, seeNOTICE.md).
Full detail: docs/SDD-WORKFLOW.md.
Project Structure
src/n3rv/
├── cli.py, cli_memory.py, cli_code_graph.py, cli_org.py
├── config.py, platform.py, limits.py, daemon.py
├── providers/ # base, qwen, openai, local, fallback, tts, tts_fallback, factory
├── models/ # memory, a2a
├── a2a/ # hub, router, state, agent_cards
├── mcp/ # memory_service, memory_server, hub_server, exec_server, code_graph_*
│ ├── exec/ # registry (20+ langs), store, watcher, service
│ └── vector_store, relation_store, session_manager, conflict_store
└── init/ # init, update, renderer, detector, context, registry, lockfile
└── templates/ # opencode.json, AGENTS.md, skills(18), agents(7), commands(8), plugins, hooks
docs/ # ARCHITECTURE, DEPLOYMENT, MCP-TOOLS, SDD-WORKFLOW, index.html (n3rv.daza.ar)
tests/ # pytest — a2a, cli, init, mcp, org, providers, tools, limits, config
Development
pip install -e ".[dev]"
ruff check . && ruff format --check .
pytest -q # or pytest -v --cov=src
mypy . --ignore-missing-imports || true
n3rv init --force # re-scaffold templates
CI (.github/workflows/ci.yml): Lint & Format + Test 3.11/3.12/3.13 — 4 required checks, strict:true, enforce_admins:true, one approval, squash-merge only.
Documentation
| Doc | Content |
|---|---|
| docs/ARCHITECTURE.md | System overview, 4 MCP servers, Evangelion map, data flows, dispatch (native subagents vs hub) |
| docs/DEPLOYMENT.md | Install, init/daemon/org/code-graph, env vars, multi-agent machine, troubleshooting |
| docs/MCP-TOOLS.md | All 31 tools — memory (12) + hub (5) + exec (8) + code-graph (6) |
| docs/SDD-WORKFLOW.md | 8 phases, memory keys, converge, Spec-Kit, change_id convention |
| EVANGELION.md | Full N3RV↔Evangelion concept map |
| n3rv.daza.ar | Public landing (served from docs/index.html) |
Wiki: the
docs/directory is the wiki. The formerwiki-syncworkflow was removed — updatedocs/*.mddirectly; GitHub Wiki (if enabled) should mirrordocs/.
License
Apache-2.0. See LICENSE. Evangelion concepts are thematic metaphor only — not affiliated with Gainax/Khara.
Metadata
Release files for n3rv 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| n3rv-0.1.1.tar.gz | 146.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| n3rv-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 353.5 kB
Release files / n3rv-0.1.1.tar.gz
| Download URL | n3rv-0.1.1.tar.gz |
|---|---|
| Size | 146.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4abb892d4ac5c4ca07efda2e1c218987d6bb87248a1defaa639f430fbd07c5c
|
|
BLAKE2b-256 checksum How to use checksums |
46666622b8187b51434d58b6056341857889e01fed935a8ba7b6dae352c012c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / n3rv-0.1.1-py3-none-any.whl
| Download URL | n3rv-0.1.1-py3-none-any.whl |
|---|---|
| Size | 207.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
70bb761cb272581c0179df0d5f2e668dc1209d8fe3a1f5014abfb10d072fba0c
|
|
BLAKE2b-256 checksum How to use checksums |
d4a2d875225b59966c7ed874beda805f3907652cb845f1251e08f71ed77696ea
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|