How to use CruxHive
Setup, daily workflow, CLI and MCP tool reference — everything in one place.
Quick start
From zero to first knowledge entry in under 3 minutes.
Install the CLI
Requires Node.js ≥ 18. Gives you the cruxhive command globally.
Init your project
$ cruxhive init
Creates .llm/ structure, installs cruxhive-mcp (Python server), wires your AI tools.
Index and verify
$ cruxhive health
Builds the SQLite search index and confirms everything is wired correctly.
Reload your AI tool
Restart Claude Code, OpenCode, Cursor, or Windsurf. CruxHive context loads automatically. MCP tools are available immediately.
Propose and approve your first entry
$ cruxhive review
Interactive prompts guide you through creating and approving a knowledge entry. Approved entries are immediately searchable by every AI tool.
Requirements
| Dependency | Required for | Install |
|---|---|---|
Node.js ≥ 18 | CLI (cruxhive command) | nodejs.org |
@cruxhive/cli | The cruxhive CLI itself | npm install -g @cruxhive/cli |
Python ≥ 3.11 | MCP server + search | python.org |
uv | Fast Python install (recommended) | curl -LsSf https://astral.sh/uv/install.sh | sh |
git | Version history, org sync | git-scm.com |
sentence-transformers | Vector search (optional) | pip install "cruxhive-mcp[full]" |
fastapi + uvicorn | Web UI (optional) | pip install "cruxhive-mcp[ui]" |
Setup steps
1. Install the CLI
$ npm install -g @cruxhive/cli
This gives you the cruxhive command. The Python MCP server (cruxhive-mcp) is installed automatically in the next step.
Want to install the Python server manually first (e.g. with extras)?
# Recommended (uv — zero dependency conflicts)
$ uv tool install cruxhive-mcp
# With optional extras
$ uv tool install "cruxhive-mcp[full]" # + hybrid vector search
$ uv tool install "cruxhive-mcp[ui]" # + web dashboard
2. Init a project
Run from your project root. CruxHive detects your AI tools automatically and wires itself in.
$ cd my-project
$ cruxhive init
✓ Created .llm/ .llm/plans/ .llm/memory/ .llm/context/
✓ Created .llm/CONTEXT.md
✓ Detected Claude Code → patched CLAUDE.md
✓ Detected OpenCode → AGENT.md symlinked
✓ Detected Cursor → .cursor/rules/cruxhive.mdc symlinked
✓ Registered cruxhive-mcp in .mcp.json
3. Edit CONTEXT.md
Open .llm/CONTEXT.md and fill in your project description, stack, and key conventions. This is the file every AI tool reads at the start of every session.
4. Index and verify
$ cruxhive index # builds .llm/cruxhive.db
$ cruxhive health # confirm everything is wired
5. Reload your AI tool
Restart Claude Code, OpenCode, Cursor, or Windsurf. The MCP server starts automatically. All CruxHive tools are now available in your AI sessions.
How it works
CruxHive has three moving parts:
- .llm/CONTEXT.md — the canonical context file. Every AI tool reads this. It's a symlink target — CLAUDE.md, AGENT.md, .cursor/rules/cruxhive.mdc all point here. One file, zero drift.
- .llm/cruxhive.db — SQLite knowledge base. Stores all indexed entries with FTS5 full-text search and optional vector embeddings for semantic search.
- cruxhive-mcp — local MCP server. Exposes 11 tools that any MCP-compatible AI tool (Claude Code, OpenCode, Cursor, Windsurf) can call to search, propose, and review knowledge.
The core loop: AI proposes → human approves → knowledge persists → next session starts smarter. Nothing enters the shared base without a human sign-off. That's the quality gate that prevents AI hallucinations from accumulating over time.
Three-tier model
CruxHive organises context across three independent tiers, each with different access control and different consumers.
| Tier | Location | Contents | Who reads it |
|---|---|---|---|
| Personal | ~/.cruxhive/personal/ |
Your coding preferences, shortcuts, style. Never shared. | You only |
| Project | .llm/ in the repo |
Plans, decisions, constraints, facts specific to this codebase. | All contributors |
| Org | Shared git remote | Cross-project standards, architecture decisions, security rules. | All org members |
The org layer lives in a shared git remote. Configure it in cruxhive.config.yaml and run cruxhive sync to pull org context into any project.
Knowledge types
Every entry has a type field. Type determines how long it stays valid, how it's routed for approval, and how the health dashboard weighs it.
| Type | What it captures | Expires? |
|---|---|---|
fact | Verified truths — IPs, versions, URLs, API contracts | 90 days |
decision | Architectural choices with rationale + trade-off. Immutable unless superseded. | 365-day review |
plan | Sprint goals, upcoming work, phase intentions | On completion |
pattern | Reusable solutions, code conventions the team repeats | 180-day review |
constraint | Things the team must NOT do and why. NLI-monitored for violations. | Never |
research | Competitive intel, technology evaluations, external findings | 90 days |
outcome | What happened — deploy results, experiment outcomes, post-mortems | Never |
Frontmatter spec
Every .llm/ markdown file carries a YAML frontmatter block. CruxHive reads this to populate the search index and drive approval routing.
---
type: constraint # fact|decision|plan|pattern|constraint|research|outcome
scope: project # personal|project|org
topic: auth # 1-3 word tag
valid_at: 2026-05-27 # when this became true
invalid_at: ~ # null = still valid; set to deprecate
confidence: high # high|medium|low
source: human # human|ai-proposed|ephemeral
approved_by: alice # git username; ~ = pending
---
Never store JWT tokens in localStorage — XSS vulnerability.
Use httpOnly cookies or in-memory storage only.
Rules: source: ai-proposed entries are confidence-capped at medium until approved. invalid_at set means the entry is deprecated — it stays in git history but is excluded from search. supersedes: filename.md links replacements.
Daily workflow
| When | Command | Why |
|---|---|---|
| Session open | context_next_slice (auto via MCP) | Find next unblocked work item |
| After commits | /radar | Check all work maps to a plan |
| Something discovered | cruxhive propose | Queue it for approval |
| Weekly | cruxhive health | Stale entries, pending queue debt |
| Pending queue builds up | cruxhive review | Approve or reject entries |
| Approve visually | cruxhive ui | Web dashboard at localhost:3847 |
Proposing entries
There are three ways to propose a knowledge entry:
1. CLI (interactive)
$ cruxhive propose
# Prompts for type → topic → opens $EDITOR for content
2. MCP tool (from your AI session)
Ask your AI tool: "Propose a constraint: never use eval() in our codebase — XSS risk." It calls context_propose automatically.
3. Write directly
Create any .md file under .llm/pending/ with the correct frontmatter. Run cruxhive index to add it to the search index.
All proposals land with source: ai-proposed and approved_by: ~. They are searchable immediately but flagged as pending in cruxhive health.
Reviewing & approving
Proposals need a human to approve before they're treated as trusted knowledge (confidence: high, source: human).
Terminal (recommended)
$ cruxhive review
» [constraint] auth — never store JWT in localStorage
> Never store JWT tokens in localStorage — XSS risk…
[a]pprove / [r]eject / [s]kip: a
Your name: alice
✓ Approved
Web dashboard
$ cruxhive ui # opens localhost:3847
# Requires: pip install "cruxhive-mcp[ui]"
MCP tools (from your AI session)
Call context_review to list pending, then context_approve or context_reject with the file path.
Searching
Use natural language. CruxHive combines BM25 keyword matching with optional vector search (Nomic Embed v1.5) fused via Reciprocal Rank Fusion at k=60. Finds relevant entries even when your query doesn't share exact words.
From your AI session
Ask your AI tool: "Search the knowledge base for auth token storage patterns." It calls context_search automatically.
Via MCP tool directly
# In your AI tool's session:
context_search(query="JWT token storage", n=5)
context_search(query="database migrations", type="constraint")
Enable hybrid search
$ pip install "cruxhive-mcp[full]"
$ cruxhive index # re-index to build vectors
# Downloads ~270 MB on first run (cached)
Slash commands (cross-tool)
cruxhive init writes six slash commands into both .claude/commands/ (Claude Code) and .opencode/commands/ (OpenCode). Same command name, same behaviour, same MCP tool under the hood.
| Slash | What it does | Calls |
|---|---|---|
/radar [days] | Scan recent commits, map to plan areas, surface work with no plan | context_radar |
/next-slice [area] | Find first unblocked work item from active plan | context_next_slice |
/review | List CruxHive proposals awaiting approval | context_review |
/propose | Interactive: capture a new knowledge entry | context_propose |
/write-plan | Draft a new plan file under .llm/plans/ | context_write_plan |
/extract | Distill the current session into N candidate entries — dedup, classify, present numbered list for user to pick from, queue selected for review | context_search + context_propose |
/summarize | Distill the current session into one structured research entry (Background / Done / Decisions / Open questions / Next steps). Lower-friction counterpart to /extract. | context_search + context_propose |
/extract is the auto-capture loop with the approval gate intact: the AI proposes, you approve. Run it at the end of a long conversation to surface durable facts before they're lost.
Cursor and Windsurf don't have a slash command system, but the same MCP tools are reachable via natural language ("run radar", "what's the next slice for auth?") — they'll route to the right tool.
Examples
# Same syntax works in Claude Code and OpenCode:
/radar # last 7 days
/radar 30 # last 30 days
/next-slice # first unchecked item
/next-slice auth # filter to area
# From any MCP-aware tool (Cursor, Windsurf, scripts):
context_radar(days=7)
context_next_slice(area="cicd")
Weekly health check
$ cruxhive health
→ Shows: entry counts · pending approvals · stale files · MCP status
Observability — measure what CruxHive is doing for you
Every MCP tool call is logged locally to .llm/cruxhive.db. No data leaves your machine. Disable with CRUXHIVE_ANALYTICS=0.
What gets logged
- Every call to
context_search,context_propose,context_approve,context_reject,context_review,context_index,context_check_faithfulness - Which AI tool called it (detected via env vars — Claude Code, Cursor, OpenCode, Windsurf)
- The search query (truncated to 500 chars), result count, and latency
- Faithfulness check violations (when
cruxhive-mcp[full]is installed)
Terminal dashboard
$ cruxhive stats
→ Activity summary, by-AI-tool breakdown, top gaps, daily sparkline
$ cruxhive stats --days 30 --gaps
→ Custom window with zero-result query list
$ cruxhive stats --export csv > usage.csv
→ Raw event log for spreadsheet analysis
Web dashboard
cruxhive ui opens four tabs at localhost:3847:
| Tab | What it shows |
|---|---|
| Approvals | Pending AI-proposed entries with approve/reject buttons |
| Usage | KPIs (calls · searches · hit rate · proposals · pending queue), daily sparkline |
| By AI Tool | Per-tool table: which model searches more, finds more, proposes more |
| Gaps & Staleness | Zero-result queries (= what to document next), entries older than 60 days |
What decisions this enables
- Which AI model to use: compare hit rate and proposal approval rate per tool
- What to document next: zero-result queries are your backlog
- When to audit: stale entries list flags knowledge that may give confidently-wrong answers
- Whether the governance loop is healthy: pending queue age > 14 days = review is the bottleneck
Workspace rollup, digest, and trends
Once you've initialized CruxHive in multiple projects, you can get a cross-project view of activity, gaps, and decay without cd-ing into each one.
Cross-project KPIs in the terminal
$ cruxhive workspace
→ Aggregate (entries · pending · sessions · hit rate · decayed) + per-project breakdown table.
$ cruxhive workspace --days 30 --json
Reads ~/.cruxhive/config.yaml if present, otherwise auto-discovers projects under ~/Projects_Local/Development/.
Workspace dashboard in the browser
$ cruxhive ui --workspace
→ Opens localhost:3847 with a 7-KPI aggregate strip + clickable project cards + drilldown drawers.
Weekly digest with trend comparison
$ cruxhive digest
→ Markdown report: key indicators, activity, top gaps, decayed entries, by-tool divergence, pending queue, next-action suggestions. Auto-saved to .llm/digests/{date}.json + .md.
$ cruxhive digest --compare
→ Same report with week-over-week deltas: ↑+3 / ↓-12 arrows per KPI.
One-line health for hooks
$ cruxhive status
→ 🐝 CruxHive: 3 pending · 5 gaps · digest 8d old → run cruxhive digest
$ cruxhive status --quiet --session-start
→ Silent if all clear; logs a session_start event. Used by the SessionStart hook installed by cruxhive init.
The 5 KPIs that matter
| KPI | Question it answers | Good · Warn · Bad |
|---|---|---|
| Hit rate | Does the KB have what AI is looking for? | ≥70% · ≥50% · <50% |
| Sessions (7d) | Is CruxHive actually being loaded? | any >0 = active |
| Gaps (30d) | What to document next | ≤2 · ≤5 · >5 |
| Pending queue age | Is governance loop healthy? | ≤3d · ≤14d · >14d |
| Decay ratio | Is knowledge rotting? | ≤5% · ≤15% · >15% |
Memory intelligence (without bypassing approval)
Mem0 / Zep patterns adapted to CruxHive's human-gated model — no auto-write.
Entity-aware search
At index time, CruxHive extracts simple entities from each entry: snake_case identifiers, ALL_CAPS constants, IPv4s, hostnames, filenames with extensions. At search time, queries that mention any of those entities boost matching entries — and pull in entries BM25 would have missed entirely.
$ cruxhive search "91.99.212.250"
→ Returns entries mentioning that IP even though FTS5 doesn't tokenize it.
Recency boost in search ranking
Banded score multiplier on top of BM25 + vector + entity match: ≤7 days old +0.20, ≤30 days +0.10, ≤90 days +0.05. Recent edits float to the top without burying older but topically-relevant matches.
Confidence decay (computed at search time)
confidence: high entries auto-downgrade as they age — to medium after 60 days, to low after 120 days. The stored frontmatter never changes; the effective confidence is computed live so search results reflect current trust. Decayed entries surface in cruxhive digest with a "revalidate or deprecate" prompt.
Ephemeral entries
Set source: ephemeral in the frontmatter (or pass ephemeral=true to context_propose) for AI-extracted "soft" facts. They auto-expire after 7 days unless explicitly approved and promoted to source: human. Catches Mem0-style decay without an auto-write gate.
Conflict detection at review time
If cruxhive-mcp[full] is installed, each pending entry is scanned by NLI against existing approved constraints. Contradictions are surfaced in both the CLI cruxhive review output and the web UI approval card — so you catch drift before approving, not after.
Automation and hooks
What cruxhive init wires up so CruxHive runs itself in the background.
| Trigger | What fires | Result |
|---|---|---|
Every git commit | .git/hooks/post-commit | Silent re-index of .llm/ |
| Claude Code session start | .claude/settings.json SessionStart hook | Logs a session_start event, prints status if anything actionable |
| OpenCode session start | .opencode/plugins/cruxhive-status.js | Same as above |
cd into project dir (opt-in) | .envrc via direnv | Session event for Cursor / Windsurf / Gemini (which don't have native hooks). Run cruxhive direnv to install. |
| Every MCP tool call | events.trace decorator | Logs the call (tool · query · result count · latency · client) to SQLite |
All logging is local. Opt out with CRUXHIVE_ANALYTICS=0. Rate-limited: repeated cd doesn't spam session events.
CLI commands
| Command | What it does |
|---|---|
cruxhive init | Bootstrap .llm/, install MCP server, wire 5 AI tools, create CONTEXT.md, install hooks & gitignore |
cruxhive index | Scan .llm/ + ~/.cruxhive/personal/ and (re)build SQLite index + entity tags. --rebuild forces full re-index. |
cruxhive propose | Interactive: type → topic → editor → dedup-check → writes to .llm/pending/ |
cruxhive review | Terminal loop: approve / reject / skip each pending entry. Surfaces NLI conflicts if installed. |
cruxhive search "..." | BM25 + entity + recency search from terminal. JSON output for scripting. |
cruxhive health | Knowledge base audit — three-tier status, pending count, stale files |
cruxhive doctor | Setup audit — symlinks, hooks, slash commands, .gitignore, direnv. Reports problems with fix suggestions. |
cruxhive status | One-line health summary for SessionStart hooks. --quiet = silent if clean. --session-start logs a session event. |
cruxhive stats | Observability — searches/day, hit rate, gaps, per-AI-tool. --days N · --gaps · --stale · --export csv · --clear. |
cruxhive digest | Markdown weekly report (auto-saved to .llm/digests/). --compare shows week-over-week deltas with arrows. |
cruxhive workspace | Cross-project rollup — aggregates KPIs across every CruxHive-initialized project in ~/Projects_Local/Development/ (or config-listed paths). |
cruxhive direnv | Write .envrc that logs a session_start when you cd in. Covers Cursor / Windsurf / Gemini (tools without SessionStart hooks). Requires direnv installed. |
cruxhive sync | Pull org-layer context from the configured org_remote or workspace sync script |
cruxhive ui | Web dashboard at localhost:3847 — Approvals · Usage · By AI Tool · Gaps tabs + sticky KPI banner + /docs route. Add --workspace for the cross-project rollup view. |
MCP tools
Available in any MCP-compatible AI tool (Claude Code, OpenCode, Cursor, Windsurf). Call them by name or ask your AI to use them.
| Tool | What it does | Read-only? |
|---|---|---|
context_index | Index or re-index all .llm/ markdown files | No (idempotent) |
context_search | Hybrid BM25 + vector search over the knowledge base | Yes |
context_propose | Write a pending entry to .llm/pending/ with source: ai-proposed | No |
context_review | List all pending entries awaiting approval | Yes |
context_approve | Approve a pending entry — sets source: human on disk | No |
context_reject | Reject a pending entry — sets invalid_at, removes from index | No |
context_check_faithfulness | NLI check: does this AI response contradict any approved constraint? | Yes |
context_radar | Scan recent git commits → classify by plan area → coverage report | Yes |
context_next_slice | Find next unblocked item from active plan | Yes |
context_write_plan | Write a plan file to .llm/plans/ and register in active.md | No |
context_sync_memory | Run the workspace sync script to pull org-layer context | No (idempotent) |
AI tool support
| Tool | Context file | MCP tools | Auto-sync |
|---|---|---|---|
| Claude Code | CLAUDE.md → .llm/CONTEXT.md |
✓ via .mcp.json | ✓ SessionStart hook |
| OpenCode | AGENT.md → .llm/CONTEXT.md |
✓ via opencode.jsonc | ✓ session.created plugin |
| Cursor | .cursor/rules/cruxhive.mdc → .llm/CONTEXT.md |
via .cursor/mcp.json | Manual |
| Windsurf | .windsurfRules → .llm/CONTEXT.md |
partial | Manual |
| Gemini CLI | GEMINI.md → .llm/CONTEXT.md |
Not yet | Manual |
| VS Code Copilot | .github/copilot-instructions.md |
via MCP config | Manual |
All tools load from the same .llm/CONTEXT.md via symlinks — one file, zero drift. Run bootstrap.sh (from ai-toolkit/) to wire all detected tools at once.
Troubleshooting
MCP tools not appearing in Claude Code
Check .mcp.json in your project root has a cruxhive entry. Restart Claude Code after editing. Verify cruxhive-mcp is on your PATH: which cruxhive-mcp.
context_search returns no results
Run cruxhive index first. The SQLite database (.llm/cruxhive.db) must be built before search works. It's not created automatically on install.
cruxhive-mcp not found
$ uv tool install cruxhive-mcp
# or: pip install cruxhive-mcp
# then add ~/.local/bin to PATH if needed
cruxhive ui fails to start
The web UI requires the [ui] extra: pip install "cruxhive-mcp[ui]". This installs FastAPI and uvicorn.
Vector search not working
Install the [full] extra: pip install "cruxhive-mcp[full]". The first run downloads ~270 MB of model weights (cached in ~/.cache/huggingface/). Then run cruxhive index to build vectors.
CONTEXT.md not loading in Cursor
Verify the symlink: ls -la .cursor/rules/cruxhive.mdc. It should point to ../../.llm/CONTEXT.md. Re-run bootstrap.sh if missing.