purecontext-mcp 1.2.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/AGENT_INSTRUCTIONS.md +110 -784
  2. package/AGENT_REFERENCE.md +561 -0
  3. package/CHANGELOG.md +177 -6
  4. package/FRAMEWORK-ADAPTERS.md +351 -0
  5. package/LANGUAGE-SUPPORT.md +144 -0
  6. package/README.md +92 -12
  7. package/USER-GUIDE.md +8 -0
  8. package/dist/cli/hooks.d.ts +28 -0
  9. package/dist/cli/hooks.d.ts.map +1 -0
  10. package/dist/cli/hooks.js +570 -0
  11. package/dist/cli/hooks.js.map +1 -0
  12. package/dist/cli/install-detect.d.ts +16 -0
  13. package/dist/cli/install-detect.d.ts.map +1 -0
  14. package/dist/cli/install-detect.js +70 -0
  15. package/dist/cli/install-detect.js.map +1 -0
  16. package/dist/cli/install-writers.d.ts +59 -0
  17. package/dist/cli/install-writers.d.ts.map +1 -0
  18. package/dist/cli/install-writers.js +292 -0
  19. package/dist/cli/install-writers.js.map +1 -0
  20. package/dist/cli/install.d.ts +14 -0
  21. package/dist/cli/install.d.ts.map +1 -0
  22. package/dist/cli/install.js +150 -0
  23. package/dist/cli/install.js.map +1 -0
  24. package/dist/config/config-loader.js +3 -0
  25. package/dist/config/config-loader.js.map +1 -1
  26. package/dist/config/config-schema.d.ts +11 -0
  27. package/dist/config/config-schema.d.ts.map +1 -1
  28. package/dist/config/config-schema.js +15 -0
  29. package/dist/config/config-schema.js.map +1 -1
  30. package/dist/core/db/symbol-store.d.ts +1 -0
  31. package/dist/core/db/symbol-store.d.ts.map +1 -1
  32. package/dist/core/db/symbol-store.js +120 -6
  33. package/dist/core/db/symbol-store.js.map +1 -1
  34. package/dist/core/file-discovery.d.ts +6 -0
  35. package/dist/core/file-discovery.d.ts.map +1 -1
  36. package/dist/core/file-discovery.js +20 -13
  37. package/dist/core/file-discovery.js.map +1 -1
  38. package/dist/core/file-processor.d.ts.map +1 -1
  39. package/dist/core/file-processor.js +26 -1
  40. package/dist/core/file-processor.js.map +1 -1
  41. package/dist/core/git-log-reader.d.ts.map +1 -1
  42. package/dist/core/git-log-reader.js +21 -0
  43. package/dist/core/git-log-reader.js.map +1 -1
  44. package/dist/core/index-manager.d.ts.map +1 -1
  45. package/dist/core/index-manager.js +21 -7
  46. package/dist/core/index-manager.js.map +1 -1
  47. package/dist/core/indexing-worker.d.ts.map +1 -1
  48. package/dist/core/indexing-worker.js +14 -0
  49. package/dist/core/indexing-worker.js.map +1 -1
  50. package/dist/core/parse-dispatcher.d.ts.map +1 -1
  51. package/dist/core/parse-dispatcher.js +20 -5
  52. package/dist/core/parse-dispatcher.js.map +1 -1
  53. package/dist/core/search/query-preprocessor.d.ts +69 -3
  54. package/dist/core/search/query-preprocessor.d.ts.map +1 -1
  55. package/dist/core/search/query-preprocessor.js +450 -17
  56. package/dist/core/search/query-preprocessor.js.map +1 -1
  57. package/dist/core/search/relevance-ranker.d.ts +60 -5
  58. package/dist/core/search/relevance-ranker.d.ts.map +1 -1
  59. package/dist/core/search/relevance-ranker.js +931 -33
  60. package/dist/core/search/relevance-ranker.js.map +1 -1
  61. package/dist/core/test-mapper.d.ts.map +1 -1
  62. package/dist/core/test-mapper.js +7 -1
  63. package/dist/core/test-mapper.js.map +1 -1
  64. package/dist/core/types.d.ts +28 -1
  65. package/dist/core/types.d.ts.map +1 -1
  66. package/dist/handlers/angular-html.d.ts +3 -0
  67. package/dist/handlers/angular-html.d.ts.map +1 -0
  68. package/dist/handlers/angular-html.js +215 -0
  69. package/dist/handlers/angular-html.js.map +1 -0
  70. package/dist/handlers/c.d.ts.map +1 -1
  71. package/dist/handlers/c.js +19 -0
  72. package/dist/handlers/c.js.map +1 -1
  73. package/dist/handlers/cpp-macro-registry.d.ts +21 -0
  74. package/dist/handlers/cpp-macro-registry.d.ts.map +1 -0
  75. package/dist/handlers/cpp-macro-registry.js +44 -0
  76. package/dist/handlers/cpp-macro-registry.js.map +1 -0
  77. package/dist/handlers/cpp.d.ts.map +1 -1
  78. package/dist/handlers/cpp.js +579 -10
  79. package/dist/handlers/cpp.js.map +1 -1
  80. package/dist/handlers/csharp.d.ts.map +1 -1
  81. package/dist/handlers/csharp.js +39 -2
  82. package/dist/handlers/csharp.js.map +1 -1
  83. package/dist/handlers/css.d.ts +3 -0
  84. package/dist/handlers/css.d.ts.map +1 -0
  85. package/dist/handlers/css.js +154 -0
  86. package/dist/handlers/css.js.map +1 -0
  87. package/dist/handlers/erlang.d.ts.map +1 -1
  88. package/dist/handlers/erlang.js +8 -1
  89. package/dist/handlers/erlang.js.map +1 -1
  90. package/dist/handlers/fortran.js +1 -1
  91. package/dist/handlers/fortran.js.map +1 -1
  92. package/dist/handlers/go.d.ts.map +1 -1
  93. package/dist/handlers/go.js +87 -2
  94. package/dist/handlers/go.js.map +1 -1
  95. package/dist/handlers/handler-registry.d.ts.map +1 -1
  96. package/dist/handlers/handler-registry.js +4 -0
  97. package/dist/handlers/handler-registry.js.map +1 -1
  98. package/dist/handlers/hcl.d.ts +3 -0
  99. package/dist/handlers/hcl.d.ts.map +1 -0
  100. package/dist/handlers/hcl.js +193 -0
  101. package/dist/handlers/hcl.js.map +1 -0
  102. package/dist/handlers/java.d.ts.map +1 -1
  103. package/dist/handlers/java.js +33 -16
  104. package/dist/handlers/java.js.map +1 -1
  105. package/dist/handlers/kotlin.d.ts.map +1 -1
  106. package/dist/handlers/kotlin.js +48 -3
  107. package/dist/handlers/kotlin.js.map +1 -1
  108. package/dist/handlers/less.d.ts +3 -0
  109. package/dist/handlers/less.d.ts.map +1 -0
  110. package/dist/handlers/less.js +255 -0
  111. package/dist/handlers/less.js.map +1 -0
  112. package/dist/handlers/objective-c.d.ts.map +1 -1
  113. package/dist/handlers/objective-c.js +122 -64
  114. package/dist/handlers/objective-c.js.map +1 -1
  115. package/dist/handlers/openapi.d.ts.map +1 -1
  116. package/dist/handlers/openapi.js +30 -5
  117. package/dist/handlers/openapi.js.map +1 -1
  118. package/dist/handlers/php.d.ts.map +1 -1
  119. package/dist/handlers/php.js +287 -41
  120. package/dist/handlers/php.js.map +1 -1
  121. package/dist/handlers/protobuf.d.ts.map +1 -1
  122. package/dist/handlers/protobuf.js +1 -0
  123. package/dist/handlers/protobuf.js.map +1 -1
  124. package/dist/handlers/python.d.ts.map +1 -1
  125. package/dist/handlers/python.js +1 -3
  126. package/dist/handlers/python.js.map +1 -1
  127. package/dist/handlers/ruby-dsl.d.ts +23 -0
  128. package/dist/handlers/ruby-dsl.d.ts.map +1 -0
  129. package/dist/handlers/ruby-dsl.js +251 -0
  130. package/dist/handlers/ruby-dsl.js.map +1 -0
  131. package/dist/handlers/ruby.d.ts.map +1 -1
  132. package/dist/handlers/ruby.js +29 -4
  133. package/dist/handlers/ruby.js.map +1 -1
  134. package/dist/handlers/rust.d.ts.map +1 -1
  135. package/dist/handlers/rust.js +98 -2
  136. package/dist/handlers/rust.js.map +1 -1
  137. package/dist/handlers/scss.d.ts +3 -0
  138. package/dist/handlers/scss.d.ts.map +1 -0
  139. package/dist/handlers/scss.js +290 -0
  140. package/dist/handlers/scss.js.map +1 -0
  141. package/dist/handlers/sql.d.ts.map +1 -1
  142. package/dist/handlers/sql.js +37 -18
  143. package/dist/handlers/sql.js.map +1 -1
  144. package/dist/handlers/typescript.d.ts.map +1 -1
  145. package/dist/handlers/typescript.js +65 -17
  146. package/dist/handlers/typescript.js.map +1 -1
  147. package/dist/handlers/xml.d.ts.map +1 -1
  148. package/dist/handlers/xml.js +35 -2
  149. package/dist/handlers/xml.js.map +1 -1
  150. package/dist/index.d.ts.map +1 -1
  151. package/dist/index.js +91 -0
  152. package/dist/index.js.map +1 -1
  153. package/dist/server/mcp-server.d.ts.map +1 -1
  154. package/dist/server/mcp-server.js +10 -0
  155. package/dist/server/mcp-server.js.map +1 -1
  156. package/dist/server/tools/detect-antipatterns.d.ts +1 -1
  157. package/dist/server/tools/get-architecture-snapshot.d.ts +1 -1
  158. package/dist/server/tools/get-entry-points.d.ts +1 -1
  159. package/dist/server/tools/get-lexical-scope-matches.d.ts +54 -0
  160. package/dist/server/tools/get-lexical-scope-matches.d.ts.map +1 -0
  161. package/dist/server/tools/get-lexical-scope-matches.js +470 -0
  162. package/dist/server/tools/get-lexical-scope-matches.js.map +1 -0
  163. package/dist/server/tools/search-symbols.d.ts +10 -0
  164. package/dist/server/tools/search-symbols.d.ts.map +1 -1
  165. package/dist/server/tools/search-symbols.js +353 -8
  166. package/dist/server/tools/search-symbols.js.map +1 -1
  167. package/dist/server/tools/trace-invocation-chain.d.ts +53 -0
  168. package/dist/server/tools/trace-invocation-chain.d.ts.map +1 -0
  169. package/dist/server/tools/trace-invocation-chain.js +280 -0
  170. package/dist/server/tools/trace-invocation-chain.js.map +1 -0
  171. package/dist/version.d.ts +1 -1
  172. package/dist/version.js +1 -1
  173. package/docs/02-installation.md +89 -17
  174. package/docs/05-cli-reference.md +89 -0
  175. package/docs/dev/benchmark-findings-eu-za-tebe.md +210 -0
  176. package/docs/dev/phase-35-coverage-audit.md +469 -0
  177. package/package.json +4 -1
@@ -1,12 +1,22 @@
1
- # PureContext MCP — AI Agent Instructions
1
+ # PureContext MCP — Agent Instructions
2
2
 
3
- These instructions tell AI agents how to use PureContext MCP correctly for token-efficient code navigation. Add this file to your agent's rules (CLAUDE.md, Windsurf rules, Cursor rules, etc.).
3
+ Add these instructions to your agent's rules file to get token-efficient code navigation with PureContext MCP.
4
+
5
+ | Agent | Rules file |
6
+ |-------|-----------|
7
+ | Claude Code (global) | `~/.claude/CLAUDE.md` |
8
+ | Claude Code (project) | `CLAUDE.md` in the project root |
9
+ | Cursor | `.cursor/rules` |
10
+ | Windsurf | `.windsurf/rules` |
11
+ | VS Code Copilot | `.github/copilot-instructions.md` |
12
+
13
+ For complete tool parameter docs, all navigation patterns, and known limitations: see **`AGENT_REFERENCE.md`** in this repository.
4
14
 
5
15
  ---
6
16
 
7
17
  ## What PureContext MCP is
8
18
 
9
- PureContext MCP is a structured code navigation server. It indexes a codebase using tree-sitter AST parsing, stores symbol metadata in SQLite, and exposes MCP tools so you can retrieve precisely the code you need — without reading entire files.
19
+ PureContext MCP is a structured code navigation server. It indexes codebases using tree-sitter AST parsing, stores symbol metadata in SQLite, and exposes MCP tools so you retrieve precisely the code you need — without reading entire files.
10
20
 
11
21
  **Token savings:** Retrieving a 45-line function by name costs ~150 tokens. Reading the 800-line file it lives in costs ~2,000 tokens. PureContext saves 88–98% of context tokens on typical navigation tasks.
12
22
 
@@ -16,634 +26,55 @@ PureContext MCP is a structured code navigation server. It indexes a codebase us
16
26
 
17
27
  ### Step 1 — Check if the project is indexed
18
28
 
19
- Before doing any code navigation, call `list_repos` to see what is already indexed.
20
-
21
29
  ```
22
30
  list_repos()
23
31
  ```
24
32
 
25
- If the current project is not in the list, index it first:
33
+ If the project is missing, index it first:
26
34
 
27
35
  ```
28
36
  index_folder({ path: "/absolute/path/to/project" })
29
37
  ```
30
38
 
31
- **Never skip this step.** All other tools require a `repoId`. `index_folder` returns the `repoId` you will use in every subsequent call. Save it.
39
+ `index_folder` returns the `repoId` you will use in every subsequent call. **Never skip this step** all other tools require a `repoId`. Re-indexing is incremental; only changed files are re-parsed.
32
40
 
33
41
  ### Step 2 — Navigate by symbol, not by file
34
42
 
35
- Do **not** read entire files to find code. Use the tools:
43
+ Do not read entire files to find code. Use the tools:
36
44
 
37
- | Goal | Tool to use |
38
- |------|-------------|
45
+ | Goal | Tool |
46
+ |------|------|
39
47
  | Find a function/class/method by name | `search_symbols` |
40
48
  | Find code by what it does | `search_semantic` |
41
49
  | Find a literal string, comment, or config value | `search_text` |
42
50
  | See all symbols in one file | `get_file_outline` |
43
51
  | See the whole project structure | `get_repo_outline` |
52
+ | Browse directory layout | `get_file_tree` |
53
+ | Understand a function's dependencies | `get_context_bundle` |
54
+ | Know what breaks if I change a symbol | `get_blast_radius` |
55
+ | Find all call sites for a symbol | `find_references` |
56
+ | Non-symbol file content (imports block, config) | `get_file_content` with `startLine`/`endLine` |
57
+ | All implementations of an interface | `find_implementations` |
58
+ | Callers/callees execution tree | `get_call_hierarchy` |
59
+ | Class inheritance structure | `get_class_hierarchy` |
60
+ | Rename / delete / move safety check | `check_rename_safe` / `check_delete_safe` / `check_move_safe` |
61
+ | Codebase health score | `health_radar` |
62
+ | Detailed debt report | `get_debt_report` |
63
+ | All TODOs and FIXMEs | `get_todos` |
64
+ | Untested exported symbols | `find_untested_symbols` |
65
+ | Most complex functions | `get_complexity_hotspots` |
66
+ | Symbols by decorator | `search_by_decorator` |
67
+ | AST node type occurrences (try/catch, arrow functions, etc.) | `search_ast` |
44
68
 
45
69
  ### Step 3 — Read summaries before fetching source
46
70
 
47
- `search_symbols` returns signatures and summaries — **no source code**. This is intentional. Read the `summary` field first to decide whether a symbol is relevant. Fetch the implementation only for symbols you will actually work with:
71
+ `search_symbols` returns signatures and summaries — no source code. Read the `summary` field first to decide whether a symbol is relevant. Fetch source only for symbols you will actually work with:
48
72
 
49
73
  ```
50
74
  get_symbol_source({ repoId, symbolId })
51
75
  ```
52
76
 
53
- Do not call `get_symbol_source` for every result in a search. Summaries let you navigate without reading source, saving 10–50× tokens on typical lookups.
54
-
55
- **Trust but verify:** summaries describe intent, not contract. For modification tasks, always read the source after using the summary to navigate. An AI-generated summary describes what a function is meant to do — source code is ground truth.
56
-
57
- ---
58
-
59
- ## Tool reference — when to use each tool
60
-
61
- ### Indexing tools
62
-
63
- #### `list_repos`
64
- Always call this first. Returns all indexed repos with their `repoId`, path, file count, and last indexed time.
65
-
66
- #### `index_folder`
67
- Index a local directory. Returns `repoId`. Re-indexing is incremental — only changed files are re-parsed. Call it again if files have changed since the last index.
68
-
69
- **Parameters:**
70
- - `path` (required) — absolute path to project root
71
- - `force` (optional) — set `true` to force re-index of all files, even unchanged ones
72
- - `fileLimit` (optional) — override the configured file limit for this run
73
-
74
- #### `resolve_repo`
75
- Convert a local path to its `repoId` without indexing. Use this when you know the project is already indexed but don't have the `repoId` at hand.
76
-
77
- #### `invalidate_cache`
78
- Force a full re-index by clearing content hashes. Use when the index seems stale and `index_folder` is not picking up changes.
79
-
80
- ---
81
-
82
- ### Symbol search & retrieval
83
-
84
- #### `search_symbols` — primary navigation tool
85
- Search by name fragment. Use this for almost all navigation tasks.
86
-
87
- ```json
88
- {
89
- "repoId": "a1b2c3d4e5f60001",
90
- "query": "authenticate",
91
- "kind": "function",
92
- "limit": 10
93
- }
94
- ```
95
-
96
- - Returns signatures and summaries — **no source code**
97
- - Use the `kind` filter to narrow results: `function`, `class`, `method`, `route`, `component`, `hook`, `middleware`, etc.
98
- - `camelCase`, `snake_case`, and space-separated queries are equivalent: `processOrder`, `process_order`, and `process order` return the same results
99
- - Use `mode: "hybrid"` for best recall when unsure of the exact name
100
-
101
- #### `search_semantic`
102
- Search by meaning, not name. Use when you know what the code does but not what it is called.
103
-
104
- ```json
105
- {
106
- "repoId": "...",
107
- "query": "function that validates user credentials and returns a session token",
108
- "mode": "hybrid",
109
- "max_results": 10
110
- }
111
- ```
112
-
113
- Requires semantic search to be enabled in config. Falls back to FTS5 keyword search automatically if the HNSW index is not available.
114
-
115
- #### `search_text`
116
- Grep-style full-text search across file content. Use for finding literal strings, error messages, config values, comments, or anything that is not a symbol name.
117
-
118
- ```json
119
- {
120
- "repoId": "...",
121
- "query": "TODO: fix this",
122
- "context_lines": 3
123
- }
124
- ```
125
-
126
- Do **not** use `search_text` when you are looking for a function or class — use `search_symbols` instead. `search_text` searches raw file content, not the symbol index.
127
-
128
- #### `get_symbol_source`
129
- Retrieve the source code of a specific symbol by its ID.
130
-
131
- ```json
132
- {
133
- "repoId": "...",
134
- "symbolId": "8f3a2c1d0e4b5f9a",
135
- "context_lines": 2
136
- }
137
- ```
138
-
139
- - `symbolId` comes from `search_symbols` or `get_file_outline` results
140
- - Use `context_lines` to include surrounding lines for additional context
141
- - Use `verify: true` when you need to confirm the source on disk matches the index (after recent file edits)
142
-
143
- #### `get_symbols`
144
- Batch-fetch multiple symbols by ID in a single call. Prefer this over calling `get_symbol_source` repeatedly when you need several symbols.
145
-
146
- ```json
147
- {
148
- "repoId": "...",
149
- "symbolIds": ["id1", "id2", "id3"]
150
- }
151
- ```
152
-
153
- #### `get_file_content`
154
- Retrieve raw file content with optional line range. Use only when you need to read a section of a file that is not a named symbol — for example, top-level imports, configuration blocks, or non-symbol prose.
155
-
156
- ```json
157
- {
158
- "repoId": "...",
159
- "filePath": "src/config/settings.ts",
160
- "startLine": 1,
161
- "endLine": 40
162
- }
163
- ```
164
-
165
- Do **not** use `get_file_content` as a substitute for `get_symbol_source`. Always prefer symbol-level retrieval.
166
-
167
- #### `get_file_outline`
168
- All symbols in a single file with signatures and summaries. Use to survey a file without reading its content.
169
-
170
- #### `get_repo_outline`
171
- All files in the repo with their top-level symbols. Use to orient yourself in an unfamiliar project.
172
-
173
- #### `get_file_tree`
174
- Directory tree with file counts. Use when you need to understand the project's folder structure.
175
-
176
- #### `find_references`
177
- Find all usage sites (call sites, references) for a symbol across the repo. Use before renaming or modifying a symbol to understand all places that use it.
178
-
179
- ---
180
-
181
- ### Dependency graph tools
182
-
183
- #### `get_context_bundle`
184
- Forward-walk from a symbol — returns the symbol and everything it transitively imports. Use **before modifying a function** to understand its full context.
185
-
186
- ```json
187
- {
188
- "repoId": "...",
189
- "symbolId": "...",
190
- "maxDepth": 2,
191
- "maxTokens": 4000
192
- }
193
- ```
194
-
195
- Use `maxTokens` to cap the response size when working with deeply connected code.
196
-
197
- #### `get_blast_radius`
198
- Reverse-walk — all files that transitively import a symbol. Use **before modifying or deleting a symbol** to understand what would break.
199
-
200
- ```json
201
- {
202
- "repoId": "...",
203
- "symbolId": "...",
204
- "maxDepth": 5
205
- }
206
- ```
207
-
208
- #### `find_importers`
209
- Direct (one-hop) importers of a file. Faster than `get_blast_radius` when you only need the immediate callers.
210
-
211
- #### `find_dead_code`
212
- Exported symbols that nothing else imports. Use for cleanup audits. Note: may produce false positives for dynamic imports and symbols consumed by external npm consumers.
213
-
214
- ---
215
-
216
- ### Architecture & quality tools
217
-
218
- #### `get_layer_violations`
219
- Detect architectural import boundary violations. Use when enforcing layered architecture rules.
220
-
221
- #### `get_quality_metrics`
222
- Per-file complexity, coupling, cohesion, and documentation coverage scores. Always use this instead of making subjective assessments from reading source code. Treat complexity scores as directional signals — cyclomatic complexity is estimated from symbol count and nesting depth, not exact AST branch-counting.
223
-
224
- #### `detect_antipatterns`
225
- Detect common architectural anti-patterns (god classes, circular dependencies, dead code) across the repo. Returns structured results with severity levels and actionable locations. Only detects static patterns — cannot find runtime coupling or dynamic dispatch issues.
226
-
227
- #### `get_architecture_doc`
228
- Auto-generate an architecture summary in Markdown or Mermaid format. Requires `ai.allowRemoteAI: true`. Use early when onboarding to an unfamiliar codebase. The generated doc is always accurate because it derives from the actual index, not hand-written documentation.
229
-
230
- **Pre-refactoring workflow:**
231
- ```
232
- get_quality_metrics → find worst files
233
- detect_antipatterns → find structural issues
234
- get_blast_radius → understand impact scope
235
- get_architecture_doc → generate "before" snapshot
236
- [make changes]
237
- detect_antipatterns → verify anti-patterns resolved
238
- ```
239
-
240
- ---
241
-
242
- ### Git & history tools
243
-
244
- #### `get_symbol_history`
245
- Symbol-level git commit history. Returns structured JSON with commits, authors, and diffs — no shell commands needed. Use to understand why a function was written the way it is, and to answer "who wrote this?" or "who should review this change?" without running `git log` or `git blame`.
246
-
247
- **Limitations:** Rename/move breaks history continuity — symbols in renamed files start fresh history from the rename commit. After a rebase, run `invalidate_cache` + `index_folder` to rebuild accurate history.
248
-
249
- #### `get_churn_metrics`
250
- File and symbol churn metrics. Use to identify high-risk files before making changes. **Before modifying any symbol, check churn:** if `churnScore > 6`, mention this to the user and suggest extra testing. High-churn files are under active development (merge conflict risk) or chronically buggy (regression risk).
251
-
252
- **For debugging:** Use `get_churn_metrics` to identify recently-changed symbols — recent changes are the most likely source of new bugs. This narrows the search space dramatically.
253
-
254
- **Note:** The default `maxCommits: 500` cap means long-lived projects may lose early history. Increase `git.maxCommits` for history-sensitive workflows.
255
-
256
- ---
257
-
258
- ### Cross-repo tools
259
-
260
- #### `search_cross_repo`
261
- Search symbols across multiple indexed repositories simultaneously. Use for architectural questions like "which services handle email sending?" or "where is `UserProfile` defined?" — a single call replaces N per-repo queries.
262
-
263
- #### `find_similar`
264
- Find semantically similar code across repos using the HNSW vector index. **Before implementing new functionality**, call this to check if equivalent code already exists elsewhere in the organization. Requires semantic search enabled (`semantic.enabled: true` with a configured provider).
265
-
266
- **Before modifying shared library code**, use `get_blast_radius` with `crossRepo: true` to understand the full downstream impact across all repos.
267
-
268
- **Note:** `crossRepoDeps` requires explicit package name configuration — there is no auto-detection of Nx/Turborepo/Lerna workspaces. Monorepo packages must each be indexed separately with `index_folder`.
269
-
270
- ---
271
-
272
- ### Ecosystem & data tools
273
-
274
- #### `search_columns`
275
- Search column definitions across dbt models. Returns upstream/downstream lineage — not just where a column is defined, but the full chain from source tables through staging models to final fact tables. Use for data lineage questions like "where does the `revenue` column come from?"
276
-
277
- **Note:** `search_columns` is dbt-only — it does not search columns in raw SQL `CREATE TABLE` statements. For those, use `get_symbol_source` on the `CREATE TABLE` symbol directly.
278
-
279
- **dbt workflow notes:**
280
- - Always run `index_folder` after `dbt compile` to ensure `manifest.json` is current — stale manifests produce incorrect column lineage.
281
- - Use `get_context_bundle` to traverse dbt model dependencies just like code dependencies.
282
- - Use `search_symbols` with `kind: "route"` to find API endpoints via the OpenAPI provider.
283
-
284
- **Templating coverage:** Jinja preprocessing is implemented only for dbt's SQL dialect. Helm/Go templates, Ansible Jinja2, Kubernetes YAML, ERB, and Kustomize are not preprocessed — those files are indexed as raw text or skipped. Terraform is fully supported.
285
-
286
- ---
287
-
288
- ### Advanced relationship analysis tools
289
-
290
- #### `find_implementations`
291
- Find all concrete implementations of a TypeScript interface or abstract class, and all method overrides for a given base method. Returns implementing classes with `implementedMethods` and `missingMethods` arrays compared against the interface contract.
292
-
293
- - `includeAbstract` (optional) — also include abstract subclasses (default false)
294
- - `limit` (optional) — max results (default 50)
295
-
296
- **Use before modifying an interface** to know every class that must be updated.
297
-
298
- #### `get_call_hierarchy`
299
- Return callers and callees of a function, N levels deep, as a tree. Unlike `find_references` (flat list) or `get_blast_radius` (file-level), this returns a hierarchical execution-flow view. Recursive calls are marked `cyclic: true`.
300
-
301
- ```json
302
- {
303
- "repoId": "...",
304
- "symbolId": "...",
305
- "direction": "callees",
306
- "maxDepth": 3,
307
- "maxNodes": 50
308
- }
309
- ```
310
-
311
- - `direction`: `"callees"` (what it calls), `"callers"` (what calls it), `"both"` (bidirectional)
312
- - `maxDepth`: 1–6 (default 3); `maxNodes`: stop expanding after N total nodes (default 50)
313
- - `maxTokens`: soft cap on response size
314
-
315
- #### `get_class_hierarchy`
316
- Return the full inheritance tree rooted at a class — both ancestors (what it extends) and descendants (what extends it). Use before refactoring a base class to understand the full polymorphism surface.
317
-
318
- - `direction`: `"ancestors"`, `"descendants"`, or `"both"` (default)
319
- - `maxDepth` (optional, default 5)
320
-
321
- #### `find_cycles`
322
- Detect circular import dependencies across the repo or a subtree. Returns strongly-connected components with member files and a severity rating. High-severity cycles increase coupling and complicate testing.
323
-
324
- - `scope` (optional) — directory prefix to restrict analysis
325
- - `minCycleLength` (optional) — ignore trivial self-referential entries (default 2)
326
-
327
- #### `get_coupling_map`
328
- Compute afferent/efferent coupling metrics for every file. Returns instability scores (`I = efferent / (afferent + efferent)`) and highlights files that are both highly coupled and unstable — the highest-risk refactoring candidates.
329
-
330
- - `scope` (optional) — directory prefix filter
331
- - `limit` (optional) — max files returned (default 50)
332
-
333
- ---
334
-
335
- ### Visualization tools
336
-
337
- #### `render_diagram`
338
- Generate a Mermaid or DOT diagram from the dependency graph. The general-purpose visualization entry point — specialized variants below build on this.
339
-
340
- ```json
341
- {
342
- "repoId": "...",
343
- "type": "module",
344
- "format": "mermaid",
345
- "maxNodes": 30,
346
- "maxDepth": 3
347
- }
348
- ```
349
-
350
- - `type`: `"module"` / `"import"` (file-level import graph), `"call"` (call graph, requires `rootSymbolId`), `"class"` (class hierarchy, requires `rootSymbolId`)
351
- - `format`: `"mermaid"` (renders natively in GitHub, VS Code, Claude) or `"dot"` (Graphviz)
352
- - `maxNodes` (default 30) and `maxDepth` (default 3) prevent oversized diagrams
353
-
354
- Mermaid output can be pasted directly into GitHub issues, README files, or Claude chat.
355
-
356
- #### `render_call_graph`
357
- Specialized call graph diagram rooted at a symbol. Equivalent to `render_diagram` with `type: "call"` but with call-graph-specific layout options.
358
-
359
- #### `render_import_graph`
360
- File-level import graph for a directory or the whole repo. Nodes are files, edges are import relationships, nodes are clustered by directory.
361
-
362
- #### `render_class_hierarchy`
363
- Class inheritance diagram in Mermaid `classDiagram` format. Shows member fields, methods, and inheritance/implementation relationships.
364
-
365
- #### `render_dep_matrix`
366
- Dependency matrix diagram showing coupling between modules as a grid. High value for spotting structural hotspots and tangled layers at a glance.
367
-
368
- #### `get_architecture_snapshot`
369
- Capture the current architectural state: file count, symbol count, module breakdown, coupling summary, and health scores. Take two snapshots (before and after a refactoring) to prove structural improvement objectively.
370
-
371
- ---
372
-
373
- ### Refactoring safety tools
374
-
375
- Always run these **before** executing a structural change. They give a binary `safe` verdict so you never have to manually inspect reference lists.
376
-
377
- #### `check_rename_safe`
378
- Pre-flight check before renaming a symbol. Returns `safe`, a plain-English `verdict`, and all `affectedSites` with file, line, column, context snippet, and change type (`call`, `import`, `type-reference`, `string-literal`, `comment`).
379
-
380
- ```json
381
- {
382
- "repoId": "...",
383
- "symbolId": "...",
384
- "newName": "processOrderV2"
385
- }
386
- ```
387
-
388
- `safe: false` when the new name conflicts with an existing symbol in the same file, or when string-literal references exist that won't be fixed by a text rename and require human judgment.
389
-
390
- #### `check_delete_safe`
391
- Pre-flight check before deleting a symbol. Returns `safe: false` if anything in the repo still imports or references the symbol. Lists all blocking references so you know exactly what to clean up first.
392
-
393
- #### `check_move_safe`
394
- Pre-flight check before moving a symbol to a different file. Validates that the move won't break imports, that the target file doesn't already define the same name, and returns all import statements that will need updating.
395
-
396
- #### `plan_refactoring`
397
- Generate a sequenced, dependency-ordered plan for a structural change. Accepts a natural-language description and returns ordered steps with risk annotations, affected file lists, and suggested verification points. Steps are ordered so lower-risk changes happen first.
398
-
399
- ```json
400
- {
401
- "repoId": "...",
402
- "description": "Extract the auth logic from UserService into a standalone AuthService",
403
- "scope": "src/services/"
404
- }
405
- ```
406
-
407
- ---
408
-
409
- ### Health & debt tools
410
-
411
- #### `health_radar`
412
- Compute a five-axis health radar for the repo. Each axis scores 0–100 (100 = perfectly healthy).
413
-
414
- | Axis | What it measures |
415
- |------|-----------------|
416
- | `complexity` | Inverse of average/peak cyclomatic complexity |
417
- | `coupling` | Inverse of high-coupling file density |
418
- | `maintainability` | Inverse of dead-code and god-class density |
419
- | `documentation` | Percentage of symbols with non-trivial summaries |
420
- | `stability` | Inverse of churn-hotspot density (requires git metadata) |
421
-
422
- Returns `overallHealth` (0–100 weighted average) and a letter grade (A–F). Designed for CI health gates and dashboard charts.
423
-
424
- ```json
425
- { "repoId": "...", "scope": "src/core/", "includeStability": true }
426
- ```
427
-
428
- Use `get_debt_report` instead when you need per-file rankings and actionable recommendations.
429
-
430
- #### `diff_health_radar`
431
- Compare two health radar snapshots — typically before and after a refactoring — and return axis-by-axis deltas with regression/improvement verdicts. Use with `get_architecture_snapshot` to produce objective before/after evidence of structural improvement.
432
-
433
- #### `get_debt_report`
434
- Detailed technical debt report with per-file rankings, priority tiers, and actionable recommendations. Unlike `health_radar` (compact scores), this returns a full breakdown: worst files by each metric, specific symbols to address, and estimated effort indicators.
435
-
436
- - `scope` (optional) — restrict to a directory
437
- - `maxFiles` (optional) — top N files per category (default 10)
438
- - `includeDead` (optional) — include dead code in the debt calculation
439
-
440
- ---
441
-
442
- ### AST-level search tools
443
-
444
- These tools re-parse stored file content using tree-sitter grammars to find structural patterns that symbol-level search cannot express. Only files backed by a WASM grammar are searched; regex-only handlers are silently skipped.
445
-
446
- #### `search_ast`
447
- Find every occurrence of a specific tree-sitter node type across all indexed files.
448
-
449
- ```json
450
- {
451
- "repoId": "...",
452
- "nodeType": "try_statement",
453
- "filePath": "src/",
454
- "limit": 50
455
- }
456
- ```
457
-
458
- Common node types (case-sensitive, exact tree-sitter names):
459
-
460
- | Language | Node types |
461
- |----------|-----------|
462
- | TypeScript/JS | `arrow_function`, `function_declaration`, `class_declaration`, `interface_declaration`, `try_statement`, `await_expression`, `call_expression`, `import_statement`, `jsx_element`, `template_string`, `throw_statement`, `type_alias_declaration` |
463
- | Python | `function_definition`, `class_definition`, `for_statement`, `with_statement`, `decorated_definition`, `lambda` |
464
- | Rust | `function_item`, `struct_item`, `impl_item`, `match_expression`, `closure_expression`, `trait_item` |
465
- | Go | `function_declaration`, `method_declaration`, `go_statement`, `defer_statement`, `type_declaration` |
466
-
467
- Returns file, line, column, and a snippet of the matched node for each result.
468
-
469
- #### `search_by_signature`
470
- Search symbols by type signature pattern (regex or substring). Use to find all functions returning `Promise<void>`, all methods accepting a `Request` parameter, or all types extending a specific base.
471
-
472
- ```json
473
- { "repoId": "...", "pattern": "Promise<.*>", "kind": "function" }
474
- ```
475
-
476
- #### `search_by_decorator`
477
- Find all symbols annotated with a specific decorator. Works for TypeScript decorators (`@Injectable`, `@Controller`, `@Entity`) and Python decorators (`@app.route`, `@property`).
478
-
479
- ```json
480
- { "repoId": "...", "decorator": "Injectable", "kind": "class" }
481
- ```
482
-
483
- #### `search_by_complexity`
484
- Find symbols above or below a complexity threshold. Use to locate the most complex functions before a refactoring sprint, or to verify that new code stays within complexity budgets.
485
-
486
- ```json
487
- { "repoId": "...", "minComplexity": 10, "kind": "function", "limit": 20 }
488
- ```
489
-
490
- Returns symbols ranked by complexity score with file path and signature.
491
-
492
- ---
493
-
494
- ### Code intelligence tools
495
-
496
- #### `get_entry_points`
497
- Identify all runnable entry points of a repo: main functions, CLI handlers, HTTP server startups, Lambda/serverless handlers, test suites, and standalone scripts. Each result includes a `kind`, `confidence` level (`high`/`medium`/`low`), and the reason for classification.
498
-
499
- Use with `get_context_bundle` to trace the full dependency chain from an entry point, or with `find_dead_code` to discover code unreachable from any entry point.
500
-
501
- - `kind` (optional) — filter: `main_function`, `cli_handler`, `server_startup`, `lambda_handler`, `test_suite`, `script`
502
- - `minConfidence` (optional) — `"high"`, `"medium"`, or `"low"` (default)
503
-
504
- #### `get_public_api`
505
- Return all exported symbols grouped by file — the public API surface of the repo or a module. Use to document a library, audit what is exposed, or check for accidental exports.
506
-
507
- - `filePath` (optional) — restrict to a file or directory prefix
508
- - `kind` (optional) — filter by symbol kind
509
- - `includeMembers` (optional) — include class/interface members
510
- - `groupByFile` (optional, default true)
511
-
512
- #### `get_todos`
513
- Find all TODO, FIXME, HACK, NOTE, and XXX comments across the repo. Returns structured results with file, line, tag type, and comment text. Use to audit tech debt or find forgotten work before a release.
514
-
515
- - `tags` (optional) — filter to specific tags: `["TODO", "FIXME"]`
516
- - `filePath` (optional) — restrict to a directory
517
- - `limit` (optional, default 200)
518
-
519
- #### `get_complexity_hotspots`
520
- Return symbols ranked by complexity score, highest first. Use to identify the worst functions before a refactoring sprint, or to track whether complexity is improving over time.
521
-
522
- - `kind` (optional) — filter by symbol kind
523
- - `filePath` (optional) — restrict to a directory
524
- - `limit` (optional, default 20); `minComplexity` (optional)
525
-
526
- #### `get_type_graph`
527
- Return the type dependency graph — which types reference which other types — rooted at a specific type or across the whole repo. Use to understand type coupling and find central hub types before a major refactoring.
528
-
529
- - `symbolId` (optional) — root the graph at a specific type
530
- - `maxDepth` (optional, default 3)
531
- - `direction`: `"uses"` (what this type references), `"usedBy"` (what references this type), or `"both"`
532
-
533
- #### `find_untested_symbols`
534
- Find exported symbols with no corresponding test coverage — no test file imports or references the symbol. Returns untested symbols ranked by complexity (most complex first, as highest priority).
535
-
536
- **Note:** uses import-based heuristics, not runtime coverage. A symbol referenced in a test file is "tested" regardless of assertion quality.
537
-
538
- - `filePath` (optional), `kind` (optional), `limit` (optional, default 50)
539
-
540
- #### `get_test_coverage_map`
541
- Return a per-file coverage map showing which symbols are referenced by test files and which are not. Produces a `coverageRatio` per file and aggregated totals.
542
-
543
- - `filePath` (optional) — restrict to a file or directory
544
- - `includeSymbols` (optional) — include per-symbol detail (default false for compact output)
545
-
546
- ---
547
-
548
- ## Decision rules — which tool to pick
549
-
550
- ```
551
- I need to find a symbol by name
552
- → search_symbols
553
-
554
- I know what the code does but not its name
555
- → search_semantic (or search_symbols with mode: "hybrid")
556
-
557
- I need to find a literal string, comment, or config value
558
- → search_text
559
-
560
- I need the source code of a specific symbol
561
- → get_symbol_source (use symbolId from search_symbols)
562
-
563
- I need source for several symbols at once
564
- → get_symbols (batch)
565
-
566
- I need to understand a function's dependencies
567
- → get_context_bundle
568
-
569
- I need to know what breaks if I change a symbol
570
- → get_blast_radius (before modifying)
571
- → find_references (for call sites specifically)
572
-
573
- I need to survey a file's contents
574
- → get_file_outline
575
-
576
- I need to understand the project layout
577
- → get_repo_outline or get_file_tree
578
-
579
- I need a non-symbol section of a file (imports block, config)
580
- → get_file_content with startLine/endLine
581
-
582
- I need all implementations of an interface or abstract class
583
- → find_implementations
584
-
585
- I need to trace execution flow (call stack, callers/callees)
586
- → get_call_hierarchy (hierarchical tree)
587
- → find_references (flat list of call sites)
588
-
589
- I need to understand the class inheritance structure
590
- → get_class_hierarchy
591
-
592
- I need to find circular dependencies
593
- → find_cycles
594
-
595
- I need to understand module coupling / instability scores
596
- → get_coupling_map
597
-
598
- I need a visual diagram of the codebase
599
- → render_diagram (general: import graph, call graph, class hierarchy)
600
- → render_call_graph / render_import_graph / render_class_hierarchy / render_dep_matrix (specialized)
601
-
602
- I need to check if a rename / delete / move is safe before doing it
603
- → check_rename_safe / check_delete_safe / check_move_safe
604
-
605
- I need a sequenced plan for a structural refactoring
606
- → plan_refactoring
607
-
608
- I need a quick health score for the codebase (CI gate / dashboard)
609
- → health_radar
610
-
611
- I need a detailed debt report with per-file rankings
612
- → get_debt_report
613
-
614
- I need to compare codebase health before and after a change
615
- → get_architecture_snapshot (before) → [change] → get_architecture_snapshot (after) → diff_health_radar
616
-
617
- I need to find all instances of a specific AST node type (try/catch, arrow functions, etc.)
618
- → search_ast
619
-
620
- I need to find functions matching a type signature pattern
621
- → search_by_signature
622
-
623
- I need to find all symbols with a specific decorator
624
- → search_by_decorator
625
-
626
- I need to find the most complex functions
627
- → search_by_complexity or get_complexity_hotspots
628
-
629
- I need to find where an application starts
630
- → get_entry_points
631
-
632
- I need to know what a module exports (public API surface)
633
- → get_public_api
634
-
635
- I need to find all TODOs and FIXMEs
636
- → get_todos
637
-
638
- I need to find untested exported symbols
639
- → find_untested_symbols
640
-
641
- I need a per-file coverage map
642
- → get_test_coverage_map
643
-
644
- I need to understand type dependencies between types
645
- → get_type_graph
646
- ```
77
+ Summaries describe intent, not contract. For modification tasks, always read the source after using the summary to navigate source code is ground truth.
647
78
 
648
79
  ---
649
80
 
@@ -653,250 +84,145 @@ I need to understand type dependencies between types
653
84
  Use `search_symbols` + `get_symbol_source`. Reading an 800-line file to locate a 45-line function wastes ~1,850 tokens.
654
85
 
655
86
  **Do not call `get_symbol_source` for every search result.**
656
- Read the `signature` and `summary` from `search_symbols` first. Fetch source only for symbols you will actually work with.
87
+ Read `signature` and `summary` from `search_symbols` first. Fetch source only for symbols you will actually work with.
657
88
 
658
89
  **Do not skip `list_repos` at the start of a session.**
659
90
  You need a `repoId` for every tool call. Get it from `list_repos` or `index_folder` — do not guess.
660
91
 
661
92
  **Do not use `search_text` for symbol lookups.**
662
- `search_text` is a grep over raw file content. It is slower and less precise than `search_symbols` for finding named code entities.
93
+ `search_text` greps raw file content. It is slower and less precise than `search_symbols` for finding named code entities. Use `search_text` for literal strings, comments, config values, and local variables that are not indexed symbols.
663
94
 
664
95
  **Do not use `get_file_content` as a fallback for reading whole files.**
665
96
  If a symbol exists in the index, use `get_symbol_source`. Only use `get_file_content` for content that is not a named symbol.
666
97
 
667
98
  **Do not ignore `_tokenEstimate` fields.**
668
- Every response includes a `_tokenEstimate`. Use it to decide whether to fetch more context or stop.
99
+ Every response includes a `_tokenEstimate`. Use it to decide whether to fetch more context or stop. Cap `maxTokens` in `get_context_bundle` to avoid hitting context limits.
100
+
101
+ **Do not re-search when `search_symbols` returns `negative_evidence`.**
102
+ If the response includes `verdict: "no_match"`, the symbol does not exist in this codebase. Report the gap to the user rather than trying variant queries.
669
103
 
670
104
  ---
671
105
 
672
- ## Efficient navigation patterns
106
+ ## Key navigation patterns
673
107
 
674
- ### Pattern: understand an unfamiliar codebase
108
+ ### Modify a function safely
675
109
 
676
110
  ```
677
- 1. list_repos() → check if indexed
678
- 2. index_folder({ path }) index if needed, get repoId
679
- 3. get_repo_outline({ repoId }) survey the structure
680
- 4. search_symbols({ query: "main entry point concept" }) locate key symbols
681
- 5. get_context_bundle({ symbolId }) → understand the entry + dependencies
111
+ 1. search_symbols({ query: "functionName", kind: "function" })
112
+ 2. get_blast_radius({ symbolId }) know the impact scope BEFORE touching it
113
+ 3. get_context_bundle({ symbolId, maxDepth: 2 }) understand its dependencies
114
+ 4. get_symbol_source({ symbolId }) read the implementation
115
+ 5. [make the change]
116
+ 6. find_dead_code({ repoId }) → verify no orphaned exports left behind
682
117
  ```
683
118
 
684
- ### Pattern: modify a function safely
119
+ ### Modify a high-risk symbol safely
685
120
 
686
121
  ```
687
122
  1. search_symbols({ query: "functionName", kind: "function" })
688
- 2. get_blast_radius({ symbolId }) know the impact scope BEFORE touching it
689
- 3. get_context_bundle({ symbolId, maxDepth: 2 }) → understand its context
690
- 4. get_symbol_source({ symbolId }) read the implementation
691
- 5. [make the change]
692
- 6. find_dead_code({ repoId }) → verify no orphaned exports left behind
123
+ 2. get_churn_metrics({ repoId, symbolId }) if churnScore > 6, warn the user
124
+ 3. get_symbol_history({ symbolId }) → understand recent change context
125
+ 4. get_blast_radius({ symbolId }) know full impact scope
126
+ 5. get_context_bundle({ symbolId, maxDepth: 2 })
127
+ 6. get_symbol_source({ symbolId })
128
+ 7. [make the change]
129
+ 8. find_dead_code({ repoId })
693
130
  ```
694
131
 
695
- ### Pattern: find where something is called
132
+ ### Find where something is called
696
133
 
697
134
  ```
698
135
  1. search_symbols({ query: "symbolName" })
699
- 2. find_references({ symbolId }) → all call sites
136
+ 2. find_references({ symbolId }) → all call sites across the repo
700
137
  3. get_symbol_source for relevant call sites
701
138
  ```
702
139
 
703
- ### Pattern: search when you know the concept but not the name
140
+ ### Search when you know what the code does but not its name
704
141
 
705
142
  ```
706
- 1. search_semantic({ query: "natural language description", mode: "hybrid" })
143
+ 1. search_semantic({ query: "validates user credentials and returns a session token", mode: "hybrid" })
707
144
  2. Review signatures and summaries in results
708
145
  3. get_symbol_source for the best match
709
146
  ```
710
147
 
711
- ### Pattern: large batch of symbols
712
-
713
- ```
714
- 1. search_symbols({ query: "...", limit: 20 })
715
- 2. Filter results by signature/summary to pick the ones you need
716
- 3. get_symbols({ symbolIds: ["id1", "id2", "id3"] }) ← one call, not three
717
- ```
718
-
719
- ### Pattern: modify a high-risk symbol safely
720
-
721
- ```
722
- 1. search_symbols({ query: "functionName", kind: "function" })
723
- 2. get_churn_metrics({ repoId, symbolId }) → if churnScore > 6, warn user
724
- 3. get_symbol_history({ symbolId }) → understand recent change context
725
- 4. get_blast_radius({ symbolId }) → know full impact scope
726
- 5. get_context_bundle({ symbolId, maxDepth: 2 }) → understand dependencies
727
- 6. get_symbol_source({ symbolId }) → read the implementation
728
- 7. [make the change]
729
- 8. find_dead_code({ repoId }) → verify no orphaned exports
730
- ```
731
-
732
- ### Pattern: architecture review / onboarding
733
-
734
- ```
735
- 1. list_repos → index_folder if needed
736
- 2. get_architecture_doc({ repoId }) → generate project overview
737
- 3. get_quality_metrics({ repoId }) → identify weakest files
738
- 4. detect_antipatterns({ repoId }) → find structural issues
739
- 5. get_repo_outline({ repoId }) → survey specific areas
740
- ```
741
-
742
- ### Pattern: before implementing new functionality
743
-
744
- ```
745
- 1. find_similar({ query: "description", crossRepo: true }) → check for existing code
746
- 2. search_cross_repo({ query: "conceptName" }) → find related symbols across repos
747
- 3. get_blast_radius({ symbolId, crossRepo: true }) → understand cross-repo impact
748
- ```
749
-
750
- ### Pattern: debug a recent regression
751
-
752
- ```
753
- 1. get_churn_metrics({ repoId }) → find recently-changed files
754
- 2. get_symbol_history({ symbolId }) → check commits in the affected area
755
- 3. search_symbols in changed files → find the suspect functions
756
- 4. get_symbol_source → get_context_bundle → read and understand the change
757
- ```
758
-
759
- ### Pattern: PR review
760
-
761
- ```
762
- 1. [obtain list of changed files from PR]
763
- 2. get_symbol_history for changed symbols → understand prior context
764
- 3. get_churn_metrics for changed files → flag hotspots
765
- 4. get_blast_radius for each modified symbol → identify affected downstream code
766
- 5. detect_antipatterns({ repoId }) → flag new structural issues
767
- ```
768
-
769
- ### Pattern: refactor safely (rename / delete / move)
148
+ ### Refactor safely (rename / delete / move)
770
149
 
771
150
  ```
772
151
  1. search_symbols({ query: "symbolName" })
773
152
  2. check_rename_safe / check_delete_safe / check_move_safe → binary verdict + affected sites
774
- 3. If safe: proceed with the change
775
- If not safe: resolve blockers listed in affectedSites first, then re-check
776
- 4. find_dead_code({ repoId }) → verify no orphaned exports remain
153
+ 3. If safe: proceed.
154
+ If not safe: resolve blockers listed in affectedSites first, then re-check.
155
+ 4. find_dead_code({ repoId }) → verify no orphaned exports remain
777
156
  ```
778
157
 
779
- ### Pattern: modify an interface or base class safely
158
+ ### Onboard to an unfamiliar codebase
780
159
 
781
160
  ```
782
- 1. search_symbols({ query: "InterfaceName", kind: "interface" })
783
- 2. find_implementations({ symbolId }) all classes that must be updated
784
- 3. get_class_hierarchy({ symbolId, direction: "descendants" }) inheritance tree
785
- 4. get_blast_radius({ symbolId }) file-level impact scope
786
- 5. [make the change]
787
- 6. find_implementations({ symbolId }) verify missingMethods is empty
161
+ 1. list_repos() index_folder({ path }) if needed
162
+ 2. get_repo_outline({ repoId }) survey the structure
163
+ 3. get_entry_points({ repoId }) where does the app start?
164
+ 4. get_context_bundle({ symbolId: entryPointId }) trace dependencies from root
165
+ 5. get_todos({ repoId }) → known rough edges
166
+ 6. get_test_coverage_map({ repoId }) where tests are thin
788
167
  ```
789
168
 
790
- ### Pattern: plan and execute a tech debt sprint
169
+ ### Tech debt sprint
791
170
 
792
171
  ```
793
- 1. health_radar({ repoId }) → 5-axis health baseline
794
- 2. get_debt_report({ repoId }) → per-file rankings + recommendations
795
- 3. get_complexity_hotspots({ repoId }) → worst functions to tackle first
796
- 4. find_untested_symbols({ repoId }) → coverage gaps
797
- 5. find_cycles({ repoId }) → circular deps to break
798
- 6. get_architecture_snapshot({ repoId }) → baseline snapshot before changes
172
+ 1. health_radar({ repoId }) → 5-axis health baseline
173
+ 2. get_debt_report({ repoId }) → per-file rankings + recommendations
174
+ 3. get_complexity_hotspots({ repoId }) → worst functions to tackle first
175
+ 4. find_untested_symbols({ repoId }) → coverage gaps
176
+ 5. find_cycles({ repoId }) → circular deps to break
177
+ 6. get_architecture_snapshot({ repoId }) → baseline snapshot before changes
799
178
  7. [fix highest-priority items]
800
- 8. get_architecture_snapshot({ repoId }) → after snapshot
801
- 9. diff_health_radar({ before, after }) → prove the improvement
802
- ```
803
-
804
- ### Pattern: generate codebase diagrams
805
-
806
- ```
807
- 1. render_diagram({ repoId, type: "module", format: "mermaid" })
808
- → whole-repo import graph
809
- 2. search_symbols + render_call_graph({ rootSymbolId })
810
- → call flow rooted at a function
811
- 3. search_symbols + render_class_hierarchy({ rootSymbolId })
812
- → inheritance tree
813
- 4. render_dep_matrix({ repoId, scope: "src/core/" })
814
- → coupling matrix for a module
815
- ```
816
-
817
- ### Pattern: onboard via code intelligence
818
-
819
- ```
820
- 1. get_entry_points({ repoId }) → where does the app start?
821
- 2. get_public_api({ repoId }) → what does it expose?
822
- 3. get_context_bundle({ symbolId: entryPointId }) → trace dependencies from root
823
- 4. get_type_graph({ repoId }) → understand type system structure
824
- 5. get_todos({ repoId }) → known rough edges
825
- 6. get_test_coverage_map({ repoId }) → where tests are thin
179
+ 8. get_architecture_snapshot({ repoId }) → after snapshot
180
+ 9. diff_health_radar({ before, after }) → prove the improvement
826
181
  ```
827
182
 
828
183
  ---
829
184
 
830
185
  ## Search tips
831
186
 
832
- - **camelCase and snake_case are equivalent** — `processOrder` and `process_order` return the same results.
833
- - **Short queries rank better** — `auth` finds more than `authentication middleware function`.
834
- - **Use `kind` to narrow results** — `kind: "function"` eliminates class/method noise.
835
- - **Use `filePath` to scope** — `filePath: "src/auth/"` restricts to a directory.
836
- - **Use `debug: true` to diagnose ranking** — shows BM25 scores and name boost factors.
837
- - **For hybrid mode** — `semantic_weight: 0.6, keyword_weight: 0.4` is a good default when you are unsure of the exact name.
187
+ - **camelCase and snake_case are equivalent** — `processOrder` and `process_order` return the same results
188
+ - **Short queries rank better** — `auth` finds more than `authentication middleware function`
189
+ - **Use `kind` to narrow results** — `kind: "function"` eliminates class/method noise
190
+ - **Use `filePath` to scope** — `filePath: "src/auth/"` restricts results to a directory
191
+ - **Use `mode: "hybrid"` when unsure of the exact name** — blends keyword and semantic search
192
+ - **Use `debug: true` to diagnose ranking** shows BM25 scores and name boost factors
838
193
 
839
194
  ---
840
195
 
841
- ## Notes on `_tokenEstimate` and `_meta`
196
+ ## Keeping the index fresh
842
197
 
843
- Every response includes:
198
+ The file watcher triggers incremental re-indexing automatically. If the index seems stale:
844
199
 
845
- ```json
846
- "_meta": {
847
- "timing_ms": 3,
848
- "tokens_saved": 1842,
849
- "total_tokens_saved": 45231
850
- }
200
+ ```
201
+ index_folder({ path, force: false }) → incremental (changed files only)
202
+ index_folder({ path, force: true }) → full re-index
203
+ invalidate_cache({ repoId }) → clear hashes, then index_folder
851
204
  ```
852
205
 
853
- And most responses include `_tokenEstimate` a rough count of tokens in the returned payload. Use this to:
854
- - Decide whether to fetch additional context or stop
855
- - Avoid hitting context limits by capping `maxTokens` in `get_context_bundle`
856
- - Track cumulative savings with `get_savings_stats`
857
-
858
- ---
859
-
860
- ## Keeping the index fresh
206
+ ### Claude Code hooks (optional but recommended)
861
207
 
862
- The file watcher triggers incremental re-indexing automatically on file changes. If you suspect the index is stale:
208
+ Install the PureContext hooks to keep the index in sync automatically and preserve session orientation across context compaction:
863
209
 
864
210
  ```
865
- index_folder({ path, force: false }) → incremental (changed files only)
866
- index_folder({ path, force: true }) → full re-index (all files)
867
- invalidate_cache({ repoId }) → clear hashes, then index_folder
211
+ npx purecontext-mcp hooks --install
868
212
  ```
869
213
 
214
+ This installs three hooks into `~/.claude/settings.json`:
215
+
216
+ | Hook | When it fires | What it does |
217
+ |------|--------------|-------------|
218
+ | **Index hook** | After `Edit` / `Write` | Re-indexes the modified file immediately |
219
+ | **Session snapshot** | Before context compaction | Injects indexed repo list into the next turn so orientation is preserved |
220
+ | **Edit guard** | Before `Edit` / `Write` | Soft warning suggesting `get_blast_radius` and `get_symbol_source` first |
221
+
222
+ All hooks are Node.js scripts — they work identically on Windows, Linux, and macOS.
223
+
870
224
  ---
871
225
 
872
- ## Known limitations
873
-
874
- These are documented gaps understand them so you can work around them rather than being confused when a tool behaves unexpectedly.
875
-
876
- | Area | Limitation | Workaround |
877
- |------|-----------|-----------|
878
- | **AI Summaries** | Summaries describe intent, not contract. Stale summaries exist until re-index. | Always verify with `get_symbol_source` before modifying. |
879
- | **AI Summaries** | `get_architecture_doc` requires `ai.allowRemoteAI: true`. | `detect_antipatterns` and `get_quality_metrics` work without AI. |
880
- | **Git History** | Rename/move breaks history continuity — prior history is lost after a rename. | Future: `git log --follow` tracking. |
881
- | **Git History** | Rebase invalidates commit hashes — re-index required after significant rebase. | Run `invalidate_cache` + `index_folder` post-rebase. |
882
- | **Git History** | Default `maxCommits: 500` drops early history on long-lived projects. | Increase `git.maxCommits` in config for history-sensitive workflows. |
883
- | **Git History** | No SVN/Mercurial/Perforce support. | Git is a hard requirement for history features. |
884
- | **Cross-Repo** | `crossRepoDeps` is manual — no auto-detection of Nx/Turborepo/pnpm workspaces. | Explicitly list package names in each repo's config. |
885
- | **Cross-Repo** | `find_similar` requires semantic search enabled and an embedding provider. | Use a local Ollama model as a zero-cost alternative. |
886
- | **Cross-Repo** | MCP Resources `resources/subscribe` is not yet supported by Claude Code or Cursor. | Polling with `search_cross_repo` is the current alternative. |
887
- | **Architecture** | Quality metrics use estimated complexity (nesting heuristics), not true AST branch-counting. | Treat scores as directional signals, not precise measurements. |
888
- | **Architecture** | `detect_antipatterns` cannot detect runtime coupling or dynamic dispatch. | Complementary to profiling and runtime observability — not a replacement. |
889
- | **Architecture** | `get_layer_violations` needs layer boundaries defined in config before it delivers value. | Requires upfront config investment. |
890
- | **Ecosystem** | Jinja preprocessing is dbt SQL only — Helm, Ansible, ERB, Kustomize not supported. | Use Terraform for IaC where possible; raw file reads otherwise. |
891
- | **Ecosystem** | `search_columns` is dbt-only — does not cover `CREATE TABLE` SQL columns. | Use `get_symbol_source` on the `CREATE TABLE` symbol instead. |
892
- | **Ecosystem** | dbt indexer does not detect stale `manifest.json`. | Always run `dbt compile` before `index_folder` on dbt projects. |
893
- | **Ecosystem** | BigQuery STRUCT/ARRAY, Snowflake QUALIFY, and DuckDB LIST/MAP may not parse fully. | Model-level symbols are still extracted even when the body fails to parse. |
894
- | **Relationship Analysis** | `find_implementations` uses signature LIKE matching + import-graph scan — may miss implementations in files that don't import the interface and use an identical name. | Check `get_blast_radius` for files that transitively depend on the interface file. |
895
- | **Relationship Analysis** | `get_call_hierarchy` uses import-edge graph, not runtime call data — dynamic dispatch, `eval`, and reflection are invisible. | Complement with runtime profiling for highly dynamic code. |
896
- | **Visualization** | Mermaid diagrams with >50 nodes become unreadable in most renderers. | Use `maxNodes` to cap output; use `scope`/`filePath` to restrict to a module. |
897
- | **Visualization** | DOT output requires Graphviz to render — not available natively in Claude or GitHub. | Use `format: "mermaid"` for in-chat and in-PR rendering. |
898
- | **Refactoring Safety** | `check_rename_safe` flags string-literal references but cannot determine if they are intentional (e.g. serialization keys). | String-literal blockers always require human review — do not automate around them. |
899
- | **Refactoring Safety** | `plan_refactoring` generates heuristic step ordering — estimated effort is approximate. | Treat as a starting point; validate step order against actual dependency analysis. |
900
- | **Health & Debt** | `health_radar` stability axis requires git metadata — set `includeStability: false` if the repo has no git history. | The remaining four axes still reflect structural health accurately. |
901
- | **Code Intelligence** | `find_untested_symbols` uses import heuristics, not runtime coverage — a symbol imported in a test file is "tested" regardless of assertion quality. | Combine with Istanbul/c8 for precise branch-level coverage data. |
902
- | **AST Search** | `search_ast` only searches files backed by a WASM grammar — regex-only handlers (Terraform, Protobuf, GraphQL, etc.) are silently skipped. | Use `search_text` for content in unsupported file types. |
226
+ ## Full reference
227
+
228
+ For complete tool parameter documentation, all navigation patterns, and the known limitations table, see **`AGENT_REFERENCE.md`** in this repository.