Session memory, a knowledge graph, a live code index, and stateful code review for any MCP host.
Quick start · Code intelligence · Code review · Memory · Host setup · Configuration · Development
LatentContext is a local Model Context Protocol server. It gives an assistant three things it normally lacks:
- A memory that survives the context window: notes, session summaries, a knowledge graph, and optional local embeddings in SQLite.
- A map of your code: a tree-sitter index of every symbol, call, and reference in the project, kept fresh by file watchers and answered in one tool call.
- A review ledger: plan-driven code review with syntax and security checks, caller impact, verdicts, and step tracking.
Everything runs in-process over stdio. No database server, no native build step, no API keys, and no child processes per tool call.
Important
New in 3.0: LatentContext now covers memory, code intelligence, and code review in one server. code_explore indexes 19 languages with tree-sitter. Four review_* tools run plan-driven reviews with syntax and security checks. Project state in .latentcontext/ keeps itself out of git. See the changelog.
| Area | Tool | What it does |
|---|---|---|
| 🧭 Code | code_explore |
Finds symbols by name, file, or question. Returns their source, call paths, references, and impact. |
| 🔍 Review | review_start |
Registers plan steps and picks a review lens. |
review_chunk |
Checks a changed chunk and returns a verdict, merged findings, patch hints, and caller context. | |
review_status |
Lists live reviews, or shows one review's steps and open findings. | |
review_end |
Deletes a review and its history. | |
| 🧠 Memory | session_start |
Starts a fresh session and archives the previous one. |
memory_store |
Records a note, decision, fact, or event. | |
memory_retrieve |
Returns relevant context within a token budget. | |
memory_compress |
Compresses working memory or summaries. | |
memory_forget |
Deprecates, corrects, or deletes a memory. | |
memory_status |
Reports storage and session statistics. |
| 🧭 One-call code exploration | code_explore takes symbol names, file names, or a plain question and returns line-numbered source, call paths, references, callees, and impact. |
| ⚡ Built for speed | Parsing and scanning run on a worker-thread pool. Results live in in-memory indexes. A compact v8 snapshot makes restarts near-instant. |
| 🔄 Always current | Native recursive watchers on Windows and macOS, per-directory watchers on Linux. Only changed files are re-parsed. |
| 🪟 Quiet on Windows | Tool calls spawn no processes, so no console windows flash. Worker threads do all the heavy work. |
| 🌍 19 languages | TypeScript, TSX, JavaScript, Python, Rust, Go, Java, C#, C, C++, Ruby, PHP, Kotlin, Scala, Lua, Zig, Elixir, Bash, PowerShell. |
| 🔍 Stateful code review | Plan steps, review lenses, syntax and security checks in 19 languages, caller impact, verdicts, and patch hints that persist across restarts. |
| 🧠 Session memory | Tiered working memory, compression, a knowledge graph, and semantic retrieval within a token budget. |
| 🔌 Works everywhere | Portable JSON Schema, tool annotations, output schemas, and server instructions for Claude Code, Claude Desktop, Cursor, VS Code, Windsurf, Codex CLI, Gemini CLI, and more. |
npx -y latentcontext-mcp@latestMost hosts take the same block:
{
"mcpServers": {
"latentcontext": {
"command": "npx",
"args": ["-y", "latentcontext-mcp@latest"]
}
}
}Tip
For faster starts, install globally with npm install -g latentcontext-mcp and use "command": "latentcontext-mcp".
Restart the host after you change its configuration. Requires Node.js 20 or later.
Ask in whatever form is natural. The tool finds the right symbols and returns their verbatim source with line numbers, so the model can edit from it directly.
code_explore { "query": "how does createServer register tools" }
code_explore { "query": "UserService.load handleRequest" }
code_explore { "query": "src/server.ts" }
| Argument | Default | Purpose |
|---|---|---|
query |
required | Symbol names, Owner.member, file names, or a question. |
root |
client roots | Absolute project directory, to explore a project other than the current one. |
max_files |
10 |
Maximum files whose source is included. |
token_budget |
8000 |
Upper bound on response size. |
A real response for "referencesTo resolveRef" on this repository, trimmed for length:
27 files, 495 symbols indexed.
## src/code-explore.ts
function resolveRef L91-105 · function referencesTo L107-113
91 export function resolveRef(ref: CodeRef): CodeSymbol[] {
92 const defs = ref.file.index.defsByName.get(ref.name);
93 if (!defs) return [];
94 if (defs.size === 1) return [...defs];
⋮
107 function referencesTo(symbol: CodeSymbol): CodeRef[] {
108 const refs = symbol.file.index.refsByName.get(symbol.name);
109 if (!refs) return [];
110 const result: CodeRef[] = [];
111 for (const ref of refs) if (ref.from !== symbol && resolveRef(ref).includes(symbol)) result.push(ref);
112 return result.sort((a, b) => Number(b.kind === "call") - Number(a.kind === "call"));
113 }
## Call paths
referencesTo → resolveRef
## References and calls
resolveRef ← referencesTo src/code-explore.ts:111, callees src/code-explore.ts:120
resolveRef → directoryOf src/code-explore.ts:87
referencesTo ← impactOf src/code-explore.ts:212, explore src/code-explore.ts:376
## Impact
6 symbols in 2 files reach resolveRef within 3 hops.
Measured on Windows 10 with Node.js 24:
| Workload | Files | Symbols | Cold index | Restart from cache | Warm query |
|---|---|---|---|---|---|
| Rust + TypeScript app | 715 | 23,341 | 1.3 s | 0.4 s | 9–92 ms |
| Folder of 40+ projects | 8,080 | 136,807 | 4.9 s | — | 92 ms |
An edit is visible on the next call, typically within a few milliseconds.
flowchart LR
A[Project files] -->|scan + .gitignore| B(Worker pool)
B -->|tree-sitter WASM| C[Symbols + references]
C --> D[(In-memory indexes)]
D -->|v8 snapshot| E[(Cache on disk)]
F[File watchers] -->|dirty paths| D
G[code_explore] --> D
D --> H[Ranked source + call graph]
- Scan. A worker walks the project, honours nested
.gitignorefiles, and skips dependency and build caches such asnode_modules,.venv, and.next. - Parse. Changed files are parsed in parallel by up to eight worker threads. Each language has its own query for definitions, calls, inheritance, imports, and type references.
- Index. Symbols land in hash maps keyed by exact name, by sub-word (
loadUserProfile→load,user,profile), and by reference name. Updates are incremental per file. - Rank. Queries are scored by exact and owner-qualified name hits, case-folded matches, IDF-weighted sub-words, prefixes, and file paths.
- Connect. The top matches are linked by a bounded breadth-first search over the call graph. Intermediate functions on a path are pulled into the result.
- Render. Source is read fresh from disk, merged into line ranges, and trimmed to the token budget. Large classes are shown as an outline of their members.
| Platform | Watcher | On change |
|---|---|---|
| Windows, macOS | One native recursive watcher | Re-parse only the touched files |
| Linux | One watcher per indexed directory | Re-parse only the touched files |
| Any, if watching fails | None | Fast full rescan in a worker before each query |
A .gitignore edit or a large burst of changes, such as a branch switch, triggers one rescan. The index persists to <data dir>/code-index/ and is reused on the next start.
| Language | Extensions |
|---|---|
| TypeScript / TSX | .ts .mts .cts .tsx |
| JavaScript | .js .mjs .cjs .jsx |
| Python | .py .pyi |
| Rust | .rs |
| Go | .go |
| Java | .java |
| C# | .cs |
| C / C++ | .c · .cc .cpp .cxx .h .hh .hpp .hxx .ino |
| Ruby | .rb .rake |
| PHP | .php |
| Kotlin | .kt .kts |
| Scala | .scala .sc |
| Lua | .lua |
| Zig | .zig |
| Elixir | .ex .exs |
| Bash | .sh .bash |
| PowerShell | .ps1 .psm1 |
The project to index is picked in this order:
- The
rootargument of the call. LATENTCONTEXT_CODE_ROOT(several paths may be joined with the platform path delimiter).- The roots the MCP client reports.
- The server's working directory, if it looks like a project (
.git,package.json,Cargo.toml,go.mod,pyproject.toml, and similar).
The home directory and drive roots are never indexed.
Four tools run a stateful review against a plan. The model does the judging; the server adds deterministic checks, caller impact from the code index, a verdict, and a ledger that survives restarts.
| Tool | Use | Annotations |
|---|---|---|
review_start |
Register plan steps and pick a review lens. Returns the review ID and the lens text. | |
review_chunk |
Submit a changed chunk for one step, with your own findings. Returns the verdict, merged findings, patch hints, and caller context. | |
review_status |
List live reviews, or show one review's steps, last verdicts, and open findings. | read-only |
review_end |
Delete a review and its chunk history. | destructive, idempotent |
review_start { "steps": ["Harden path handling", "Remove shell calls"], "profile": "cybersec-auditor-general-v2.0" }
review_chunk { "review_id": "…", "step": 2, "file": "src/run.ts", "code": "…", "findings": [{ "severity": "high", "category": "logic", "message": "Exit code is ignored.", "line": 4 }] }
What review_chunk adds on top of your findings:
- Syntax: tree-sitter parse errors and missing tokens for all 19 indexed languages.
- Security: language-aware rules for
eval, shell execution, unsafe deserialization, raw HTML sinks, disabled TLS checks, SQL built by interpolation, unbounded C buffer writes, hardcoded secrets, private keys, and AWS keys. - Debug leftovers:
debugger,pdb.set_trace(),breakpoint(), anddbg!. - Patch hints: exact search and replace pairs, only where a drop-in fix exists (for example
yaml.load(→yaml.safe_load(, or a hardcoded JS secret →process.env.NAME). - Context: for each symbol the chunk defines (or the
symbolyou name), its references, first callers, and impact from the code index.
Any critical or high finding makes the verdict NEEDS_WORK and keeps the step IN_PROGRESS; otherwise the step is VALIDATED. A review is COMPLETED when every step is validated. Finding lines are relative to the chunk; context lines are relative to the file. Reviews expire 7 days after their last update.
A lens is a Markdown prompt that sets what the review looks for. Four ship with the package: universal-auditor-general-v3 (the default), cybersec-auditor-general-v2.0, performance-reliability-auditor-v2.0, and design-audit-director-v2.0. The profile argument is an enum of the available lenses, so hosts show them without an extra tool. Set LATENTCONTEXT_REVIEW_PROFILES to a directory of *.md files to use your own; the file name is the ID and the first # heading is the title.
| Tool | Use | Annotations |
|---|---|---|
session_start |
Start a session; any active session is archived first. | |
memory_store |
Record a note, decision, fact, or event for the active session. | |
memory_retrieve |
Retrieve relevant session context within a token budget. | read-only |
memory_compress |
Compress working memory or summaries (lossy). | destructive |
memory_forget |
Deprecate, correct, or remove a memory. | destructive, idempotent |
memory_status |
Report current storage and session statistics. | read-only |
Stored notes need at least 10 words; 25 or more are recommended. Working memory is isolated by session ID, and it is archived when a session changes or the server shuts down.
session_start, memory_store, memory_retrieve, memory_status, code_explore, review_start, review_chunk, and review_status return structuredContent that matches a published outputSchema.
Resources and prompts
| URI | Content |
|---|---|
memory://core |
Persistent Tier 3 core memories. |
memory://session/current |
Working memory for the active session. |
memory://graph/schema |
Entity types and relation predicates (JSON). |
memory://stats |
Storage statistics (JSON). |
extract_facts, compress_session, and consolidate_epoch are prompt templates. They turn text into fact triples, summarize working memory, and merge session summaries.
Claude Code
claude mcp add latentcontext --scope user -- npx -y latentcontext-mcp@latestUse --scope project to share the configuration through .mcp.json.
Claude Desktop
Add the mcpServers block from Quick start to claude_desktop_config.json (Settings → Developer → Edit Config).
Cursor
Add the mcpServers block to .cursor/mcp.json in the project, or to ~/.cursor/mcp.json for all projects.
VS Code (GitHub Copilot)
Create .vscode/mcp.json:
{
"servers": {
"latentcontext": {
"type": "stdio",
"command": "npx",
"args": ["-y", "latentcontext-mcp@latest"]
}
}
}Windsurf
Add the mcpServers block to ~/.codeium/windsurf/mcp_config.json.
Codex CLI
Add to ~/.codex/config.toml:
[mcp_servers.latentcontext]
command = "npx"
args = ["-y", "latentcontext-mcp@latest"]Gemini CLI
Add the mcpServers block to ~/.gemini/settings.json, or to .gemini/settings.json in the project.
| Variable | Effect |
|---|---|
LATENTCONTEXT_CODE_ROOT |
Project directory (or directories) for code_explore. Overrides client roots. |
LATENTCONTEXT_CODE_INDEX |
Set to 0 or off to disable the code index and hide code_explore. Reviews then skip caller context. |
LATENTCONTEXT_REVIEW_PROFILES |
Directory of *.md review lenses. Replaces the bundled lenses. |
LATENTCONTEXT_DATA_DIR |
Directory for memory.db, server.log, and code-index/. Overrides every other storage setting. |
LATENTCONTEXT_CONFIG |
Path to a latentcontext.config.json to load. |
LATENTCONTEXT_ALLOW_PROJECT_CONFIG |
Set to 1 to also read latentcontext.config.json from the launched project. |
LATENTCONTEXT_HIDE_CONSOLE |
Windows only. Set to 0 to keep the console window visible. |
Runtime state is project-local by default:
<launched-project>/.latentcontext/
├── .gitignore # "*" so the folder never reaches git
├── memory.db
├── server.log
└── code-index/
<launched-project> is the working directory of the server process. The folder ignores itself, so no repository needs a .gitignore entry for it. To share memory across projects, set LATENTCONTEXT_DATA_DIR:
{
"mcpServers": {
"latentcontext": {
"command": "latentcontext-mcp",
"env": { "LATENTCONTEXT_DATA_DIR": "C:/shared/latentcontext" }
}
}
}Configuration file
Point LATENTCONTEXT_CONFIG at a JSON file:
{
"storage": { "dataDir": "./shared-state", "sqliteFile": "memory.db" },
"embedding": { "provider": "local" }
}A relative storage.dataDir resolves against the configuration file. The server also reads latentcontext.config.json from the default data directory or beside the installed package. A latentcontext.config.json in the launched project is ignored unless LATENTCONTEXT_ALLOW_PROJECT_CONFIG=1 is set. Use "provider": "none" to disable embeddings.
Diagnostics go to server.log in the data directory. After the MCP handshake, records at info and above are also sent as notifications/message with logger latentcontext. Clients can change the threshold with logging/setLevel. Stdout carries only protocol frames, and nothing is written to stderr.
git clone https://github.com/Master0fFate/LatentContext-MCP.git
cd LatentContext-MCP
npm install
npm run build| Script | Purpose |
|---|---|
npm run build |
Compile TypeScript and prepare the executable. |
npm run dev |
Run the TypeScript source directly. |
npm run typecheck |
Type-check sources, tests, and benchmarks. |
npm test |
Run the full suite over real stdio. |
npm run test:smoke |
Pack, install, and exercise the packaged server. |
npm run check |
typecheck + test. |
npm run audit:production |
Audit production dependencies. |
npm run benchmark:retrieval |
Benchmark memory retrieval. |
To run a local build from a host, point it at the entry point:
{
"mcpServers": {
"latentcontext": {
"command": "node",
"args": ["/absolute/path/to/LatentContext-MCP/dist/index.js"]
}
}
}CI runs on Linux, macOS, and Windows with Node.js 20, 22, and 24.
Note
If npm install fails while onnxruntime-node downloads optional CUDA binaries (Linux x64 only), set ONNXRUNTIME_NODE_INSTALL_CUDA=skip. The server does not use them.
Grammar sources
Grammars for TypeScript, TSX, JavaScript, Python, Rust, Go, Java, C#, C++, Ruby, PHP, Bash, and PowerShell come from @vscode/tree-sitter-wasm. The C, Kotlin, Scala, Lua, Zig, and Elixir grammars in grammars/ are the prebuilt WebAssembly files published with tree-sitter-c 0.24.1, @tree-sitter-grammars/tree-sitter-kotlin 1.1.0, tree-sitter-scala 0.24.0, @tree-sitter-grammars/tree-sitter-lua 0.4.1, @tree-sitter-grammars/tree-sitter-zig 1.1.2, and tree-sitter-elixir 0.3.5.