purecontext-mcp 1.7.0 → 1.11.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 (156) hide show
  1. package/AGENT_INSTRUCTIONS.md +18 -10
  2. package/AGENT_REFERENCE.md +684 -561
  3. package/CHANGELOG.md +567 -445
  4. package/CODE-HISTORY.md +29 -1
  5. package/FULL-INSTALLATION-GUIDE.md +351 -341
  6. package/README.md +411 -339
  7. package/REFACTORING-SAFELY.md +338 -279
  8. package/SAFE-CHANGES.md +208 -156
  9. package/USER-GUIDE.md +3 -1
  10. package/WHY-PURECONTEXT.md +103 -73
  11. package/WORKFLOW-PR-REVIEW.md +245 -199
  12. package/dist/bin.d.ts +16 -0
  13. package/dist/bin.d.ts.map +1 -0
  14. package/dist/bin.js +21 -0
  15. package/dist/bin.js.map +1 -0
  16. package/dist/cli/hooks.d.ts.map +1 -1
  17. package/dist/cli/hooks.js +20 -15
  18. package/dist/cli/hooks.js.map +1 -1
  19. package/dist/cli/install-writers.d.ts.map +1 -1
  20. package/dist/cli/install-writers.js +281 -36
  21. package/dist/cli/install-writers.js.map +1 -1
  22. package/dist/cli/resolve-node.d.ts +53 -0
  23. package/dist/cli/resolve-node.d.ts.map +1 -0
  24. package/dist/cli/resolve-node.js +84 -0
  25. package/dist/cli/resolve-node.js.map +1 -0
  26. package/dist/config/config-loader.js +24 -0
  27. package/dist/config/config-loader.js.map +1 -1
  28. package/dist/config/config-schema.d.ts +71 -0
  29. package/dist/config/config-schema.d.ts.map +1 -1
  30. package/dist/config/config-schema.js +102 -0
  31. package/dist/config/config-schema.js.map +1 -1
  32. package/dist/core/db/api-keys.d.ts +1 -1
  33. package/dist/core/db/api-keys.d.ts.map +1 -1
  34. package/dist/core/db/api-keys.js +39 -39
  35. package/dist/core/db/api-keys.js.map +1 -1
  36. package/dist/core/db/co-change-store.d.ts +34 -0
  37. package/dist/core/db/co-change-store.d.ts.map +1 -0
  38. package/dist/core/db/co-change-store.js +78 -0
  39. package/dist/core/db/co-change-store.js.map +1 -0
  40. package/dist/core/db/schema.d.ts +3 -3
  41. package/dist/core/db/schema.d.ts.map +1 -1
  42. package/dist/core/db/schema.js +12 -30
  43. package/dist/core/db/schema.js.map +1 -1
  44. package/dist/core/db/sqlite-loader.d.ts +51 -0
  45. package/dist/core/db/sqlite-loader.d.ts.map +1 -0
  46. package/dist/core/db/sqlite-loader.js +94 -0
  47. package/dist/core/db/sqlite-loader.js.map +1 -0
  48. package/dist/core/db/wasm-sqlite.d.ts +4 -0
  49. package/dist/core/db/wasm-sqlite.d.ts.map +1 -0
  50. package/dist/core/db/wasm-sqlite.js +270 -0
  51. package/dist/core/db/wasm-sqlite.js.map +1 -0
  52. package/dist/core/diff-parser.d.ts.map +1 -1
  53. package/dist/core/diff-parser.js +6 -1
  54. package/dist/core/diff-parser.js.map +1 -1
  55. package/dist/core/git-log-reader.d.ts +28 -0
  56. package/dist/core/git-log-reader.d.ts.map +1 -1
  57. package/dist/core/git-log-reader.js +74 -3
  58. package/dist/core/git-log-reader.js.map +1 -1
  59. package/dist/core/index-manager.d.ts.map +1 -1
  60. package/dist/core/index-manager.js +20 -1
  61. package/dist/core/index-manager.js.map +1 -1
  62. package/dist/graph/path-resolver.js +86 -17
  63. package/dist/graph/path-resolver.js.map +1 -1
  64. package/dist/index.d.ts +1 -0
  65. package/dist/index.d.ts.map +1 -1
  66. package/dist/index.js +9 -1
  67. package/dist/index.js.map +1 -1
  68. package/dist/node-guard.d.ts +15 -0
  69. package/dist/node-guard.d.ts.map +1 -0
  70. package/dist/node-guard.js +33 -0
  71. package/dist/node-guard.js.map +1 -0
  72. package/dist/server/admin-api.d.ts +1 -1
  73. package/dist/server/admin-api.d.ts.map +1 -1
  74. package/dist/server/admin-api.js +2 -2
  75. package/dist/server/admin-api.js.map +1 -1
  76. package/dist/server/auth/api-key.d.ts +1 -1
  77. package/dist/server/auth/api-key.d.ts.map +1 -1
  78. package/dist/server/mcp-server.d.ts.map +1 -1
  79. package/dist/server/mcp-server.js +25 -0
  80. package/dist/server/mcp-server.js.map +1 -1
  81. package/dist/server/tools/analyze-diff.d.ts +8 -0
  82. package/dist/server/tools/analyze-diff.d.ts.map +1 -1
  83. package/dist/server/tools/analyze-diff.js +80 -16
  84. package/dist/server/tools/analyze-diff.js.map +1 -1
  85. package/dist/server/tools/change-synthesis.d.ts +90 -0
  86. package/dist/server/tools/change-synthesis.d.ts.map +1 -0
  87. package/dist/server/tools/change-synthesis.js +236 -0
  88. package/dist/server/tools/change-synthesis.js.map +1 -0
  89. package/dist/server/tools/co-change.d.ts +65 -0
  90. package/dist/server/tools/co-change.d.ts.map +1 -0
  91. package/dist/server/tools/co-change.js +146 -0
  92. package/dist/server/tools/co-change.js.map +1 -0
  93. package/dist/server/tools/compare-change-impact.d.ts +58 -0
  94. package/dist/server/tools/compare-change-impact.d.ts.map +1 -0
  95. package/dist/server/tools/compare-change-impact.js +0 -0
  96. package/dist/server/tools/compare-change-impact.js.map +1 -0
  97. package/dist/server/tools/find-refactoring-opportunities.d.ts +1 -1
  98. package/dist/server/tools/get-architecture-snapshot.d.ts.map +1 -1
  99. package/dist/server/tools/get-architecture-snapshot.js +28 -14
  100. package/dist/server/tools/get-architecture-snapshot.js.map +1 -1
  101. package/dist/server/tools/get-churn-metrics.d.ts.map +1 -1
  102. package/dist/server/tools/get-churn-metrics.js +1 -12
  103. package/dist/server/tools/get-churn-metrics.js.map +1 -1
  104. package/dist/server/tools/get-co-change.d.ts +37 -0
  105. package/dist/server/tools/get-co-change.d.ts.map +1 -0
  106. package/dist/server/tools/get-co-change.js +120 -0
  107. package/dist/server/tools/get-co-change.js.map +1 -0
  108. package/dist/server/tools/get-context-bundle.d.ts.map +1 -1
  109. package/dist/server/tools/get-context-bundle.js +56 -3
  110. package/dist/server/tools/get-context-bundle.js.map +1 -1
  111. package/dist/server/tools/get-entry-points.d.ts +1 -1
  112. package/dist/server/tools/get-symbol-risk.d.ts +25 -0
  113. package/dist/server/tools/get-symbol-risk.d.ts.map +1 -0
  114. package/dist/server/tools/get-symbol-risk.js +60 -0
  115. package/dist/server/tools/get-symbol-risk.js.map +1 -0
  116. package/dist/server/tools/get-symbol-source.d.ts +2 -0
  117. package/dist/server/tools/get-symbol-source.d.ts.map +1 -1
  118. package/dist/server/tools/get-symbol-source.js +18 -1
  119. package/dist/server/tools/get-symbol-source.js.map +1 -1
  120. package/dist/server/tools/prepare-change.d.ts +61 -0
  121. package/dist/server/tools/prepare-change.d.ts.map +1 -0
  122. package/dist/server/tools/prepare-change.js +262 -0
  123. package/dist/server/tools/prepare-change.js.map +1 -0
  124. package/dist/server/tools/search-symbols.d.ts +2 -0
  125. package/dist/server/tools/search-symbols.d.ts.map +1 -1
  126. package/dist/server/tools/search-symbols.js +33 -0
  127. package/dist/server/tools/search-symbols.js.map +1 -1
  128. package/dist/server/tools/symbol-lines.d.ts +25 -0
  129. package/dist/server/tools/symbol-lines.d.ts.map +1 -0
  130. package/dist/server/tools/symbol-lines.js +40 -0
  131. package/dist/server/tools/symbol-lines.js.map +1 -0
  132. package/dist/server/tools/symbol-risk.d.ts +109 -0
  133. package/dist/server/tools/symbol-risk.d.ts.map +1 -0
  134. package/dist/server/tools/symbol-risk.js +251 -0
  135. package/dist/server/tools/symbol-risk.js.map +1 -0
  136. package/dist/server/tools/verify-change.d.ts +40 -0
  137. package/dist/server/tools/verify-change.d.ts.map +1 -0
  138. package/dist/server/tools/verify-change.js +149 -0
  139. package/dist/server/tools/verify-change.js.map +1 -0
  140. package/dist/version.d.ts +1 -1
  141. package/dist/version.d.ts.map +1 -1
  142. package/dist/version.js +1 -1
  143. package/dist/version.js.map +1 -1
  144. package/docs/01-introduction.md +2 -2
  145. package/docs/02-installation.md +97 -89
  146. package/docs/03-quick-start.md +138 -135
  147. package/docs/04-configuration.md +247 -214
  148. package/docs/05-cli-reference.md +236 -219
  149. package/docs/06-tools-reference.md +902 -499
  150. package/docs/14-transport-modes.md +170 -167
  151. package/docs/18-git-history.md +43 -0
  152. package/docs/23-performance.md +123 -121
  153. package/docs/26-troubleshooting.md +249 -234
  154. package/grammars/README.md +88 -0
  155. package/package.json +7 -25
  156. package/AGENT_INSTRUCTIONS_SHORT.md +0 -150
@@ -1,561 +1,684 @@
1
- # PureContext MCP — Agent Reference
2
-
3
- Full tool reference, navigation patterns, search tips, and known limitations.
4
- The always-on instructions (mandatory workflow, decision rules, anti-patterns) live in `~/.claude/CLAUDE.md`.
5
-
6
- ---
7
-
8
- ## Indexing tools
9
-
10
- ### `list_repos`
11
- Always call this first. Returns all indexed repos with their `repoId`, path, file count, and last indexed time.
12
-
13
- ### `index_folder`
14
- Index a local directory. Returns `repoId`. Re-indexing is incremental only changed files are re-parsed.
15
-
16
- - `path` (required) absolute path to project root
17
- - `force` (optional) set `true` to force re-index of all files, even unchanged ones
18
- - `fileLimit` (optional) override the configured file limit for this run
19
-
20
- ### `resolve_repo`
21
- Convert a local path to its `repoId` without indexing. Use when the project is already indexed but you don't have the `repoId` at hand.
22
-
23
- ### `invalidate_cache`
24
- Force a full re-index by clearing content hashes. Use when the index seems stale and `index_folder` is not picking up changes.
25
-
26
- ### Keeping the index fresh
27
-
28
- The file watcher triggers incremental re-indexing automatically. If you suspect the index is stale:
29
-
30
- ```
31
- index_folder({ path, force: false }) → incremental (changed files only)
32
- index_folder({ path, force: true }) → full re-index (all files)
33
- invalidate_cache({ repoId }) → clear hashes, then index_folder
34
- ```
35
-
36
- ---
37
-
38
- ## Symbol search & retrieval
39
-
40
- ### `search_symbols` primary navigation tool
41
- Search by name fragment. Use this for almost all navigation tasks.
42
-
43
- ```json
44
- { "repoId": "...", "query": "authenticate", "kind": "function", "limit": 10 }
45
- ```
46
-
47
- - Returns signatures and summaries no source code
48
- - `kind` filter: `function`, `class`, `method`, `route`, `component`, `hook`, `middleware`, etc.
49
- - `camelCase`, `snake_case`, and space-separated queries are equivalent
50
- - Use `mode: "hybrid"` for best recall when unsure of the exact name
51
- - When the response includes `negative_evidence.verdict: "no_match"` the symbol does not exist; do not re-search
52
-
53
- ### `search_semantic`
54
- Search by meaning, not name. Use when you know what the code does but not what it is called.
55
-
56
- ```json
57
- { "repoId": "...", "query": "validates user credentials and returns a session token", "mode": "hybrid", "max_results": 10 }
58
- ```
59
-
60
- Requires semantic search enabled in config. Falls back to FTS5 keyword search automatically if unavailable.
61
-
62
- ### `search_text`
63
- Grep-style full-text search. Use for literal strings, error messages, config values, comments — anything that is not a symbol name.
64
-
65
- ```json
66
- { "repoId": "...", "query": "TODO: fix this", "context_lines": 3 }
67
- ```
68
-
69
- ### `get_symbol_source`
70
- Retrieve the source code of a specific symbol by its ID.
71
-
72
- ```json
73
- { "repoId": "...", "symbolId": "8f3a2c1d0e4b5f9a", "context_lines": 2 }
74
- ```
75
-
76
- - `symbolId` comes from `search_symbols` or `get_file_outline` results
77
- - `context_lines` — include surrounding lines for additional context
78
- - `verify: true` — confirm the source on disk matches the index (after recent file edits)
79
-
80
- ### `get_symbols`
81
- Batch-fetch multiple symbols by ID in a single call. Prefer this over calling `get_symbol_source` repeatedly.
82
-
83
- ```json
84
- { "repoId": "...", "symbolIds": ["id1", "id2", "id3"] }
85
- ```
86
-
87
- ### `get_file_content`
88
- Retrieve raw file content with optional line range. Use only for content that is not a named symbol — top-level imports, configuration blocks, non-symbol prose.
89
-
90
- ```json
91
- { "repoId": "...", "filePath": "src/config/settings.ts", "startLine": 1, "endLine": 40 }
92
- ```
93
-
94
- ### `get_file_outline`
95
- All symbols in a single file with signatures and summaries. Use to survey a file without reading its content.
96
-
97
- ### `get_repo_outline`
98
- All files in the repo with their top-level symbols. Use to orient yourself in an unfamiliar project.
99
-
100
- ### `get_file_tree`
101
- Directory tree with file counts. Use when you need to understand the project's folder structure.
102
-
103
- ### `find_references`
104
- Find all usage sites for a symbol across the repo. Use before renaming or modifying a symbol.
105
-
106
- ---
107
-
108
- ## Dependency graph tools
109
-
110
- ### `get_context_bundle`
111
- Forward-walk from a symbol — returns the symbol and everything it transitively imports. Use before modifying a function to understand its full context.
112
-
113
- ```json
114
- { "repoId": "...", "symbolId": "...", "maxDepth": 2, "maxTokens": 4000 }
115
- ```
116
-
117
- Use `maxTokens` to cap the response size when working with deeply connected code.
118
-
119
- ### `get_blast_radius`
120
- Reverse-walk all files that transitively import a symbol. Use before modifying or deleting a symbol to understand what would break.
121
-
122
- ```json
123
- { "repoId": "...", "symbolId": "...", "maxDepth": 5 }
124
- ```
125
-
126
- ### `find_importers`
127
- Direct (one-hop) importers of a file. Faster than `get_blast_radius` when you only need the immediate callers.
128
-
129
- ### `find_dead_code`
130
- Exported symbols that nothing else imports. Use for cleanup audits. May produce false positives for dynamic imports and symbols consumed by external npm consumers.
131
-
132
- ---
133
-
134
- ## Architecture & quality tools
135
-
136
- ### `get_layer_violations`
137
- Detect architectural import boundary violations. Requires layer boundaries defined in config.
138
-
139
- ### `get_quality_metrics`
140
- Per-file complexity, coupling, cohesion, and documentation coverage scores. Use instead of making subjective assessments from reading source code. Complexity scores are directional signals, not exact measurements.
141
-
142
- ### `detect_antipatterns`
143
- Detect common architectural anti-patterns (god classes, circular dependencies, dead code). Returns structured results with severity levels. Cannot detect runtime coupling or dynamic dispatch issues.
144
-
145
- ### `get_architecture_doc`
146
- Auto-generate an architecture summary in Markdown or Mermaid format. Requires `ai.allowRemoteAI: true`.
147
-
148
- **Pre-refactoring workflow:**
149
- ```
150
- get_quality_metrics → find worst files
151
- detect_antipatterns → find structural issues
152
- get_blast_radius → understand impact scope
153
- get_architecture_doc generate "before" snapshot
154
- [make changes]
155
- detect_antipatterns → verify anti-patterns resolved
156
- ```
157
-
158
- ---
159
-
160
- ## Git & history tools
161
-
162
- ### `get_symbol_history`
163
- Symbol-level git commit history. Returns structured JSON with commits, authors, and diffs.
164
-
165
- - Rename/move breaks history continuity — symbols in renamed files start fresh history from the rename commit
166
- - After a rebase, run `invalidate_cache` + `index_folder` to rebuild accurate history
167
- - Default `maxCommits: 500` cap increase `git.maxCommits` for history-sensitive workflows
168
-
169
- ### `get_churn_metrics`
170
- File and symbol churn metrics. 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 or chronically buggy.
171
-
172
- For debugging, use `get_churn_metrics` to find recently-changed symbols — recent changes are the most likely source of new bugs.
173
-
174
- ---
175
-
176
- ## Cross-repo tools
177
-
178
- ### `search_cross_repo`
179
- Search symbols across multiple indexed repositories simultaneously.
180
-
181
- ### `find_similar`
182
- Find semantically similar code across repos. Before implementing new functionality, call this to check if equivalent code already exists. Requires semantic search enabled.
183
-
184
- Before modifying shared library code, use `get_blast_radius` with `crossRepo: true`.
185
-
186
- **Note:** `crossRepoDeps` requires explicit package name configuration no auto-detection of Nx/Turborepo/Lerna workspaces.
187
-
188
- ---
189
-
190
- ## Ecosystem & data tools
191
-
192
- ### `search_columns`
193
- Search column definitions across dbt models. Returns full upstream/downstream lineage.
194
-
195
- - dbt-only — does not search columns in raw SQL `CREATE TABLE` statements
196
- - Always run `dbt compile` before `index_folder` stale manifests produce incorrect lineage
197
- - Use `search_symbols` with `kind: "route"` to find API endpoints via the OpenAPI provider
198
-
199
- **Templating coverage:** Jinja preprocessing is dbt SQL only. Helm, Ansible Jinja2, Kubernetes YAML, ERB, and Kustomize are not preprocessed. Terraform is fully supported.
200
-
201
- ---
202
-
203
- ## Advanced relationship analysis tools
204
-
205
- ### `find_implementations`
206
- Find all concrete implementations of an interface or abstract class. Returns `implementedMethods` and `missingMethods` per class. Use before modifying an interface to know every class that must be updated.
207
-
208
- - `includeAbstract` (optional) — also include abstract subclasses (default false)
209
- - `limit` (optional) max results (default 50)
210
-
211
- ### `get_call_hierarchy`
212
- Return callers and callees of a function, N levels deep, as a tree. Recursive calls marked `cyclic: true`.
213
-
214
- ```json
215
- { "repoId": "...", "symbolId": "...", "direction": "callees", "maxDepth": 3, "maxNodes": 50 }
216
- ```
217
-
218
- - `direction`: `"callees"`, `"callers"`, or `"both"`
219
- - Uses import-edge graph, not runtime call data — dynamic dispatch, `eval`, and reflection are invisible
220
-
221
- ### `get_class_hierarchy`
222
- Full inheritance tree rooted at a class — ancestors (what it extends) and descendants (what extends it).
223
-
224
- - `direction`: `"ancestors"`, `"descendants"`, or `"both"` (default)
225
- - `maxDepth` (optional, default 5)
226
-
227
- ### `find_cycles`
228
- Detect circular import dependencies. Returns strongly-connected components with severity ratings.
229
-
230
- - `scope` (optional) — directory prefix to restrict analysis
231
- - `minCycleLength` (optional) — ignore trivial self-referential entries (default 2)
232
-
233
- ### `get_coupling_map`
234
- Afferent/efferent coupling metrics per file. Returns instability scores (`I = efferent / (afferent + efferent)`).
235
-
236
- - `scope` (optional), `limit` (optional, default 50)
237
-
238
- ---
239
-
240
- ## Visualization tools
241
-
242
- ### `render_diagram`
243
- Generate a Mermaid or DOT diagram from the dependency graph.
244
-
245
- ```json
246
- { "repoId": "...", "type": "module", "format": "mermaid", "maxNodes": 30, "maxDepth": 3 }
247
- ```
248
-
249
- - `type`: `"module"` / `"import"` (file-level), `"call"` (call graph, requires `rootSymbolId`), `"class"` (hierarchy, requires `rootSymbolId`)
250
- - `format`: `"mermaid"` (renders in GitHub, VS Code, Claude) or `"dot"` (Graphviz)
251
- - Diagrams with >50 nodes become unreadable use `maxNodes` to cap
252
-
253
- ### `render_call_graph` / `render_import_graph` / `render_class_hierarchy` / `render_dep_matrix`
254
- Specialized variants of `render_diagram` for specific diagram types.
255
-
256
- ### `get_architecture_snapshot`
257
- Capture the current architectural state: file count, symbol count, module breakdown, coupling summary, health scores. Take two snapshots (before/after a refactoring) to prove structural improvement objectively.
258
-
259
- ---
260
-
261
- ## Refactoring safety tools
262
-
263
- Always run these before executing a structural change. They give a binary `safe` verdict.
264
-
265
- ### `check_rename_safe`
266
- ```json
267
- { "repoId": "...", "symbolId": "...", "newName": "processOrderV2" }
268
- ```
269
- Returns `safe`, `verdict`, and all `affectedSites` with file, line, column, context snippet, and change type. `safe: false` when the new name conflicts with an existing symbol, or when string-literal references exist that require human judgment.
270
-
271
- ### `check_delete_safe`
272
- Returns `safe: false` if anything still imports or references the symbol. Lists all blocking references.
273
-
274
- ### `check_move_safe`
275
- Validates 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.
276
-
277
- ### `plan_refactoring`
278
- Generate a sequenced, dependency-ordered plan for a structural change.
279
-
280
- ```json
281
- { "repoId": "...", "description": "Extract auth logic from UserService into AuthService", "scope": "src/services/" }
282
- ```
283
-
284
- Step ordering is heuristic — validate against actual dependency analysis.
285
-
286
- ---
287
-
288
- ## Health & debt tools
289
-
290
- ### `health_radar`
291
- Five-axis health radar. Each axis scores 0–100 (100 = perfectly healthy).
292
-
293
- | Axis | What it measures |
294
- |------|-----------------|
295
- | `complexity` | Inverse of average/peak cyclomatic complexity |
296
- | `coupling` | Inverse of high-coupling file density |
297
- | `maintainability` | Inverse of dead-code and god-class density |
298
- | `documentation` | Percentage of symbols with non-trivial summaries |
299
- | `stability` | Inverse of churn-hotspot density (requires git metadata) |
300
-
301
- ```json
302
- { "repoId": "...", "scope": "src/core/", "includeStability": true }
303
- ```
304
-
305
- Set `includeStability: false` if the repo has no git history.
306
-
307
- ### `diff_health_radar`
308
- Compare two health radar snapshots axis-by-axis. Use with `get_architecture_snapshot` for before/after evidence.
309
-
310
- ### `get_debt_report`
311
- Detailed debt report with per-file rankings, priority tiers, and actionable recommendations.
312
-
313
- - `scope` (optional), `maxFiles` (optional, default 10), `includeDead` (optional)
314
-
315
- ---
316
-
317
- ## AST-level search tools
318
-
319
- These re-parse stored file content using tree-sitter grammars. Only files backed by a WASM grammar are searched — regex-only handlers are silently skipped; use `search_text` for those.
320
-
321
- ### `search_ast`
322
- Find every occurrence of a specific tree-sitter node type.
323
-
324
- ```json
325
- { "repoId": "...", "nodeType": "try_statement", "filePath": "src/", "limit": 50 }
326
- ```
327
-
328
- Common node types:
329
-
330
- | Language | Node types |
331
- |----------|-----------|
332
- | TypeScript/JS | `arrow_function`, `function_declaration`, `class_declaration`, `interface_declaration`, `try_statement`, `await_expression`, `call_expression`, `import_statement`, `jsx_element`, `throw_statement`, `type_alias_declaration` |
333
- | Python | `function_definition`, `class_definition`, `for_statement`, `with_statement`, `decorated_definition`, `lambda` |
334
- | Rust | `function_item`, `struct_item`, `impl_item`, `match_expression`, `closure_expression`, `trait_item` |
335
- | Go | `function_declaration`, `method_declaration`, `go_statement`, `defer_statement`, `type_declaration` |
336
-
337
- ### `search_by_signature`
338
- Search symbols by type signature pattern (regex or substring).
339
-
340
- ```json
341
- { "repoId": "...", "pattern": "Promise<.*>", "kind": "function" }
342
- ```
343
-
344
- ### `search_by_decorator`
345
- Find all symbols annotated with a specific decorator.
346
-
347
- ```json
348
- { "repoId": "...", "decorator": "Injectable", "kind": "class" }
349
- ```
350
-
351
- ### `search_by_complexity`
352
- Find symbols above a complexity threshold.
353
-
354
- ```json
355
- { "repoId": "...", "minComplexity": 10, "kind": "function", "limit": 20 }
356
- ```
357
-
358
- ---
359
-
360
- ## Code intelligence tools
361
-
362
- ### `get_entry_points`
363
- Identify all runnable entry points: main functions, CLI handlers, HTTP server startups, Lambda handlers, test suites, scripts. Each result includes `kind`, `confidence` (`high`/`medium`/`low`), and the reason for classification.
364
-
365
- - `kind` (optional): `main_function`, `cli_handler`, `server_startup`, `lambda_handler`, `test_suite`, `script`
366
- - `minConfidence` (optional): `"high"`, `"medium"`, or `"low"` (default)
367
-
368
- ### `get_public_api`
369
- All exported symbols grouped by file — the public API surface of the repo or a module.
370
-
371
- - `filePath` (optional), `kind` (optional), `includeMembers` (optional), `groupByFile` (optional, default true)
372
-
373
- ### `get_todos`
374
- All TODO, FIXME, HACK, NOTE, and XXX comments. Returns file, line, tag type, and comment text.
375
-
376
- - `tags` (optional), `filePath` (optional), `limit` (optional, default 200)
377
-
378
- ### `get_complexity_hotspots`
379
- Symbols ranked by complexity score, highest first.
380
-
381
- - `kind` (optional), `filePath` (optional), `limit` (optional, default 20), `minComplexity` (optional)
382
-
383
- ### `get_type_graph`
384
- Type dependency graph — which types reference which other types.
385
-
386
- - `symbolId` (optional) root at a specific type
387
- - `maxDepth` (optional, default 3)
388
- - `direction`: `"uses"`, `"usedBy"`, or `"both"`
389
-
390
- ### `find_untested_symbols`
391
- Exported symbols with no corresponding test coverage (import-based heuristics, not runtime coverage).
392
-
393
- - `filePath` (optional), `kind` (optional), `limit` (optional, default 50)
394
-
395
- ### `get_test_coverage_map`
396
- Per-file coverage map with `coverageRatio` per file and aggregated totals.
397
-
398
- - `filePath` (optional), `includeSymbols` (optional, default false)
399
-
400
- ---
401
-
402
- ## Navigation patterns
403
-
404
- ### Understand an unfamiliar codebase
405
- ```
406
- 1. list_repos() → check if indexed
407
- 2. index_folder({ path }) → index if needed, get repoId
408
- 3. get_repo_outline({ repoId }) → survey the structure
409
- 4. search_symbols({ query: "..." }) → locate key symbols
410
- 5. get_context_bundle({ symbolId }) → understand entry + dependencies
411
- ```
412
-
413
- ### Modify a function safely
414
- ```
415
- 1. search_symbols({ query: "functionName", kind: "function" })
416
- 2. get_blast_radius({ symbolId }) → know the impact scope BEFORE touching it
417
- 3. get_context_bundle({ symbolId, maxDepth: 2 }) understand its context
418
- 4. get_symbol_source({ symbolId }) → read the implementation
419
- 5. [make the change]
420
- 6. find_dead_code({ repoId }) → verify no orphaned exports left behind
421
- ```
422
-
423
- ### Modify a high-risk symbol safely
424
- ```
425
- 1. search_symbols({ query: "functionName", kind: "function" })
426
- 2. get_churn_metrics({ repoId, symbolId }) → if churnScore > 6, warn the user
427
- 3. get_symbol_history({ symbolId }) → understand recent change context
428
- 4. get_blast_radius({ symbolId }) → know full impact scope
429
- 5. get_context_bundle({ symbolId, maxDepth: 2 })
430
- 6. get_symbol_source({ symbolId })
431
- 7. [make the change]
432
- 8. find_dead_code({ repoId })
433
- ```
434
-
435
- ### Find where something is called
436
- ```
437
- 1. search_symbols({ query: "symbolName" })
438
- 2. find_references({ symbolId }) → all call sites
439
- 3. get_symbol_source for relevant call sites
440
- ```
441
-
442
- ### Search when you know the concept but not the name
443
- ```
444
- 1. search_semantic({ query: "natural language description", mode: "hybrid" })
445
- 2. Review signatures and summaries
446
- 3. get_symbol_source for the best match
447
- ```
448
-
449
- ### Modify an interface or base class safely
450
- ```
451
- 1. search_symbols({ query: "InterfaceName", kind: "interface" })
452
- 2. find_implementations({ symbolId }) → all classes that must be updated
453
- 3. get_class_hierarchy({ symbolId, direction: "descendants" })
454
- 4. get_blast_radius({ symbolId })
455
- 5. [make the change]
456
- 6. find_implementations({ symbolId }) → verify missingMethods is empty
457
- ```
458
-
459
- ### Refactor safely (rename / delete / move)
460
- ```
461
- 1. search_symbols({ query: "symbolName" })
462
- 2. check_rename_safe / check_delete_safe / check_move_safe
463
- 3. If safe: proceed. If not safe: resolve blockers in affectedSites first, then re-check.
464
- 4. find_dead_code({ repoId }) → verify no orphaned exports remain
465
- ```
466
-
467
- ### Tech debt sprint
468
- ```
469
- 1. health_radar({ repoId }) → 5-axis baseline
470
- 2. get_debt_report({ repoId }) → per-file rankings + recommendations
471
- 3. get_complexity_hotspots({ repoId }) → worst functions first
472
- 4. find_untested_symbols({ repoId }) → coverage gaps
473
- 5. find_cycles({ repoId }) → circular deps to break
474
- 6. get_architecture_snapshot({ repoId }) → baseline snapshot before changes
475
- 7. [fix highest-priority items]
476
- 8. get_architecture_snapshot({ repoId }) → after snapshot
477
- 9. diff_health_radar({ before, after }) → prove the improvement
478
- ```
479
-
480
- ### Debug a recent regression
481
- ```
482
- 1. get_churn_metrics({ repoId }) → find recently-changed files
483
- 2. get_symbol_history({ symbolId }) → check commits in the affected area
484
- 3. search_symbols in changed files → find the suspect functions
485
- 4. get_symbol_source → get_context_bundle → read and understand the change
486
- ```
487
-
488
- ### PR review
489
- ```
490
- 1. [obtain list of changed files from PR]
491
- 2. get_symbol_history for changed symbols → understand prior context
492
- 3. get_churn_metrics for changed files → flag hotspots
493
- 4. get_blast_radius for each modified symbol
494
- 5. detect_antipatterns({ repoId }) → flag new structural issues
495
- ```
496
-
497
- ### Architecture review / onboarding
498
- ```
499
- 1. list_repos → index_folder if needed
500
- 2. get_architecture_doc({ repoId }) → generate project overview
501
- 3. get_quality_metrics({ repoId }) → identify weakest files
502
- 4. detect_antipatterns({ repoId }) find structural issues
503
- 5. get_repo_outline({ repoId }) → survey specific areas
504
- ```
505
-
506
- ---
507
-
508
- ## Search tips
509
-
510
- - **camelCase and snake_case are equivalent** — `processOrder` and `process_order` return the same results
511
- - **Short queries rank better** — `auth` finds more than `authentication middleware function`
512
- - **Use `kind` to narrow results** `kind: "function"` eliminates class/method noise
513
- - **Use `filePath` to scope** — `filePath: "src/auth/"` restricts to a directory
514
- - **Use `debug: true` to diagnose ranking** shows BM25 scores and name boost factors
515
- - **For hybrid mode** — `semantic_weight: 0.6, keyword_weight: 0.4` is a good starting point
516
-
517
- ---
518
-
519
- ## `_tokenEstimate` and `_meta`
520
-
521
- Every response includes:
522
-
523
- ```json
524
- "_meta": { "timing_ms": 3, "tokens_saved": 1842, "total_tokens_saved": 45231 }
525
- ```
526
-
527
- `_tokenEstimate` rough token count of the returned payload. Use it to:
528
- - Decide whether to fetch additional context or stop
529
- - Cap `maxTokens` in `get_context_bundle` to avoid hitting context limits
530
- - Track cumulative savings with `get_savings_stats`
531
-
532
- ---
533
-
534
- ## Known limitations
535
-
536
- | Area | Limitation | Workaround |
537
- |------|-----------|-----------|
538
- | **AI Summaries** | Summaries describe intent, not contract. Stale summaries exist until re-index. | Always verify with `get_symbol_source` before modifying. |
539
- | **AI Summaries** | `get_architecture_doc` requires `ai.allowRemoteAI: true`. | `detect_antipatterns` and `get_quality_metrics` work without AI. |
540
- | **Git History** | Rename/move breaks history continuity. | Future: `git log --follow` tracking. |
541
- | **Git History** | Rebase invalidates commit hashes re-index required. | Run `invalidate_cache` + `index_folder` post-rebase. |
542
- | **Git History** | Default `maxCommits: 500` drops early history on long-lived projects. | Increase `git.maxCommits` in config. |
543
- | **Git History** | No SVN/Mercurial/Perforce support. | Git is a hard requirement for history features. |
544
- | **Cross-Repo** | `crossRepoDeps` is manual — no auto-detection of Nx/Turborepo/pnpm workspaces. | Explicitly list package names in each repo's config. |
545
- | **Cross-Repo** | `find_similar` requires semantic search and an embedding provider. | Use a local Ollama model as a zero-cost alternative. |
546
- | **Cross-Repo** | MCP Resources `resources/subscribe` not yet supported by Claude Code or Cursor. | Poll with `search_cross_repo`. |
547
- | **Architecture** | Quality metrics use estimated complexity (nesting heuristics), not true AST branch-counting. | Treat scores as directional signals. |
548
- | **Architecture** | `detect_antipatterns` cannot detect runtime coupling or dynamic dispatch. | Complement with runtime profiling. |
549
- | **Architecture** | `get_layer_violations` needs layer boundaries defined in config first. | Requires upfront config investment. |
550
- | **Ecosystem** | Jinja preprocessing is dbt SQL only — Helm, Ansible, ERB, Kustomize not supported. | Use Terraform for IaC where possible. |
551
- | **Ecosystem** | `search_columns` is dbt-only does not cover `CREATE TABLE` SQL columns. | Use `get_symbol_source` on the `CREATE TABLE` symbol. |
552
- | **Ecosystem** | dbt indexer does not detect stale `manifest.json`. | Always run `dbt compile` before `index_folder`. |
553
- | **Relationship Analysis** | `find_implementations` may miss implementations in files that don't import the interface. | Check `get_blast_radius` for files that transitively depend on the interface file. |
554
- | **Relationship Analysis** | `get_call_hierarchy` uses import-edge graph dynamic dispatch, `eval`, and reflection are invisible. | Complement with runtime profiling for highly dynamic code. |
555
- | **Visualization** | Mermaid diagrams with >50 nodes become unreadable. | Use `maxNodes` to cap; use `scope`/`filePath` to restrict to a module. |
556
- | **Visualization** | DOT output requires Graphviz — not available natively in Claude or GitHub. | Use `format: "mermaid"`. |
557
- | **Refactoring Safety** | `check_rename_safe` flags string-literal references but cannot determine if they are intentional. | String-literal blockers always require human review. |
558
- | **Refactoring Safety** | `plan_refactoring` generates heuristic step ordering — effort is approximate. | Validate step order against actual dependency analysis. |
559
- | **Health & Debt** | `health_radar` stability axis requires git metadata. | Set `includeStability: false` if no git history. |
560
- | **Code Intelligence** | `find_untested_symbols` uses import heuristics, not runtime coverage. | Combine with Istanbul/c8 for precise branch-level coverage data. |
561
- | **AST Search** | `search_ast` only searches files backed by a WASM grammar — regex-only handlers silently skipped. | Use `search_text` for content in unsupported file types. |
1
+ # PureContext MCP — Agent Reference
2
+
3
+ Full tool reference, navigation patterns, search tips, and known limitations.
4
+ The always-on instructions (mandatory workflow, decision rules, anti-patterns) live in `~/.claude/CLAUDE.md`.
5
+
6
+ ---
7
+
8
+ ## Pick the right tool
9
+
10
+ | I need to… | Use |
11
+ |---|---|
12
+ | Find a function/class/method by name | `search_symbols` |
13
+ | Find code by what it does (meaning, not name) | `search_semantic` |
14
+ | Find a literal string, comment, or config value | `search_text` |
15
+ | Read a symbol's implementation | `get_symbol_source` |
16
+ | Fetch several symbols at once | `get_symbols` |
17
+ | Survey all symbols in one file | `get_file_outline` |
18
+ | Survey the whole project layout | `get_repo_outline` or `get_file_tree` |
19
+ | Read a non-symbol file section (imports, config block) | `get_file_content` with `startLine`/`endLine` |
20
+ | Understand what a symbol depends on | `get_context_bundle` |
21
+ | Know what breaks if I change a symbol | `get_blast_radius` |
22
+ | Find all call sites of a symbol | `find_references` |
23
+ | Check who imports a file directly | `find_importers` |
24
+ | Find unused exports | `find_dead_code` |
25
+ | Judge how risky a symbol is to change | `get_symbol_risk` |
26
+ | Review a diff/PR by impact (risk, missing co-changes, tests, flags) | `analyze_diff` |
27
+ | Find files that historically change together with one | `get_co_change` |
28
+ | Understand symbol-level git history | `get_symbol_history` |
29
+ | Identify high-churn / high-risk files | `get_churn_metrics` |
30
+ | Check if similar code exists across repos | `search_similar` |
31
+ | Find which other repos consume a symbol | `find_cross_repo_usages` |
32
+ | Search all indexed repos at once | `search_symbols` (set `repoIds`, or omit `repoId`) |
33
+ | Trace a dbt column's lineage | `search_columns` |
34
+ | Get per-file quality scores (complexity, coupling) | `get_quality_metrics` |
35
+ | Find god classes, circular deps, dead code | `detect_antipatterns` |
36
+ | Generate an architecture overview doc | `generate_docs` |
37
+ | Find all implementations of an interface / abstract class | `find_implementations` |
38
+ | Trace execution flow (callers / callees tree) | `get_call_hierarchy` |
39
+ | Understand class inheritance (ancestors / descendants) | `get_class_hierarchy` |
40
+ | Detect circular import dependencies | `find_cycles` |
41
+ | Get per-file coupling and instability scores | `get_coupling_map` |
42
+ | Generate a Mermaid / DOT diagram | `render_diagram` (or specialized variants) |
43
+ | Capture an architectural snapshot for before/after | `get_architecture_snapshot` |
44
+ | Pre-flight check before rename / delete / move | `check_rename_safe` / `check_delete_safe` / `check_move_safe` |
45
+ | Get a sequenced, risk-annotated refactoring plan | `plan_refactoring` |
46
+ | Pre-edit impact verdict for an intended change | `prepare_change` |
47
+ | Confirm an applied change is complete (plan vs actual) | `verify_change` |
48
+ | Did my change introduce a new cycle / layer violation? | `compare_change_impact` |
49
+ | 5-axis codebase health score (CI gate / dashboard) | `health_radar` |
50
+ | Compare health before and after a refactoring | `diff_health_radar` |
51
+ | Detailed debt report with per-file rankings | `get_debt_report` |
52
+ | Find every occurrence of an AST node type | `search_ast` |
53
+ | Find symbols matching a type signature pattern | `search_by_signature` |
54
+ | Find all symbols with a specific decorator | `search_by_decorator` |
55
+ | Find the most complex functions by threshold | `search_by_complexity` |
56
+ | Identify where an application starts | `get_entry_points` |
57
+ | Audit a module's exported public API surface | `get_public_api` |
58
+ | Find all TODO / FIXME / HACK comments | `get_todos` |
59
+ | Rank symbols by complexity score | `get_complexity_hotspots` |
60
+ | Understand type dependency relationships | `get_type_graph` |
61
+ | Find exported symbols with no test coverage | `find_untested_symbols` |
62
+ | Get a per-file test coverage map | `get_test_coverage_map` |
63
+
64
+ ### Rules of thumb
65
+
66
+ - **Batch reads** when you need source for several symbols, one `get_symbols` call beats many `get_symbol_source` calls.
67
+ - **Unsure of the exact name?** Use `mode: "hybrid"` to combine keyword precision with semantic recall.
68
+ - **Before rename / delete / move** — always run the matching `check_*` tool; if `safe: false`, resolve the listed blockers before proceeding.
69
+ - **Before modifying an interface or base class** — `find_implementations` lists every class that must change; `get_class_hierarchy` shows the descendant tree.
70
+ - **Before broad edits to a symbol** `get_symbol_risk` for the verdict; for a `high` band, inspect `get_co_change` + `get_blast_radius` first.
71
+ - **dbt projects** — run `dbt compile` before `index_folder`; use `search_columns` for column lineage.
72
+
73
+ The sections below document every tool's parameters in full, grouped by category.
74
+
75
+ ---
76
+
77
+ ## Indexing tools
78
+
79
+ ### `list_repos`
80
+ Always call this first. Returns all indexed repos with their `repoId`, path, file count, and last indexed time.
81
+
82
+ ### `index_folder`
83
+ Index a local directory. Returns `repoId`. Re-indexing is incremental — only changed files are re-parsed.
84
+
85
+ - `path` (required) — absolute path to project root
86
+ - `force` (optional) — set `true` to force re-index of all files, even unchanged ones
87
+ - `fileLimit` (optional) — override the configured file limit for this run
88
+
89
+ ### `resolve_repo`
90
+ Convert a local path to its `repoId` without indexing. Use when the project is already indexed but you don't have the `repoId` at hand.
91
+
92
+ ### `invalidate_cache`
93
+ Force a full re-index by clearing content hashes. Use when the index seems stale and `index_folder` is not picking up changes.
94
+
95
+ ### Keeping the index fresh
96
+
97
+ The file watcher triggers incremental re-indexing automatically. If you suspect the index is stale:
98
+
99
+ ```
100
+ index_folder({ path, force: false }) → incremental (changed files only)
101
+ index_folder({ path, force: true }) → full re-index (all files)
102
+ invalidate_cache({ repoId }) → clear hashes, then index_folder
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Symbol search & retrieval
108
+
109
+ ### `search_symbols` — primary navigation tool
110
+ Search by name fragment. Use this for almost all navigation tasks.
111
+
112
+ ```json
113
+ { "repoId": "...", "query": "authenticate", "kind": "function", "limit": 10 }
114
+ ```
115
+
116
+ - Returns signatures and summaries — no source code
117
+ - `kind` filter: `function`, `class`, `method`, `route`, `component`, `hook`, `middleware`, etc.
118
+ - `camelCase`, `snake_case`, and space-separated queries are equivalent
119
+ - Use `mode: "hybrid"` for best recall when unsure of the exact name
120
+ - When the response includes `negative_evidence.verdict: "no_match"` the symbol does not exist; do not re-search
121
+
122
+ ### `search_semantic`
123
+ Search by meaning, not name. Use when you know what the code does but not what it is called.
124
+
125
+ ```json
126
+ { "repoId": "...", "query": "validates user credentials and returns a session token", "mode": "hybrid", "max_results": 10 }
127
+ ```
128
+
129
+ Requires semantic search enabled in config. Falls back to FTS5 keyword search automatically if unavailable.
130
+
131
+ ### `search_text`
132
+ Grep-style full-text search. Use for literal strings, error messages, config values, comments — anything that is not a symbol name.
133
+
134
+ ```json
135
+ { "repoId": "...", "query": "TODO: fix this", "context_lines": 3 }
136
+ ```
137
+
138
+ ### `get_symbol_source`
139
+ Retrieve the source code of a specific symbol by its ID.
140
+
141
+ ```json
142
+ { "repoId": "...", "symbolId": "8f3a2c1d0e4b5f9a", "context_lines": 2 }
143
+ ```
144
+
145
+ - `symbolId` comes from `search_symbols` or `get_file_outline` results
146
+ - `context_lines` include surrounding lines for additional context
147
+ - `verify: true` — confirm the source on disk matches the index (after recent file edits)
148
+
149
+ ### `get_symbols`
150
+ Batch-fetch multiple symbols by ID in a single call. Prefer this over calling `get_symbol_source` repeatedly.
151
+
152
+ ```json
153
+ { "repoId": "...", "symbolIds": ["id1", "id2", "id3"] }
154
+ ```
155
+
156
+ ### `get_file_content`
157
+ Retrieve raw file content with optional line range. Use only for content that is not a named symbol — top-level imports, configuration blocks, non-symbol prose.
158
+
159
+ ```json
160
+ { "repoId": "...", "filePath": "src/config/settings.ts", "startLine": 1, "endLine": 40 }
161
+ ```
162
+
163
+ ### `get_file_outline`
164
+ All symbols in a single file with signatures and summaries. Use to survey a file without reading its content.
165
+
166
+ ### `get_repo_outline`
167
+ All files in the repo with their top-level symbols. Use to orient yourself in an unfamiliar project.
168
+
169
+ ### `get_file_tree`
170
+ Directory tree with file counts. Use when you need to understand the project's folder structure.
171
+
172
+ ### `find_references`
173
+ Find all usage sites for a symbol across the repo. Use before renaming or modifying a symbol.
174
+
175
+ ---
176
+
177
+ ## Dependency graph tools
178
+
179
+ ### `get_context_bundle`
180
+ Forward-walk from a symbol — returns the symbol and everything it transitively imports. Use before modifying a function to understand its full context.
181
+
182
+ ```json
183
+ { "repoId": "...", "symbolId": "...", "maxDepth": 2, "maxTokens": 4000 }
184
+ ```
185
+
186
+ Use `maxTokens` to cap the response size when working with deeply connected code.
187
+
188
+ ### `get_blast_radius`
189
+ Reverse-walk — all files that transitively import a symbol. Use before modifying or deleting a symbol to understand what would break.
190
+
191
+ ```json
192
+ { "repoId": "...", "symbolId": "...", "maxDepth": 5 }
193
+ ```
194
+
195
+ ### `find_importers`
196
+ Direct (one-hop) importers of a file. Faster than `get_blast_radius` when you only need the immediate callers.
197
+
198
+ ### `find_dead_code`
199
+ Exported symbols that nothing else imports. Use for cleanup audits. May produce false positives for dynamic imports and symbols consumed by external npm consumers.
200
+
201
+ ---
202
+
203
+ ## Architecture & quality tools
204
+
205
+ ### `get_layer_violations`
206
+ Detect architectural import boundary violations. Requires layer boundaries defined in config.
207
+
208
+ ### `get_quality_metrics`
209
+ Per-file complexity, coupling, cohesion, and documentation coverage scores. Use instead of making subjective assessments from reading source code. Complexity scores are directional signals, not exact measurements.
210
+
211
+ ### `detect_antipatterns`
212
+ Detect common architectural anti-patterns (god classes, circular dependencies, dead code). Returns structured results with severity levels. Cannot detect runtime coupling or dynamic dispatch issues.
213
+
214
+ ### `generate_docs`
215
+ Auto-generate an architecture summary in Markdown or Mermaid format. Requires `ai.allowRemoteAI: true`.
216
+
217
+ **Pre-refactoring workflow:**
218
+ ```
219
+ get_quality_metrics → find worst files
220
+ detect_antipatterns → find structural issues
221
+ get_blast_radius → understand impact scope
222
+ generate_docs → generate "before" overview
223
+ [make changes]
224
+ detect_antipatterns → verify anti-patterns resolved
225
+ ```
226
+
227
+ ---
228
+
229
+ ## Git & history tools
230
+
231
+ ### `get_symbol_history`
232
+ Symbol-level git commit history. Returns structured JSON with commits, authors, and diffs.
233
+
234
+ - Rename/move breaks history continuity symbols in renamed files start fresh history from the rename commit
235
+ - After a rebase, run `invalidate_cache` + `index_folder` to rebuild accurate history
236
+ - Default `maxCommits: 500` cap — increase `git.maxCommits` for history-sensitive workflows
237
+
238
+ ### `get_churn_metrics`
239
+ File and symbol churn metrics. 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 or chronically buggy.
240
+
241
+ For debugging, use `get_churn_metrics` to find recently-changed symbols — recent changes are the most likely source of new bugs.
242
+
243
+ ### `get_co_change`
244
+ Temporal coupling — files that historically change together with a target file/symbol, from git history. Reveals coupling the import graph cannot (a route and its test, a feature flag and the code it gates). Returns `support` (shared commits), `confidence` (directional A→B), `lift`, with mega-commits filtered out. Granularity is file-level (a `symbolId` resolves to its file). Requires `git.coChangeDepth > 0` at index time; returns `signalQuality: "low"` on shallow histories rather than overstating weak ratios.
245
+
246
+ ### `get_symbol_risk`
247
+ Composite, explainable change-risk verdict for a symbol: `riskScore` 0–100, banded `low` / `review` / `high`. Blends churn, centrality (afferent coupling + reverse blast radius), complexity, test gap, and co-change spread — each normalized repo-relative. Always returns `factors` (raw + normalized) and `reasons[]`.
248
+
249
+ **Guardrail:** before broad automated edits to a symbol, consult its risk. For a `high` symbol, inspect its callers (`get_blast_radius`) and co-changers (`get_co_change`) *first* — those are the second-order edits most likely to break. `search_symbols` and `get_symbol_source` accept `includeRisk: true` to attach a compact `{ band, riskScore }` inline (opt-in, default off). `get_context_bundle` returns `historicalNeighbors` — co-changing files not reachable via imports — when co-change data exists.
250
+
251
+ > Risk and co-change are **code-centered**they intentionally model no author/ownership/productivity metrics.
252
+
253
+ ### `analyze_diff`
254
+ Impact-aware review of a unified git diff (paste `git diff` / `git diff HEAD~1` output). Beyond the changed-symbol list + blast radius, it returns:
255
+ - `risk` — aggregate band (`low`/`review`/`high`) + the top composite-risk symbols touched.
256
+ - `missingCoChange` — **the headline signal**: files that *historically* change together with the edited files but are **absent from this diff** (the "you touched `refundService` but `ledgerService` usually moves with it — and it's not here" instinct). Empty + suppressed when `signalQuality:"low"` (thin history) — it never invents warnings.
257
+ - `recommendedTests` tests that exercise the changed symbols (plus co-changing test files).
258
+ - `coverageGaps` — changed symbols with no detected test coverage.
259
+ - `architecturalFlags` — import cycles / layer-boundary crossings the changed files **currently sit on** (current-state *flags*, not "regressions introduced by the diff").
260
+ - `reviewPriority` — `low`/`medium`/`high`/`critical`, now folding in risk band + coverage gaps.
261
+
262
+ All impact sections default **on**; switch any off (`includeRisk`, `includeCoChangeGaps`, `includeTests`, `includeArchitectureFlags`) for cheap runs. Built for CI and AI-assisted PR review: *review by impact, not by diff size.*
263
+
264
+ ---
265
+
266
+ ## Cross-repo tools
267
+
268
+ ### Searching all repos at once
269
+ `search_symbols` (and `search_text`) search every indexed repo when you omit `repoId`/`repoIds`, or a chosen subset via `repoIds: [...]`. There is no separate cross-repo *search* tool.
270
+
271
+ ### `find_cross_repo_usages`
272
+ Find which *other* indexed repos reference an identifier defined in a given repo — i.e. the downstream packages/services that consume a shared-library symbol. Word-boundary text search; heuristic, not type-resolved. Params: `sourceRepoId`, `symbolName`, `symbolKind?`, `targetRepoIds?`, `limit?`.
273
+
274
+ ### `search_similar`
275
+ Find semantically similar code across repos (HNSW vector similarity). Before implementing new functionality, call this to check if equivalent code already exists. Requires semantic search enabled.
276
+
277
+ Before modifying shared library code, use `get_blast_radius` with `crossRepo: true`.
278
+
279
+ **Note:** `crossRepoDeps` requires explicit package name configuration — no auto-detection of Nx/Turborepo/Lerna workspaces.
280
+
281
+ ---
282
+
283
+ ## Ecosystem & data tools
284
+
285
+ ### `search_columns`
286
+ Search column definitions across dbt models. Returns full upstream/downstream lineage.
287
+
288
+ - dbt-only does not search columns in raw SQL `CREATE TABLE` statements
289
+ - Always run `dbt compile` before `index_folder` — stale manifests produce incorrect lineage
290
+ - Use `search_symbols` with `kind: "route"` to find API endpoints via the OpenAPI provider
291
+
292
+ **Templating coverage:** Jinja preprocessing is dbt SQL only. Helm, Ansible Jinja2, Kubernetes YAML, ERB, and Kustomize are not preprocessed. Terraform is fully supported.
293
+
294
+ ---
295
+
296
+ ## Advanced relationship analysis tools
297
+
298
+ ### `find_implementations`
299
+ Find all concrete implementations of an interface or abstract class. Returns `implementedMethods` and `missingMethods` per class. Use before modifying an interface to know every class that must be updated.
300
+
301
+ - `includeAbstract` (optional) — also include abstract subclasses (default false)
302
+ - `limit` (optional) max results (default 50)
303
+
304
+ ### `get_call_hierarchy`
305
+ Return callers and callees of a function, N levels deep, as a tree. Recursive calls marked `cyclic: true`.
306
+
307
+ ```json
308
+ { "repoId": "...", "symbolId": "...", "direction": "callees", "maxDepth": 3, "maxNodes": 50 }
309
+ ```
310
+
311
+ - `direction`: `"callees"`, `"callers"`, or `"both"`
312
+ - Uses import-edge graph, not runtime call data — dynamic dispatch, `eval`, and reflection are invisible
313
+
314
+ ### `get_class_hierarchy`
315
+ Full inheritance tree rooted at a class — ancestors (what it extends) and descendants (what extends it).
316
+
317
+ - `direction`: `"ancestors"`, `"descendants"`, or `"both"` (default)
318
+ - `maxDepth` (optional, default 5)
319
+
320
+ ### `find_cycles`
321
+ Detect circular import dependencies. Returns strongly-connected components with severity ratings.
322
+
323
+ - `scope` (optional) — directory prefix to restrict analysis
324
+ - `minCycleLength` (optional) — ignore trivial self-referential entries (default 2)
325
+
326
+ ### `get_coupling_map`
327
+ Afferent/efferent coupling metrics per file. Returns instability scores (`I = efferent / (afferent + efferent)`).
328
+
329
+ - `scope` (optional), `limit` (optional, default 50)
330
+
331
+ ---
332
+
333
+ ## Visualization tools
334
+
335
+ ### `render_diagram`
336
+ Generate a Mermaid or DOT diagram from the dependency graph.
337
+
338
+ ```json
339
+ { "repoId": "...", "type": "module", "format": "mermaid", "maxNodes": 30, "maxDepth": 3 }
340
+ ```
341
+
342
+ - `type`: `"module"` / `"import"` (file-level), `"call"` (call graph, requires `rootSymbolId`), `"class"` (hierarchy, requires `rootSymbolId`)
343
+ - `format`: `"mermaid"` (renders in GitHub, VS Code, Claude) or `"dot"` (Graphviz)
344
+ - Diagrams with >50 nodes become unreadable — use `maxNodes` to cap
345
+
346
+ ### `render_call_graph` / `render_import_graph` / `render_class_hierarchy` / `render_dep_matrix`
347
+ Specialized variants of `render_diagram` for specific diagram types.
348
+
349
+ ### `get_architecture_snapshot`
350
+ Capture the current architectural state: file count, symbol count, module breakdown, coupling summary, health scores. Take two snapshots (before/after a refactoring) to prove structural improvement objectively.
351
+
352
+ ---
353
+
354
+ ## Refactoring safety tools
355
+
356
+ Always run these before executing a structural change. They give a binary `safe` verdict.
357
+
358
+ ### `check_rename_safe`
359
+ ```json
360
+ { "repoId": "...", "symbolId": "...", "newName": "processOrderV2" }
361
+ ```
362
+ Returns `safe`, `verdict`, and all `affectedSites` with file, line, column, context snippet, and change type. `safe: false` when the new name conflicts with an existing symbol, or when string-literal references exist that require human judgment.
363
+
364
+ ### `check_delete_safe`
365
+ Returns `safe: false` if anything still imports or references the symbol. Lists all blocking references.
366
+
367
+ ### `check_move_safe`
368
+ Validates 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.
369
+
370
+ ### `plan_refactoring`
371
+ Generate a sequenced, dependency-ordered plan for a structural change.
372
+
373
+ ```json
374
+ { "repoId": "...", "description": "Extract auth logic from UserService into AuthService", "scope": "src/services/" }
375
+ ```
376
+
377
+ Step ordering is heuristic — validate against actual dependency analysis.
378
+
379
+ ### The refactoring loop: `prepare_change` edit → `verify_change` → `compare_change_impact`
380
+
381
+ These three tools are **judgment, not actuation** none of them edit code. You apply the change with your own tools; they tell you what's safe and what's still missing, each with a plain-English `reasons[]`.
382
+
383
+ **`prepare_change`** — pre-edit verdict for a stated intent. Give it an `intent` (`rename` / `delete` / `modify` / `extract`) and a target (`targetSymbolId` **or** `query`).
384
+
385
+ ```json
386
+ { "repoId": "...", "intent": "rename", "targetSymbolId": "ab12cd34ef56" }
387
+ ```
388
+
389
+ Returns `verdict`: `ready` (with `target`, `predictedChange`, `risk`, `missingCoChange`, `recommendedTests`, `coverageGaps`, `architecturalFlags`, `predictionId`, `reasons`), `ambiguous_target` (with `candidates[]` — re-call with the chosen `targetSymbolId`; it never guesses), or `no_target`. Keep `predictedChange.changedFilePaths` and `missingCoChange[].filePath` — `verify_change` needs them.
390
+
391
+ **`verify_change`** after you edit, reconcile the real diff against the prediction. Stateless: pass the prediction back inline.
392
+
393
+ ```json
394
+ { "repoId": "...", "diff": "<git diff>", "predictedFilePaths": ["..."], "predictedCoChange": ["..."] }
395
+ ```
396
+
397
+ Returns `verdict` (`complete` / `incomplete` / `scope_expanded`), `unaddressedCoChange` (planned partners you still didn't touch — the headline), `addressedCoChange`, `unplannedChanges` (scope creep), `coverageGapsRemaining`. Co-change reconciliation is suppressed when `signalQuality` is `low` (shallow git history).
398
+
399
+ **`compare_change_impact`** — did the change introduce a *new* cycle or layer violation? Snapshot the architecture *before* the change with `get_architecture_snapshot` (action `create`), then after editing + reindexing:
400
+
401
+ ```json
402
+ { "repoId": "...", "baselineSnapshotId": "<id from get_architecture_snapshot>" }
403
+ ```
404
+
405
+ Returns `verdict` (`regressed` / `improved` / `unchanged` / `no_baseline`), `newCycles` / `newLayerViolations` (what the change introduced), and `resolvedCycles` / `resolvedLayerViolations`. Distinct from `analyze_diff`'s `architecturalFlags`, which flag *pre-existing* issues — this reports only the delta and never blames the change for problems it didn't create. With no baseline snapshot it returns `no_baseline` and degrades to current-state counts.
406
+
407
+ ---
408
+
409
+ ## Health & debt tools
410
+
411
+ ### `health_radar`
412
+ Five-axis health radar. 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
+ ```json
423
+ { "repoId": "...", "scope": "src/core/", "includeStability": true }
424
+ ```
425
+
426
+ Set `includeStability: false` if the repo has no git history.
427
+
428
+ ### `diff_health_radar`
429
+ Compare two health radar snapshots axis-by-axis. Use with `get_architecture_snapshot` for before/after evidence.
430
+
431
+ ### `get_debt_report`
432
+ Detailed debt report with per-file rankings, priority tiers, and actionable recommendations.
433
+
434
+ - `scope` (optional), `maxFiles` (optional, default 10), `includeDead` (optional)
435
+
436
+ ---
437
+
438
+ ## AST-level search tools
439
+
440
+ These re-parse stored file content using tree-sitter grammars. Only files backed by a WASM grammar are searched — regex-only handlers are silently skipped; use `search_text` for those.
441
+
442
+ ### `search_ast`
443
+ Find every occurrence of a specific tree-sitter node type.
444
+
445
+ ```json
446
+ { "repoId": "...", "nodeType": "try_statement", "filePath": "src/", "limit": 50 }
447
+ ```
448
+
449
+ Common node types:
450
+
451
+ | Language | Node types |
452
+ |----------|-----------|
453
+ | TypeScript/JS | `arrow_function`, `function_declaration`, `class_declaration`, `interface_declaration`, `try_statement`, `await_expression`, `call_expression`, `import_statement`, `jsx_element`, `throw_statement`, `type_alias_declaration` |
454
+ | Python | `function_definition`, `class_definition`, `for_statement`, `with_statement`, `decorated_definition`, `lambda` |
455
+ | Rust | `function_item`, `struct_item`, `impl_item`, `match_expression`, `closure_expression`, `trait_item` |
456
+ | Go | `function_declaration`, `method_declaration`, `go_statement`, `defer_statement`, `type_declaration` |
457
+
458
+ ### `search_by_signature`
459
+ Search symbols by type signature pattern (regex or substring).
460
+
461
+ ```json
462
+ { "repoId": "...", "pattern": "Promise<.*>", "kind": "function" }
463
+ ```
464
+
465
+ ### `search_by_decorator`
466
+ Find all symbols annotated with a specific decorator.
467
+
468
+ ```json
469
+ { "repoId": "...", "decorator": "Injectable", "kind": "class" }
470
+ ```
471
+
472
+ ### `search_by_complexity`
473
+ Find symbols above a complexity threshold.
474
+
475
+ ```json
476
+ { "repoId": "...", "minComplexity": 10, "kind": "function", "limit": 20 }
477
+ ```
478
+
479
+ ---
480
+
481
+ ## Code intelligence tools
482
+
483
+ ### `get_entry_points`
484
+ Identify all runnable entry points: main functions, CLI handlers, HTTP server startups, Lambda handlers, test suites, scripts. Each result includes `kind`, `confidence` (`high`/`medium`/`low`), and the reason for classification.
485
+
486
+ - `kind` (optional): `main_function`, `cli_handler`, `server_startup`, `lambda_handler`, `test_suite`, `script`
487
+ - `minConfidence` (optional): `"high"`, `"medium"`, or `"low"` (default)
488
+
489
+ ### `get_public_api`
490
+ All exported symbols grouped by file — the public API surface of the repo or a module.
491
+
492
+ - `filePath` (optional), `kind` (optional), `includeMembers` (optional), `groupByFile` (optional, default true)
493
+
494
+ ### `get_todos`
495
+ All TODO, FIXME, HACK, NOTE, and XXX comments. Returns file, line, tag type, and comment text.
496
+
497
+ - `tags` (optional), `filePath` (optional), `limit` (optional, default 200)
498
+
499
+ ### `get_complexity_hotspots`
500
+ Symbols ranked by complexity score, highest first.
501
+
502
+ - `kind` (optional), `filePath` (optional), `limit` (optional, default 20), `minComplexity` (optional)
503
+
504
+ ### `get_type_graph`
505
+ Type dependency graph — which types reference which other types.
506
+
507
+ - `symbolId` (optional) — root at a specific type
508
+ - `maxDepth` (optional, default 3)
509
+ - `direction`: `"uses"`, `"usedBy"`, or `"both"`
510
+
511
+ ### `find_untested_symbols`
512
+ Exported symbols with no corresponding test coverage (import-based heuristics, not runtime coverage).
513
+
514
+ - `filePath` (optional), `kind` (optional), `limit` (optional, default 50)
515
+
516
+ ### `get_test_coverage_map`
517
+ Per-file coverage map with `coverageRatio` per file and aggregated totals.
518
+
519
+ - `filePath` (optional), `includeSymbols` (optional, default false)
520
+
521
+ ---
522
+
523
+ ## Navigation patterns
524
+
525
+ ### Understand an unfamiliar codebase
526
+ ```
527
+ 1. list_repos() → check if indexed
528
+ 2. index_folder({ path }) → index if needed, get repoId
529
+ 3. get_repo_outline({ repoId }) → survey the structure
530
+ 4. search_symbols({ query: "..." }) → locate key symbols
531
+ 5. get_context_bundle({ symbolId }) → understand entry + dependencies
532
+ ```
533
+
534
+ ### Modify a function safely
535
+ ```
536
+ 1. search_symbols({ query: "functionName", kind: "function" })
537
+ 2. get_blast_radius({ symbolId }) → know the impact scope BEFORE touching it
538
+ 3. get_context_bundle({ symbolId, maxDepth: 2 }) understand its context
539
+ 4. get_symbol_source({ symbolId }) → read the implementation
540
+ 5. [make the change]
541
+ 6. find_dead_code({ repoId }) → verify no orphaned exports left behind
542
+ ```
543
+
544
+ ### Modify a high-risk symbol safely
545
+ ```
546
+ 1. search_symbols({ query: "functionName", kind: "function" })
547
+ 2. get_symbol_risk({ repoId, symbolId }) → composite verdict (band + factors + reasons)
548
+ 3. If band is "high", inspect BEFORE editing:
549
+ - get_co_change({ repoId, symbolId }) → files that move with it but don't import it
550
+ - get_blast_radius({ symbolId }) → full reverse-dependency impact
551
+ - get_symbol_history({ symbolId }) → recent change context
552
+ 4. get_context_bundle({ symbolId, maxDepth: 2 }) → also returns historicalNeighbors when co-change data exists
553
+ 5. get_symbol_source({ symbolId })
554
+ 6. [make the change — and its co-changers, if they must move together]
555
+ 7. find_dead_code({ repoId })
556
+ ```
557
+
558
+ ### Find where something is called
559
+ ```
560
+ 1. search_symbols({ query: "symbolName" })
561
+ 2. find_references({ symbolId }) → all call sites
562
+ 3. get_symbol_source for relevant call sites
563
+ ```
564
+
565
+ ### Search when you know the concept but not the name
566
+ ```
567
+ 1. search_semantic({ query: "natural language description", mode: "hybrid" })
568
+ 2. Review signatures and summaries
569
+ 3. get_symbol_source for the best match
570
+ ```
571
+
572
+ ### Modify an interface or base class safely
573
+ ```
574
+ 1. search_symbols({ query: "InterfaceName", kind: "interface" })
575
+ 2. find_implementations({ symbolId }) → all classes that must be updated
576
+ 3. get_class_hierarchy({ symbolId, direction: "descendants" })
577
+ 4. get_blast_radius({ symbolId })
578
+ 5. [make the change]
579
+ 6. find_implementations({ symbolId }) → verify missingMethods is empty
580
+ ```
581
+
582
+ ### Refactor safely (rename / delete / move)
583
+ ```
584
+ 1. search_symbols({ query: "symbolName" })
585
+ 2. check_rename_safe / check_delete_safe / check_move_safe
586
+ 3. If safe: proceed. If not safe: resolve blockers in affectedSites first, then re-check.
587
+ 4. find_dead_code({ repoId }) → verify no orphaned exports remain
588
+ ```
589
+
590
+ ### Tech debt sprint
591
+ ```
592
+ 1. health_radar({ repoId }) → 5-axis baseline
593
+ 2. get_debt_report({ repoId }) → per-file rankings + recommendations
594
+ 3. get_complexity_hotspots({ repoId }) → worst functions first
595
+ 4. find_untested_symbols({ repoId }) → coverage gaps
596
+ 5. find_cycles({ repoId }) → circular deps to break
597
+ 6. get_architecture_snapshot({ repoId }) → baseline snapshot before changes
598
+ 7. [fix highest-priority items]
599
+ 8. get_architecture_snapshot({ repoId }) → after snapshot
600
+ 9. diff_health_radar({ before, after }) → prove the improvement
601
+ ```
602
+
603
+ ### Debug a recent regression
604
+ ```
605
+ 1. get_churn_metrics({ repoId }) → find recently-changed files
606
+ 2. get_symbol_history({ symbolId }) → check commits in the affected area
607
+ 3. search_symbols in changed files → find the suspect functions
608
+ 4. get_symbol_source → get_context_bundle → read and understand the change
609
+ ```
610
+
611
+ ### PR review
612
+ ```
613
+ 1. [obtain list of changed files from PR]
614
+ 2. get_symbol_history for changed symbols → understand prior context
615
+ 3. get_churn_metrics for changed files → flag hotspots
616
+ 4. get_blast_radius for each modified symbol
617
+ 5. detect_antipatterns({ repoId }) → flag new structural issues
618
+ ```
619
+
620
+ ### Architecture review / onboarding
621
+ ```
622
+ 1. list_repos → index_folder if needed
623
+ 2. generate_docs({ repoId }) → generate project overview
624
+ 3. get_quality_metrics({ repoId }) → identify weakest files
625
+ 4. detect_antipatterns({ repoId }) → find structural issues
626
+ 5. get_repo_outline({ repoId }) → survey specific areas
627
+ ```
628
+
629
+ ---
630
+
631
+ ## Search tips
632
+
633
+ - **camelCase and snake_case are equivalent** — `processOrder` and `process_order` return the same results
634
+ - **Short queries rank better** — `auth` finds more than `authentication middleware function`
635
+ - **Use `kind` to narrow results** — `kind: "function"` eliminates class/method noise
636
+ - **Use `filePath` to scope** — `filePath: "src/auth/"` restricts to a directory
637
+ - **Use `debug: true` to diagnose ranking** — shows BM25 scores and name boost factors
638
+ - **For hybrid mode** — `semantic_weight: 0.6, keyword_weight: 0.4` is a good starting point
639
+
640
+ ---
641
+
642
+ ## `_tokenEstimate` and `_meta`
643
+
644
+ Every response includes:
645
+
646
+ ```json
647
+ { "_meta": { "timing_ms": 3, "tokens_saved": 1842, "total_tokens_saved": 45231 } }
648
+ ```
649
+
650
+ `_tokenEstimate` — rough token count of the returned payload. Use it to:
651
+ - Decide whether to fetch additional context or stop
652
+ - Cap `maxTokens` in `get_context_bundle` to avoid hitting context limits
653
+ - Track cumulative savings with `get_savings_stats`
654
+
655
+ ---
656
+
657
+ ## Known limitations
658
+
659
+ | Area | Limitation | Workaround |
660
+ |------|-----------|-----------|
661
+ | **AI Summaries** | Summaries describe intent, not contract. Stale summaries exist until re-index. | Always verify with `get_symbol_source` before modifying. |
662
+ | **AI Summaries** | `get_architecture_doc` requires `ai.allowRemoteAI: true`. | `detect_antipatterns` and `get_quality_metrics` work without AI. |
663
+ | **Git History** | Rename/move breaks history continuity. | Future: `git log --follow` tracking. |
664
+ | **Git History** | Rebase invalidates commit hashes — re-index required. | Run `invalidate_cache` + `index_folder` post-rebase. |
665
+ | **Git History** | Default `maxCommits: 500` drops early history on long-lived projects. | Increase `git.maxCommits` in config. |
666
+ | **Git History** | No SVN/Mercurial/Perforce support. | Git is a hard requirement for history features. |
667
+ | **Cross-Repo** | `crossRepoDeps` is manual — no auto-detection of Nx/Turborepo/pnpm workspaces. | Explicitly list package names in each repo's config. |
668
+ | **Cross-Repo** | `find_similar` requires semantic search and an embedding provider. | Use a local Ollama model as a zero-cost alternative. |
669
+ | **Cross-Repo** | MCP Resources `resources/subscribe` not yet supported by Claude Code or Cursor. | Poll with `search_cross_repo`. |
670
+ | **Architecture** | Quality metrics use estimated complexity (nesting heuristics), not true AST branch-counting. | Treat scores as directional signals. |
671
+ | **Architecture** | `detect_antipatterns` cannot detect runtime coupling or dynamic dispatch. | Complement with runtime profiling. |
672
+ | **Architecture** | `get_layer_violations` needs layer boundaries defined in config first. | Requires upfront config investment. |
673
+ | **Ecosystem** | Jinja preprocessing is dbt SQL only — Helm, Ansible, ERB, Kustomize not supported. | Use Terraform for IaC where possible. |
674
+ | **Ecosystem** | `search_columns` is dbt-only — does not cover `CREATE TABLE` SQL columns. | Use `get_symbol_source` on the `CREATE TABLE` symbol. |
675
+ | **Ecosystem** | dbt indexer does not detect stale `manifest.json`. | Always run `dbt compile` before `index_folder`. |
676
+ | **Relationship Analysis** | `find_implementations` may miss implementations in files that don't import the interface. | Check `get_blast_radius` for files that transitively depend on the interface file. |
677
+ | **Relationship Analysis** | `get_call_hierarchy` uses import-edge graph — dynamic dispatch, `eval`, and reflection are invisible. | Complement with runtime profiling for highly dynamic code. |
678
+ | **Visualization** | Mermaid diagrams with >50 nodes become unreadable. | Use `maxNodes` to cap; use `scope`/`filePath` to restrict to a module. |
679
+ | **Visualization** | DOT output requires Graphviz — not available natively in Claude or GitHub. | Use `format: "mermaid"`. |
680
+ | **Refactoring Safety** | `check_rename_safe` flags string-literal references but cannot determine if they are intentional. | String-literal blockers always require human review. |
681
+ | **Refactoring Safety** | `plan_refactoring` generates heuristic step ordering — effort is approximate. | Validate step order against actual dependency analysis. |
682
+ | **Health & Debt** | `health_radar` stability axis requires git metadata. | Set `includeStability: false` if no git history. |
683
+ | **Code Intelligence** | `find_untested_symbols` uses import heuristics, not runtime coverage. | Combine with Istanbul/c8 for precise branch-level coverage data. |
684
+ | **AST Search** | `search_ast` only searches files backed by a WASM grammar — regex-only handlers silently skipped. | Use `search_text` for content in unsupported file types. |