purecontext-mcp 1.5.0 → 1.5.2
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.
- package/BENCHMARKS.md +153 -0
- package/FULL-INSTALLATION-GUIDE.md +341 -0
- package/README.md +73 -15
- package/USER-GUIDE.md +21 -21
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/02-installation.md +43 -317
- package/docs/07-language-support.md +73 -50
- package/docs/08-framework-adapters.md +7 -2
- package/docs/15-team-setup.md +70 -200
- package/docs/17-web-ui.md +73 -93
- package/docs/README.md +60 -39
- package/package.json +3 -3
- package/user-manual.md +0 -2466
package/user-manual.md
DELETED
|
@@ -1,2466 +0,0 @@
|
|
|
1
|
-
# PureContext MCP — User Manual
|
|
2
|
-
|
|
3
|
-
## Table of Contents
|
|
4
|
-
|
|
5
|
-
1. [What is PureContext MCP?](#1-what-is-purecontext-mcp)
|
|
6
|
-
2. [Installation](#2-installation)
|
|
7
|
-
3. [Connecting to Claude Code (Quick Start)](#3-connecting-to-claude-code-quick-start)
|
|
8
|
-
4. [Configuration](#4-configuration)
|
|
9
|
-
5. [CLI Commands](#5-cli-commands)
|
|
10
|
-
6. [MCP Tools Reference](#6-mcp-tools-reference)
|
|
11
|
-
7. [Language Support](#7-language-support)
|
|
12
|
-
8. [Framework Adapters](#8-framework-adapters)
|
|
13
|
-
9. [Transport Modes](#9-transport-modes)
|
|
14
|
-
10. [AI Summarization](#10-ai-summarization)
|
|
15
|
-
11. [Semantic Search (HNSW)](#11-semantic-search-hnsw)
|
|
16
|
-
12. [Token Savings Tracker](#12-token-savings-tracker)
|
|
17
|
-
13. [Multi-Tenant Hosting](#13-multi-tenant-hosting)
|
|
18
|
-
14. [Web UI](#14-web-ui)
|
|
19
|
-
15. [Security](#15-security)
|
|
20
|
-
16. [Architecture Overview](#16-architecture-overview)
|
|
21
|
-
17. [Troubleshooting](#17-troubleshooting)
|
|
22
|
-
18. [Advanced Relationship Analysis](#18-advanced-relationship-analysis)
|
|
23
|
-
19. [Architectural Visualization](#19-architectural-visualization)
|
|
24
|
-
20. [Refactoring Safety Checks](#20-refactoring-safety-checks)
|
|
25
|
-
21. [Health Dashboards & Debt Reporting](#21-health-dashboards--debt-reporting)
|
|
26
|
-
22. [AST-Level Search](#22-ast-level-search)
|
|
27
|
-
23. [Code Intelligence Helpers](#23-code-intelligence-helpers)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## 1. What is PureContext MCP?
|
|
32
|
-
|
|
33
|
-
PureContext MCP is a **token-efficient source code navigation server** for AI agents. Instead of reading entire files, AI agents can retrieve exactly the symbols they need — functions, classes, methods, routes, and more — saving 90–98% of context tokens.
|
|
34
|
-
|
|
35
|
-
It implements the **Model Context Protocol (MCP)** so it works natively with Claude Code and any other MCP-compatible AI client.
|
|
36
|
-
|
|
37
|
-
**Key capabilities:**
|
|
38
|
-
- Index TypeScript, JavaScript, Python, Go, Rust, Java, C#, PHP, Ruby, Kotlin, C, C++, Lua, Dart, Swift, Elixir, Haskell, Scala, and R
|
|
39
|
-
- Framework-aware extraction: Vue, React, Nuxt, Next.js, Angular, NestJS, Express, Fastify, Django, Flask, FastAPI, Gin, Rails, Laravel, and more
|
|
40
|
-
- Dependency graph: find what a symbol depends on and what depends on it
|
|
41
|
-
- Semantic search: find symbols by meaning, not just keywords
|
|
42
|
-
- Advanced relationship analysis: call hierarchies, class hierarchies, interface implementations, import cycles, coupling maps
|
|
43
|
-
- Architectural visualization: Mermaid/DOT diagrams for call graphs, import graphs, class hierarchies, and dependency matrices
|
|
44
|
-
- Refactoring safety checks: pre-flight analysis before renaming, deleting, or moving symbols
|
|
45
|
-
- Health dashboards: multi-axis health radar, debt reports, and before/after diff comparisons
|
|
46
|
-
- AST-level search: find any node type, signature pattern, decorator, or complexity threshold
|
|
47
|
-
- Code intelligence: entry points, public API surface, TODO inventory, complexity hotspots, type graphs, and coverage mapping
|
|
48
|
-
- Web UI for visual codebase exploration
|
|
49
|
-
- Multi-tenant hosting for team deployments
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## 2. Installation
|
|
54
|
-
|
|
55
|
-
### Prerequisites
|
|
56
|
-
|
|
57
|
-
- **Node.js** >= 18.0.0
|
|
58
|
-
- **npm** >= 9.0.0
|
|
59
|
-
- **Git** (required for `index_repo` to clone remote repositories)
|
|
60
|
-
|
|
61
|
-
### Install from source
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
git clone <repository-url> purecontext-mcp
|
|
65
|
-
cd purecontext-mcp
|
|
66
|
-
npm install
|
|
67
|
-
npm run build
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Install globally
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
npm install -g .
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
After this, `purecontext-mcp` is available as a command globally.
|
|
77
|
-
|
|
78
|
-
### Verify installation
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
purecontext-mcp config --check
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
This validates your installation and checks that all prerequisites (tree-sitter grammars, SQLite) are working.
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
## 3. Connecting to Claude Code (Quick Start)
|
|
89
|
-
|
|
90
|
-
### Step 1 — Add PureContext as an MCP server
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
claude mcp add purecontext-mcp npx purecontext-mcp
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Or, if installed globally:
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
claude mcp add purecontext-mcp purecontext-mcp
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Step 2 — Index your project
|
|
103
|
-
|
|
104
|
-
In Claude Code, ask:
|
|
105
|
-
|
|
106
|
-
> "Index this project so I can search its symbols."
|
|
107
|
-
|
|
108
|
-
Claude will call the `index_folder` tool. Or explicitly:
|
|
109
|
-
|
|
110
|
-
> "Use index_folder to index /path/to/your/project."
|
|
111
|
-
|
|
112
|
-
### Step 3 — Start navigating
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
search_symbols → find functions/classes by name
|
|
116
|
-
get_file_outline → see all symbols in a file
|
|
117
|
-
get_symbol_source → retrieve a symbol's source code
|
|
118
|
-
get_blast_radius → see what a symbol affects
|
|
119
|
-
get_context_bundle → get a symbol + everything it depends on
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Workflow example
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
User: "Find the authentication logic in this project."
|
|
126
|
-
|
|
127
|
-
Claude:
|
|
128
|
-
1. search_symbols(query: "auth", kind: "function")
|
|
129
|
-
→ Returns: validateToken, hashPassword, verifySession (3 matches)
|
|
130
|
-
|
|
131
|
-
2. get_symbol_source(id: "validateToken-id")
|
|
132
|
-
→ Returns: 45 lines of source (instead of the entire 800-line file)
|
|
133
|
-
|
|
134
|
-
Token cost: ~150 tokens instead of ~2,000 tokens → 93% savings
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
## 4. Configuration
|
|
140
|
-
|
|
141
|
-
The configuration file lives at `~/.purecontext/config.json`. Generate a default one with:
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
purecontext-mcp config --init
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
View the effective configuration with:
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
purecontext-mcp config
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Complete configuration reference
|
|
154
|
-
|
|
155
|
-
```json
|
|
156
|
-
{
|
|
157
|
-
"indexDir": "~/.purecontext/indexes",
|
|
158
|
-
"fileLimit": 1000,
|
|
159
|
-
"watchDebounceMs": 2000,
|
|
160
|
-
"excludePatterns": [],
|
|
161
|
-
"adapters": "auto",
|
|
162
|
-
"maxFileSizeBytes": 1048576,
|
|
163
|
-
"allowSymlinks": false,
|
|
164
|
-
"transport": "stdio",
|
|
165
|
-
|
|
166
|
-
"ai": {
|
|
167
|
-
"provider": "none",
|
|
168
|
-
"allowRemoteAI": false,
|
|
169
|
-
"apiKey": "",
|
|
170
|
-
"endpoint": null,
|
|
171
|
-
"model": "claude-haiku-4-5-20251001",
|
|
172
|
-
"batchSize": 50,
|
|
173
|
-
"embeddingModel": null,
|
|
174
|
-
"embeddingProvider": null,
|
|
175
|
-
"openaiApiKey": ""
|
|
176
|
-
},
|
|
177
|
-
|
|
178
|
-
"semantic": {
|
|
179
|
-
"enabled": false,
|
|
180
|
-
"provider": "none",
|
|
181
|
-
"localEmbeddingEndpoint": null,
|
|
182
|
-
"dimension": null,
|
|
183
|
-
"threshold": 50000,
|
|
184
|
-
"batchSize": 500,
|
|
185
|
-
"concurrency": 2
|
|
186
|
-
},
|
|
187
|
-
|
|
188
|
-
"http": {
|
|
189
|
-
"port": 3000,
|
|
190
|
-
"host": "127.0.0.1",
|
|
191
|
-
"corsOrigins": ["http://localhost:*"],
|
|
192
|
-
"auth": {
|
|
193
|
-
"enabled": false,
|
|
194
|
-
"token": ""
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
|
|
198
|
-
"rateLimit": {
|
|
199
|
-
"enabled": true,
|
|
200
|
-
"maxTokens": 100,
|
|
201
|
-
"refillRate": 10,
|
|
202
|
-
"perToolLimits": {
|
|
203
|
-
"index_folder": 10,
|
|
204
|
-
"index_repo": 10,
|
|
205
|
-
"get_context_bundle": 3,
|
|
206
|
-
"get_blast_radius": 3,
|
|
207
|
-
"get_repo_outline": 2,
|
|
208
|
-
"find_dead_code": 5
|
|
209
|
-
}
|
|
210
|
-
},
|
|
211
|
-
|
|
212
|
-
"layers": {
|
|
213
|
-
"definitions": [
|
|
214
|
-
{ "name": "core", "paths": ["src/core/**"] },
|
|
215
|
-
{ "name": "handlers", "paths": ["src/handlers/**"] },
|
|
216
|
-
{ "name": "adapters", "paths": ["src/adapters/**"] },
|
|
217
|
-
{ "name": "server", "paths": ["src/server/**"] }
|
|
218
|
-
],
|
|
219
|
-
"rules": [
|
|
220
|
-
{ "from": "core", "to": "handlers", "allowed": false },
|
|
221
|
-
{ "from": "core", "to": "adapters", "allowed": false },
|
|
222
|
-
{ "from": "handlers", "to": "adapters", "allowed": false }
|
|
223
|
-
]
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Key configuration options explained
|
|
229
|
-
|
|
230
|
-
| Option | Default | Description |
|
|
231
|
-
|--------|---------|-------------|
|
|
232
|
-
| `indexDir` | `~/.purecontext/indexes` | Where SQLite databases are stored |
|
|
233
|
-
| `fileLimit` | `1000` | Max files to index per project. Increase for large repos. |
|
|
234
|
-
| `watchDebounceMs` | `2000` | Delay in ms before re-indexing after file changes |
|
|
235
|
-
| `excludePatterns` | `[]` | Additional glob patterns to exclude (on top of built-ins like `node_modules/`, `.git/`) |
|
|
236
|
-
| `adapters` | `"auto"` | `"auto"` detects frameworks automatically; `"none"` disables; or `["vue", "nuxt"]` for explicit list |
|
|
237
|
-
| `maxFileSizeBytes` | `1048576` | Files larger than 1 MB are skipped. Increase if needed. |
|
|
238
|
-
| `allowSymlinks` | `false` | When false, symlinks that resolve outside the project root are blocked |
|
|
239
|
-
| `transport` | `"stdio"` | `"stdio"` for Claude Code; `"http"` for browser/remote; `"both"` for both simultaneously |
|
|
240
|
-
|
|
241
|
-
### Environment variable support in config
|
|
242
|
-
|
|
243
|
-
API keys can reference environment variables:
|
|
244
|
-
|
|
245
|
-
```json
|
|
246
|
-
{
|
|
247
|
-
"ai": {
|
|
248
|
-
"apiKey": "${ANTHROPIC_API_KEY}"
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
## 5. CLI Commands
|
|
256
|
-
|
|
257
|
-
### Start the MCP server (default)
|
|
258
|
-
|
|
259
|
-
```bash
|
|
260
|
-
purecontext-mcp
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
Starts in stdio transport mode — the default for Claude Code integration.
|
|
264
|
-
|
|
265
|
-
### HTTP transport
|
|
266
|
-
|
|
267
|
-
```bash
|
|
268
|
-
purecontext-mcp --transport http
|
|
269
|
-
purecontext-mcp --transport http --port 3001
|
|
270
|
-
purecontext-mcp --transport both
|
|
271
|
-
```
|
|
272
|
-
|
|
273
|
-
CLI flags override `config.json` values.
|
|
274
|
-
|
|
275
|
-
### Configuration commands
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
# Generate a default config.json
|
|
279
|
-
purecontext-mcp config --init
|
|
280
|
-
|
|
281
|
-
# Validate config + check prerequisites
|
|
282
|
-
purecontext-mcp config --check
|
|
283
|
-
|
|
284
|
-
# Show effective configuration (merged with defaults)
|
|
285
|
-
purecontext-mcp config
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
### API key management (for hosted deployments)
|
|
289
|
-
|
|
290
|
-
```bash
|
|
291
|
-
# Create an API key for a tenant
|
|
292
|
-
purecontext-mcp keys create --tenant <tenantId> --permissions read,write
|
|
293
|
-
|
|
294
|
-
# List API keys for a tenant
|
|
295
|
-
purecontext-mcp keys list --tenant <tenantId>
|
|
296
|
-
|
|
297
|
-
# Revoke an API key
|
|
298
|
-
purecontext-mcp keys revoke <key-prefix>
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## 6. MCP Tools Reference
|
|
304
|
-
|
|
305
|
-
All tools return a `_meta` envelope with:
|
|
306
|
-
- `timing_ms` — how long the call took
|
|
307
|
-
- `tokens_saved` — tokens saved vs. reading raw files (where applicable)
|
|
308
|
-
- `total_tokens_saved` — cumulative session total
|
|
309
|
-
- `cost_avoided` — estimated USD saved at current model rates
|
|
310
|
-
- `powered_by: "PureContext MCP"`
|
|
311
|
-
|
|
312
|
-
---
|
|
313
|
-
|
|
314
|
-
### `index_folder`
|
|
315
|
-
|
|
316
|
-
Index a local project directory.
|
|
317
|
-
|
|
318
|
-
```json
|
|
319
|
-
{
|
|
320
|
-
"path": "/path/to/your/project",
|
|
321
|
-
"fileLimit": 1000
|
|
322
|
-
}
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Returns:** `{ repoId, symbolCount, fileCount, duration, languages }`
|
|
326
|
-
|
|
327
|
-
Subsequent calls are incremental — only changed files are re-indexed. The file watcher automatically triggers re-indexing on file changes.
|
|
328
|
-
|
|
329
|
-
---
|
|
330
|
-
|
|
331
|
-
### `index_repo`
|
|
332
|
-
|
|
333
|
-
Clone and index a remote Git repository.
|
|
334
|
-
|
|
335
|
-
```json
|
|
336
|
-
{
|
|
337
|
-
"url": "https://github.com/owner/repo",
|
|
338
|
-
"branch": "main",
|
|
339
|
-
"token": "ghp_...",
|
|
340
|
-
"fileLimit": 5000
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
**Returns:** Same as `index_folder`. The clone is stored under `~/.purecontext/clones/`. Use `delete_index` to remove it.
|
|
345
|
-
|
|
346
|
-
Requires `git` on your `PATH`. Shallow clones (`--depth=1`) are used for efficiency.
|
|
347
|
-
|
|
348
|
-
---
|
|
349
|
-
|
|
350
|
-
### `list_repos`
|
|
351
|
-
|
|
352
|
-
List all indexed repositories.
|
|
353
|
-
|
|
354
|
-
```json
|
|
355
|
-
{}
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
**Returns:** Array of `{ repoId, rootPath, symbolCount, fileCount, languages, indexedAt }`
|
|
359
|
-
|
|
360
|
-
---
|
|
361
|
-
|
|
362
|
-
### `resolve_repo`
|
|
363
|
-
|
|
364
|
-
Get metadata for a specific repository.
|
|
365
|
-
|
|
366
|
-
```json
|
|
367
|
-
{
|
|
368
|
-
"path": "/path/to/project"
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
**Returns:** Repo metadata, or a hint to call `index_folder` if not indexed.
|
|
373
|
-
|
|
374
|
-
---
|
|
375
|
-
|
|
376
|
-
### `search_symbols`
|
|
377
|
-
|
|
378
|
-
Search for symbols by name, kind, or file pattern. The primary tool for code navigation.
|
|
379
|
-
|
|
380
|
-
```json
|
|
381
|
-
{
|
|
382
|
-
"repo": "repoId or path",
|
|
383
|
-
"query": "validateToken",
|
|
384
|
-
"kind": "function",
|
|
385
|
-
"file": "src/auth/**",
|
|
386
|
-
"limit": 20,
|
|
387
|
-
"mode": "keyword"
|
|
388
|
-
}
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
| Parameter | Type | Description |
|
|
392
|
-
|-----------|------|-------------|
|
|
393
|
-
| `query` | string | Name to search for (substring match) |
|
|
394
|
-
| `kind` | string | Filter by symbol kind (see [Symbol Kinds](#symbol-kinds)) |
|
|
395
|
-
| `file` | string | Glob pattern to restrict to specific files |
|
|
396
|
-
| `limit` | number | Max results (default 20) |
|
|
397
|
-
| `mode` | string | `"keyword"` (default), `"semantic"`, or `"hybrid"` |
|
|
398
|
-
|
|
399
|
-
**Returns:** Array of `{ id, name, kind, filePath, signature, summary, score }`
|
|
400
|
-
|
|
401
|
-
Does **not** return source code — use `get_symbol_source` for that.
|
|
402
|
-
|
|
403
|
-
---
|
|
404
|
-
|
|
405
|
-
### `get_symbol_source`
|
|
406
|
-
|
|
407
|
-
Retrieve the full source code of a symbol by ID.
|
|
408
|
-
|
|
409
|
-
```json
|
|
410
|
-
{
|
|
411
|
-
"id": "abc123def456"
|
|
412
|
-
}
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
**Returns:** `{ symbol, source, filePath, startLine, endLine }`
|
|
416
|
-
|
|
417
|
-
Extremely token-efficient: returns only the specific symbol's bytes, not the entire file.
|
|
418
|
-
|
|
419
|
-
---
|
|
420
|
-
|
|
421
|
-
### `get_file_outline`
|
|
422
|
-
|
|
423
|
-
List all symbols in a file with signatures and summaries.
|
|
424
|
-
|
|
425
|
-
```json
|
|
426
|
-
{
|
|
427
|
-
"repo": "repoId or path",
|
|
428
|
-
"file": "src/auth/validator.ts"
|
|
429
|
-
}
|
|
430
|
-
```
|
|
431
|
-
|
|
432
|
-
**Returns:** `{ file, symbols: [{ name, kind, signature, summary, startLine }] }`
|
|
433
|
-
|
|
434
|
-
---
|
|
435
|
-
|
|
436
|
-
### `get_repo_outline`
|
|
437
|
-
|
|
438
|
-
High-level view of all files and their top-level symbols.
|
|
439
|
-
|
|
440
|
-
```json
|
|
441
|
-
{
|
|
442
|
-
"repo": "repoId or path",
|
|
443
|
-
"maxDepth": 2
|
|
444
|
-
}
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
**Returns:** Nested structure of directories → files → top-level symbols.
|
|
448
|
-
|
|
449
|
-
---
|
|
450
|
-
|
|
451
|
-
### `get_file_tree`
|
|
452
|
-
|
|
453
|
-
Directory structure with file counts. Useful for understanding project layout.
|
|
454
|
-
|
|
455
|
-
```json
|
|
456
|
-
{
|
|
457
|
-
"repo": "repoId or path",
|
|
458
|
-
"maxDepth": 3
|
|
459
|
-
}
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
**Returns:** Nested directory/file tree with symbol counts per file.
|
|
463
|
-
|
|
464
|
-
---
|
|
465
|
-
|
|
466
|
-
### `get_context_bundle`
|
|
467
|
-
|
|
468
|
-
Get a symbol plus all of its forward dependencies (what it imports/calls).
|
|
469
|
-
|
|
470
|
-
```json
|
|
471
|
-
{
|
|
472
|
-
"repo": "repoId or path",
|
|
473
|
-
"symbolId": "abc123",
|
|
474
|
-
"depth": 2
|
|
475
|
-
}
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
**Returns:** `{ symbol, dependencies: SymbolRecord[], _tokenEstimate }`
|
|
479
|
-
|
|
480
|
-
Ideal for understanding a symbol in context without reading entire files.
|
|
481
|
-
|
|
482
|
-
---
|
|
483
|
-
|
|
484
|
-
### `get_blast_radius`
|
|
485
|
-
|
|
486
|
-
Reverse dependency analysis — find everything that depends on a symbol.
|
|
487
|
-
|
|
488
|
-
```json
|
|
489
|
-
{
|
|
490
|
-
"repo": "repoId or path",
|
|
491
|
-
"symbolId": "abc123",
|
|
492
|
-
"depth": 3
|
|
493
|
-
}
|
|
494
|
-
```
|
|
495
|
-
|
|
496
|
-
**Returns:** `{ symbol, dependents: SymbolRecord[], _tokenEstimate }`
|
|
497
|
-
|
|
498
|
-
Use before changing a function to understand the impact scope.
|
|
499
|
-
|
|
500
|
-
---
|
|
501
|
-
|
|
502
|
-
### `find_importers`
|
|
503
|
-
|
|
504
|
-
Find all files that import a specific module.
|
|
505
|
-
|
|
506
|
-
```json
|
|
507
|
-
{
|
|
508
|
-
"repo": "repoId or path",
|
|
509
|
-
"file": "src/utils/auth.ts"
|
|
510
|
-
}
|
|
511
|
-
```
|
|
512
|
-
|
|
513
|
-
**Returns:** `{ importers: [{ file, symbols }] }`
|
|
514
|
-
|
|
515
|
-
---
|
|
516
|
-
|
|
517
|
-
### `find_dead_code`
|
|
518
|
-
|
|
519
|
-
Find exported symbols with zero importers — potential dead code.
|
|
520
|
-
|
|
521
|
-
```json
|
|
522
|
-
{
|
|
523
|
-
"repo": "repoId or path"
|
|
524
|
-
}
|
|
525
|
-
```
|
|
526
|
-
|
|
527
|
-
**Returns:** `{ deadSymbols: SymbolRecord[] }`
|
|
528
|
-
|
|
529
|
-
---
|
|
530
|
-
|
|
531
|
-
### `search_text`
|
|
532
|
-
|
|
533
|
-
Full-text search across raw file content (like grep, but from the index).
|
|
534
|
-
|
|
535
|
-
```json
|
|
536
|
-
{
|
|
537
|
-
"repo": "repoId or path",
|
|
538
|
-
"query": "validateToken(",
|
|
539
|
-
"is_regex": false,
|
|
540
|
-
"file_pattern": "**/*.ts",
|
|
541
|
-
"context_lines": 2,
|
|
542
|
-
"max_results": 50
|
|
543
|
-
}
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
**Returns:** `{ matches: [{ file, line, column, match, context }], truncated }`
|
|
547
|
-
|
|
548
|
-
Uses cached content — no live file reads. Supports regular expressions when `is_regex: true`.
|
|
549
|
-
|
|
550
|
-
---
|
|
551
|
-
|
|
552
|
-
### `search_semantic`
|
|
553
|
-
|
|
554
|
-
Semantic (meaning-based) search using embeddings. Finds conceptually related symbols even when no literal string matches.
|
|
555
|
-
|
|
556
|
-
```json
|
|
557
|
-
{
|
|
558
|
-
"repo": "repoId or path",
|
|
559
|
-
"query": "functions that validate user credentials",
|
|
560
|
-
"mode": "hybrid",
|
|
561
|
-
"semantic_weight": 0.6,
|
|
562
|
-
"keyword_weight": 0.4,
|
|
563
|
-
"max_results": 10,
|
|
564
|
-
"kind": "function"
|
|
565
|
-
}
|
|
566
|
-
```
|
|
567
|
-
|
|
568
|
-
**Returns:** `{ results: [{ ...symbol, scores: { keyword, semantic, combined } }] }`
|
|
569
|
-
|
|
570
|
-
Requires semantic search to be enabled and an embedding provider configured. Falls back to FTS keyword search if no semantic index exists.
|
|
571
|
-
|
|
572
|
-
---
|
|
573
|
-
|
|
574
|
-
### `get_layer_violations`
|
|
575
|
-
|
|
576
|
-
Analyze architectural dependency violations based on configured layer rules.
|
|
577
|
-
|
|
578
|
-
```json
|
|
579
|
-
{
|
|
580
|
-
"repo": "repoId or path",
|
|
581
|
-
"layers": [
|
|
582
|
-
{ "name": "core", "paths": ["src/core/**"] },
|
|
583
|
-
{ "name": "handlers", "paths": ["src/handlers/**"] }
|
|
584
|
-
]
|
|
585
|
-
}
|
|
586
|
-
```
|
|
587
|
-
|
|
588
|
-
**Returns:** `{ violations: [{ from_layer, to_layer, from_file, to_file, import_spec }], summary }`
|
|
589
|
-
|
|
590
|
-
If `layers` is omitted, reads from `config.json`. Useful for enforcing clean architecture.
|
|
591
|
-
|
|
592
|
-
---
|
|
593
|
-
|
|
594
|
-
### `get_savings_stats`
|
|
595
|
-
|
|
596
|
-
View cumulative token savings across all PureContext tool calls.
|
|
597
|
-
|
|
598
|
-
```json
|
|
599
|
-
{
|
|
600
|
-
"reset": false
|
|
601
|
-
}
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
**Returns:**
|
|
605
|
-
```json
|
|
606
|
-
{
|
|
607
|
-
"total_tokens_saved": 123456,
|
|
608
|
-
"equivalent_context_windows": { "claude_200k": 0.62, "gpt4_128k": 0.96 },
|
|
609
|
-
"total_cost_avoided": {
|
|
610
|
-
"claude_opus_4": 1.85,
|
|
611
|
-
"claude_sonnet_4": 0.37,
|
|
612
|
-
"claude_haiku_4": 0.10,
|
|
613
|
-
"gpt4o": 0.31,
|
|
614
|
-
"gpt4o_mini": 0.02
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
Set `reset: true` to clear the counter.
|
|
620
|
-
|
|
621
|
-
---
|
|
622
|
-
|
|
623
|
-
### Symbol Kinds
|
|
624
|
-
|
|
625
|
-
The `kind` parameter in search accepts any of these values:
|
|
626
|
-
|
|
627
|
-
| Kind | Description |
|
|
628
|
-
|------|-------------|
|
|
629
|
-
| `function` | Standalone function / top-level def |
|
|
630
|
-
| `class` | Class, struct (Go/Rust), or OOP type |
|
|
631
|
-
| `method` | Method inside a class/struct/impl |
|
|
632
|
-
| `const` | Constant, exported variable, field |
|
|
633
|
-
| `type` | Type alias, typedef, newtype |
|
|
634
|
-
| `interface` | Interface or protocol |
|
|
635
|
-
| `enum` | Enumeration |
|
|
636
|
-
| `component` | UI component (Vue, React, Angular) |
|
|
637
|
-
| `composable` | Vue composable (`useXxx`) |
|
|
638
|
-
| `hook` | React hook (`useXxx`) |
|
|
639
|
-
| `route` | HTTP route (any framework) |
|
|
640
|
-
| `middleware` | Middleware or guard |
|
|
641
|
-
| `decorator` | Decorator / annotation |
|
|
642
|
-
| `model` | ORM model (Django, Rails, Laravel, Hibernate, SQLAlchemy) |
|
|
643
|
-
| `view` | Request handler / controller action |
|
|
644
|
-
| `struct` | C/C++ struct (distinct from class) |
|
|
645
|
-
| `macro` | C/C++ `#define` macro |
|
|
646
|
-
| `signal` | Django signal receiver |
|
|
647
|
-
| `namespace` | C++ namespace |
|
|
648
|
-
| `widget` | Flutter widget |
|
|
649
|
-
|
|
650
|
-
---
|
|
651
|
-
|
|
652
|
-
## 7. Language Support
|
|
653
|
-
|
|
654
|
-
PureContext supports 19 languages via tree-sitter AST parsing.
|
|
655
|
-
|
|
656
|
-
### Full symbol extraction
|
|
657
|
-
|
|
658
|
-
| Language | Extensions | Symbol Types | Doc Comments |
|
|
659
|
-
|----------|-----------|--------------|--------------|
|
|
660
|
-
| **TypeScript** | `.ts`, `.tsx`, `.mts`, `.cts` | function, class, method, const, type, interface, enum | JSDoc `/** */` |
|
|
661
|
-
| **JavaScript** | `.js`, `.jsx`, `.mjs`, `.cjs` | function, class, method, const | JSDoc `/** */` |
|
|
662
|
-
| **Python** | `.py` | function, class, method, const | Docstrings `"""` |
|
|
663
|
-
| **Go** | `.go` | function, method, class (struct), interface, const, type | `//` preceding comments |
|
|
664
|
-
| **Rust** | `.rs` | function, method, class (struct), enum, interface (trait), const, type | `///` doc comments |
|
|
665
|
-
| **Java** | `.java` | class, interface, enum, method, const | Javadoc `/** */` |
|
|
666
|
-
| **C#** | `.cs` | class, interface, enum, struct, record, method, const, property | XML docs `/// <summary>` |
|
|
667
|
-
| **PHP** | `.php` | function, class, interface, trait, enum, method, const | PHPDoc `/** */` |
|
|
668
|
-
| **Ruby** | `.rb` | function, class, method, module, const | `#` comments |
|
|
669
|
-
| **Kotlin** | `.kt`, `.kts` | function, class, interface, enum, method, typealias, object | KDoc `/**` |
|
|
670
|
-
| **C** | `.c`, `.h` | function, struct, enum, macro, type | `//` and `/* */` |
|
|
671
|
-
| **C++** | `.cpp`, `.cxx`, `.cc`, `.hpp`, `.hxx`, `.hh` | All C types + namespace, template | `///` Doxygen |
|
|
672
|
-
| **Lua** | `.lua` | function, method, const | `--` comments |
|
|
673
|
-
| **Dart** | `.dart` | class, mixin, extension, enum, function, method, const, type | `///` doc comments |
|
|
674
|
-
| **Swift** | `.swift` | class, struct, protocol, actor, extension, method, enum, type | `///` DocC |
|
|
675
|
-
| **Elixir** | `.ex`, `.exs` | module (class), function, macro, struct, protocol | `@doc` attribute |
|
|
676
|
-
| **Haskell** | `.hs`, `.lhs` | function, data (class), typeclass (interface), instance, type, newtype | Haddock `-- \|` |
|
|
677
|
-
| **Scala** | `.scala`, `.sc` | class, trait, object, case class, function, method, type, enum | Scaladoc `/** */` |
|
|
678
|
-
| **R** | `.r`, `.R`, `.Rmd` | function, const, S3/S4/R6 class | Roxygen2 `#'` |
|
|
679
|
-
|
|
680
|
-
### What gets indexed
|
|
681
|
-
|
|
682
|
-
- **All non-private symbols** by default (exact visibility rules vary by language)
|
|
683
|
-
- **Byte offsets** for precise source retrieval
|
|
684
|
-
- **Import/dependency edges** for the dependency graph
|
|
685
|
-
- **Docstrings** as symbol summaries (stage 1 of the summarizer pipeline)
|
|
686
|
-
|
|
687
|
-
### What is excluded automatically
|
|
688
|
-
|
|
689
|
-
- `node_modules/`, `.git/`, `dist/`, `build/`, `.claude/`
|
|
690
|
-
- `*.lock` files, `.env*` files
|
|
691
|
-
- Binary files (detected by null-byte scanning)
|
|
692
|
-
- Files > 1 MB (configurable)
|
|
693
|
-
- Secret files: `*.pem`, `*.key`, `id_rsa`, `credentials.json`, etc.
|
|
694
|
-
- `private` methods in Java, C#, PHP (language-specific visibility rules)
|
|
695
|
-
- Unexported symbols in Go (lowercase names)
|
|
696
|
-
- `static` functions in C (translation-unit internal)
|
|
697
|
-
- Private (`_`-prefixed) symbols in Dart
|
|
698
|
-
|
|
699
|
-
---
|
|
700
|
-
|
|
701
|
-
## 8. Framework Adapters
|
|
702
|
-
|
|
703
|
-
Framework adapters run on top of language handlers and extract framework-specific metadata. They are auto-detected from project config files.
|
|
704
|
-
|
|
705
|
-
### JavaScript / TypeScript Frameworks
|
|
706
|
-
|
|
707
|
-
#### Vue 3
|
|
708
|
-
**Detected by:** `vue` in `package.json`, or any `.vue` files present.
|
|
709
|
-
|
|
710
|
-
Extracts from `.vue` Single File Components:
|
|
711
|
-
- `component` — the component itself (from filename or `defineComponent`)
|
|
712
|
-
- `composable` — exported `use*` functions
|
|
713
|
-
|
|
714
|
-
`frameworkMeta` includes: `vue_component`, `vue_composable`.
|
|
715
|
-
|
|
716
|
-
#### Nuxt
|
|
717
|
-
**Detected by:** `nuxt.config.ts` (or `.js`/`.mts`/`.mjs`) in project root.
|
|
718
|
-
|
|
719
|
-
Extracts:
|
|
720
|
-
- `route` from `pages/**/*.vue` (with derived route path like `/blog/:slug`)
|
|
721
|
-
- `route` from `server/api/**/*.ts` (with HTTP method from filename suffix)
|
|
722
|
-
- `middleware` from `plugins/**` and `middleware/**`
|
|
723
|
-
- Enriches composables in `composables/**` with `nuxt_auto_import: true`
|
|
724
|
-
|
|
725
|
-
#### React
|
|
726
|
-
**Detected by:** `react` in `package.json` dependencies.
|
|
727
|
-
|
|
728
|
-
Enriches TypeScript handler symbols:
|
|
729
|
-
- PascalCase functions returning JSX → `component`
|
|
730
|
-
- `use*` functions → `hook`
|
|
731
|
-
|
|
732
|
-
#### Next.js
|
|
733
|
-
**Detected by:** `next.config.*` or `next` in `package.json`.
|
|
734
|
-
|
|
735
|
-
Extracts:
|
|
736
|
-
- **Pages Router** (`pages/**`): `route` symbols with path derivation
|
|
737
|
-
- `pages/blog/[slug].tsx` → `/blog/:slug`
|
|
738
|
-
- Detects `getServerSideProps` (SSR), `getStaticProps` (SSG)
|
|
739
|
-
- **App Router** (`app/**/page.tsx`): `route` symbols
|
|
740
|
-
- `app/(marketing)/about/page.tsx` → `/about` (route groups stripped)
|
|
741
|
-
- Detects `'use client'` directive
|
|
742
|
-
- **API routes**: `pages/api/**` and `app/**/route.ts` (with HTTP method exports)
|
|
743
|
-
- **Middleware** (`middleware.ts`): `middleware` symbol with matcher
|
|
744
|
-
|
|
745
|
-
#### Angular
|
|
746
|
-
**Detected by:** `@angular/core` in `package.json`.
|
|
747
|
-
|
|
748
|
-
Extracts from decorated classes:
|
|
749
|
-
- `@Component` → `component` (with `selector`)
|
|
750
|
-
- `@Injectable` → `class` (service)
|
|
751
|
-
- `@NgModule` → `class` (module)
|
|
752
|
-
- `@Directive` → `component` (with `selector`)
|
|
753
|
-
- `@Pipe` → `component` (with pipe name)
|
|
754
|
-
- `RouterModule.forRoot/forChild` → `route` symbols
|
|
755
|
-
|
|
756
|
-
#### NestJS
|
|
757
|
-
**Detected by:** `@nestjs/core` in `package.json`.
|
|
758
|
-
|
|
759
|
-
Extracts from decorated controllers:
|
|
760
|
-
- `@Controller('prefix')` + `@Get(':id')` → `route` with combined path (`GET /prefix/:id`)
|
|
761
|
-
- `@Injectable` → `class` with `nestjs_provider: true`
|
|
762
|
-
- `@Module` → `class` with `nestjs_module: true`
|
|
763
|
-
- `@Guard` / `CanActivate` → `middleware`
|
|
764
|
-
|
|
765
|
-
#### Express
|
|
766
|
-
**Detected by:** `express` in `package.json`.
|
|
767
|
-
|
|
768
|
-
Extracts string-literal route registrations:
|
|
769
|
-
- `app.get('/path', ...)` → `route`
|
|
770
|
-
- `router.post('/path', ...)` → `route`
|
|
771
|
-
- `app.use('/path', ...)` → `middleware`
|
|
772
|
-
|
|
773
|
-
Dynamic paths (variables, template literals) are skipped.
|
|
774
|
-
|
|
775
|
-
#### Fastify
|
|
776
|
-
**Detected by:** `fastify` in `package.json`.
|
|
777
|
-
|
|
778
|
-
Same pattern as Express: `fastify.get(path, ...)` → `route`.
|
|
779
|
-
|
|
780
|
-
---
|
|
781
|
-
|
|
782
|
-
### Python Frameworks
|
|
783
|
-
|
|
784
|
-
#### Flask
|
|
785
|
-
**Detected by:** `Flask` in `requirements.txt` or `pyproject.toml`.
|
|
786
|
-
|
|
787
|
-
Extracts:
|
|
788
|
-
- `@app.route('/path')` → `route`
|
|
789
|
-
- `@app.get('/path')`, `@app.post(...)` → `route`
|
|
790
|
-
- Blueprint routes: `@bp.route(...)` → `route`
|
|
791
|
-
- Class-based views (inheriting `MethodView`) → `view`
|
|
792
|
-
|
|
793
|
-
Flask path parameters (`<int:user_id>`) are preserved as-is.
|
|
794
|
-
|
|
795
|
-
#### FastAPI
|
|
796
|
-
**Detected by:** `fastapi` in `requirements.txt` or `pyproject.toml`.
|
|
797
|
-
|
|
798
|
-
Extracts:
|
|
799
|
-
- `@app.get('/items/{id}')` → `route`
|
|
800
|
-
- `@router.post(...)` (APIRouter) → `route`
|
|
801
|
-
|
|
802
|
-
FastAPI path parameters (`{param}`) are preserved as-is.
|
|
803
|
-
|
|
804
|
-
#### Django
|
|
805
|
-
**Detected by:** `manage.py` at project root, or `django` in requirements.
|
|
806
|
-
|
|
807
|
-
Extracts:
|
|
808
|
-
- `models.Model` subclasses → `model`
|
|
809
|
-
- Class-based views (`APIView`, `ViewSet`, etc.) → `view`
|
|
810
|
-
- Function-based views (with `@login_required`, `@api_view`) → `view`
|
|
811
|
-
- `path(...)` / `re_path(...)` in `urls.py` → `route`
|
|
812
|
-
- `@receiver(post_save)` → `signal`
|
|
813
|
-
|
|
814
|
-
---
|
|
815
|
-
|
|
816
|
-
### Go Frameworks
|
|
817
|
-
|
|
818
|
-
#### Gin
|
|
819
|
-
**Detected by:** `github.com/gin-gonic/gin` in `go.mod`.
|
|
820
|
-
|
|
821
|
-
Extracts: `r.GET("/path", handler)`, `r.POST(...)`, etc. → `route`
|
|
822
|
-
Groups: `r.Group("/api")` prefix applied to child routes.
|
|
823
|
-
|
|
824
|
-
#### Echo
|
|
825
|
-
**Detected by:** `github.com/labstack/echo` in `go.mod`.
|
|
826
|
-
|
|
827
|
-
Same pattern as Gin: `e.GET("/path", handler)` → `route`.
|
|
828
|
-
|
|
829
|
-
#### Fiber
|
|
830
|
-
**Detected by:** `github.com/gofiber/fiber` in `go.mod`.
|
|
831
|
-
|
|
832
|
-
Uses title-case methods: `app.Get("/path", handler)` → `route`.
|
|
833
|
-
|
|
834
|
-
---
|
|
835
|
-
|
|
836
|
-
### PHP Frameworks
|
|
837
|
-
|
|
838
|
-
#### Laravel
|
|
839
|
-
**Detected by:** `laravel/framework` in `composer.json`.
|
|
840
|
-
|
|
841
|
-
Extracts:
|
|
842
|
-
- `Route::get('/path', ...)` → `route`
|
|
843
|
-
- `Route::resource('users', Controller::class)` → multiple CRUD routes
|
|
844
|
-
- `Route::group(['prefix' => '/api'], ...)` → prefix applied to children
|
|
845
|
-
- `User extends Model` → `model`
|
|
846
|
-
- Controller public methods → `view`
|
|
847
|
-
- Middleware classes → `middleware`
|
|
848
|
-
|
|
849
|
-
#### Symfony
|
|
850
|
-
**Detected by:** `symfony/framework-bundle` in `composer.json`.
|
|
851
|
-
|
|
852
|
-
Extracts:
|
|
853
|
-
- `#[Route('/path', methods: ['GET'])]` → `route` (PHP 8 attributes)
|
|
854
|
-
- `@Route('/path')` in docblock → `route` (annotation style)
|
|
855
|
-
- `#[AsController]` or `AbstractController` subclasses → controller
|
|
856
|
-
|
|
857
|
-
---
|
|
858
|
-
|
|
859
|
-
### Ruby Frameworks
|
|
860
|
-
|
|
861
|
-
#### Rails
|
|
862
|
-
**Detected by:** `gem 'rails'` in `Gemfile`.
|
|
863
|
-
|
|
864
|
-
Extracts:
|
|
865
|
-
- `ApplicationRecord` subclasses → `model` (with `has_many` associations)
|
|
866
|
-
- `ApplicationController` subclasses → `class` (controller)
|
|
867
|
-
- Controller public methods → `view` (action)
|
|
868
|
-
- `get '/path'`, `resources :users` in `routes.rb` → `route`
|
|
869
|
-
|
|
870
|
-
#### Sinatra
|
|
871
|
-
**Detected by:** `gem 'sinatra'` in `Gemfile` or `require 'sinatra'` in source.
|
|
872
|
-
|
|
873
|
-
Extracts: `get '/path' do ... end` → `route`
|
|
874
|
-
|
|
875
|
-
---
|
|
876
|
-
|
|
877
|
-
### Kotlin Frameworks
|
|
878
|
-
|
|
879
|
-
#### Ktor
|
|
880
|
-
**Detected by:** `io.ktor` in `build.gradle` / `pom.xml`.
|
|
881
|
-
|
|
882
|
-
Extracts from routing DSL:
|
|
883
|
-
- `get("/path") { ... }` → `route`
|
|
884
|
-
- `route("/api") { get("/users") }` → combined path `/api/users`
|
|
885
|
-
- `authenticate { ... }` → `frameworkMeta.authenticated: true`
|
|
886
|
-
|
|
887
|
-
#### Spring (Kotlin)
|
|
888
|
-
**Detected by:** `org.springframework.boot` in `build.gradle` / `pom.xml`.
|
|
889
|
-
|
|
890
|
-
Extracts:
|
|
891
|
-
- `@RestController` + `@GetMapping("/path")` → `route`
|
|
892
|
-
- `@Service`, `@Component`, `@Repository` → class with metadata
|
|
893
|
-
|
|
894
|
-
---
|
|
895
|
-
|
|
896
|
-
### Rust Frameworks
|
|
897
|
-
|
|
898
|
-
#### Axum
|
|
899
|
-
**Detected by:** `axum` in `Cargo.toml` dependencies.
|
|
900
|
-
|
|
901
|
-
Extracts: `.route("/path", get(handler))` chains → `route`
|
|
902
|
-
Layers: `.layer(...)` → `middleware`
|
|
903
|
-
|
|
904
|
-
#### Actix-web
|
|
905
|
-
**Detected by:** `actix-web` in `Cargo.toml`.
|
|
906
|
-
|
|
907
|
-
Extracts:
|
|
908
|
-
- `#[get("/path")]` attribute macro → `route`
|
|
909
|
-
- `web::resource("/path").route(web::get().to(handler))` → `route`
|
|
910
|
-
- `.wrap(...)` → `middleware`
|
|
911
|
-
|
|
912
|
-
#### Rocket
|
|
913
|
-
**Detected by:** `rocket` in `Cargo.toml`.
|
|
914
|
-
|
|
915
|
-
Extracts:
|
|
916
|
-
- `#[get("/path")]` → `route`
|
|
917
|
-
- `#[catch(404)]` → error catcher
|
|
918
|
-
- `Fairing` implementations → `middleware`
|
|
919
|
-
|
|
920
|
-
---
|
|
921
|
-
|
|
922
|
-
### Java Frameworks
|
|
923
|
-
|
|
924
|
-
#### Spring Boot
|
|
925
|
-
**Detected by:** `spring-boot-starter` in `pom.xml` / `build.gradle`.
|
|
926
|
-
|
|
927
|
-
Extracts:
|
|
928
|
-
- `@GetMapping`, `@PostMapping`, etc. (combined with `@RequestMapping` prefix) → `route`
|
|
929
|
-
- `@Service`, `@Component`, `@Repository` → bean classes
|
|
930
|
-
- `@Bean` methods → bean symbols
|
|
931
|
-
- `@Scheduled` methods → scheduled tasks
|
|
932
|
-
|
|
933
|
-
#### Micronaut
|
|
934
|
-
**Detected by:** `io.micronaut` in build files.
|
|
935
|
-
|
|
936
|
-
Extracts: `@Get("/path")`, `@Post(...)` → `route`; `@Client` interfaces → `interface`.
|
|
937
|
-
|
|
938
|
-
#### Quarkus
|
|
939
|
-
**Detected by:** `io.quarkus` in build files.
|
|
940
|
-
|
|
941
|
-
Extracts: JAX-RS `@GET` / `@Path` → `route`; `@ApplicationScoped` → bean.
|
|
942
|
-
|
|
943
|
-
---
|
|
944
|
-
|
|
945
|
-
### ORM Adapters
|
|
946
|
-
|
|
947
|
-
#### Hibernate (Java)
|
|
948
|
-
**Detected by:** `hibernate-core` or `jakarta.persistence` in dependencies.
|
|
949
|
-
|
|
950
|
-
Extracts from `@Entity` classes:
|
|
951
|
-
- Table name (from `@Table(name = "...")` or class name)
|
|
952
|
-
- Columns with types and nullability
|
|
953
|
-
- Relationships (`@OneToMany`, `@ManyToOne`, etc.)
|
|
954
|
-
- Named queries (`@NamedQuery`)
|
|
955
|
-
|
|
956
|
-
#### SQLAlchemy (Python)
|
|
957
|
-
**Detected by:** `sqlalchemy` in requirements.
|
|
958
|
-
|
|
959
|
-
Extracts from `Base` / `DeclarativeBase` subclasses:
|
|
960
|
-
- `__tablename__` attribute
|
|
961
|
-
- `Column(Type)` fields with types and constraints
|
|
962
|
-
- `relationship()` associations
|
|
963
|
-
- `@hybrid_property` methods
|
|
964
|
-
|
|
965
|
-
Supports both SQLAlchemy 1.x and 2.0 (`mapped_column`) styles.
|
|
966
|
-
|
|
967
|
-
#### Django ORM
|
|
968
|
-
**Detected by:** Django project with `manage.py`.
|
|
969
|
-
|
|
970
|
-
Extracts from `models.py` files:
|
|
971
|
-
- `models.Model` subclasses with table names
|
|
972
|
-
- Field types: `CharField`, `IntegerField`, `ForeignKey`, `ManyToManyField`, etc.
|
|
973
|
-
- `on_delete` constraint metadata
|
|
974
|
-
- Custom managers
|
|
975
|
-
|
|
976
|
-
---
|
|
977
|
-
|
|
978
|
-
### Mobile Frameworks
|
|
979
|
-
|
|
980
|
-
#### Flutter
|
|
981
|
-
**Detected by:** `sdk: flutter` in `pubspec.yaml`.
|
|
982
|
-
|
|
983
|
-
Extracts from `.dart` files:
|
|
984
|
-
- `StatelessWidget` subclasses → `widget` (with `flutter_widget_type: 'stateless'`)
|
|
985
|
-
- `StatefulWidget` subclasses → `widget` (with linked State class)
|
|
986
|
-
- `ChangeNotifier` subclasses → `class` (with `flutter_notifier: true`)
|
|
987
|
-
|
|
988
|
-
Test files (`*_test.dart`) are excluded from widget extraction.
|
|
989
|
-
|
|
990
|
-
---
|
|
991
|
-
|
|
992
|
-
## 9. Transport Modes
|
|
993
|
-
|
|
994
|
-
### stdio (default)
|
|
995
|
-
|
|
996
|
-
The standard transport for Claude Code and other MCP-native clients.
|
|
997
|
-
|
|
998
|
-
```bash
|
|
999
|
-
purecontext-mcp
|
|
1000
|
-
```
|
|
1001
|
-
|
|
1002
|
-
No network exposure. Communication happens via stdin/stdout.
|
|
1003
|
-
|
|
1004
|
-
**Claude Code configuration:**
|
|
1005
|
-
```bash
|
|
1006
|
-
claude mcp add purecontext-mcp purecontext-mcp
|
|
1007
|
-
```
|
|
1008
|
-
|
|
1009
|
-
### HTTP / Streamable HTTP
|
|
1010
|
-
|
|
1011
|
-
For browser-based clients, remote development, or multi-client setups.
|
|
1012
|
-
|
|
1013
|
-
```bash
|
|
1014
|
-
purecontext-mcp --transport http --port 3000
|
|
1015
|
-
```
|
|
1016
|
-
|
|
1017
|
-
```json
|
|
1018
|
-
// config.json
|
|
1019
|
-
{
|
|
1020
|
-
"transport": "http",
|
|
1021
|
-
"http": {
|
|
1022
|
-
"port": 3000,
|
|
1023
|
-
"host": "127.0.0.1",
|
|
1024
|
-
"corsOrigins": ["http://localhost:*"]
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
```
|
|
1028
|
-
|
|
1029
|
-
**Endpoints:**
|
|
1030
|
-
- `GET /health` — Server health check (always public)
|
|
1031
|
-
- `GET /sse` — MCP SSE stream
|
|
1032
|
-
- `POST /message` — MCP message handler
|
|
1033
|
-
- `GET /` — Web UI (when built)
|
|
1034
|
-
|
|
1035
|
-
**Claude Code + HTTP:**
|
|
1036
|
-
Add to your Claude Code MCP config:
|
|
1037
|
-
```json
|
|
1038
|
-
{
|
|
1039
|
-
"mcpServers": {
|
|
1040
|
-
"purecontext": {
|
|
1041
|
-
"transport": "http",
|
|
1042
|
-
"url": "http://localhost:3000/sse"
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
### Both (development mode)
|
|
1049
|
-
|
|
1050
|
-
Runs stdio and HTTP simultaneously:
|
|
1051
|
-
|
|
1052
|
-
```bash
|
|
1053
|
-
purecontext-mcp --transport both
|
|
1054
|
-
```
|
|
1055
|
-
|
|
1056
|
-
### HTTP Authentication
|
|
1057
|
-
|
|
1058
|
-
When deploying on a non-loopback address, enable bearer token authentication:
|
|
1059
|
-
|
|
1060
|
-
```json
|
|
1061
|
-
{
|
|
1062
|
-
"http": {
|
|
1063
|
-
"host": "0.0.0.0",
|
|
1064
|
-
"auth": {
|
|
1065
|
-
"enabled": true,
|
|
1066
|
-
"token": "${PURECONTEXT_API_TOKEN}"
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
}
|
|
1070
|
-
```
|
|
1071
|
-
|
|
1072
|
-
If `token` is empty with `enabled: true`, a random 32-byte hex token is generated at startup and printed to stderr. Save it.
|
|
1073
|
-
|
|
1074
|
-
All MCP requests must include: `Authorization: Bearer <token>`
|
|
1075
|
-
|
|
1076
|
-
---
|
|
1077
|
-
|
|
1078
|
-
## 10. AI Summarization
|
|
1079
|
-
|
|
1080
|
-
PureContext can generate natural-language summaries for symbols that have no docstring, using a multi-stage fallback:
|
|
1081
|
-
|
|
1082
|
-
1. **Stage 1** — Docstring (JSDoc, Python docstring, `///`, `@doc`, etc.)
|
|
1083
|
-
2. **Stage 2** — Framework-derived: `"Vue component UserCard"`, `"GET /api/users server route"`
|
|
1084
|
-
3. **Stage 3** — AI batch summarization (optional, requires config)
|
|
1085
|
-
4. **Stage 4** — Signature fallback: `"function validateToken(token: string): boolean"`
|
|
1086
|
-
|
|
1087
|
-
### Enable AI summarization
|
|
1088
|
-
|
|
1089
|
-
**Using Anthropic (Claude Haiku):**
|
|
1090
|
-
|
|
1091
|
-
```json
|
|
1092
|
-
{
|
|
1093
|
-
"ai": {
|
|
1094
|
-
"provider": "anthropic",
|
|
1095
|
-
"allowRemoteAI": true,
|
|
1096
|
-
"apiKey": "${ANTHROPIC_API_KEY}",
|
|
1097
|
-
"model": "claude-haiku-4-5-20251001",
|
|
1098
|
-
"batchSize": 50
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
```
|
|
1102
|
-
|
|
1103
|
-
**Using a local Ollama model:**
|
|
1104
|
-
|
|
1105
|
-
```json
|
|
1106
|
-
{
|
|
1107
|
-
"ai": {
|
|
1108
|
-
"provider": "openai-compatible",
|
|
1109
|
-
"allowRemoteAI": true,
|
|
1110
|
-
"endpoint": "http://localhost:11434",
|
|
1111
|
-
"model": "llama3.2",
|
|
1112
|
-
"batchSize": 10
|
|
1113
|
-
}
|
|
1114
|
-
}
|
|
1115
|
-
```
|
|
1116
|
-
|
|
1117
|
-
AI summarization is **always optional**. With `allowRemoteAI: false` (the default), no network calls are made and all tests pass.
|
|
1118
|
-
|
|
1119
|
-
Summaries are generated post-indexing in batches. On incremental re-index, changed symbols get their summaries refreshed.
|
|
1120
|
-
|
|
1121
|
-
---
|
|
1122
|
-
|
|
1123
|
-
## 11. Semantic Search (HNSW)
|
|
1124
|
-
|
|
1125
|
-
Semantic search uses embedding vectors and HNSW (Hierarchical Navigable Small Worlds) indexing to find symbols by meaning, not just keywords.
|
|
1126
|
-
|
|
1127
|
-
**When is it active?**
|
|
1128
|
-
- `semantic.enabled: true` in config
|
|
1129
|
-
- Repository has more than `semantic.threshold` symbols (default: 50,000)
|
|
1130
|
-
- An embedding provider is configured
|
|
1131
|
-
|
|
1132
|
-
**Below the threshold**, all search uses SQLite FTS5 keyword search.
|
|
1133
|
-
|
|
1134
|
-
### Enable semantic search
|
|
1135
|
-
|
|
1136
|
-
**Using OpenAI embeddings:**
|
|
1137
|
-
|
|
1138
|
-
```json
|
|
1139
|
-
{
|
|
1140
|
-
"semantic": {
|
|
1141
|
-
"enabled": true,
|
|
1142
|
-
"provider": "openai",
|
|
1143
|
-
"threshold": 50000
|
|
1144
|
-
},
|
|
1145
|
-
"ai": {
|
|
1146
|
-
"openaiApiKey": "${OPENAI_API_KEY}"
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
```
|
|
1150
|
-
|
|
1151
|
-
**Using local Ollama embeddings:**
|
|
1152
|
-
|
|
1153
|
-
```json
|
|
1154
|
-
{
|
|
1155
|
-
"semantic": {
|
|
1156
|
-
"enabled": true,
|
|
1157
|
-
"provider": "local",
|
|
1158
|
-
"localEmbeddingEndpoint": "http://localhost:11434",
|
|
1159
|
-
"threshold": 1000
|
|
1160
|
-
}
|
|
1161
|
-
}
|
|
1162
|
-
```
|
|
1163
|
-
|
|
1164
|
-
Set `threshold` low (e.g., 100) to test on small repos.
|
|
1165
|
-
|
|
1166
|
-
### Using semantic search
|
|
1167
|
-
|
|
1168
|
-
Via `search_semantic` tool:
|
|
1169
|
-
|
|
1170
|
-
```json
|
|
1171
|
-
{
|
|
1172
|
-
"repo": "my-project",
|
|
1173
|
-
"query": "functions that validate user credentials",
|
|
1174
|
-
"mode": "hybrid",
|
|
1175
|
-
"semantic_weight": 0.6,
|
|
1176
|
-
"keyword_weight": 0.4
|
|
1177
|
-
}
|
|
1178
|
-
```
|
|
1179
|
-
|
|
1180
|
-
Via `search_symbols` tool (automatic hybrid mode when index exists):
|
|
1181
|
-
|
|
1182
|
-
```json
|
|
1183
|
-
{
|
|
1184
|
-
"repo": "my-project",
|
|
1185
|
-
"query": "auth validate",
|
|
1186
|
-
"mode": "hybrid"
|
|
1187
|
-
}
|
|
1188
|
-
```
|
|
1189
|
-
|
|
1190
|
-
### How hybrid search works
|
|
1191
|
-
|
|
1192
|
-
1. Run FTS keyword search → top N results
|
|
1193
|
-
2. Embed the query → run HNSW vector search → top N results
|
|
1194
|
-
3. Merge using Reciprocal Rank Fusion (RRF):
|
|
1195
|
-
`score = keywordWeight × (1/(60+rank)) + semanticWeight × (1/(60+rank))`
|
|
1196
|
-
4. Return top results sorted by combined score
|
|
1197
|
-
|
|
1198
|
-
### Performance
|
|
1199
|
-
|
|
1200
|
-
- HNSW search: < 10ms for k=10 in a 100k vector index
|
|
1201
|
-
- Embedding generation: batched, ~50ms per symbol
|
|
1202
|
-
- Indexes are persisted to `~/.purecontext/indexes/{repoId}/hnsw.idx`
|
|
1203
|
-
|
|
1204
|
-
---
|
|
1205
|
-
|
|
1206
|
-
## 12. Token Savings Tracker
|
|
1207
|
-
|
|
1208
|
-
Every retrieval tool call automatically tracks how many tokens were saved compared to reading full files.
|
|
1209
|
-
|
|
1210
|
-
### How savings are calculated
|
|
1211
|
-
|
|
1212
|
-
```
|
|
1213
|
-
tokens_saved = max(0, (rawFileBytes - responseBytes) / 4)
|
|
1214
|
-
```
|
|
1215
|
-
|
|
1216
|
-
The `4 bytes/token` ratio is the cl100k_base encoding approximation.
|
|
1217
|
-
|
|
1218
|
-
### Viewing savings
|
|
1219
|
-
|
|
1220
|
-
Use the `get_savings_stats` tool:
|
|
1221
|
-
|
|
1222
|
-
```json
|
|
1223
|
-
{}
|
|
1224
|
-
```
|
|
1225
|
-
|
|
1226
|
-
```json
|
|
1227
|
-
{
|
|
1228
|
-
"total_tokens_saved": 1234567,
|
|
1229
|
-
"equivalent_context_windows": {
|
|
1230
|
-
"claude_200k": 6.17,
|
|
1231
|
-
"gpt4_128k": 9.64
|
|
1232
|
-
},
|
|
1233
|
-
"total_cost_avoided": {
|
|
1234
|
-
"claude_opus_4": 18.52,
|
|
1235
|
-
"claude_sonnet_4": 3.70,
|
|
1236
|
-
"claude_haiku_4": 0.99,
|
|
1237
|
-
"gpt4o": 3.09,
|
|
1238
|
-
"gpt4o_mini": 0.19
|
|
1239
|
-
}
|
|
1240
|
-
}
|
|
1241
|
-
```
|
|
1242
|
-
|
|
1243
|
-
Savings are included in the `_meta` field of every retrieval tool response:
|
|
1244
|
-
|
|
1245
|
-
```json
|
|
1246
|
-
{
|
|
1247
|
-
"symbol": { ... },
|
|
1248
|
-
"source": "...",
|
|
1249
|
-
"_meta": {
|
|
1250
|
-
"timing_ms": 3,
|
|
1251
|
-
"tokens_saved": 1842,
|
|
1252
|
-
"total_tokens_saved": 45231,
|
|
1253
|
-
"cost_avoided": { "claude_opus_4": 0.028 },
|
|
1254
|
-
"powered_by": "PureContext MCP"
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
```
|
|
1258
|
-
|
|
1259
|
-
Savings persist to `~/.purecontext/_savings.json` across sessions. Reset with `get_savings_stats(reset: true)`.
|
|
1260
|
-
|
|
1261
|
-
---
|
|
1262
|
-
|
|
1263
|
-
## 13. Multi-Tenant Hosting
|
|
1264
|
-
|
|
1265
|
-
PureContext supports hosting as a shared service for teams or organizations.
|
|
1266
|
-
|
|
1267
|
-
### Rate Limiting
|
|
1268
|
-
|
|
1269
|
-
Enabled automatically when using HTTP transport. Uses a token bucket algorithm:
|
|
1270
|
-
- Each client gets a bucket with capacity `maxTokens` (default 100)
|
|
1271
|
-
- Tokens refill at `refillRate` per second (default 10)
|
|
1272
|
-
- Expensive operations cost more tokens (indexing costs 10 tokens by default)
|
|
1273
|
-
|
|
1274
|
-
When rate limited, responses return `429 Too Many Requests` with a `Retry-After` header.
|
|
1275
|
-
|
|
1276
|
-
Configure in `config.json`:
|
|
1277
|
-
|
|
1278
|
-
```json
|
|
1279
|
-
{
|
|
1280
|
-
"rateLimit": {
|
|
1281
|
-
"enabled": true,
|
|
1282
|
-
"maxTokens": 100,
|
|
1283
|
-
"refillRate": 10,
|
|
1284
|
-
"perToolLimits": {
|
|
1285
|
-
"index_folder": 10,
|
|
1286
|
-
"search_symbols": 1
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
```
|
|
1291
|
-
|
|
1292
|
-
### API Key Authentication
|
|
1293
|
-
|
|
1294
|
-
Create and manage API keys for tenant identification:
|
|
1295
|
-
|
|
1296
|
-
```bash
|
|
1297
|
-
# Create a key
|
|
1298
|
-
purecontext-mcp keys create --tenant myorg --permissions read,write
|
|
1299
|
-
|
|
1300
|
-
# Output: cl_live_a1b2c3d4_<random>_<checksum>
|
|
1301
|
-
# Save this — it's shown only once
|
|
1302
|
-
|
|
1303
|
-
# List keys
|
|
1304
|
-
purecontext-mcp keys list --tenant myorg
|
|
1305
|
-
|
|
1306
|
-
# Revoke a key
|
|
1307
|
-
purecontext-mcp keys revoke cl_live_a1b2c3
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
|
-
**Key format:** `cl_live_{tenantId}_{24-char-random}_{checksum}`
|
|
1311
|
-
|
|
1312
|
-
Keys include a checksum for fast format validation without a database hit. Raw keys are never stored — only SHA-256 hashes.
|
|
1313
|
-
|
|
1314
|
-
**Permissions:**
|
|
1315
|
-
- `read` — query tools (search, retrieval)
|
|
1316
|
-
- `write` — indexing tools (index_folder, index_repo)
|
|
1317
|
-
- `admin` — tenant management, stats
|
|
1318
|
-
|
|
1319
|
-
### Tenant Data Isolation
|
|
1320
|
-
|
|
1321
|
-
When running multi-tenant:
|
|
1322
|
-
- Each tenant's repositories, symbols, and embeddings are isolated
|
|
1323
|
-
- Queries across tenants are prevented at the data layer
|
|
1324
|
-
- Separate HNSW indexes per tenant
|
|
1325
|
-
- Storage quotas per tenant
|
|
1326
|
-
|
|
1327
|
-
### Admin API
|
|
1328
|
-
|
|
1329
|
-
Accessible at `http://localhost:3000/admin/*` with `admin` permission:
|
|
1330
|
-
|
|
1331
|
-
| Endpoint | Description |
|
|
1332
|
-
|----------|-------------|
|
|
1333
|
-
| `GET /admin/stats` | Server-wide statistics |
|
|
1334
|
-
| `POST /admin/tenants` | Create a tenant |
|
|
1335
|
-
| `GET /admin/tenants` | List all tenants |
|
|
1336
|
-
| `GET /admin/tenants/:id/stats` | Tenant-specific stats |
|
|
1337
|
-
| `DELETE /admin/tenants/:id` | Delete tenant and all data |
|
|
1338
|
-
| `POST /admin/tenants/:id/keys` | Create API key for tenant |
|
|
1339
|
-
|
|
1340
|
-
---
|
|
1341
|
-
|
|
1342
|
-
## 14. Web UI
|
|
1343
|
-
|
|
1344
|
-
A browser-based interface for visual codebase exploration. Served at `http://localhost:3000` when HTTP transport is active.
|
|
1345
|
-
|
|
1346
|
-
### Building the UI
|
|
1347
|
-
|
|
1348
|
-
```bash
|
|
1349
|
-
npm run build:ui
|
|
1350
|
-
```
|
|
1351
|
-
|
|
1352
|
-
Or include it in the full build:
|
|
1353
|
-
|
|
1354
|
-
```bash
|
|
1355
|
-
npm run build
|
|
1356
|
-
```
|
|
1357
|
-
|
|
1358
|
-
### Features
|
|
1359
|
-
|
|
1360
|
-
#### Repository Browser
|
|
1361
|
-
- List all indexed repositories with symbol counts and languages
|
|
1362
|
-
- Collapsible file tree with file type icons
|
|
1363
|
-
- File outline: all symbols in a file, grouped by kind
|
|
1364
|
-
|
|
1365
|
-
#### Symbol Search
|
|
1366
|
-
- Real-time search with 300ms debounce
|
|
1367
|
-
- Filter by: kind, language, file pattern
|
|
1368
|
-
- Keyboard navigation (arrow keys + Enter)
|
|
1369
|
-
- Term highlighting in results
|
|
1370
|
-
|
|
1371
|
-
#### Symbol Source Viewer
|
|
1372
|
-
- Syntax-highlighted source code (via Shiki — VS Code accuracy)
|
|
1373
|
-
- Line numbers with anchors
|
|
1374
|
-
- Light/dark theme toggle (persisted in localStorage)
|
|
1375
|
-
- Related symbols panel: importers, dependencies, same-file symbols
|
|
1376
|
-
|
|
1377
|
-
#### Dependency Graph
|
|
1378
|
-
- Interactive force-directed graph of file/symbol dependencies
|
|
1379
|
-
- Pan, zoom, fit-to-view controls
|
|
1380
|
-
- Layout options: force-directed, hierarchical, radial
|
|
1381
|
-
- Depth slider (1-hop to N-hop)
|
|
1382
|
-
- Powered by React Flow + D3
|
|
1383
|
-
|
|
1384
|
-
#### Blast Radius Visualization
|
|
1385
|
-
- Radial layout: affected symbols radiate from the source
|
|
1386
|
-
- Color gradient: red (direct impact) → yellow (indirect)
|
|
1387
|
-
- Impact statistics: files affected, symbols affected
|
|
1388
|
-
- Toggle between graph and list view
|
|
1389
|
-
|
|
1390
|
-
### Development mode
|
|
1391
|
-
|
|
1392
|
-
```bash
|
|
1393
|
-
npm run dev
|
|
1394
|
-
```
|
|
1395
|
-
|
|
1396
|
-
Runs TypeScript compiler in watch mode alongside Vite dev server with hot reload.
|
|
1397
|
-
|
|
1398
|
-
---
|
|
1399
|
-
|
|
1400
|
-
## 15. Security
|
|
1401
|
-
|
|
1402
|
-
### Path Traversal Prevention
|
|
1403
|
-
|
|
1404
|
-
All file paths are validated before reading:
|
|
1405
|
-
- Resolved to absolute paths
|
|
1406
|
-
- Verified to start within the project root
|
|
1407
|
-
- Symlinks that escape the root are blocked (unless `allowSymlinks: true`)
|
|
1408
|
-
|
|
1409
|
-
### Secret File Exclusion
|
|
1410
|
-
|
|
1411
|
-
The following files are automatically excluded from indexing:
|
|
1412
|
-
- `.env`, `.env.*`, `.env.local`, `.env.production`
|
|
1413
|
-
- `*.pem`, `*.key`, `*.p12`, `*.pfx`, `*.crt`, `*.cer`
|
|
1414
|
-
- `id_rsa`, `id_ed25519`, `id_ecdsa`, `id_dsa`
|
|
1415
|
-
- `credentials.json`, `credentials.yaml`, `secrets.json`
|
|
1416
|
-
- `serviceAccountKey*.json`, `*-service-account.json`
|
|
1417
|
-
- `*.token`, `*.secret`
|
|
1418
|
-
|
|
1419
|
-
### Binary File Detection
|
|
1420
|
-
|
|
1421
|
-
Files with null bytes in the first 8 KB are treated as binary and skipped.
|
|
1422
|
-
|
|
1423
|
-
### HTTP Security
|
|
1424
|
-
|
|
1425
|
-
- Default host: `127.0.0.1` (loopback only) — not exposed on the network
|
|
1426
|
-
- Warning logged if `host` is not loopback and `auth.enabled` is false
|
|
1427
|
-
- Token comparison uses `crypto.timingSafeEqual()` (timing-attack resistant)
|
|
1428
|
-
- Request bodies limited to 1 MB
|
|
1429
|
-
- CORS origins whitelist-controlled
|
|
1430
|
-
|
|
1431
|
-
### Remote Repository Cloning
|
|
1432
|
-
|
|
1433
|
-
- Only `https://`, `http://`, and `git@` URL schemes are accepted
|
|
1434
|
-
- Clone tokens are never logged
|
|
1435
|
-
- Clones are isolated under `~/.purecontext/clones/`
|
|
1436
|
-
|
|
1437
|
-
---
|
|
1438
|
-
|
|
1439
|
-
## 16. Architecture Overview
|
|
1440
|
-
|
|
1441
|
-
PureContext uses a strict three-layer architecture:
|
|
1442
|
-
|
|
1443
|
-
```
|
|
1444
|
-
Adapters → Handlers → Core
|
|
1445
|
-
```
|
|
1446
|
-
|
|
1447
|
-
- **Core** (`src/core/`) — File discovery, hashing, tree-sitter dispatch, SQLite storage, MCP transport, file watcher. Language-agnostic.
|
|
1448
|
-
- **Handlers** (`src/handlers/`) — One handler per language. Implements `LanguageHandler`: parse with tree-sitter, extract symbols and imports.
|
|
1449
|
-
- **Adapters** (`src/adapters/`) — One adapter per framework. Implements `FrameworkAdapter`: auto-detect from project files, extract framework-specific symbols, enrich metadata.
|
|
1450
|
-
|
|
1451
|
-
The dependency graph, semantic indexer, summarizer, and MCP server all build on Core without violating the layer boundary. Use `get_layer_violations` to verify your own projects follow similar rules.
|
|
1452
|
-
|
|
1453
|
-
### Data flow
|
|
1454
|
-
|
|
1455
|
-
```
|
|
1456
|
-
index_folder(path)
|
|
1457
|
-
→ FileDiscovery (scan, priority order, exclude patterns, secret detection)
|
|
1458
|
-
→ HashCache (skip unchanged files)
|
|
1459
|
-
→ LanguageHandler.parseFile(buffer) → AST
|
|
1460
|
-
→ LanguageHandler.extractSymbols(AST) → SymbolRecord[]
|
|
1461
|
-
→ LanguageHandler.extractImports(AST) → ImportRecord[]
|
|
1462
|
-
→ FrameworkAdapter.extractFrameworkSymbols(AST) → SymbolRecord[]
|
|
1463
|
-
→ FrameworkAdapter.enrichMetadata(symbol) → SymbolRecord
|
|
1464
|
-
→ Summarizer (docstring → framework-derived → AI → signature)
|
|
1465
|
-
→ SymbolStore.insertSymbols(batch) → SQLite
|
|
1466
|
-
→ PathResolver.resolve(imports) → DepEdge[]
|
|
1467
|
-
→ DepStore.insertEdges(batch) → SQLite
|
|
1468
|
-
→ SemanticIndexer.index(symbols) → HNSW (if enabled)
|
|
1469
|
-
```
|
|
1470
|
-
|
|
1471
|
-
### Storage locations
|
|
1472
|
-
|
|
1473
|
-
| Path | Contents |
|
|
1474
|
-
|------|----------|
|
|
1475
|
-
| `~/.purecontext/indexes/` | SQLite databases (one per project) |
|
|
1476
|
-
| `~/.purecontext/indexes/{repoId}/hnsw.idx` | HNSW vector index |
|
|
1477
|
-
| `~/.purecontext/clones/` | Remote repo clones |
|
|
1478
|
-
| `~/.purecontext/config.json` | Configuration file |
|
|
1479
|
-
| `~/.purecontext/_savings.json` | Cumulative token savings |
|
|
1480
|
-
|
|
1481
|
-
---
|
|
1482
|
-
|
|
1483
|
-
## 17. Troubleshooting
|
|
1484
|
-
|
|
1485
|
-
### "Repo not indexed" error
|
|
1486
|
-
|
|
1487
|
-
The repository has not been indexed yet. Call `index_folder` first.
|
|
1488
|
-
|
|
1489
|
-
### Incremental re-index not triggered
|
|
1490
|
-
|
|
1491
|
-
The file watcher has a 2-second debounce. For manual force re-index: call `index_folder` again — it skips unchanged files using content hashing.
|
|
1492
|
-
|
|
1493
|
-
### Missing symbols after indexing
|
|
1494
|
-
|
|
1495
|
-
Check if the file is excluded:
|
|
1496
|
-
1. File may be in `node_modules/`, `dist/`, or another built-in exclusion
|
|
1497
|
-
2. File may match a `excludePatterns` glob
|
|
1498
|
-
3. File may exceed `maxFileSizeBytes`
|
|
1499
|
-
4. File may be a secret file (matched by security patterns)
|
|
1500
|
-
5. For some languages: private symbols are skipped by design (e.g., Go unexported, C static functions)
|
|
1501
|
-
|
|
1502
|
-
### Adapter not activating
|
|
1503
|
-
|
|
1504
|
-
Run `purecontext-mcp config --check` and look at the detected adapters. Adapter detection:
|
|
1505
|
-
- Vue: requires `vue` in `package.json`
|
|
1506
|
-
- Nuxt: requires `nuxt.config.ts`
|
|
1507
|
-
- Django: requires `manage.py` at project root
|
|
1508
|
-
- Gin: requires `github.com/gin-gonic/gin` in `go.mod`
|
|
1509
|
-
|
|
1510
|
-
Force a specific adapter by setting `adapters` in config:
|
|
1511
|
-
```json
|
|
1512
|
-
{ "adapters": ["vue", "nuxt"] }
|
|
1513
|
-
```
|
|
1514
|
-
|
|
1515
|
-
### HTTP transport not accessible from browser
|
|
1516
|
-
|
|
1517
|
-
1. Check `http.host` — default is `127.0.0.1` (loopback). Set to `0.0.0.0` for network access.
|
|
1518
|
-
2. Check `http.corsOrigins` — must include the browser's origin.
|
|
1519
|
-
3. Check `http.auth` — if enabled, all requests need `Authorization: Bearer <token>`.
|
|
1520
|
-
|
|
1521
|
-
### Semantic search not working
|
|
1522
|
-
|
|
1523
|
-
1. Verify `semantic.enabled: true` in config
|
|
1524
|
-
2. Verify a provider is configured (`semantic.provider`)
|
|
1525
|
-
3. Check if the repo meets the threshold: `semantic.threshold` (default 50,000 symbols — lower it for small repos)
|
|
1526
|
-
4. Check API key environment variables
|
|
1527
|
-
|
|
1528
|
-
### Config validation errors
|
|
1529
|
-
|
|
1530
|
-
```bash
|
|
1531
|
-
purecontext-mcp config --check
|
|
1532
|
-
```
|
|
1533
|
-
|
|
1534
|
-
This validates `~/.purecontext/config.json` and reports any schema errors.
|
|
1535
|
-
|
|
1536
|
-
### Performance — indexing is slow
|
|
1537
|
-
|
|
1538
|
-
- Increase `fileLimit` if you want more files indexed
|
|
1539
|
-
- The first index is always slower; subsequent runs are incremental
|
|
1540
|
-
- AI summarization (`allowRemoteAI: true`) adds network latency
|
|
1541
|
-
- Semantic indexing also adds API call time
|
|
1542
|
-
|
|
1543
|
-
### "git not found" when using index_repo
|
|
1544
|
-
|
|
1545
|
-
Install Git and ensure it is on `PATH`. Verify with `git --version`.
|
|
1546
|
-
|
|
1547
|
-
---
|
|
1548
|
-
|
|
1549
|
-
---
|
|
1550
|
-
|
|
1551
|
-
## 18. Advanced Relationship Analysis
|
|
1552
|
-
|
|
1553
|
-
Tools for understanding deep structural relationships between symbols and files.
|
|
1554
|
-
|
|
1555
|
-
---
|
|
1556
|
-
|
|
1557
|
-
### `find_implementations`
|
|
1558
|
-
|
|
1559
|
-
Find all concrete implementations of a TypeScript interface or abstract class, and all method overrides for a given base method.
|
|
1560
|
-
|
|
1561
|
-
```json
|
|
1562
|
-
{
|
|
1563
|
-
"repoId": "a1b2c3d4e5f60001",
|
|
1564
|
-
"symbolId": "abc123def456",
|
|
1565
|
-
"includeAbstract": false,
|
|
1566
|
-
"limit": 50
|
|
1567
|
-
}
|
|
1568
|
-
```
|
|
1569
|
-
|
|
1570
|
-
| Parameter | Type | Description |
|
|
1571
|
-
|-----------|------|-------------|
|
|
1572
|
-
| `symbolId` | string | ID of the interface or abstract class (from `search_symbols`) |
|
|
1573
|
-
| `includeAbstract` | boolean | Include abstract subclasses in results (default false) |
|
|
1574
|
-
| `limit` | number | Max implementations to return (default 50) |
|
|
1575
|
-
|
|
1576
|
-
**Returns:** `{ interfaceName, interfaceFilePath, implementations: [{ symbolId, name, kind, filePath, startLine, signature, summary, implementedMethods, missingMethods }], totalFound }`
|
|
1577
|
-
|
|
1578
|
-
Each implementation records which interface methods it has implemented and which are missing.
|
|
1579
|
-
|
|
1580
|
-
---
|
|
1581
|
-
|
|
1582
|
-
### `get_call_hierarchy`
|
|
1583
|
-
|
|
1584
|
-
Return the callers and callees of a function, N levels deep, as a tree structure. Unlike `get_blast_radius` (file-level, reverse-only), this tool returns a hierarchical view of the call stack.
|
|
1585
|
-
|
|
1586
|
-
```json
|
|
1587
|
-
{
|
|
1588
|
-
"repoId": "...",
|
|
1589
|
-
"symbolId": "abc123",
|
|
1590
|
-
"direction": "callees",
|
|
1591
|
-
"maxDepth": 3,
|
|
1592
|
-
"maxNodes": 50
|
|
1593
|
-
}
|
|
1594
|
-
```
|
|
1595
|
-
|
|
1596
|
-
| Parameter | Type | Description |
|
|
1597
|
-
|-----------|------|-------------|
|
|
1598
|
-
| `direction` | string | `"callees"` — what this function calls; `"callers"` — what calls it; `"both"` — bidirectional |
|
|
1599
|
-
| `maxDepth` | number | Maximum tree depth (default 3, max 6) |
|
|
1600
|
-
| `maxNodes` | number | Stop expanding once this many nodes are reached (default 50) |
|
|
1601
|
-
| `maxTokens` | number | Soft cap on response size in tokens |
|
|
1602
|
-
|
|
1603
|
-
**Returns:** `{ root: CallNode, direction, totalNodes, truncated }` where each `CallNode` has `children`, `callCount`, and `cyclic: true` for recursive calls.
|
|
1604
|
-
|
|
1605
|
-
---
|
|
1606
|
-
|
|
1607
|
-
### `get_class_hierarchy`
|
|
1608
|
-
|
|
1609
|
-
Return the full inheritance chain for a class or interface — ancestors (extends chain upward) and/or descendants (all subclasses downward). External base classes not indexed in the repo appear as leaf nodes with `symbolId: null`.
|
|
1610
|
-
|
|
1611
|
-
```json
|
|
1612
|
-
{
|
|
1613
|
-
"repoId": "...",
|
|
1614
|
-
"symbolId": "abc123",
|
|
1615
|
-
"direction": "both",
|
|
1616
|
-
"maxDepth": 5,
|
|
1617
|
-
"includeInterfaces": true
|
|
1618
|
-
}
|
|
1619
|
-
```
|
|
1620
|
-
|
|
1621
|
-
| Parameter | Type | Description |
|
|
1622
|
-
|-----------|------|-------------|
|
|
1623
|
-
| `direction` | string | `"ancestors"`, `"descendants"`, or `"both"` (default) |
|
|
1624
|
-
| `maxDepth` | number | Maximum traversal depth in each direction (default 5) |
|
|
1625
|
-
| `includeInterfaces` | boolean | Include implemented interfaces in the chain (default true) |
|
|
1626
|
-
|
|
1627
|
-
**Returns:** `{ root: HierarchyNode, direction, totalNodes }` as a tree with `ancestors` and `descendants` sub-trees.
|
|
1628
|
-
|
|
1629
|
-
---
|
|
1630
|
-
|
|
1631
|
-
### `find_cycles`
|
|
1632
|
-
|
|
1633
|
-
Detect all import cycles in the dependency graph and return them as ordered file paths. Unlike `detect_antipatterns` (which only counts cycles), this tool returns the actual cycle paths so you can resolve them.
|
|
1634
|
-
|
|
1635
|
-
```json
|
|
1636
|
-
{
|
|
1637
|
-
"repoId": "...",
|
|
1638
|
-
"filePath": "src/auth/",
|
|
1639
|
-
"maxCycles": 20,
|
|
1640
|
-
"minLength": 2
|
|
1641
|
-
}
|
|
1642
|
-
```
|
|
1643
|
-
|
|
1644
|
-
| Parameter | Type | Description |
|
|
1645
|
-
|-----------|------|-------------|
|
|
1646
|
-
| `filePath` | string | Scope to cycles involving this file/directory |
|
|
1647
|
-
| `maxCycles` | number | Stop after finding this many cycles (default 20) |
|
|
1648
|
-
| `minLength` | number | Minimum cycle length to report (default 2). Raise to skip direct mutual imports. |
|
|
1649
|
-
|
|
1650
|
-
**Returns:** `{ cycles: [{ files: string[], length, severity }], totalFound, truncated }`
|
|
1651
|
-
|
|
1652
|
-
Severity: `"error"` for tight 2–3-node cycles; `"warning"` for longer chains.
|
|
1653
|
-
|
|
1654
|
-
---
|
|
1655
|
-
|
|
1656
|
-
### `get_coupling_map`
|
|
1657
|
-
|
|
1658
|
-
Return per-file coupling scores using Martin's instability metric. Goes beyond `get_quality_metrics` to show exactly which files each file imports and which files import it.
|
|
1659
|
-
|
|
1660
|
-
```json
|
|
1661
|
-
{
|
|
1662
|
-
"repoId": "...",
|
|
1663
|
-
"topN": 20,
|
|
1664
|
-
"minScore": 3,
|
|
1665
|
-
"direction": "both"
|
|
1666
|
-
}
|
|
1667
|
-
```
|
|
1668
|
-
|
|
1669
|
-
| Parameter | Type | Description |
|
|
1670
|
-
|-----------|------|-------------|
|
|
1671
|
-
| `filePath` | string | Scope to a single file. Omit for top-N across the whole repo. |
|
|
1672
|
-
| `topN` | number | Max files to return when `filePath` is omitted (default 20) |
|
|
1673
|
-
| `minScore` | number | Only include files whose total coupling ≥ this value |
|
|
1674
|
-
| `direction` | string | `"efferent"`, `"afferent"`, or `"both"` (default) |
|
|
1675
|
-
|
|
1676
|
-
**Returns:** `{ files: [{ filePath, efferentCoupling, afferentCoupling, instability, efferentDeps, afferentDeps }] }`
|
|
1677
|
-
|
|
1678
|
-
- `instability = efferentCoupling / (efferentCoupling + afferentCoupling)`
|
|
1679
|
-
- Score near `0` = stable hub (risky to change)
|
|
1680
|
-
- Score near `1` = leaf node (safe to change)
|
|
1681
|
-
|
|
1682
|
-
---
|
|
1683
|
-
|
|
1684
|
-
## 19. Architectural Visualization
|
|
1685
|
-
|
|
1686
|
-
Generate diagrams of your codebase structure. All diagram tools support Mermaid format (renders natively in GitHub, VS Code, and Claude) and DOT format (for Graphviz).
|
|
1687
|
-
|
|
1688
|
-
---
|
|
1689
|
-
|
|
1690
|
-
### `render_diagram`
|
|
1691
|
-
|
|
1692
|
-
The general-purpose diagram generator. Produces file-level import graphs, call graphs, or class hierarchy diagrams.
|
|
1693
|
-
|
|
1694
|
-
```json
|
|
1695
|
-
{
|
|
1696
|
-
"repoId": "...",
|
|
1697
|
-
"type": "module",
|
|
1698
|
-
"filePath": "src/core/",
|
|
1699
|
-
"maxNodes": 30,
|
|
1700
|
-
"maxDepth": 3,
|
|
1701
|
-
"format": "mermaid"
|
|
1702
|
-
}
|
|
1703
|
-
```
|
|
1704
|
-
|
|
1705
|
-
| Parameter | Type | Description |
|
|
1706
|
-
|-----------|------|-------------|
|
|
1707
|
-
| `type` | string | `"module"`/`"import"` — file-level import graph; `"call"` — call graph; `"class"` — class hierarchy |
|
|
1708
|
-
| `rootSymbolId` | string | Anchor for `call` and `class` diagrams (required for those types) |
|
|
1709
|
-
| `filePath` | string | Scope to a directory/file prefix |
|
|
1710
|
-
| `maxNodes` | number | Stop adding nodes at this count (default 30) |
|
|
1711
|
-
| `maxDepth` | number | Maximum traversal depth (default 3) |
|
|
1712
|
-
| `format` | string | `"mermaid"` (default) or `"dot"` |
|
|
1713
|
-
|
|
1714
|
-
**Returns:** `{ diagram: string, format, nodeCount, edgeCount, truncated }`
|
|
1715
|
-
|
|
1716
|
-
---
|
|
1717
|
-
|
|
1718
|
-
### `render_call_graph`
|
|
1719
|
-
|
|
1720
|
-
Render a call graph rooted at a symbol as a Mermaid flowchart or DOT diagram. A focused alternative to `render_diagram` with type `"call"`.
|
|
1721
|
-
|
|
1722
|
-
```json
|
|
1723
|
-
{
|
|
1724
|
-
"repoId": "...",
|
|
1725
|
-
"symbolId": "abc123",
|
|
1726
|
-
"direction": "both",
|
|
1727
|
-
"maxDepth": 3,
|
|
1728
|
-
"format": "mermaid"
|
|
1729
|
-
}
|
|
1730
|
-
```
|
|
1731
|
-
|
|
1732
|
-
The root node is styled distinctly. Recursive/cyclic calls are shown as dashed arrows.
|
|
1733
|
-
|
|
1734
|
-
---
|
|
1735
|
-
|
|
1736
|
-
### `render_import_graph`
|
|
1737
|
-
|
|
1738
|
-
Render a file-level import graph for a directory or the whole repo. A focused alternative to `render_diagram` with type `"module"`.
|
|
1739
|
-
|
|
1740
|
-
```json
|
|
1741
|
-
{
|
|
1742
|
-
"repoId": "...",
|
|
1743
|
-
"filePath": "src/",
|
|
1744
|
-
"maxNodes": 40,
|
|
1745
|
-
"format": "mermaid"
|
|
1746
|
-
}
|
|
1747
|
-
```
|
|
1748
|
-
|
|
1749
|
-
Files are clustered by directory. Use `filePath` to restrict the graph to a subtree.
|
|
1750
|
-
|
|
1751
|
-
---
|
|
1752
|
-
|
|
1753
|
-
### `render_class_hierarchy`
|
|
1754
|
-
|
|
1755
|
-
Render a class inheritance diagram as a Mermaid `classDiagram`. A focused alternative to `render_diagram` with type `"class"`.
|
|
1756
|
-
|
|
1757
|
-
```json
|
|
1758
|
-
{
|
|
1759
|
-
"repoId": "...",
|
|
1760
|
-
"symbolId": "abc123",
|
|
1761
|
-
"direction": "both",
|
|
1762
|
-
"maxDepth": 4,
|
|
1763
|
-
"format": "mermaid"
|
|
1764
|
-
}
|
|
1765
|
-
```
|
|
1766
|
-
|
|
1767
|
-
---
|
|
1768
|
-
|
|
1769
|
-
### `render_dep_matrix`
|
|
1770
|
-
|
|
1771
|
-
Render a dependency matrix (coupling heatmap) for the top-N most coupled files.
|
|
1772
|
-
|
|
1773
|
-
```json
|
|
1774
|
-
{
|
|
1775
|
-
"repoId": "...",
|
|
1776
|
-
"topN": 10,
|
|
1777
|
-
"filePath": "src/core/",
|
|
1778
|
-
"format": "ascii"
|
|
1779
|
-
}
|
|
1780
|
-
```
|
|
1781
|
-
|
|
1782
|
-
| Parameter | Type | Description |
|
|
1783
|
-
|-----------|------|-------------|
|
|
1784
|
-
| `topN` | number | Number of files in the matrix (default 10) |
|
|
1785
|
-
| `filePath` | string | Scope file selection to a directory |
|
|
1786
|
-
| `format` | string | `"ascii"` (default, token-efficient) or `"mermaid"` (graph diagram) |
|
|
1787
|
-
|
|
1788
|
-
**Returns:** `{ matrix: string, files: string[], format }`
|
|
1789
|
-
|
|
1790
|
-
Cell `[row][col]` is `1` when the row file imports the column file, `—` on the diagonal.
|
|
1791
|
-
|
|
1792
|
-
---
|
|
1793
|
-
|
|
1794
|
-
### `get_architecture_snapshot`
|
|
1795
|
-
|
|
1796
|
-
Freeze the current architecture state into a named snapshot, then diff two snapshots to measure structural change over time.
|
|
1797
|
-
|
|
1798
|
-
```json
|
|
1799
|
-
{
|
|
1800
|
-
"repoId": "...",
|
|
1801
|
-
"action": "create",
|
|
1802
|
-
"label": "before-auth-refactor"
|
|
1803
|
-
}
|
|
1804
|
-
```
|
|
1805
|
-
|
|
1806
|
-
| `action` | Description |
|
|
1807
|
-
|----------|-------------|
|
|
1808
|
-
| `"create"` | Compute and store a snapshot (fileCount, symbolCount, edgeCount, cycleCount, avgCoupling, avgComplexity) |
|
|
1809
|
-
| `"list"` | Return all snapshots for the repo, newest first |
|
|
1810
|
-
| `"diff"` | Compare two snapshots — requires `snapshotId` (base) and `compareId` (head) |
|
|
1811
|
-
| `"delete"` | Remove a snapshot by `snapshotId` |
|
|
1812
|
-
|
|
1813
|
-
**Diff returns:** `{ base, head, deltas: { cycleCountDelta, avgCouplingDelta, ... }, trend }` — a negative `cycleCountDelta` means fewer cycles (improvement).
|
|
1814
|
-
|
|
1815
|
-
**Workflow:**
|
|
1816
|
-
```
|
|
1817
|
-
1. get_architecture_snapshot(action: "create", label: "before")
|
|
1818
|
-
2. [make changes, re-index]
|
|
1819
|
-
3. get_architecture_snapshot(action: "create", label: "after")
|
|
1820
|
-
4. get_architecture_snapshot(action: "diff", snapshotId: "before-id", compareId: "after-id")
|
|
1821
|
-
```
|
|
1822
|
-
|
|
1823
|
-
---
|
|
1824
|
-
|
|
1825
|
-
## 20. Refactoring Safety Checks
|
|
1826
|
-
|
|
1827
|
-
Pre-flight tools that return a verdict and an impact map before you make a destructive change.
|
|
1828
|
-
|
|
1829
|
-
---
|
|
1830
|
-
|
|
1831
|
-
### `check_rename_safe`
|
|
1832
|
-
|
|
1833
|
-
Pre-flight check for renaming a symbol. Returns a verdict, all affected files, and the specific lines that need updating.
|
|
1834
|
-
|
|
1835
|
-
```json
|
|
1836
|
-
{
|
|
1837
|
-
"repoId": "...",
|
|
1838
|
-
"symbolId": "abc123",
|
|
1839
|
-
"newName": "validateCredentials",
|
|
1840
|
-
"checkConflicts": true
|
|
1841
|
-
}
|
|
1842
|
-
```
|
|
1843
|
-
|
|
1844
|
-
**Returns:** `{ safe: boolean, verdict, oldName, newName, affectedFiles: [{ filePath, line, column, changeType, snippet }], blockers: string[] }`
|
|
1845
|
-
|
|
1846
|
-
`safe: false` when:
|
|
1847
|
-
- `newName` already exists in the same file (name conflict)
|
|
1848
|
-
- Any references are string literals (require manual updates — a rename tool can't fix these)
|
|
1849
|
-
|
|
1850
|
-
`changeType` values: `"import"`, `"call"`, `"type-reference"`, `"string-literal"`, `"comment"`
|
|
1851
|
-
|
|
1852
|
-
---
|
|
1853
|
-
|
|
1854
|
-
### `check_delete_safe`
|
|
1855
|
-
|
|
1856
|
-
Pre-flight check for deleting a symbol or an entire file.
|
|
1857
|
-
|
|
1858
|
-
```json
|
|
1859
|
-
{
|
|
1860
|
-
"repoId": "...",
|
|
1861
|
-
"symbolId": "abc123",
|
|
1862
|
-
"includeExternalRisk": true
|
|
1863
|
-
}
|
|
1864
|
-
```
|
|
1865
|
-
|
|
1866
|
-
| Parameter | Type | Description |
|
|
1867
|
-
|-----------|------|-------------|
|
|
1868
|
-
| `symbolId` | string | Single symbol to check |
|
|
1869
|
-
| `filePath` | string | All symbols in a file (aggregate verdict) — use instead of `symbolId` |
|
|
1870
|
-
| `includeExternalRisk` | boolean | Flag exported symbols as risky (external npm consumers; default true) |
|
|
1871
|
-
|
|
1872
|
-
**Returns:** `{ safe: boolean, verdict, risks: [{ kind, filePath, line, snippet }] }`
|
|
1873
|
-
|
|
1874
|
-
Risk kinds: `"live-reference"`, `"exported-symbol"`, `"entry-point"`, `"test-subject"`
|
|
1875
|
-
|
|
1876
|
-
---
|
|
1877
|
-
|
|
1878
|
-
### `check_move_safe`
|
|
1879
|
-
|
|
1880
|
-
Pre-flight check for moving a file to a new path. Identifies all import statements that reference the current path and reports which will break.
|
|
1881
|
-
|
|
1882
|
-
```json
|
|
1883
|
-
{
|
|
1884
|
-
"repoId": "...",
|
|
1885
|
-
"filePath": "src/utils/auth.ts",
|
|
1886
|
-
"newFilePath": "src/auth/utils.ts"
|
|
1887
|
-
}
|
|
1888
|
-
```
|
|
1889
|
-
|
|
1890
|
-
**Returns:** `{ safe: boolean, verdict, affectedImports: [{ filePath, line, currentSpecifier, updatedSpecifier }], manualUpdatesRequired: boolean }`
|
|
1891
|
-
|
|
1892
|
-
`safe: false` when any import uses a non-relative specifier (path alias, bare module name) that can't be automatically updated.
|
|
1893
|
-
|
|
1894
|
-
---
|
|
1895
|
-
|
|
1896
|
-
### `plan_refactoring`
|
|
1897
|
-
|
|
1898
|
-
Generate a sequenced, risk-annotated refactoring plan for a symbol or file. Synthesizes the outputs of `check_rename_safe`, `check_delete_safe`, `check_move_safe`, `find_cycles`, `get_coupling_map`, `detect_antipatterns`, and `get_quality_metrics` into a prioritized action list.
|
|
1899
|
-
|
|
1900
|
-
```json
|
|
1901
|
-
{
|
|
1902
|
-
"repoId": "...",
|
|
1903
|
-
"goal": "rename-symbol",
|
|
1904
|
-
"symbolId": "abc123",
|
|
1905
|
-
"newName": "validateCredentials"
|
|
1906
|
-
}
|
|
1907
|
-
```
|
|
1908
|
-
|
|
1909
|
-
| `goal` | Description |
|
|
1910
|
-
|--------|-------------|
|
|
1911
|
-
| `"rename-symbol"` | Rename a symbol everywhere — requires `symbolId` + `newName` |
|
|
1912
|
-
| `"delete-symbol"` | Safely remove a symbol — requires `symbolId` |
|
|
1913
|
-
| `"break-cycle"` | Resolve a circular import — requires `filePath` or `symbolId` |
|
|
1914
|
-
| `"extract-module"` | Move a file to a new location — requires `filePath` + `newFilePath` |
|
|
1915
|
-
| `"reduce-coupling"` | Split a highly-coupled file — requires `filePath` or `symbolId` |
|
|
1916
|
-
| `"general"` | Open-ended analysis — surfaces top findings |
|
|
1917
|
-
|
|
1918
|
-
**Returns:** `{ goal, steps: [{ order, action, target, risk, rationale }], summary, estimatedFiles, warnings }`
|
|
1919
|
-
|
|
1920
|
-
Steps are ordered bottom-up: leaf files before hub files, reference updates before declaration changes.
|
|
1921
|
-
|
|
1922
|
-
---
|
|
1923
|
-
|
|
1924
|
-
## 21. Health Dashboards & Debt Reporting
|
|
1925
|
-
|
|
1926
|
-
Tools for measuring, tracking, and comparing codebase health over time.
|
|
1927
|
-
|
|
1928
|
-
---
|
|
1929
|
-
|
|
1930
|
-
### `health_radar`
|
|
1931
|
-
|
|
1932
|
-
Compute a multi-axis health radar for an indexed repo. Each axis is scored 0–100 (100 = perfectly healthy).
|
|
1933
|
-
|
|
1934
|
-
```json
|
|
1935
|
-
{
|
|
1936
|
-
"repoId": "...",
|
|
1937
|
-
"scope": "src/core/",
|
|
1938
|
-
"includeStability": true
|
|
1939
|
-
}
|
|
1940
|
-
```
|
|
1941
|
-
|
|
1942
|
-
| Parameter | Type | Description |
|
|
1943
|
-
|-----------|------|-------------|
|
|
1944
|
-
| `scope` | string | Directory prefix to narrow analysis |
|
|
1945
|
-
| `includeStability` | boolean | Include churn-based stability axis (requires git metadata; default true) |
|
|
1946
|
-
|
|
1947
|
-
**Returns:**
|
|
1948
|
-
```json
|
|
1949
|
-
{
|
|
1950
|
-
"axes": {
|
|
1951
|
-
"complexity": { "score": 72, "label": "Good", "rationale": "..." },
|
|
1952
|
-
"coupling": { "score": 58, "label": "Warning", "rationale": "..." },
|
|
1953
|
-
"maintainability": { "score": 81, "label": "Good", "rationale": "..." },
|
|
1954
|
-
"documentation": { "score": 44, "label": "Poor", "rationale": "..." },
|
|
1955
|
-
"stability": { "score": 65, "label": "Fair", "rationale": "..." }
|
|
1956
|
-
},
|
|
1957
|
-
"overallHealth": 64,
|
|
1958
|
-
"grade": "C",
|
|
1959
|
-
"summary": { "totalFiles": 120, "symbolCount": 1840, "highRiskFiles": 7 }
|
|
1960
|
-
}
|
|
1961
|
-
```
|
|
1962
|
-
|
|
1963
|
-
Five axes:
|
|
1964
|
-
- **complexity** — inverse of average/peak cyclomatic complexity
|
|
1965
|
-
- **coupling** — inverse of high-coupling file density
|
|
1966
|
-
- **maintainability** — inverse of dead-code and god-class density
|
|
1967
|
-
- **documentation** — percentage of symbols with non-trivial summaries
|
|
1968
|
-
- **stability** — inverse of churn-hotspot density (requires git metadata)
|
|
1969
|
-
|
|
1970
|
-
---
|
|
1971
|
-
|
|
1972
|
-
### `diff_health_radar`
|
|
1973
|
-
|
|
1974
|
-
Compare health radar scores between two indexed repos (or two states of the same codebase). Positive delta = improvement; negative delta = regression.
|
|
1975
|
-
|
|
1976
|
-
```json
|
|
1977
|
-
{
|
|
1978
|
-
"baseRepoId": "main-branch-id",
|
|
1979
|
-
"headRepoId": "feature-branch-id",
|
|
1980
|
-
"scope": "src/"
|
|
1981
|
-
}
|
|
1982
|
-
```
|
|
1983
|
-
|
|
1984
|
-
**Primary use cases:**
|
|
1985
|
-
- PR review: index `main` branch → index feature branch → compare
|
|
1986
|
-
- Refactoring validation: re-index before/after changes → compare
|
|
1987
|
-
- Cross-repo benchmarking
|
|
1988
|
-
|
|
1989
|
-
**Returns:** `{ base, head, axes: { complexity: { base, head, delta, trend }, ... }, overallDelta, trend, regressions, improvements }`
|
|
1990
|
-
|
|
1991
|
-
A delta ≥ +5 is a meaningful improvement; ≤ −5 is a meaningful regression.
|
|
1992
|
-
|
|
1993
|
-
---
|
|
1994
|
-
|
|
1995
|
-
### `get_debt_report`
|
|
1996
|
-
|
|
1997
|
-
Generate a comprehensive technical debt report aggregating complexity, structural, maintainability, and volatility signals.
|
|
1998
|
-
|
|
1999
|
-
```json
|
|
2000
|
-
{
|
|
2001
|
-
"repoId": "...",
|
|
2002
|
-
"scope": "src/",
|
|
2003
|
-
"topN": 10,
|
|
2004
|
-
"includeChurn": true
|
|
2005
|
-
}
|
|
2006
|
-
```
|
|
2007
|
-
|
|
2008
|
-
| Parameter | Type | Description |
|
|
2009
|
-
|-----------|------|-------------|
|
|
2010
|
-
| `scope` | string | Directory prefix to narrow analysis |
|
|
2011
|
-
| `topN` | number | Number of top debt files to return (default 10) |
|
|
2012
|
-
| `includeChurn` | boolean | Include churn-based volatility debt (requires git metadata; default true) |
|
|
2013
|
-
|
|
2014
|
-
**Returns:**
|
|
2015
|
-
```json
|
|
2016
|
-
{
|
|
2017
|
-
"overallDebt": 43,
|
|
2018
|
-
"grade": "C",
|
|
2019
|
-
"categories": {
|
|
2020
|
-
"complexity": { "score": 38, "topIssues": [...] },
|
|
2021
|
-
"structural": { "score": 61, "topIssues": [...] },
|
|
2022
|
-
"maintainability": { "score": 29, "topIssues": [...] },
|
|
2023
|
-
"volatility": { "score": 44, "topIssues": [...] }
|
|
2024
|
-
},
|
|
2025
|
-
"topDebtFiles": [{ "filePath": "...", "score": 87, "reasons": [...] }],
|
|
2026
|
-
"actionItems": [{ "priority": "high", "action": "...", "estimatedROI": "..." }]
|
|
2027
|
-
}
|
|
2028
|
-
```
|
|
2029
|
-
|
|
2030
|
-
Debt score 0–100: higher = more debt. Use periodically for debt reviews, CI gates, and architecture planning.
|
|
2031
|
-
|
|
2032
|
-
**Differs from `health_radar`:** Debt scores are inverted (100 = bad); adds a Documentation axis; no per-file breakdown in `health_radar`.
|
|
2033
|
-
|
|
2034
|
-
---
|
|
2035
|
-
|
|
2036
|
-
## 22. AST-Level Search
|
|
2037
|
-
|
|
2038
|
-
Tools for searching source code at the structural (AST) level rather than by symbol name or text.
|
|
2039
|
-
|
|
2040
|
-
---
|
|
2041
|
-
|
|
2042
|
-
### `search_ast`
|
|
2043
|
-
|
|
2044
|
-
Find every occurrence of a specific tree-sitter AST node type across all indexed files — without reading files manually.
|
|
2045
|
-
|
|
2046
|
-
```json
|
|
2047
|
-
{
|
|
2048
|
-
"repoId": "...",
|
|
2049
|
-
"nodeType": "arrow_function",
|
|
2050
|
-
"language": "typescript",
|
|
2051
|
-
"filePath": "src/",
|
|
2052
|
-
"limit": 50
|
|
2053
|
-
}
|
|
2054
|
-
```
|
|
2055
|
-
|
|
2056
|
-
| Parameter | Type | Description |
|
|
2057
|
-
|-----------|------|-------------|
|
|
2058
|
-
| `nodeType` | string | Tree-sitter node type name (exact, case-sensitive) |
|
|
2059
|
-
| `language` | string | Restrict to a specific language handler |
|
|
2060
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2061
|
-
| `limit` | number | Max results (default 50) |
|
|
2062
|
-
|
|
2063
|
-
**Common node types:**
|
|
2064
|
-
|
|
2065
|
-
| Language | Node Types |
|
|
2066
|
-
|----------|-----------|
|
|
2067
|
-
| 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` |
|
|
2068
|
-
| Python | `function_definition`, `class_definition`, `for_statement`, `with_statement`, `decorated_definition`, `lambda` |
|
|
2069
|
-
| Rust | `function_item`, `struct_item`, `impl_item`, `match_expression`, `closure_expression`, `trait_item` |
|
|
2070
|
-
| Go | `function_declaration`, `method_declaration`, `go_statement`, `defer_statement`, `type_declaration`, `interface_type` |
|
|
2071
|
-
| Java/Kotlin | `method_declaration`, `class_declaration`, `try_statement`, `lambda_expression`, `annotation` |
|
|
2072
|
-
|
|
2073
|
-
**Returns:** `{ matches: [{ filePath, startLine, endLine, text, nodeType }], totalFound, skippedFiles }`
|
|
2074
|
-
|
|
2075
|
-
Note: only files backed by a WASM grammar are searched. Regex-only handlers (Terraform, Protobuf, GraphQL, etc.) are silently skipped and reported in `skippedFiles`.
|
|
2076
|
-
|
|
2077
|
-
---
|
|
2078
|
-
|
|
2079
|
-
### `search_by_signature`
|
|
2080
|
-
|
|
2081
|
-
Find all symbols whose type signature matches a pattern. Operates on the stored one-line signature string — no AST re-parsing needed.
|
|
2082
|
-
|
|
2083
|
-
```json
|
|
2084
|
-
{
|
|
2085
|
-
"repoId": "...",
|
|
2086
|
-
"pattern": "Promise<void>",
|
|
2087
|
-
"mode": "contains",
|
|
2088
|
-
"kind": "function",
|
|
2089
|
-
"limit": 50
|
|
2090
|
-
}
|
|
2091
|
-
```
|
|
2092
|
-
|
|
2093
|
-
| Parameter | Type | Description |
|
|
2094
|
-
|-----------|------|-------------|
|
|
2095
|
-
| `pattern` | string | Pattern to match against the signature |
|
|
2096
|
-
| `mode` | string | `"contains"` (default), `"startsWith"`, or `"regex"` |
|
|
2097
|
-
| `kind` | string | Filter by symbol kind |
|
|
2098
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2099
|
-
|
|
2100
|
-
**Pattern examples:**
|
|
2101
|
-
```
|
|
2102
|
-
"Promise<void>" → all functions returning Promise<void>
|
|
2103
|
-
"async" → all async functions
|
|
2104
|
-
"(req: Request" → all functions accepting a Request parameter
|
|
2105
|
-
": string[]" → all functions returning string[]
|
|
2106
|
-
"export async" → all exported async symbols (use startsWith mode)
|
|
2107
|
-
```
|
|
2108
|
-
|
|
2109
|
-
**Returns:** `{ matches: [{ ...symbol, signature }], totalFound }`
|
|
2110
|
-
|
|
2111
|
-
---
|
|
2112
|
-
|
|
2113
|
-
### `search_by_decorator`
|
|
2114
|
-
|
|
2115
|
-
Find all symbols annotated with a specific decorator. Re-parses stored file content via tree-sitter to locate decorator nodes.
|
|
2116
|
-
|
|
2117
|
-
```json
|
|
2118
|
-
{
|
|
2119
|
-
"repoId": "...",
|
|
2120
|
-
"decoratorName": "Injectable",
|
|
2121
|
-
"matchMode": "exact",
|
|
2122
|
-
"filePath": "src/services/"
|
|
2123
|
-
}
|
|
2124
|
-
```
|
|
2125
|
-
|
|
2126
|
-
| Parameter | Type | Description |
|
|
2127
|
-
|-----------|------|-------------|
|
|
2128
|
-
| `decoratorName` | string | Decorator name without the `@` prefix |
|
|
2129
|
-
| `matchMode` | string | `"exact"` (default), `"contains"`, or `"prefix"` |
|
|
2130
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2131
|
-
|
|
2132
|
-
**Examples:**
|
|
2133
|
-
```
|
|
2134
|
-
decoratorName: "Injectable" → all @Injectable classes
|
|
2135
|
-
decoratorName: "Controller" → all @Controller route handlers
|
|
2136
|
-
decoratorName: "Column", matchMode: "prefix" → @Column, @ColumnType, etc.
|
|
2137
|
-
decoratorName: "test", matchMode: "contains" → anything with "test" in decorator
|
|
2138
|
-
```
|
|
2139
|
-
|
|
2140
|
-
**Returns:** `{ matches: [{ ...symbol, decoratorName, decoratorArgs }], totalFound, skippedFiles }`
|
|
2141
|
-
|
|
2142
|
-
---
|
|
2143
|
-
|
|
2144
|
-
### `search_by_complexity`
|
|
2145
|
-
|
|
2146
|
-
Find all symbols whose complexity metrics match a set of min/max filters. Covers six dimensions stored at index time.
|
|
2147
|
-
|
|
2148
|
-
```json
|
|
2149
|
-
{
|
|
2150
|
-
"repoId": "...",
|
|
2151
|
-
"minCyclomaticComplexity": 8,
|
|
2152
|
-
"minParamCount": 5,
|
|
2153
|
-
"kind": "function",
|
|
2154
|
-
"limit": 50
|
|
2155
|
-
}
|
|
2156
|
-
```
|
|
2157
|
-
|
|
2158
|
-
**Available filters** (all optional, combined with AND):
|
|
2159
|
-
|
|
2160
|
-
| Filter | Description |
|
|
2161
|
-
|--------|-------------|
|
|
2162
|
-
| `minCyclomaticComplexity` / `maxCyclomaticComplexity` | Branching complexity |
|
|
2163
|
-
| `minCognitiveComplexity` / `maxCognitiveComplexity` | Cognitive load |
|
|
2164
|
-
| `minLineCount` / `maxLineCount` | Function body size |
|
|
2165
|
-
| `minNestingDepth` / `maxNestingDepth` | Maximum nesting level |
|
|
2166
|
-
| `minParamCount` / `maxParamCount` | Number of parameters |
|
|
2167
|
-
| `minReturnCount` / `maxReturnCount` | Number of return statements |
|
|
2168
|
-
|
|
2169
|
-
**Use cases:**
|
|
2170
|
-
```
|
|
2171
|
-
minCyclomaticComplexity: 8 → dangerously complex functions
|
|
2172
|
-
minParamCount: 5 → functions with too many arguments
|
|
2173
|
-
minLineCount: 100 → long functions to split
|
|
2174
|
-
minNestingDepth: 4 → deeply nested, hard-to-read code
|
|
2175
|
-
maxCyclomaticComplexity: 2, maxLineCount: 15 → simple utility functions
|
|
2176
|
-
```
|
|
2177
|
-
|
|
2178
|
-
**Returns:** `{ matches: [{ ...symbol, metrics: { cyclomaticComplexity, cognitiveComplexity, lineCount, nestingDepth, paramCount, returnCount } }], totalFound }`
|
|
2179
|
-
|
|
2180
|
-
---
|
|
2181
|
-
|
|
2182
|
-
## 23. Code Intelligence Helpers
|
|
2183
|
-
|
|
2184
|
-
Higher-level tools that answer specific questions about a codebase without requiring manual navigation.
|
|
2185
|
-
|
|
2186
|
-
---
|
|
2187
|
-
|
|
2188
|
-
### `get_entry_points`
|
|
2189
|
-
|
|
2190
|
-
Identify the runnable entry points of a repository: main functions, CLI handlers, HTTP server startups, Lambda/serverless handlers, test suites, and standalone scripts.
|
|
2191
|
-
|
|
2192
|
-
```json
|
|
2193
|
-
{
|
|
2194
|
-
"repoId": "...",
|
|
2195
|
-
"kind": "server_startup",
|
|
2196
|
-
"minConfidence": "high",
|
|
2197
|
-
"filePath": "src/cmd/"
|
|
2198
|
-
}
|
|
2199
|
-
```
|
|
2200
|
-
|
|
2201
|
-
| Parameter | Type | Description |
|
|
2202
|
-
|-----------|------|-------------|
|
|
2203
|
-
| `kind` | string | Filter: `"main_function"`, `"cli_handler"`, `"server_startup"`, `"lambda_handler"`, `"test_suite"`, `"script"` |
|
|
2204
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2205
|
-
| `minConfidence` | string | `"high"`, `"medium"`, or `"low"` (default: `"low"` — returns all candidates) |
|
|
2206
|
-
|
|
2207
|
-
**Returns:** `{ entryPoints: [{ symbolId, name, kind, filePath, confidence, reason, signature }], totalFound }`
|
|
2208
|
-
|
|
2209
|
-
**Use with:**
|
|
2210
|
-
- `get_context_bundle` to follow the full dependency chain from an entry point
|
|
2211
|
-
- `get_call_hierarchy` for a callee tree rooted at an entry point
|
|
2212
|
-
- `find_dead_code` to discover unreachable code relative to entry points
|
|
2213
|
-
|
|
2214
|
-
---
|
|
2215
|
-
|
|
2216
|
-
### `get_public_api`
|
|
2217
|
-
|
|
2218
|
-
Return the public API surface of a repository: all exported symbols, grouped by file.
|
|
2219
|
-
|
|
2220
|
-
```json
|
|
2221
|
-
{
|
|
2222
|
-
"repoId": "...",
|
|
2223
|
-
"filePath": "src/",
|
|
2224
|
-
"kind": "function",
|
|
2225
|
-
"includeMembers": false,
|
|
2226
|
-
"groupByFile": true,
|
|
2227
|
-
"limit": 200
|
|
2228
|
-
}
|
|
2229
|
-
```
|
|
2230
|
-
|
|
2231
|
-
| Parameter | Type | Description |
|
|
2232
|
-
|-----------|------|-------------|
|
|
2233
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2234
|
-
| `kind` | string | Filter by symbol kind |
|
|
2235
|
-
| `includeMembers` | boolean | Also include public methods of exported classes (default false) |
|
|
2236
|
-
| `groupByFile` | boolean | Group results by file path (default true) |
|
|
2237
|
-
| `limit` | number | Max symbols to return |
|
|
2238
|
-
|
|
2239
|
-
**Returns:** `{ files: [{ filePath, exports: [{ symbolId, name, kind, signature, summary, isDefault }] }], totalExports }`
|
|
2240
|
-
|
|
2241
|
-
A symbol is considered public when its signature begins with the `export` keyword.
|
|
2242
|
-
|
|
2243
|
-
**Use with:**
|
|
2244
|
-
- `find_dead_code` to find exported symbols that nobody imports
|
|
2245
|
-
- `get_blast_radius` before removing an export
|
|
2246
|
-
|
|
2247
|
-
---
|
|
2248
|
-
|
|
2249
|
-
### `get_todos`
|
|
2250
|
-
|
|
2251
|
-
Scan all indexed source files for comment tags and return a structured inventory.
|
|
2252
|
-
|
|
2253
|
-
```json
|
|
2254
|
-
{
|
|
2255
|
-
"repoId": "...",
|
|
2256
|
-
"tags": ["TODO", "FIXME"],
|
|
2257
|
-
"assignee": "alice",
|
|
2258
|
-
"filePath": "src/",
|
|
2259
|
-
"groupByFile": true,
|
|
2260
|
-
"limit": 100
|
|
2261
|
-
}
|
|
2262
|
-
```
|
|
2263
|
-
|
|
2264
|
-
| Parameter | Type | Description |
|
|
2265
|
-
|-----------|------|-------------|
|
|
2266
|
-
| `tags` | array | Tags to scan for (default: all 7 — `TODO`, `FIXME`, `HACK`, `NOTE`, `OPTIMIZE`, `BUG`, `XXX`) |
|
|
2267
|
-
| `filePath` | string | Restrict to a file or directory prefix |
|
|
2268
|
-
| `assignee` | string | Filter by assignee — matches `TODO(alice):` when `assignee: "alice"` (case-insensitive) |
|
|
2269
|
-
| `groupByFile` | boolean | Group results by file (default false) |
|
|
2270
|
-
| `limit` | number | Max results to return |
|
|
2271
|
-
|
|
2272
|
-
**Returns:** `{ todos: [{ filePath, line, tag, assignee, text }], totalFound, byTag: { TODO: 12, FIXME: 3, ... } }`
|
|
2273
|
-
|
|
2274
|
-
---
|
|
2275
|
-
|
|
2276
|
-
### `get_complexity_hotspots`
|
|
2277
|
-
|
|
2278
|
-
Aggregate per-symbol complexity metrics to the file level and return a ranked list of the files with the highest complexity concentration.
|
|
2279
|
-
|
|
2280
|
-
```json
|
|
2281
|
-
{
|
|
2282
|
-
"repoId": "...",
|
|
2283
|
-
"scope": "src/core/",
|
|
2284
|
-
"topN": 10,
|
|
2285
|
-
"minComplexity": 3
|
|
2286
|
-
}
|
|
2287
|
-
```
|
|
2288
|
-
|
|
2289
|
-
| Parameter | Type | Description |
|
|
2290
|
-
|-----------|------|-------------|
|
|
2291
|
-
| `scope` | string | Restrict to a directory prefix |
|
|
2292
|
-
| `topN` | number | Number of hotspot files to return (default 10) |
|
|
2293
|
-
| `minComplexity` | number | Only count symbols with cyclomatic complexity ≥ this (default 1) |
|
|
2294
|
-
|
|
2295
|
-
**Returns:** `{ hotspots: [{ filePath, hotspotScore, avgComplexity, maxComplexity, symbolCount, topOffenders: [{ name, kind, complexity }] }] }`
|
|
2296
|
-
|
|
2297
|
-
`hotspotScore` is 0–100 (higher = more complex). Use this to answer "where should I focus refactoring effort?"
|
|
2298
|
-
|
|
2299
|
-
**Differs from related tools:**
|
|
2300
|
-
- `get_quality_metrics` — per-symbol composite score
|
|
2301
|
-
- `search_by_complexity` — threshold/range filter for individual symbols
|
|
2302
|
-
- `get_debt_report` — broader tech-debt summary including structural issues
|
|
2303
|
-
|
|
2304
|
-
---
|
|
2305
|
-
|
|
2306
|
-
### `get_type_graph`
|
|
2307
|
-
|
|
2308
|
-
Return the type dependency graph for a repository, showing how interfaces, classes, type aliases, and enums relate to each other through inheritance (`extends`), implementation (`implements`), and usage.
|
|
2309
|
-
|
|
2310
|
-
```json
|
|
2311
|
-
{
|
|
2312
|
-
"repoId": "...",
|
|
2313
|
-
"rootSymbol": "UserRepository",
|
|
2314
|
-
"maxDepth": 3,
|
|
2315
|
-
"scope": "src/domain/",
|
|
2316
|
-
"format": "mermaid"
|
|
2317
|
-
}
|
|
2318
|
-
```
|
|
2319
|
-
|
|
2320
|
-
| Parameter | Type | Description |
|
|
2321
|
-
|-----------|------|-------------|
|
|
2322
|
-
| `rootSymbol` | string | Name or ID of a type to root the graph at. Omit to return the full graph for the scope. |
|
|
2323
|
-
| `maxDepth` | number | Maximum traversal depth from `rootSymbol` (default 3) |
|
|
2324
|
-
| `scope` | string | Restrict to a directory prefix |
|
|
2325
|
-
| `includeExternal` | boolean | Include types that extend non-indexed base classes (default false) |
|
|
2326
|
-
| `format` | string | `"json"` (default) or `"mermaid"` |
|
|
2327
|
-
|
|
2328
|
-
**Returns (`json`):** `{ nodes: [{ id, name, kind, filePath }], edges: [{ source, target, relationship }] }` where `relationship` is `"extends"`, `"implements"`, or `"uses"`.
|
|
2329
|
-
|
|
2330
|
-
**Returns (`mermaid`):** A `classDiagram` block ready to paste into any Mermaid renderer.
|
|
2331
|
-
|
|
2332
|
-
**Differs from related tools:**
|
|
2333
|
-
- `get_class_hierarchy` — single-root ancestor/descendant tree for one class
|
|
2334
|
-
- `find_implementations` — all concrete implementations of one interface
|
|
2335
|
-
- `get_type_graph` — full multi-root graph of all type relationships in a scope
|
|
2336
|
-
|
|
2337
|
-
---
|
|
2338
|
-
|
|
2339
|
-
### `find_untested_symbols`
|
|
2340
|
-
|
|
2341
|
-
Identify symbols that do not appear to have test coverage by scanning test files for references to each symbol name. Returns a prioritized list ranked by cyclomatic complexity.
|
|
2342
|
-
|
|
2343
|
-
```json
|
|
2344
|
-
{
|
|
2345
|
-
"repoId": "...",
|
|
2346
|
-
"scope": "src/services/",
|
|
2347
|
-
"kinds": ["function", "method"],
|
|
2348
|
-
"minComplexity": 2,
|
|
2349
|
-
"limit": 50
|
|
2350
|
-
}
|
|
2351
|
-
```
|
|
2352
|
-
|
|
2353
|
-
| Parameter | Type | Description |
|
|
2354
|
-
|-----------|------|-------------|
|
|
2355
|
-
| `scope` | string | Restrict to a directory prefix |
|
|
2356
|
-
| `kinds` | array | Symbol kinds to check (default: `function`, `method`, `class`, `interface`, `middleware`, `route`) |
|
|
2357
|
-
| `minComplexity` | number | Only include symbols with cyclomatic complexity ≥ this (default 1) |
|
|
2358
|
-
| `limit` | number | Max symbols to return |
|
|
2359
|
-
|
|
2360
|
-
**Returns:** `{ untestedSymbols: [{ symbolId, name, kind, filePath, complexity, priority }], totalUntested, totalChecked }`
|
|
2361
|
-
|
|
2362
|
-
Priority: `"high"` (complexity ≥ 5 or ≥ 20 lines), `"medium"` (complexity ≥ 2 or ≥ 8 lines), `"low"` (all others).
|
|
2363
|
-
|
|
2364
|
-
**Detection strategy:** Static heuristic — a symbol's name must appear as an identifier in at least one test file. Not a coverage-report parser; use `get_test_coverage_map` for line-level accuracy.
|
|
2365
|
-
|
|
2366
|
-
---
|
|
2367
|
-
|
|
2368
|
-
### `get_test_coverage_map`
|
|
2369
|
-
|
|
2370
|
-
Parse a coverage JSON report (Istanbul/NYC or V8/c8 format) and map line-level coverage data to symbols in the indexed codebase.
|
|
2371
|
-
|
|
2372
|
-
```json
|
|
2373
|
-
{
|
|
2374
|
-
"repoId": "...",
|
|
2375
|
-
"coveragePath": "/project/coverage/coverage-final.json",
|
|
2376
|
-
"scope": "src/",
|
|
2377
|
-
"includeUncoveredOnly": false
|
|
2378
|
-
}
|
|
2379
|
-
```
|
|
2380
|
-
|
|
2381
|
-
| Parameter | Type | Description |
|
|
2382
|
-
|-----------|------|-------------|
|
|
2383
|
-
| `coveragePath` | string | Absolute path to the coverage JSON file |
|
|
2384
|
-
| `scope` | string | Restrict to a directory prefix |
|
|
2385
|
-
| `includeUncoveredOnly` | boolean | Return only uncovered symbols (default false) |
|
|
2386
|
-
| `format` | string | Auto-detected: `"istanbul"` or `"v8"` |
|
|
2387
|
-
|
|
2388
|
-
**Returns:** `{ files: [{ filePath, statements, functions, branches, lines, symbols: [{ name, kind, covered, callCount }] }], summary: { totalSymbols, coveredSymbols, coveragePercent } }`
|
|
2389
|
-
|
|
2390
|
-
**Supported report formats:**
|
|
2391
|
-
- **Istanbul/NYC:** `coverage-final.json` produced by `nyc`, `jest --coverage`, `vitest --coverage.reporter=json`, `c8`
|
|
2392
|
-
- **V8:** Array of `{ url, functions }` objects produced by `node --experimental-vm-modules` or `c8 --reporter=json`
|
|
2393
|
-
|
|
2394
|
-
**Differs from `find_untested_symbols`:** This tool requires a coverage file and delivers line-level accuracy. `find_untested_symbols` uses name-based heuristics and needs no coverage file.
|
|
2395
|
-
|
|
2396
|
-
---
|
|
2397
|
-
|
|
2398
|
-
## Quick Reference Card
|
|
2399
|
-
|
|
2400
|
-
```
|
|
2401
|
-
# Install
|
|
2402
|
-
npm install -g .
|
|
2403
|
-
|
|
2404
|
-
# Connect to Claude Code
|
|
2405
|
-
claude mcp add purecontext-mcp purecontext-mcp
|
|
2406
|
-
|
|
2407
|
-
# Generate config
|
|
2408
|
-
purecontext-mcp config --init
|
|
2409
|
-
|
|
2410
|
-
# Start HTTP server with Web UI
|
|
2411
|
-
purecontext-mcp --transport http --port 3000
|
|
2412
|
-
|
|
2413
|
-
# In Claude Code — core navigation
|
|
2414
|
-
index_folder → index a project
|
|
2415
|
-
search_symbols → find code by name or kind
|
|
2416
|
-
get_file_outline → see all symbols in a file
|
|
2417
|
-
get_symbol_source → retrieve a symbol's source
|
|
2418
|
-
get_context_bundle → symbol + what it depends on
|
|
2419
|
-
get_blast_radius → symbol + what depends on it
|
|
2420
|
-
search_text → grep-style text search
|
|
2421
|
-
search_semantic → meaning-based search
|
|
2422
|
-
find_dead_code → unused exports
|
|
2423
|
-
get_layer_violations → architecture rule checking
|
|
2424
|
-
get_savings_stats → view token savings
|
|
2425
|
-
|
|
2426
|
-
# Advanced relationship analysis (Phase 28)
|
|
2427
|
-
find_implementations → all classes implementing an interface
|
|
2428
|
-
get_call_hierarchy → callers/callees tree, N levels deep
|
|
2429
|
-
get_class_hierarchy → full inheritance chain (up and down)
|
|
2430
|
-
find_cycles → all import cycles with file paths
|
|
2431
|
-
get_coupling_map → per-file coupling scores (Martin's instability)
|
|
2432
|
-
|
|
2433
|
-
# Architectural visualization (Phase 29)
|
|
2434
|
-
render_diagram → Mermaid/DOT: import graph, call graph, class diagram
|
|
2435
|
-
render_call_graph → call graph rooted at a symbol
|
|
2436
|
-
render_import_graph → file-level import graph for a directory
|
|
2437
|
-
render_class_hierarchy → class inheritance diagram
|
|
2438
|
-
render_dep_matrix → dependency matrix heatmap (ASCII or Mermaid)
|
|
2439
|
-
get_architecture_snapshot → snapshot + diff of architecture state over time
|
|
2440
|
-
|
|
2441
|
-
# Refactoring safety checks (Phase 30)
|
|
2442
|
-
check_rename_safe → pre-flight: rename a symbol everywhere
|
|
2443
|
-
check_delete_safe → pre-flight: delete a symbol or file
|
|
2444
|
-
check_move_safe → pre-flight: move a file to a new path
|
|
2445
|
-
plan_refactoring → sequenced, risk-annotated refactoring plan
|
|
2446
|
-
|
|
2447
|
-
# Health dashboards & debt reporting (Phase 31)
|
|
2448
|
-
health_radar → 5-axis health score (0–100) with letter grade
|
|
2449
|
-
diff_health_radar → compare health between two repo states (PR review)
|
|
2450
|
-
get_debt_report → comprehensive debt report with action items
|
|
2451
|
-
|
|
2452
|
-
# AST-level search (Phase 32)
|
|
2453
|
-
search_ast → find any tree-sitter node type across all files
|
|
2454
|
-
search_by_signature → find symbols by type signature pattern
|
|
2455
|
-
search_by_decorator → find all symbols with a specific decorator
|
|
2456
|
-
search_by_complexity → find symbols matching complexity thresholds
|
|
2457
|
-
|
|
2458
|
-
# Code intelligence helpers (Phase 33)
|
|
2459
|
-
get_entry_points → find main functions, CLI handlers, Lambda, server startups
|
|
2460
|
-
get_public_api → all exported symbols grouped by file
|
|
2461
|
-
get_todos → TODO/FIXME/HACK/BUG inventory from comment tags
|
|
2462
|
-
get_complexity_hotspots → file-level complexity ranking for refactoring focus
|
|
2463
|
-
get_type_graph → full type/interface dependency graph (Mermaid or JSON)
|
|
2464
|
-
find_untested_symbols → symbols with no test coverage, ranked by complexity
|
|
2465
|
-
get_test_coverage_map → map Istanbul/V8 coverage JSON to indexed symbols
|
|
2466
|
-
```
|