AI can write code, but it does not know whether it has seen enough of your codebase to change it safely.

RagCode is a fully local, MCP-native, verified context layer for coding agents. Instead of stopping at a handful of similar snippets, it builds the smallest task-focused evidence pack an agent needs to answer, debug, edit, or review code.

Every answer includes explicit source citations, freshness, ownership, blast radius, coverage signals, and an edit-readiness verdict (safe_to_edit_after_reading / investigate_only / not_enough_context). When the evidence is incomplete, RagCode says what is still missing instead of encouraging a confident guess.

It is editor-agnostic and MCP-native (Claude Code, Codex, or any MCP client — not locked to one editor) and runs entirely on your machine (no account, no API key, no code leaving the building). The first run works offline with deterministic embeddings; swap in an OpenAI-compatible provider only if and when you want better recall.

Under the hood it cleanly separates structural code indexing, semantic retrieval, context packing, and MCP integration so each layer evolves independently — building on ideas from projects like CodeGraph and Understand-Anything, with a LanceDB semantic layer and a stronger context-engine contract on top.

RagCode also includes a project-scoped shared memory system for durable decisions, feedback, user preferences, and project facts. Memory is exposed through MCP, can be synced across agents, and is kept advisory: implementation facts still have to be verified against the current code index.

Retrieval is now language-aware and reranker-ready. English, Chinese, and code-mixed queries are normalized into weighted raw/path/symbol/lexicon terms before hybrid search runs, so Chinese questions about protocols, configs, tests, entrypoints, docs, and ownership can still land on implementation evidence. If you configure an OpenAI-compatible reranker, RagCode uses it after graph expansion and falls back to the built-in graph reranker if the provider fails.

Freshness is now lazy by default. CLI and MCP read paths perform a light dirty/stale check and refresh affected files on demand before answering. ragcode service install installs no resident watcher unless you explicitly choose --mode supervisor or --mode hot, so large repos can stay usable without a permanent indexing process.

The Web dashboard now ships as a packaged Vue SPA served by ragcode dashboard, with project brief, graph expansion, context budget trace, memory, impact review, request-flow, diff-review, runtime health, and config-source views. Semantic generation storage can also be pruned safely with ragcode semantic-prune, which dry-runs by default and protects active/rollback tables.


Why RagCode

If you need… RagCode fits because…
Agents that know when they have enough evidence Verified subgraphs with citations, coverage signals, missing evidence, and edit-readiness
Context that is not locked to one editor MCP-native; works with Claude Code, Codex, and any compatible agent harness
Code that never leaves your machine Fully local index + offline embeddings; no account, hosted service, or cloud round-trip
Multiple agents that do not start from zero Project-scoped shared memory preserves decisions, feedback, preferences, and verified facts

Technology Stack

Area Technology
Language / Runtime TypeScript 5.9, Node.js >= 24 (uses node:sqlite), ESM modules
Structural graph better-sqlite3 (SQLite + FTS) with an in-memory store for tests
Semantic / vector store @lancedb/lancedb + apache-arrow, with an in-memory store fallback
Shared memory SQLite + FTS event store, optional LanceDB vectors, frontmatter adapters, JSONL File-Hub sync
AST / parsing TypeScript Compiler API (TS/JS), tree-sitter (Python, Go, Rust, Java)
MCP integration @modelcontextprotocol/sdk (stdio server)
CLI commander, ink + react (interactive wizards)
Web dashboard express + ws backend, Vue frontend (in web/)
File watching chokidar
Validation zod
Tooling tsx (dev), vitest (tests), tsc (build + type check)

Project Architecture

RagCode is layered so that no concrete store leaks across boundaries. Every external surface (CLI, MCP, web) depends on the contracts in src/core, never on a specific database.

            ┌──────────┐   ┌──────────┐   ┌──────────────┐
 surfaces   │   CLI    │   │   MCP    │   │ Web dashboard │
            └────┬─────┘   └────┬─────┘   └──────┬───────┘
                 └──────────────┴────────────────┘
                                │
                    ┌───────────▼───────────┐
                    │  ContextEngine (core)  │  canonical contracts
                    └───────────┬───────────┘
        ┌──────────────┬────────┼────────┬──────────────┬──────────┐
        ▼              ▼        ▼         ▼              ▼
   ┌────────┐    ┌─────────┐ ┌──────┐ ┌─────────┐  ┌─────────┐ ┌────────┐
   │indexing│    │  graph  │ │ sem. │ │retrieval│  │ context │
   │  scan  │    │ SQLite  │ │Lance │ │ planner │  │  packer │ │ memory │
   │ chunk  │    │  +FTS   │ │  DB  │ │ +fusion │  │ +budget │ │ SQLite │
   └────────┘    └─────────┘ └──────┘ └─────────┘  └─────────┘ └────────┘
                                │
                          ┌─────▼─────┐
                          │   watch   │  incremental freshness
                          └───────────┘

Layer ownership (see docs/ARCHITECTURE.md):

  • core — canonical contracts: RepoIndex, CodeFile, CodeChunk, GraphStore, SemanticStore, ContextEngine. The stable boundary everything else depends on.
  • indexing — filesystem scan, ignore rules, hashing, chunking, and index-pipeline steps. Knows nothing about MCP.
  • graph — exact code structure: files, symbols, edges, lookup, callers/callees/impact. In-memory for tests, SQLite + FTS for production.
  • semantic — embeddings and vector search behind an interface, so providers (deterministic, OpenAI-compatible, local) and stores swap freely.
  • retrieval — query planning: English/Chinese/code-mixed query context, intent detection, exact/graph/keyword/semantic recall, optional external reranking, score fusion, and result normalization.
  • context — agent-ready output: snippet selection under a character/token budget, reasons, scores, citations, and missingEvidence.
  • memory — project-scoped shared agent memory: MCP tools, SQLite/FTS store, optional vectors, MQS ranking, verification, context injection, and cross-agent sync. See docs/MEMORY_SYSTEM.md.
  • watch — long-running watcher, durable event journal, dirty-file coalescing, and background batched re-index scheduling.
  • mcp — thin protocol adaptation: tool names, input validation, handler dispatch. No search logic lives here.

The context-pack contract is the heart of the engine. get_context returns:

brief → freshness → ownerChain → topology → evidence snippets → missingEvidence → nextQueries

Snippets are evidence, not the primary organization. Large files default to a skeleton expansion level rather than full source, and every snippet reports how many lines were elided.


Getting Started

Prerequisites

  • Node.js >= 24.0.0 (required — the SQLite graph store uses node:sqlite)
  • Windows, macOS, or Linux
  • ~100 MB disk for dependencies + index data

Install and run (terminal-first, offline-first)

The first run needs no embedding API key, no account, and no hosted service.

# Install globally
npm install -g ragcode-context-engine

cd my-project
ragcode init          # offline-first config: sqlite + lancedb + deterministic embeddings
ragcode index .       # build the index; large first runs use a bounded bootstrap batch
ragcode setup-mcp     # register the MCP server for your agent client
ragcode install-guidance . # install the update-safe AGENTS.md operating contract

Or try it without installing:

npx ragcode-context-engine index .
npx ragcode-context-engine search . "query"

Working from source (no global install)? Run any command through the dev script — it executes the TypeScript entry directly via tsx:

npm run dev -- index .
npm run dev -- setup-mcp --client codex --print

Paste-ready agent onboarding

RagCode ships an AI startup protocol intended to be loaded automatically from a repository AGENTS.md. It tells the host agent when to use RagCode retrieval, how to recover a missing or stale index, when to read or write shared memory, and when to use RagCode's cross-CLI control plane for registered Codex, Claude, Gemini, or Grok providers.

Install or update only the managed marker block without overwriting the repository's other instructions:

ragcode install-guidance .

Print the authoritative block for manual copy/paste:

ragcode install-guidance --print

The plural filename AGENTS.md is the standard repository instruction filename. Provider registration is not treated as live readiness: the protocol requires ragcode agents doctor . --agent <id> before cross-CLI execution and distinguishes host-native subagents from durable RagCode Agent runs.

<!-- RAGCODE:AGENT-GUIDANCE:START -->
## RagCode Operating Contract

RagCode is this repository's evidence layer for code intelligence, shared memory, and controlled multi-agent workflows. Use it proactively; do not wait for the user to name it.

### Session Bootstrap

- For the first non-trivial repository task in a session, query shared memory for relevant prior decisions, then use `get_context` to build a task-focused context pack before broad grep or manual file traversal.
- If RagCode MCP tools are unavailable, use the CLI equivalents from the repository root. Do not block the user's task merely because MCP is absent.
- When the index is missing or retrieval reports incomplete/stale evidence, check `index_status`; run `index_repo` for a missing index or `refresh_index` for a stale index, then retry the original query. CLI fallback: `ragcode status .`, `ragcode index .`, `ragcode refresh .`.
- Treat the Web dashboard as observability only. Never use it as the setup, configuration, or agent-control path.

### Task Routing

- Implementation, debugging, refactor, review, or architecture: start with `get_context` and select `debug`, `feature`, `refactor`, `review`, or `explain` mode to match the task.
- Locate the current owner or edit point: use `find_owner`; find an exact symbol with `find_symbol`; inspect one indexed file with `explain_file` or expand a returned node with `expand_node`.
- Before adding a helper, component, service, or abstraction: use `find_reuse_candidates` and prefer an existing pattern when the evidence supports reuse.
- Understand runtime or request/data flow: use `trace_request_flow`; use `topology_map` when relationships matter more than full snippets.
- Before a risky change: use `explain_impact` or `impact_analysis`. Before verification: use `related_tests`. For a completed diff: use `review_diff` before reporting completion.
- For frontend work, call `get_project_brief` before coding when framework, design system, styling, theme, or component ownership is not already proven.
- Use direct file reads after RagCode identifies the relevant files, to confirm exact implementation details, or when retrieval declares missing evidence. Report retrieval quality gaps explicitly instead of silently presenting guesses as repo truth.

### Evidence and Completion

- Base repository claims on current RagCode results plus direct source verification where exact behavior matters. Distinguish indexed evidence, inference, and live runtime proof.
- Follow `nextQueries`, `missingEvidence`, freshness diagnostics, and memory hints only while they materially improve the task. Stop retrieving when the owner chain and required evidence are sufficient.
- Keep edits scoped. Run the smallest relevant tests first, then broader typecheck/lint/build gates when applicable. Do not claim completion without fresh validation or an explicit validation gap.

## Cross-AI Shared Memory

- Before non-trivial work, call `memory_query` for prior decisions, feedback, constraints, and known failure modes. Treat memory as routing context, then verify drift-prone facts against current code or runtime state.
- After a durable decision, user correction, non-obvious project fact, verified workaround, or completed architectural change, call `memory_write` with a clear topic, type (`decision`, `feedback`, `project`, `reference`, `user`, or `context`), and concise evidence-backed body.
- When a prior memory is outdated, supersede it with `memory_write` (set `supersede` to the old entry ID) rather than deleting — the history is valuable for audit.
- When a tool response includes `memoryHints` or `memorySnippets`, follow up with `memory_query` to explore. Heed `memory_write` results: `duplicates` (prefer `supersede` over piling on) and `conflicts` (same-topic disagreements from another agent — reconcile them).
- Memory is project-scoped (bound to repo root), not agent-scoped. What you write is visible to Claude, Codex, and other agents working on the same repo.
- CLI fallback: `ragcode memory query <query>`, `ragcode memory write <topic> --body <text>`, and `ragcode memory list`.

## Agent Selection

- Use the host client's native subagents for bounded work inside the current AI session when they are sufficient.
- Use RagCode Agents when work requires registered external CLI providers, explicit role-to-provider assignment, durable run artifacts, cross-provider consultation, review gates, background execution, mid-turn steering, or resumable workflows.
- Built-in agent IDs are `codex`, `claude`, `gemini`, and `grok`, and repositories may override them in `.ragcode/agents/agents.json`. Registration does not prove installation, authentication, or live-model readiness.
- Preserve explicit assignments such as "Claude plans, Grok breaks down tasks, Codex implements, Gemini reviews." Do not replace them with a hard-coded provider pair.
- Never claim that an external agent ran unless a real RagCode run, ledger event, provider response, or artifact proves it. A dry run, static probe, or installed executable is not completed model execution.

## Controlled Cross-CLI Agent Workflows

- Before using an external provider, run `ragcode agents doctor . --agent <id>`. Add `--live` only when a disposable real-provider turn is needed to prove authenticated readiness.
- Run `ragcode agents init .` when `.ragcode/agents/` is absent, then inspect or edit `.ragcode/agents/agents.json` instead of assuming the built-in command fits the local installation.
- For one bounded delegation, dry-run `ragcode agents consult . --leader <id> --consultant <id> --task "<task>" --dry-run`, then remove `--dry-run` only when real execution is requested.
- For multi-step collaboration, create or compile a workflow JSON, validate it with `ragcode agents validate . --workflow <path>`, and inspect execution using `ragcode agents run . --workflow <path> --task "<task>" --dry-run` before a real run.
- Use `ragcode agents start` for detached execution; `ragcode agents status` and `ragcode agents events` for observation; `ragcode agents invoke` only to steer an actually running node; `ragcode agents report` for deterministic completion evidence; `ragcode agents resume` for interrupted runs; `ragcode agents cancel` to stop a run; and gated `ragcode agents integrate` to apply a completed patch artifact.
- Mark plan, research, review, and verification nodes `read_only`. Mark implementation nodes `write` and restrict `writePolicy.allowedPaths` to the smallest valid scope. Keep one workspace-writing node at a time and use bounded fail-closed review loops.
- MCP workflow tools are read-only (`agent_workflow_validate`, `agent_workflow_status`, `agent_workflow_report`). Starting runs, steering agents, cancellation, and workspace integration remain CLI control-plane operations.
- Agent nodes automatically receive bounded, role-aware shared memory unless `memoryPolicy.read.mode` is `off`. Providers cannot write memory directly: `memoryPolicy.write.mode` may record proposals or promote evidence-backed candidates only after required node and final gates pass.
<!-- RAGCODE:AGENT-GUIDANCE:END -->

ragcode index <repoRoot> is safe for large repositories by default. On an empty index it writes the first bounded structural batch, records the remaining files as pending, and lets later index, watch, or service runs continue from persisted state. Semantic vectors are deferred during this first partial bootstrap so graph search and ownership queries become available without forcing one huge embedding pass.

ragcode index . --max-batch-files 2000 --max-analysis-memory-mb 4096
ragcode index . --semantic-on-bootstrap   # also write vectors for the first partial batch
ragcode index . --full                    # force the legacy all-at-once index

Progress is durable under .ragcode/index-state.json and .ragcode/index-progress.jsonl. ragcode status . keeps the machine-readable JSON contract for agents and scripts, reporting graphFresh, pendingFileCount, indexingFileCount, semanticFresh, semanticCoverage, and semanticRebuildNeeded so agents can tell whether retrieval covers the whole repo or only the indexed graph slice. For humans, ragcode status-human . renders the same index, watcher, and embedding health as an Ink terminal summary.

Default freshness is lazy/on-demand. ragcode search, context, owner, impact, flow, and MCP retrieval tools perform a light freshness check and refresh stale files before returning unless you pass --stale-ok / --no-refresh. The first query after edits can be slower because it may run a bounded refresh.

Set RAGCODE_REFRESH_ON_READ=off (or stale-ok / no-refresh) to keep read paths strictly observational, or RAGCODE_REFRESH_ON_READ=always to force refresh on every read. ragcode status . uses the light status path by default; add --full when you need chunk, symbol, edge, and semantic-store counts.

For background freshness, ragcode service install <repoRoot> now defaults to lazy mode and installs no resident watcher. Add --index-now to run one bounded pre-install batch, --mode supervisor to install the light supervisor plus short-lived workers, or --mode hot for the legacy always-live watcher:

ragcode service install .
ragcode service install . --mode supervisor --max-analysis-memory-mb 4096
ragcode service install . --mode hot --index-now --bootstrap-batch-size 2000 --max-analysis-memory-mb 4096

The onboarding freshness path is guarded by watcher/service/configure regression tests: first-run setup uses bounded indexing and lazy read-time refresh by default, while supervisor/hot services remain explicit opt-ins.

Upgrade semantic recall (optional, never a blocker)

ragcode configure          # edit storage / provider / model / base URL / dimensions
ragcode configure --test   # verify the provider (classified failures; secrets never printed)

OpenAI-compatible providers (OpenAI, Azure, Ollama, etc.):

# Cloud (OpenAI)
export RAGCODE_EMBEDDING_PROVIDER=openai-compatible
export RAGCODE_EMBEDDING_API_KEY=sk-your-key

# Local (Ollama) - recommended for privacy + quality
ollama pull nomic-embed-text
export RAGCODE_EMBEDDING_PROVIDER=openai-compatible
export RAGCODE_EMBEDDING_BASE_URL=http://localhost:11434/v1
export RAGCODE_EMBEDDING_MODEL=nomic-embed-text
export RAGCODE_EMBEDDING_API_KEY=ollama  # any non-empty string works

See docs/EMBEDDING_PROVIDERS.md for Azure, Ollama setup, troubleshooting, and performance comparison.

Upgrade reranking quality (optional)

External reranking is separate from embeddings. Graph expansion still runs first so structural candidates stay in the pool, then RagCode can send a bounded candidate window to an OpenAI-compatible /rerank endpoint. If the provider errors, retrieval falls back to the local graph reranker.

export RAGCODE_RERANK_PROVIDER=openai-compatible
export RAGCODE_RERANK_BASE_URL=https://your-router.example/v1
export RAGCODE_RERANK_API_KEY=your-key
export RAGCODE_RERANK_MODEL=your-rerank-model
export RAGCODE_RERANK_PATH=/rerank
export RAGCODE_RERANK_TOP_N=80

RAGCODE_RRANK_* aliases are accepted for the same settings. Secrets are redacted in config and diagnostics output.

ragcode init walks you through the full first-run flow; ragcode <command> --help documents each command's options.

CLI commands

# Setup and diagnostics
ragcode init [directory]
ragcode configure [repoRoot]
ragcode doctor [repoRoot]
ragcode update [--check]
ragcode setup-mcp [--client codex]
ragcode install-guidance [repoRoot]
ragcode mcp

# Indexing and freshness
ragcode index <repoRoot>
ragcode refresh <repoRoot>
ragcode status <repoRoot>
ragcode status-human <repoRoot>             # Alias: status-ui
ragcode status-ui <repoRoot>
ragcode watch <repoRoot>
ragcode watch-worker <repoRoot>
ragcode watch-supervisor <repoRoot>
ragcode record-events <repoRoot> <files...>
ragcode service install <repoRoot>          # Lazy by default; --mode supervisor/hot enables a resident service
ragcode service status <repoRoot>
ragcode service uninstall <repoRoot>

# Semantic generation lifecycle
ragcode semantic-status <repoRoot>
ragcode semantic-rebuild <repoRoot> [--promote]
ragcode semantic-promote <repoRoot> <generation>
ragcode semantic-rollback <repoRoot>
ragcode semantic-prune <repoRoot> [--apply]
ragcode semantic-optimize <repoRoot>

# Retrieval and analysis
ragcode search <repoRoot> <query>
ragcode context <repoRoot> <query>
ragcode brief <repoRoot> [--query <query>]
ragcode owner <repoRoot> <query>
ragcode reuse <repoRoot> <query>
ragcode expand-node <repoRoot> <nodeRef>
ragcode impact <repoRoot> <target>
ragcode explain-impact <repoRoot> <target>
ragcode tests <repoRoot> <target>
ragcode trace-request-flow <repoRoot> <entry>

# Memory, dashboard, and multi-agent workflows
ragcode memory --help
ragcode dashboard
ragcode agents run . --workflow <path> --task "<task>"
ragcode agents start . --workflow <path> --task "<task>"
ragcode agents events . --run <id> [--no-follow]
ragcode agents invoke . --run <id> --message "<message>"
ragcode agents consult . --leader <id> --consultant <id> --task "<task>"
ragcode agents status . --run <id>
ragcode agents cancel . --run <id>

Run ragcode --help or ragcode <command> --help for details.

Multi-agent runs are stored under .ragcode/agents/runs/ with a durable ledger, artifacts, reports, execution identity, cancellation state, and native-session checkpoints. Workflow JSON supports dependency ordering, bounded retry/fix loops, verification and artifact gates, read-only/write policies, and CLI-backed agent connectors. See docs/agents/workflow-spec.md and docs/agents/cli-adapters.md.

MCP server integration

RagCode runs as an MCP server so agents like Claude can call its tools directly. Auto-register for your client:

ragcode setup-mcp                       # Claude Code     (project ./.mcp.json, default)
ragcode setup-mcp --client claude       # Claude Desktop  (~/.../claude_desktop_config.json)
ragcode setup-mcp --client codex        # Codex CLI       (~/.codex/config.toml)
ragcode setup-mcp --client codex --print # print config, write nothing

Existing config is merged in place (other servers and unrelated keys are preserved, and the previous file is backed up). Add --force to overwrite an existing ragcode entry without prompting. MCP starts in the repo root and reads runtime settings from .ragcode/config.json by default, so later config changes apply without regenerating the MCP entry. Add --include-secrets only if you explicitly want to embed API keys as MCP environment variables.

Or add it manually to your MCP client config:

{
  "mcpServers": {
    "ragcode": {
      "command": "ragcode",
      "args": ["mcp"],
      "cwd": "/path/to/your/repo"
    }
  }
}

CLI aliases for focused code lookup include ragcode find-symbol, ragcode explain-file, and ragcode topology.

Document retrieval uses its own command group and storage namespace:

ragcode document index <sourceRoot> <filePath> --profile default
ragcode document search <sourceRoot> "query" --profile default
ragcode document context <sourceRoot> "query" --profile default --budget 10000 --transport-budget-bytes 18000
ragcode document assets <sourceRoot> --source-id <sourceId> --profile default
ragcode document asset <sourceRoot> --source-id <sourceId> --block-id <blockId> --profile default
ragcode document status <sourceRoot>
ragcode document benchmark <manifestPath> --workspace <isolatedDir> --report <report.json>
ragcode doctor <sourceRoot>

--budget limits context characters; --transport-budget-bytes is a separate hard MCP/JSON byte cap. Figure assets are discovered from an active generation and reverified on every read; provider paths are never returned, and provider-managed files are not retained by RagCode. Document reads reject a file changed after indexing by default. Use --allow-stale only when deliberately inspecting stale source-backed evidence; returned hits identify that state. ragcode doctor <sourceRoot> reports document SQLite integrity, generation state, changed/missing active sources, and local/remote provider readiness without exposing credentials.

ragcode document benchmark runs the production read, extraction, indexing, retrieval, and evaluator pipeline from a strict JSON manifest; it does not inject synthetic hits or download datasets. The manifest pins chunking and a secret-free runtime profile covering OCR, layout, and image-embedding identities. A profile mismatch fails before indexing. Existing workspaces are rejected unless --reuse-index is explicitly supplied, so baseline reports remain attributable to one corpus and runtime configuration. The same entry point is available in a checkout as npm run benchmark:document -- <manifestPath> .... Remote-OCR reports include requestedAssets, cache hits/misses, in-flight joins, provider calls/successes/failures, retries, and uploaded byte/pixel totals. Set RAGCODE_DOCUMENT_IMAGE_EMBEDDING_PROVIDER=off to keep a native-only benchmark reproducible when the surrounding environment otherwise enables Gemini image embeddings.

The production document registry supports local text/structured formats, narrow native DOCX/XLSX/PPTX/PDF profiles, and explicit local or remote OCR. Local OCR remains available through RAGCODE_DOCUMENT_OCR_MANIFEST. Remote OCR requires all three authorization layers: RAGCODE_DOCUMENT_OCR_MODE=remote, RAGCODE_DOCUMENT_REMOTE_OCR_PROVIDER=openrouter, and RAGCODE_DOCUMENT_REMOTE_OCR_SCOPES=image,pdf,office (list only the formats you consent to upload), plus RAGCODE_OPENROUTER_API_KEY and a pinned RAGCODE_OPENROUTER_OCR_MODEL. Configuring a provider or key alone never uploads a document. Only normalized PNG bytes for an authorized standalone image, eligible scanned PDF page/PDF image region, or Office embedded image leave the machine. API keys and HTTP requests stay in the parent process; untrusted PDF/OOXML parser hosts remain network=false and receive neither credentials nor network access. Remote OCR uses persistent provider-profile-aware caches keyed by normalized-image SHA-256, bounded concurrency, total pixels, upload bytes, PDF pages, retries, response size, and wall-clock time. Remote coordinates remain estimates, and all OCR citations remain EXTRACTED evidence rather than byte-exact or PRIMARY source text.

Figure image vectors are a separate opt-in path. Set RAGCODE_DOCUMENT_IMAGE_EMBEDDING_PROVIDER=gemini with RAGCODE_GEMINI_API_KEY; optional RAGCODE_GEMINI_IMAGE_EMBEDDING_MODEL, RAGCODE_GEMINI_IMAGE_EMBEDDING_DIMENSIONS, and RAGCODE_DOCUMENT_IMAGE_VECTOR_STORE_URI override the pinned defaults. Image vectors use the document-image namespace and a dedicated LanceDB store; the OpenRouter OCR key never enables them.

Adaptive retrieval modes and rollback (document)

Product modes change budgets only; they never disable ACL, freshness, generation, or citation gates.

Mode Default behavior
fast (default) Single-step search; verification NOT_RUN unless opted in
deep Bounded adaptive attempts (rewrite / missing facet / registered structured-graph actions)
audit Conservative verification + provenance-oriented reporting

Environment defaults (safe off):

Variable Values Default
RAGCODE_DOC_RETRIEVAL_MODE fast deep
RAGCODE_DOC_CLAIM_VERIFY off shadow
RAGCODE_DOC_ADAPTIVE off shadow
RAGCODE_DOC_ADAPTIVE_MAX_ATTEMPTS 13 mode-dependent (fast → 1)
RAGCODE_DOC_STRUCTURED_JOIN on off
RAGCODE_DOC_GRAPH_EXPAND on off

Independent rollback: turn off claim verify, adaptive, structured join, or graph expand without deleting source generations or entity/event rows. shadow modes record metrics/planned actions without changing public hit lists when execution is disabled. Doctor surfaces these flags under retrievalFeatures (including independent disable keys and soft mode SLO budgets).

MCP additive fields on search_documents / adaptive path: mode, maxAttempts, verifyClaims, continuation. Read-only tools: verify_document_answer, document_retrieval_metrics. GraphRAG global synthesis is not enabled; local GRAPH_EXPAND is source block topology only, and STRUCTURED_JOIN is one-hop source-bound entities/events.

Local stratified baseline (no external download):

ragcode document benchmark tests/fixtures/document/benchmark-stratified-v1.json   --source-root tests/fixtures/document   --workspace /tmp/ragcode-stratified-ws   --report /tmp/ragcode-stratified-report.json

Reports include candidate metrics plus optional trust (auto-collected) and soft slo evaluation for the active product mode.

Available MCP tools (38):

  • Index lifecycleindex_repo, refresh_index, index_status, record_file_events, watch_status
  • Search & contextsearch_code, get_context, get_project_brief, topology_map, expand_node
  • Symbols & filesfind_symbol, explain_file, find_owner, find_reuse_candidates
  • Impact & flowimpact_analysis, explain_impact, related_tests, trace_flow, trace_request_flow
  • Reviewreview_diff
  • Shared memorymemory_write, memory_query, memory_list, memory_delete
  • Agent workflowsagent_workflow_validate, agent_workflow_status, agent_workflow_report
  • Document retrievalindex_documents, refresh_documents, document_status, search_documents, get_document_context, list_document_assets, get_document_asset, delete_document, rollback_document, verify_document_answer, document_retrieval_metrics

watch_status is read-only: it reports whether a live watcher is keeping the index fresh, but never starts one (that belongs to ragcode watch or the OS service).


MCP Tool Usage

get_context — Agent-Ready Context Packs

The get_context tool is RagCode's primary interface for AI agents. It returns verified, budget-controlled context with explicit reasoning and completeness signals.

Output Format (New in v0.1.6)

Format parameter controls output structure:

// JSON format (default, backward compatible)
{
  tool: "get_context",
  input: {
    query: "authentication flow",
    format: "json",        // Returns ContextPack structure
    budgetChars: 15000
  }
}

// Markdown format (AI-friendly, recommended)
{
  tool: "get_context",
  input: {
    query: "authentication flow",
    format: "markdown",    // Returns formatted markdown string
    budgetChars: 15000
  }
}

Markdown output includes:

  • Primary files section with relevance scores and reasoning
  • Code snippets with syntax highlighting, grouped by file
  • Call graph visualization showing function relationships
  • Completeness metrics (index freshness, coverage)
  • Budget usage statistics (characters used, snippets included)

Budget Enforcement (Fixed in v0.1.6)

The budgetChars parameter is now strictly enforced:

  • ✅ Output size guaranteed ≤ budgetChars × 1.2
  • ✅ Individual snippets capped at 150 lines or 8000 characters
  • ✅ Smart truncation at natural boundaries (functions, classes)
  • ✅ Truncation warnings included in missingEvidence

Real-world impact: Typical outputs reduced from 3.3MB to ≤18KB (99%+ compression).

Example:

// Before v0.1.6: could return 3.3MB
// After v0.1.6: guaranteed ≤18KB
await mcp.callTool('get_context', {
  query: 'login implementation',
  budgetChars: 15000  // Now enforced!
});

Reasoning Transparency (New in v0.1.6)

Every search result includes a reason field explaining relevance:

{
  "filePath": "src/auth/login.ts",
  "score": 9.2,
  "reason": "🎯 Keyword match: login, authentication • Symbol match: registerLoginCommand (0.95 confidence) • Graph position: 0 hops from query"
}

This helps agents understand:

  • Why a file was selected (keyword vs semantic match)
  • What symbols matched the query
  • How the file relates to other code (graph distance)

Completeness Metrics (New in v0.1.6)

The response includes freshness and coverage signals:

{
  "freshness": {
    "freshnessScore": 0.95,    // 0.0 = stale, 1.0 = fresh
    "coverageScore": 1.0,      // 0.0 = incomplete, 1.0 = complete
    "graphFresh": true,
    "semanticFresh": true,
    "pendingFiles": [],        // Files not yet indexed
    "staleFiles": []           // Files changed since last index
  }
}

Use these signals to know when results might be incomplete:

  • freshnessScore < 0.8 → Run ragcode refresh <repoRoot> on an existing index, or ragcode index <repoRoot> if no index exists
  • pendingFiles.length > 100 → Large portions of the repo not yet indexed
  • staleFiles.length > 10 → Recent changes not reflected in results

Query Language Behavior

Chinese and code-mixed queries are normalized before retrieval

RagCode extracts code tokens, paths, symbols, CJK word segments, and domain lexicon terms before scoring. The query and SQLite FTS index share Intl.Segmenter terms with a bigram fallback/shadow, and Chinese comments or documentation references can create deterministic aliases to real symbols. Chinese questions about protocols, configuration, docs, tests, runtime errors, ownership, and graph relationships can therefore reach implementation evidence without a native tokenizer dependency.

await mcp.callTool('get_context', {
  query: '网关启动尚未就绪返回哪个 close code 常量',
  budgetChars: 15000
});

The trace diagnostics expose detectedLanguage, termCategories, and weighted match reasons such as raw/lexicon/path/symbol/content contribution.

⚠️ Semantic quality still depends on the embedding model

The deterministic embedding fallback is offline and reliable, but it is not a multilingual neural model. For best Chinese semantic recall, use a multilingual OpenAI-compatible embedding model. Capped semantic indexes preserve per-file coverage before quality fill, while exact symbols, paths, and protocol/config terms remain the strongest precision signals.

Good query shapes:

// Chinese plus exact symbol/path hints
await mcp.callTool('get_context', {
  query: '登录功能 registerLoginCommand 的实现'
});

// English still works
await mcp.callTool('get_context', {
  query: 'login implementation'
});

// Exact symbol names remain strongest
await mcp.callTool('get_context', {
  query: 'registerLoginCommand'
});

⚠️ Large repositories with incomplete indexes

When pendingFileCount is high, results may not cover the entire codebase:

  • Check freshness.pendingFiles count in the response
  • Run ragcode index <repoRoot> to continue indexing
  • Use ragcode status <repoRoot> to monitor progress

Complete Example

// MCP client calling get_context
const result = await mcp.callTool('get_context', {
  query: 'authentication flow',
  format: 'markdown',
  budgetChars: 15000,
  mode: 'debug'  // Optional: debug, feature, refactor, review, explain
});

// Markdown format returns
{
  content: "## Authentication Flow (high confidence)\n\n### Primary Files\n...",
  metadata: {
    confidence: "high",
    totalSnippets: 5,
    budgetUsed: 14500,
    freshnessScore: 0.95
  }
}

// JSON format returns ContextPack (unchanged from v0.1.5)
{
  query: "authentication flow",
  brief: "...",
  confidence: "high",
  snippets: [...],
  ownerChain: [...],
  freshness: {...},
  missingEvidence: [...]
}

Web dashboard (observation and debugging)

The dashboard is RagCode's observability surface — project brief, graph visualization and node expansion, search debugging, context-pack and budget-trace inspection, memory, impact/request-flow/diff review, watcher monitoring, and a runtime-config view with per-field source labels and redacted secrets. Setup and configuration stay in the terminal.

ragcode dashboard       # packaged API + Vue dashboard at http://localhost:3000

# Source development only:
npm run web:server
cd web && npm run dev   # Vite frontend on http://localhost:5173

See docs/DASHBOARD.md and web/README.md.


Project Structure

ragcode/
├── src/
│   ├── core/          # Canonical contracts and orchestration facade (stable boundary)
│   ├── indexing/      # Scan, ignore rules, hashing, chunking, analyzers, pipeline
│   ├── graph/         # Structural code graph: symbols, files, edges, lookup
│   ├── semantic/      # Embeddings + vector store (LanceDB / in-memory)
│   ├── re