PureContext MCP
README.md
# PureContext MCP
[](https://www.npmjs.com/package/purecontext-mcp)
[](docs/27-api-stability.md)
[](LICENSE)
**Most tools help an AI agent *read* your codebase. PureContext helps it *change* your codebase safely.**
Agents are already good at finding code. What they can't see is the part that breaks things: what a symbol connects to, what quietly changes alongside it, and whether it's risky to touch at all. PureContext MCP indexes your codebase into a structured, queryable model and gives agents that missing layer — **impact, coupling, and change-risk intelligence, before the edit.**
```
Before changing processRefund(), the agent checks:
get_symbol_risk → band: HIGH — 47 dependents · churn 8/90d
· no direct test · co-changes with ledger.ts (conf 0.71)
get_blast_radius → 23 files affected across 4 modules
get_co_change → usually moves together with refund.test.ts and ledger.ts
→ so it updates those together, instead of shipping a half-change that
passes locally and breaks billing in production.
```
This is the layer autonomous agents are missing. Refactoring and change-safety tooling is still mostly built for humans clicking through an IDE — not for an agent about to edit code it has never seen. PureContext closes that gap: blast radius, temporal co-change, rename/delete/move safety checks, and a composite per-symbol risk score — all queryable as MCP tools.
It's built on **token-efficient retrieval** as the foundation: agents pull a single function, class, or route by name or meaning instead of reading whole files — typically **90%+ fewer context tokens** ([see it in action](#what-this-looks-like-in-practice)). Precise context means less hallucination, more accurate edits, and the ability to work on codebases far larger than any context window.
---
## Quick start
```bash
# Inside your project: registers the MCP server (pinned to your global Node) AND
# adds the workflow rules — auto-detects Claude / Cursor / Windsurf / Continue /
# Cline / Roo Code / Copilot / Claude Desktop
npx purecontext-mcp@latest install all
# Prefer to wire up Claude Code by hand? Register the server manually:
claude mcp add purecontext-mcp -- npx purecontext-mcp@latest
# Recommended: keep the index fresh after checkout / pull / merge / rebase.
# Installs post-checkout, post-merge and post-rewrite git hooks for this repo
# (all worktrees). They re-index only what git says changed and never block git.
npx purecontext-mcp@latest hooks --install --git
# (or: npx purecontext-mcp@latest install all --with-git-hooks)
```
Then in a Claude Code conversation:
```
Index my project at /path/to/my-project
```
That's it. Claude will index your codebase and you can start navigating it by name, by meaning, or by dependency — without reading files.
---
## What this looks like in practice
### First, find and understand it
A typical "find and understand" conversation, before vs. after:
**Without PureContext**
```
You: Where do we handle Stripe webhook signature verification?
Claude: I'll search the codebase.
[reads src/api/webhooks/stripe.ts — 412 lines, ~3,100 tokens]
[reads src/lib/stripe-client.ts — 287 lines, ~2,150 tokens]
[reads src/middleware/webhook.ts — 198 lines, ~1,490 tokens]
Verification happens in verifyStripeSignature() at line 87 of stripe.ts.
Total context used: ~6,740 tokens
```
**With PureContext**
```
You: Where do we handle Stripe webhook signature verification?
Claude: search_symbols(query: "stripe webhook signature")
→ 3 matches, 78 tokens
get_symbol_source(symbolId: "verifyStripeSignature")
→ 32 lines, 180 tokens
verifyStripeSignature() at src/api/webhooks/stripe.ts:87.
It uses the timing-safe HMAC check from Stripe's SDK with a 5-minute tolerance.
Total context used: ~258 tokens — 96% less
```
The agent stays in the conversation instead of running out of context after one file read — which frees it to get to the part that actually matters: changing the code safely.
### Then change it without breaking things
A typical "modify this" conversation, before vs. after:
**Without PureContext**
```
You: Add a partial-refund path to processRefund().
Claude: [reads processRefund, edits it]
Done — added the partial-refund branch.
(Never saw that ledger.ts reconciles every refund, or that
refund.test.ts asserts the old totals. CI breaks; billing
drifts in production.)
```
**With PureContext**
```
You: Add a partial-refund path to processRefund().
Claude: get_symbol_risk(symbolId: "processRefund")
→ band: HIGH — 47 dependents · churn 8/90d · no direct test
· co-changes with ledger.ts (conf 0.71)
get_blast_radius(symbolId: "processRefund")
→ 23 files affected across 4 modules
get_co_change(symbolId: "processRefund")
→ usually moves together with ledger.ts and refund.test.ts
This symbol is high-risk and untested. I'll update processRefund(),
adjust the reconciliation in ledger.ts, and extend refund.test.ts
in the same change.
```
The difference here isn't tokens — it's that the agent saw the second-order edits *before* writing code, instead of discovering them in a failed CI run or a production incident.
---
## Change & refactoring intelligence
This is the part most code tools leave to humans. PureContext exposes it as MCP tools an agent can call *before* it edits — so autonomous changes come with the same impact awareness a careful senior engineer would bring.
| Question the agent can answer | Tool |
|---|---|
| What breaks if I change this symbol? | `get_blast_radius` |
| What files historically change *together* with this one (but don't import it)? | `get_co_change` |
| How risky is this symbol to change, and why? | `get_symbol_risk` |
| Is it safe to rename / delete / move this? | `check_rename_safe` · `check_delete_safe` · `check_move_safe` |
| What's the impact *before* I edit, and what will I forget to touch? | `prepare_change` |
| Did my applied change actually cover everything I planned? | `verify_change` |
| Did my change introduce a new cycle or layer violation? | `compare_change_impact` |
| What's the sequenced, risk-annotated plan for a larger refactor? | `plan_refactoring` |
| Who calls this, and who do they call? | `get_call_hierarchy` · `find_references` |
| What's churning or accumulating debt? | `get_churn_metrics` · `get_debt_report` · `health_radar` |
**`get_symbol_risk`** is the composite verdict: it fuses change frequency (churn), centrality (how much depends on it), complexity, test-coverage gaps, and temporal co-change into one banded score (`low` / `review` / `high`) with human-readable reasons — never a black-box number, and deliberately **code-centered** (no author or productivity metrics). **`get_co_change`** surfaces the coupling the import graph can't see — the test, the migration, or the feature flag that always moves with a file. Together they let an agent edit unfamiliar code the way a cautious human does: check the blast radius, update what moves with it, and flag what it shouldn't touch alone.
PureContext also closes the loop *around* an edit — **judgment, not actuation** (it never writes files; your agent does): **`prepare_change`** gives a pre-edit impact verdict for a stated intent (and flags the co-change partners you're about to forget), **`verify_change`** reconciles the real diff against that plan (`complete` / `incomplete` / `scope_expanded`), and **`compare_change_impact`** reports the *new* cycles or layer violations a change introduced — never blaming it for pre-existing ones.
→ Full tool list and parameters: [AGENT_REFERENCE.md](AGENT_REFERENCE.md) · safe-change workflow: [SAFE-CHANGES.md](SAFE-CHANGES.md)
---
## Measured search precision
PureContext is benchmarked on **87 real-world open-source projects** with 25 curated ground-truth queries each. Top-rank precision (P@1) reaches 84% on NestJS, 84% on Terraform, 72% on Protobuf and GraphQL, 60% on Nix, 52% on LÖVE (Lua/C++), and 40% on Tokio (Rust). Full per-language tables, methodology, and reproduction steps are in [BENCHMARKS.md](BENCHMARKS.md).
---
## Documentation
### User Guide — start here
The guide explains what PureContext does, why each feature exists, and how to use it effectively in real-world situations. It covers both solo developers and team deployments.
| | |
|-|-|
| [Why PureContext](WHY-PURECONTEXT.md) | The full case — beyond token savings |
| [Navigating a New Codebase](NAVIGATING-NEW-CODE.md) | Day one on an unfamiliar project |
| [Finding Code](FINDING-CODE.md) | Three search modes with examples |
| [Making Changes Safely](SAFE-CHANGES.md) | Blast radius and dependency analysis |
| [Understanding Code Relationships](UNDERSTANDING-RELATIONSHIPS.md) | Call hierarchies, cycles, coupling, implementations |
| [Refactoring Safely](REFACTORING-SAFELY.md) | Pre-flight checks before rename, delete, or move |
| [Understanding Code History](CODE-HISTORY.md) | Symbol-level git history and churn |
| [The Web UI](WEB-UI.md) | Visual graph, heatmap, symbol timeline |
| [AI Summaries](AI-SUMMARIES.md) | Better search on undocumented codebases |
| [Code Health & Architecture Analysis](CODE-HEALTH.md) | Quality metrics, anti-patterns, arch docs |
| [Health Dashboards & Debt Reporting](HEALTH-DASHBOARDS.md) | Health radar, debt scores, PR health diffs |
| [Visualizing Code Structure](VISUALIZING-CODE.md) | Mermaid/DOT diagrams, architecture snapshots |
| [AST-Level Search](AST-SEARCH.md) | Node types, signatures, decorators, complexity |
| [Code Intelligence](CODE-INTELLIGENCE.md) | Entry points, public API, TODOs, coverage |
| [Language Support](LANGUAGE-SUPPORT.md) | All 34 supported languages and what's extracted |
| [Framework Adapters](FRAMEWORK-ADAPTERS.md) | Vue, React, Django, Spring, Rails, Flutter, ORMs, and more |
| [Using PureContext with a Team](TEAM-SETUP.md) | Shared server, enterprise setup |
| [Operations Guide](docs/28-operations.md) | Large repos, scoped indexes, branch discipline, verification, privacy |
**Real-world workflows:**
| | |
|-|-|
| [Onboarding to a New Codebase](WORKFLOW-ONBOARDING.md) | First day on a 6,000-file microservices platform |
| [Refactoring Legacy Code](WORKFLOW-REFACTORING.md) | Replacing auth in a 6-year-old Django monolith |
| [Reviewing a Pull Request](WORKFLOW-PR-REVIEW.md) | 40-file PR, 45 minutes, two real bugs found |
| [Running a Tech Debt Sprint](WORKFLOW-TECH-DEBT.md) | Two-week debt reduction: assess, plan, execute, measure |
→ [Full guide index](USER-GUIDE.md)
### Reference Manual
Parameter-level documentation for every tool, configuration option, language, framework adapter, and deployment option lives in [`docs/README.md`](docs/README.md). The reference manual is cross-linked with the user guide above — every topic has both a narrative and a reference page where one helps.
---
## What it indexes
### Languages
**34 languages** via bundled tree-sitter WASM grammars — no separate install required.
Symbol indexing and search cover all 34. Dependency **edges** (blast radius, importers, cycles) currently cover TypeScript/JavaScript, the JVM family (Kotlin, Java, Scala, Groovy — package-aware, multi-module safe), C# (namespace-aware, multi-project safe), Python (layout-convention resolver, `src/` layouts and relative imports), Go (`go.mod` resolver, workspaces supported), PHP (namespace + composer PSR-4), Haskell, Elixir, Erlang, Fortran (v1.19.0), Rust (v1.20.0 — mod-tree resolver, Cargo workspaces supported), Dart (v1.31.0), Ruby and Swift (v1.36.0 — discovered load paths + Zeitwerk constants; SwiftPM targets), and languages whose imports are file paths — see [which languages get dependency edges](LANGUAGE-SUPPORT.md#which-languages-get-dependency-edges) before relying on the graph tools for the remaining long tail.
| Category | Languages |
|----------|-----------|
| Web / Application | TypeScript, JavaScript, Python, PHP, Ruby, Go, Java, Kotlin, C#, Scala, Dart, Swift, Elixir, Haskell, Lua, R, Perl, Groovy, Erlang, Gleam |
| Systems | C, C++, Rust, Fortran, Objective-C |
| Scripting & Game | Bash, GDScript |
| Infrastructure & Config | Terraform / HCL, Nix |
| Data & API | SQL, Protobuf, GraphQL, OpenAPI / YAML, XML |
| Styling (regex-based) | SCSS, SASS, LESS, CSS |
→ [Language Support guide](LANGUAGE-SUPPORT.md) · [Full reference](docs/07-language-support.md)
### Frameworks
**Framework-aware extraction** — routes, components, hooks, models, ORM entities, and middleware are pulled out as first-class symbols (not just functions and classes).
| Stack | Frameworks |
|-------|-----------|
| JavaScript / TypeScript | Vue 3, React, Nuxt, Next.js (Pages + App Router), Angular, NestJS, Express, Fastify |
| Python | Django, FastAPI, Flask |
| Go | Gin, Echo, Fiber |
| PHP | Laravel, Symfony |
| Ruby | Rails, Sinatra |
| Java | Spring Boot, Micronaut, Quarkus |
| Kotlin | Ktor, Spring (Kotlin) |
| Rust | Axum, Actix-web, Rocket |
| Mobile | Flutter, Android (Compose + Hilt + Manifest) |
| ORMs | Hibernate, SQLAlchemy, Django ORM, Prisma, TypeORM |
→ [Framework Adapters guide](FRAMEWORK-ADAPTERS.md) · [Full reference](docs/08-framework-adapters.md)
---
## Installation
**Requirements:** Node.js 18, 20, or 22. Prebuilt binaries included for Windows, macOS, and Linux — no native compilation needed.
### Claude Code
```bash
claude mcp add purecontext-mcp -- npx purecontext-mcp@latest
```
### Git hooks — keep the index fresh (recommended)
An index built before your last `git checkout` / `pull` / `rebase` returns
old symbol locations. Fix that once per repository:
```bash
npx purecontext-mcp@latest hooks --install --git # in any worktree of the repo
npx purecontext-mcp@latest hooks --list # shows the state
npx purecontext-mcp@latest hooks --uninstall --git # removes them
```
What you get:
- `post-checkout`, `post-merge`, `post-rewrite` shims in the directory git runs
hooks from (`core.hooksPath` respected — husky / lefthook friendly; an
existing hook body is kept and chained). A linked worktree installs into the
shared hooks dir, so one install covers every worktree.
- After each of those git operations the index is brought up to HEAD from
git's own change list — no directory walk. Small changes run inline (10 s
cap); big ones run detached, and `list_repos` shows `re-index in progress`.
- `git worktree add` clones the sibling worktree's index instead of
re-parsing (measured: a 7k-file tree went from 309 s to 4 s).
- Nothing here can make a git command fail — every shim exits 0.
Without the hooks, run `index_folder({ path, onlyChanged: true })` after a
branch change; `list_repos` reports `freshness` per repo either way.
**Keep it small.** Since 1.33.0 an index no longer carries the source text;
every file's bytes live once in a shared, content-addressed store
(`~/.purecontext/blobs.db`), so a second worktree costs its symbols and
edges only. Indexes whose checkout is gone, and half-written ones from a
crashed run, are listed by `list_repos` (`store`) and removed by
```bash
npx purecontext-mcp@latest index gc # dry run
npx purecontext-mcp@latest index gc --blobs --yes
```
### Claude Desktop
Edit `~/.claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"purecontext": {
"command": "npx",
"args": ["purecontext-mcp@latest"]
}
}
}
```
### Cursor
Create `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for global):
```json
{
"mcpServers": {
"purecontext": {
"command": "npx",
"args": ["purecontext-mcp@latest"]
}
}
}
```
### Windsurf
Open Windsurf Settings → MCP section, or edit the MCP config file directly:
```json
{
"mcpServers": {
"purecontext": {
"command": "npx",
"args": ["purecontext-mcp@latest"]
}
}
}
```
### VS Code
Create `.vscode/mcp.json` in your project:
```json
{
"servers": {
"purecontext": {
"type": "stdio",
"command": "npx",
"args": ["purecontext-mcp@latest"]
}
}
}
```
### Shared team server (HTTP)
If your team runs a shared PureContext server, connect with an HTTP transport instead:
```json
{
"mcpServers": {
"purecontext": {
"transport": "http",
"url": "https://purecontext.yourcompany.com/mcp/sse",
"headers": {
"Authorization": "Bearer pctx_yourpersonalkey"
}
}
}
}
```
### Data directory
Indexes, the shared content store (`blobs.db`), config, and telemetry live
under `~/.purecontext/` by default. Set the `PCTX_DATA_DIR` environment
variable to relocate everything (useful for CI, test isolation, or keeping
experiments away from your real indexes):
```bash
PCTX_DATA_DIR=/tmp/pctx-scratch npx purecontext-mcp
```
The test suite sets this automatically (`test/setup.ts`), so `npm test` never
touches your real `~/.purecontext`.
**Branches:** an index is keyed on the folder path, not the git branch, and
since 1.30.0 it records the commit it reflects (`head` / `freshness` on
`list_repos`). Install the git hooks once — `npx purecontext-mcp hooks
--install --git` — and every checkout / merge / rebase re-indexes what
changed from git's own change list (no directory walk, never blocks git).
Without hooks: `index_folder({ path, onlyChanged: true })` after an in-place
switch. For parallel branch work use one git worktree per branch: a new
worktree clones a sibling's index and applies the delta instead of
re-parsing.
→ [Full installation guide](FULL-INSTALLATION-GUIDE.md)
---
## Teaching your AI agent to use PureContext well
Installing PureContext gives your agent the tools. Adding the agent instructions tells it *how* to use them — which tool to pick for each task, in what order, and what to avoid.
Without these instructions, an agent may default to reading entire files rather than using `search_symbols`, or may not know to call `list_repos` first to get the repository ID required by every tool.
### One-command install (recommended)
Run this once inside your project directory:
```bash
npx purecontext-mcp@latest install all
```
This auto-detects which AI coding tools you have set up in the project and writes the PureContext workflow rules to the right place for each. Re-running is safe — every writer is idempotent (managed blocks are marked and replaced rather than appended).
When no `--scope` flag is given, the CLI prompts you to choose where to install:
```
Where should PureContext be installed?
1) Local — this project only
2) Global — all projects (user-level config)
3) Both
```
Pass `--scope` to skip the prompt:
```bash
npx purecontext-mcp@latest install all --scope=local # this project only
npx purecontext-mcp@latest install all --scope=global # user-level, all projects
npx purecontext-mcp@latest install all --scope=both # both places at once
```
For a single tool:
```bash
npx purecontext-mcp@latest install <tool> --scope=global
```
To preview without writing files:
```bash
npx purecontext-mcp@latest install all --dry-run
npx purecontext-mcp@latest install --list # show which IDEs were detected
```
Supported tools and where each one writes its workflow rules (it also registers the `purecontext-mcp` MCP server with each — pinned to your global Node — in that tool's own MCP config):
| Tool | Local | Global |
|------|-------|--------|
| `claude` | `CLAUDE.md` in project | `~/.claude/CLAUDE.md` + hooks |
| `cursor` | `.cursor/rules/purecontext.mdc` | `~/.cursor/rules/purecontext.mdc` |
| `windsurf` | `.windsurf/rules/purecontext.md` | `~/.windsurf/rules/purecontext.md` |
| `continue` | `.continue/config.json` | `~/.continue/config.json` |
| `cline` | `.clinerules` | local only |
| `roo-code` | `.roo/rules-code.md` | local only |
| `copilot` | `.github/copilot-instructions.md` | local only |
| `claude-desktop` | always global | always global |
### Manual install
If you'd rather paste the rules yourself, two instruction files are at the repository root:
- **[`AGENT_INSTRUCTIONS.md`](AGENT_INSTRUCTIONS.md)** — the onboarding doc: mandatory workflow, tool-selection table, navigation patterns, and anti-patterns. Paste into your agent's rules file, or run `npx purecontext-mcp install <tool>` to write a compact, always-on version automatically.
- **[`AGENT_REFERENCE.md`](AGENT_REFERENCE.md)** — the single canonical reference: a full intent→tool picker, every parameter, every navigation pattern, and known limitations. Installed automatically by `hooks --install`; read this when an agent needs the authoritative answer.
Paste the contents into whatever system prompt, memory, or rules configuration your agent uses.
---
## License
MIT — see [LICENSE](LICENSE).
## Contributing
Issues and pull requests are welcome at [github.com/goranocokoljic/pure-context](https://github.com/goranocokoljic/pure-context). Before opening a feature PR, please open an issue to discuss the design — the three-layer architecture (Core → Handlers → Adapters) has hard rules about dependency direction that are easy to violate accidentally. See [`CLAUDE.md`](CLAUDE.md) at the project root for the architectural conventions.
For language or framework adapters: pick a real-world repository, add a 25-query ground-truth file in `benchmarks/<project>/queries.json`, and include benchmark numbers (P@1 / P@3 / R@5) in the PR description so reviewers can confirm the change is a net improvement.
## Support
- **Bug reports and feature requests:** [GitHub Issues](https://github.com/goranocokoljic/pure-context/issues)
- **Questions about MCP integration:** Open a Discussion on the repository
- **Changelog:** [CHANGELOG.md](CHANGELOG.md)
- **Stability and semver policy:** [docs/27-api-stability.md](docs/27-api-stability.md)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues