codecompass-mcp 3.0.0__tar.gz → 3.0.1__tar.gz
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.
- codecompass_mcp-3.0.1/PKG-INFO +250 -0
- codecompass_mcp-3.0.1/README.md +212 -0
- codecompass_mcp-3.0.1/codecompass_mcp.egg-info/PKG-INFO +250 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/graph/code_graph_client.py +41 -29
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/graph/code_query_cli.py +1 -1
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/mcp_server.py +5 -2
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/pyproject.toml +1 -1
- codecompass_mcp-3.0.0/PKG-INFO +0 -421
- codecompass_mcp-3.0.0/README.md +0 -383
- codecompass_mcp-3.0.0/codecompass_mcp.egg-info/PKG-INFO +0 -421
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/LICENSE +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/SOURCES.txt +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/dependency_links.txt +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/entry_points.txt +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/requires.txt +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/codecompass_mcp.egg-info/top_level.txt +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/config.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/graph/__init__.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/graph/cli.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/graph/setup.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/__init__.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/chunker.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/code_normalizer.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/code_parser.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/description_enricher.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/entity_resolver.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/file_watcher.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/graph_writer.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/hierarchy_builder.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/reader_agent.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/ingestion/source_context.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/main.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/models/__init__.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/models/code_types.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/models/types.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/setup.cfg +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_accuracy_fixes.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_batch_impact.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_blast_radius.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_code_parser.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_description_enricher.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_ingestion.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_lit_css_parser.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_mcp_server.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/tests/test_php_parser.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/utils/__init__.py +0 -0
- {codecompass_mcp-3.0.0 → codecompass_mcp-3.0.1}/utils/formatting.py +0 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: codecompass-mcp
|
|
3
|
+
Version: 3.0.1
|
|
4
|
+
Summary: Structural code context for AI coding agents — a local code knowledge graph for blast radius, impact, deps, dead code, and flow tracing
|
|
5
|
+
Author: CodeCompass contributors
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: ai,code-graph,llm,coding-agent,tree-sitter
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Topic :: Software Development :: Code Generators
|
|
16
|
+
Classifier: Topic :: Software Development :: Compilers
|
|
17
|
+
Requires-Python: >=3.10
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
Requires-Dist: anthropic>=0.40.0
|
|
21
|
+
Requires-Dist: fastmcp>=2.0.0
|
|
22
|
+
Requires-Dist: networkx>=3.0
|
|
23
|
+
Requires-Dist: pypdf2>=3.0.0
|
|
24
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: tqdm>=4.66.0
|
|
27
|
+
Requires-Dist: tree-sitter>=0.21.0
|
|
28
|
+
Requires-Dist: tree-sitter-python>=0.21.0
|
|
29
|
+
Requires-Dist: tree-sitter-javascript>=0.21.0
|
|
30
|
+
Requires-Dist: tree-sitter-typescript>=0.21.0
|
|
31
|
+
Requires-Dist: tree-sitter-html>=0.21.0
|
|
32
|
+
Requires-Dist: tree-sitter-css>=0.21.0
|
|
33
|
+
Requires-Dist: watchdog>=4.0.0
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
# CodeCompass
|
|
40
|
+
|
|
41
|
+
A local code knowledge graph that gives AI agents a map of your codebase — so they navigate by structure instead of grepping blind, and know what's connected before they edit.
|
|
42
|
+
|
|
43
|
+
No database. No cloud. One JSON file per repo. Python, JavaScript/TypeScript, PHP, HTML/CSS.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Why it's faster
|
|
48
|
+
|
|
49
|
+
AI agents read files one at a time and grep to find their way. On a real task that means opening candidate after candidate to answer "who calls this?" or "what breaks if I change this?" CodeCompass answers those from a precomputed graph, so the agent reads *only the code it actually needs*.
|
|
50
|
+
|
|
51
|
+
We benchmarked it against traditional grep/read on six standard tasks (impact, blast radius, dead code, flow trace, find-and-edit, feature scoping) across four real repos, measuring **tokens to a verified answer** — the query output *plus* the code still read to trust it.
|
|
52
|
+
|
|
53
|
+

|
|
54
|
+
|
|
55
|
+
CodeCompass wins every relational and discovery task; grep only holds even on a
|
|
56
|
+
plain textual find of a known string. The advantage grows with codebase size and
|
|
57
|
+
name collisions. Full breakdown, per-task numbers, and honest limitations in
|
|
58
|
+
**[docs/benchmark-results.md](docs/benchmark-results.md)**.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## The workflow
|
|
63
|
+
|
|
64
|
+
The graph turns navigation into a cheap, deterministic loop:
|
|
65
|
+
|
|
66
|
+
**discover → trace → read → edit**
|
|
67
|
+
|
|
68
|
+
1. **Discover** — find the symbols you care about without opening files:
|
|
69
|
+
|
|
70
|
+
| You have… | Use |
|
|
71
|
+
|---|---|
|
|
72
|
+
| a feature request that names a concept ("session timeout") | `grep` the concept |
|
|
73
|
+
| a regex / name pattern | `grep` |
|
|
74
|
+
| keywords | `search` |
|
|
75
|
+
| a vague, nameless need | `map` (compact index to reason over) |
|
|
76
|
+
|
|
77
|
+
2. **Trace** — a relationship around a known symbol/file:
|
|
78
|
+
|
|
79
|
+
| Question | Use |
|
|
80
|
+
|---|---|
|
|
81
|
+
| who calls / would break if I change this? | `impact` |
|
|
82
|
+
| what files are affected if I edit this file? | `blast_radius` |
|
|
83
|
+
| what does this file depend on? | `deps` |
|
|
84
|
+
| what does this entry point call, step by step? | `flow` |
|
|
85
|
+
| explain a flow to a human (diagram + narration) | `flow_summary` |
|
|
86
|
+
| anything unused? | `dead_code` |
|
|
87
|
+
|
|
88
|
+
3. **Read** the specific slice the graph points to (`impact` gives `file:line`).
|
|
89
|
+
4. **Edit** — check `impact`/`blast_radius` first so you don't miss a caller.
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## What makes it accurate
|
|
94
|
+
|
|
95
|
+
- **Precise call graph.** Nodes are file- *and* class-qualified, so
|
|
96
|
+
`Command.invoke` and `Context.invoke` (same file) stay distinct, and
|
|
97
|
+
`impact` returns the callers of a *specific* method — no same-named
|
|
98
|
+
look-alikes, no test noise.
|
|
99
|
+
- **Receiver-type resolution.** `self.send()` resolves to the enclosing class;
|
|
100
|
+
`x = new Adapter()` / `x: Adapter` / `x = make()` (with a return type) resolve
|
|
101
|
+
by type. Calls that can't be typed statically (dynamic dispatch) are
|
|
102
|
+
**surfaced flagged `resolved: false`** — never dropped, never claimed precise.
|
|
103
|
+
- **Line-anchored.** Every `impact` caller carries its real call-site
|
|
104
|
+
`file:line`, so verification reads a few lines, not a whole function.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Install
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
pip install codecompass-mcp
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Gives you the `codecompass` CLI and the `codecompass-mcp` MCP server.
|
|
115
|
+
|
|
116
|
+
### Index a project
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cd /path/to/your/project
|
|
120
|
+
codecompass init # creates .codecompass/, writes AGENTS.md
|
|
121
|
+
codecompass ingest-code # parses source and builds the graph
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`ingest-code` runs `init` automatically if needed. Re-ingest after refactors (or run `codecompass watch` to keep the graph live).
|
|
125
|
+
|
|
126
|
+
### Connect an MCP client
|
|
127
|
+
|
|
128
|
+
The server speaks stdio MCP and defaults to the working directory.
|
|
129
|
+
|
|
130
|
+
**Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
131
|
+
|
|
132
|
+
```json
|
|
133
|
+
{ "mcpServers": { "codecompass": { "command": "codecompass-mcp" } } }
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Cline / Cursor / other** — add a server with command `codecompass-mcp`. To query a different repo, the agent calls `set_repo`, or set `CODECOMPASS_REPO=/path/to/project` in the server env.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Queries (CLI)
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# discover
|
|
144
|
+
codecompass query --grep "^get_" # regex over graph entities
|
|
145
|
+
codecompass query --search "session cookie" # keyword search
|
|
146
|
+
codecompass query --map # compact {file: [symbols]} index
|
|
147
|
+
|
|
148
|
+
# trace
|
|
149
|
+
codecompass query --impact "Session.send" # callers (disambiguated), with file:line
|
|
150
|
+
codecompass query --blast-radius src/app.py # what depends on this file
|
|
151
|
+
codecompass query --deps src/api/routes.py # what this file imports
|
|
152
|
+
codecompass query --flow "Session.request" # lean call-flow structure
|
|
153
|
+
codecompass query --flow-summary "main" # flow + mermaid + narration
|
|
154
|
+
codecompass query --dead-code # unreferenced candidates
|
|
155
|
+
codecompass query --tree # full hierarchy
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Add `--hops N` for traversal depth (start at 1 and follow the one path you need). Add `--rich` for tables.
|
|
159
|
+
|
|
160
|
+
### Flow: `flow` vs `flow-summary`
|
|
161
|
+
|
|
162
|
+
- **`flow`** — lean structure only (node name/kind/file/depth, edge from/to/order/line). What an agent needs to navigate; no embedded source.
|
|
163
|
+
- **`flow-summary`** — the trace rendered for a human: a mermaid flowchart with prose narration (`--format mermaid`, default), or source-embedded JSON (`--format json`), or a draw.io diagram (`--format drawio`). Written to `.codecompass/flow_<entry>.*`.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## MCP tools
|
|
168
|
+
|
|
169
|
+
| Tool | Returns |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `grep(pattern, field, ignore_case)` | Regex search over graph entities |
|
|
172
|
+
| `search(query, kind)` | Keyword search, ranked |
|
|
173
|
+
| `map(include_tests)` | Compact `{file: [symbols]}` index |
|
|
174
|
+
| `impact(symbol, hops)` | Callers/importers, disambiguated, with `resolved` + `line` |
|
|
175
|
+
| `blast_radius(target, hops)` | Files reachable from a file or symbol |
|
|
176
|
+
| `batch_impact(targets, hops)` | Union of blast radii for a multi-file change |
|
|
177
|
+
| `deps(file_path, hops)` | What a file imports |
|
|
178
|
+
| `flow(entry_symbol, hops)` | Lean call/import flow structure |
|
|
179
|
+
| `flow_summary(entry_symbol, hops, format)` | Flow + narration (mermaid/json/drawio) |
|
|
180
|
+
| `trace(symbol, hops)` | Forward call chain |
|
|
181
|
+
| `dead_code(include_entrypoints)` | Entities with no inbound caller |
|
|
182
|
+
| `styles(element)` | CSS selectors that style an element |
|
|
183
|
+
| `tree()` | Full project hierarchy |
|
|
184
|
+
| `set_repo` / `get_repo` / `init` / `ingest` | Project selection & indexing |
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## Supported languages
|
|
189
|
+
|
|
190
|
+
| Language | Extracted |
|
|
191
|
+
|---|---|
|
|
192
|
+
| Python | functions, classes, imports, calls, inheritance, receiver/return-type inference, `__all__`/public exports |
|
|
193
|
+
| JavaScript / JSX | functions, classes, `require`/`import`, calls, receiver/return-type inference, `module.exports`/`export` |
|
|
194
|
+
| TypeScript / TSX | as JS, plus type annotations for receiver resolution |
|
|
195
|
+
| PHP | functions, classes, methods, calls, receiver/return-type inference, `public`/`private`/`protected` visibility |
|
|
196
|
+
| HTML | elements, references, includes |
|
|
197
|
+
| CSS / SCSS | selectors, variables, `@import`/`@use` |
|
|
198
|
+
| `.styles.ts` (Lit) | CSS-in-JS `var(--token)` usages and `:host` declarations |
|
|
199
|
+
|
|
200
|
+
Receiver capture, type inference, and export/visibility awareness apply to all
|
|
201
|
+
call-based languages (JS/TS, Python, PHP). Node de-merge and the discovery tools
|
|
202
|
+
are language-agnostic.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Navigation guardrail (optional, installed by `init`)
|
|
207
|
+
|
|
208
|
+
`AGENTS.md` guides any agent through the discover→trace→read→edit loop. For
|
|
209
|
+
Claude Code and [pi](https://pi.dev), `init` also installs a `PreToolUse` hook
|
|
210
|
+
that **blocks code *search*** (`grep`/`rg`, the `Grep`/`Glob` tools) and
|
|
211
|
+
**whole-file `cat`**, routing discovery through the graph — while leaving
|
|
212
|
+
**targeted reads free** (the `Read` tool, `sed -n`, `head`/`tail`). The point is
|
|
213
|
+
to change the default reflex to graph-first, not to remove reads. Both pick the
|
|
214
|
+
files up after a one-time trust prompt (they execute shell commands). The hook
|
|
215
|
+
is a plain file under `.claude/hooks/` — edit or delete it to adjust.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## How it works
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
Source files
|
|
223
|
+
▼ hierarchy_builder walks repo → Project / Folder / File skeleton
|
|
224
|
+
▼ code_parser tree-sitter extraction (no API calls) → typed CodeTriples
|
|
225
|
+
▼ graph.json NetworkX MultiDiGraph as JSON; file+class-qualified nodes,
|
|
226
|
+
typed edges (CALLS/IMPORTS/INHERITS/STYLES/…), resolved calls
|
|
227
|
+
▼ code_query_cli traversal: grep / search / map / impact / blast-radius /
|
|
228
|
+
deps / flow / dead-code / tree
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Everything runs locally, in-process. No network, no database, no API keys.
|
|
232
|
+
|
|
233
|
+
Inside each indexed project:
|
|
234
|
+
|
|
235
|
+
```
|
|
236
|
+
your-project/
|
|
237
|
+
├── .codecompass/graph.json the code knowledge graph (auto-generated)
|
|
238
|
+
└── AGENTS.md discovery guide for agents (auto-updated)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Limitations
|
|
244
|
+
|
|
245
|
+
- **Structure, not semantics** — the graph knows what calls what, not what it means.
|
|
246
|
+
- **Static analysis** — dynamic dispatch, reflection, and string-based invocation
|
|
247
|
+
can't be fully resolved. `impact` surfaces those flagged `resolved: false`, and
|
|
248
|
+
`dead_code` results are always candidates to verify.
|
|
249
|
+
- **No cross-repo edges** — entities outside the indexed repo don't appear.
|
|
250
|
+
- **Re-ingest after refactors** — the graph doesn't auto-update unless `watch` is running.
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
# CodeCompass
|
|
2
|
+
|
|
3
|
+
A local code knowledge graph that gives AI agents a map of your codebase — so they navigate by structure instead of grepping blind, and know what's connected before they edit.
|
|
4
|
+
|
|
5
|
+
No database. No cloud. One JSON file per repo. Python, JavaScript/TypeScript, PHP, HTML/CSS.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why it's faster
|
|
10
|
+
|
|
11
|
+
AI agents read files one at a time and grep to find their way. On a real task that means opening candidate after candidate to answer "who calls this?" or "what breaks if I change this?" CodeCompass answers those from a precomputed graph, so the agent reads *only the code it actually needs*.
|
|
12
|
+
|
|
13
|
+
We benchmarked it against traditional grep/read on six standard tasks (impact, blast radius, dead code, flow trace, find-and-edit, feature scoping) across four real repos, measuring **tokens to a verified answer** — the query output *plus* the code still read to trust it.
|
|
14
|
+
|
|
15
|
+

|
|
16
|
+
|
|
17
|
+
CodeCompass wins every relational and discovery task; grep only holds even on a
|
|
18
|
+
plain textual find of a known string. The advantage grows with codebase size and
|
|
19
|
+
name collisions. Full breakdown, per-task numbers, and honest limitations in
|
|
20
|
+
**[docs/benchmark-results.md](docs/benchmark-results.md)**.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## The workflow
|
|
25
|
+
|
|
26
|
+
The graph turns navigation into a cheap, deterministic loop:
|
|
27
|
+
|
|
28
|
+
**discover → trace → read → edit**
|
|
29
|
+
|
|
30
|
+
1. **Discover** — find the symbols you care about without opening files:
|
|
31
|
+
|
|
32
|
+
| You have… | Use |
|
|
33
|
+
|---|---|
|
|
34
|
+
| a feature request that names a concept ("session timeout") | `grep` the concept |
|
|
35
|
+
| a regex / name pattern | `grep` |
|
|
36
|
+
| keywords | `search` |
|
|
37
|
+
| a vague, nameless need | `map` (compact index to reason over) |
|
|
38
|
+
|
|
39
|
+
2. **Trace** — a relationship around a known symbol/file:
|
|
40
|
+
|
|
41
|
+
| Question | Use |
|
|
42
|
+
|---|---|
|
|
43
|
+
| who calls / would break if I change this? | `impact` |
|
|
44
|
+
| what files are affected if I edit this file? | `blast_radius` |
|
|
45
|
+
| what does this file depend on? | `deps` |
|
|
46
|
+
| what does this entry point call, step by step? | `flow` |
|
|
47
|
+
| explain a flow to a human (diagram + narration) | `flow_summary` |
|
|
48
|
+
| anything unused? | `dead_code` |
|
|
49
|
+
|
|
50
|
+
3. **Read** the specific slice the graph points to (`impact` gives `file:line`).
|
|
51
|
+
4. **Edit** — check `impact`/`blast_radius` first so you don't miss a caller.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## What makes it accurate
|
|
56
|
+
|
|
57
|
+
- **Precise call graph.** Nodes are file- *and* class-qualified, so
|
|
58
|
+
`Command.invoke` and `Context.invoke` (same file) stay distinct, and
|
|
59
|
+
`impact` returns the callers of a *specific* method — no same-named
|
|
60
|
+
look-alikes, no test noise.
|
|
61
|
+
- **Receiver-type resolution.** `self.send()` resolves to the enclosing class;
|
|
62
|
+
`x = new Adapter()` / `x: Adapter` / `x = make()` (with a return type) resolve
|
|
63
|
+
by type. Calls that can't be typed statically (dynamic dispatch) are
|
|
64
|
+
**surfaced flagged `resolved: false`** — never dropped, never claimed precise.
|
|
65
|
+
- **Line-anchored.** Every `impact` caller carries its real call-site
|
|
66
|
+
`file:line`, so verification reads a few lines, not a whole function.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Install
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
pip install codecompass-mcp
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Gives you the `codecompass` CLI and the `codecompass-mcp` MCP server.
|
|
77
|
+
|
|
78
|
+
### Index a project
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
cd /path/to/your/project
|
|
82
|
+
codecompass init # creates .codecompass/, writes AGENTS.md
|
|
83
|
+
codecompass ingest-code # parses source and builds the graph
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`ingest-code` runs `init` automatically if needed. Re-ingest after refactors (or run `codecompass watch` to keep the graph live).
|
|
87
|
+
|
|
88
|
+
### Connect an MCP client
|
|
89
|
+
|
|
90
|
+
The server speaks stdio MCP and defaults to the working directory.
|
|
91
|
+
|
|
92
|
+
**Claude Desktop** — `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
93
|
+
|
|
94
|
+
```json
|
|
95
|
+
{ "mcpServers": { "codecompass": { "command": "codecompass-mcp" } } }
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Cline / Cursor / other** — add a server with command `codecompass-mcp`. To query a different repo, the agent calls `set_repo`, or set `CODECOMPASS_REPO=/path/to/project` in the server env.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Queries (CLI)
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# discover
|
|
106
|
+
codecompass query --grep "^get_" # regex over graph entities
|
|
107
|
+
codecompass query --search "session cookie" # keyword search
|
|
108
|
+
codecompass query --map # compact {file: [symbols]} index
|
|
109
|
+
|
|
110
|
+
# trace
|
|
111
|
+
codecompass query --impact "Session.send" # callers (disambiguated), with file:line
|
|
112
|
+
codecompass query --blast-radius src/app.py # what depends on this file
|
|
113
|
+
codecompass query --deps src/api/routes.py # what this file imports
|
|
114
|
+
codecompass query --flow "Session.request" # lean call-flow structure
|
|
115
|
+
codecompass query --flow-summary "main" # flow + mermaid + narration
|
|
116
|
+
codecompass query --dead-code # unreferenced candidates
|
|
117
|
+
codecompass query --tree # full hierarchy
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Add `--hops N` for traversal depth (start at 1 and follow the one path you need). Add `--rich` for tables.
|
|
121
|
+
|
|
122
|
+
### Flow: `flow` vs `flow-summary`
|
|
123
|
+
|
|
124
|
+
- **`flow`** — lean structure only (node name/kind/file/depth, edge from/to/order/line). What an agent needs to navigate; no embedded source.
|
|
125
|
+
- **`flow-summary`** — the trace rendered for a human: a mermaid flowchart with prose narration (`--format mermaid`, default), or source-embedded JSON (`--format json`), or a draw.io diagram (`--format drawio`). Written to `.codecompass/flow_<entry>.*`.
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## MCP tools
|
|
130
|
+
|
|
131
|
+
| Tool | Returns |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `grep(pattern, field, ignore_case)` | Regex search over graph entities |
|
|
134
|
+
| `search(query, kind)` | Keyword search, ranked |
|
|
135
|
+
| `map(include_tests)` | Compact `{file: [symbols]}` index |
|
|
136
|
+
| `impact(symbol, hops)` | Callers/importers, disambiguated, with `resolved` + `line` |
|
|
137
|
+
| `blast_radius(target, hops)` | Files reachable from a file or symbol |
|
|
138
|
+
| `batch_impact(targets, hops)` | Union of blast radii for a multi-file change |
|
|
139
|
+
| `deps(file_path, hops)` | What a file imports |
|
|
140
|
+
| `flow(entry_symbol, hops)` | Lean call/import flow structure |
|
|
141
|
+
| `flow_summary(entry_symbol, hops, format)` | Flow + narration (mermaid/json/drawio) |
|
|
142
|
+
| `trace(symbol, hops)` | Forward call chain |
|
|
143
|
+
| `dead_code(include_entrypoints)` | Entities with no inbound caller |
|
|
144
|
+
| `styles(element)` | CSS selectors that style an element |
|
|
145
|
+
| `tree()` | Full project hierarchy |
|
|
146
|
+
| `set_repo` / `get_repo` / `init` / `ingest` | Project selection & indexing |
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Supported languages
|
|
151
|
+
|
|
152
|
+
| Language | Extracted |
|
|
153
|
+
|---|---|
|
|
154
|
+
| Python | functions, classes, imports, calls, inheritance, receiver/return-type inference, `__all__`/public exports |
|
|
155
|
+
| JavaScript / JSX | functions, classes, `require`/`import`, calls, receiver/return-type inference, `module.exports`/`export` |
|
|
156
|
+
| TypeScript / TSX | as JS, plus type annotations for receiver resolution |
|
|
157
|
+
| PHP | functions, classes, methods, calls, receiver/return-type inference, `public`/`private`/`protected` visibility |
|
|
158
|
+
| HTML | elements, references, includes |
|
|
159
|
+
| CSS / SCSS | selectors, variables, `@import`/`@use` |
|
|
160
|
+
| `.styles.ts` (Lit) | CSS-in-JS `var(--token)` usages and `:host` declarations |
|
|
161
|
+
|
|
162
|
+
Receiver capture, type inference, and export/visibility awareness apply to all
|
|
163
|
+
call-based languages (JS/TS, Python, PHP). Node de-merge and the discovery tools
|
|
164
|
+
are language-agnostic.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Navigation guardrail (optional, installed by `init`)
|
|
169
|
+
|
|
170
|
+
`AGENTS.md` guides any agent through the discover→trace→read→edit loop. For
|
|
171
|
+
Claude Code and [pi](https://pi.dev), `init` also installs a `PreToolUse` hook
|
|
172
|
+
that **blocks code *search*** (`grep`/`rg`, the `Grep`/`Glob` tools) and
|
|
173
|
+
**whole-file `cat`**, routing discovery through the graph — while leaving
|
|
174
|
+
**targeted reads free** (the `Read` tool, `sed -n`, `head`/`tail`). The point is
|
|
175
|
+
to change the default reflex to graph-first, not to remove reads. Both pick the
|
|
176
|
+
files up after a one-time trust prompt (they execute shell commands). The hook
|
|
177
|
+
is a plain file under `.claude/hooks/` — edit or delete it to adjust.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
## How it works
|
|
182
|
+
|
|
183
|
+
```
|
|
184
|
+
Source files
|
|
185
|
+
▼ hierarchy_builder walks repo → Project / Folder / File skeleton
|
|
186
|
+
▼ code_parser tree-sitter extraction (no API calls) → typed CodeTriples
|
|
187
|
+
▼ graph.json NetworkX MultiDiGraph as JSON; file+class-qualified nodes,
|
|
188
|
+
typed edges (CALLS/IMPORTS/INHERITS/STYLES/…), resolved calls
|
|
189
|
+
▼ code_query_cli traversal: grep / search / map / impact / blast-radius /
|
|
190
|
+
deps / flow / dead-code / tree
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Everything runs locally, in-process. No network, no database, no API keys.
|
|
194
|
+
|
|
195
|
+
Inside each indexed project:
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
your-project/
|
|
199
|
+
├── .codecompass/graph.json the code knowledge graph (auto-generated)
|
|
200
|
+
└── AGENTS.md discovery guide for agents (auto-updated)
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Limitations
|
|
206
|
+
|
|
207
|
+
- **Structure, not semantics** — the graph knows what calls what, not what it means.
|
|
208
|
+
- **Static analysis** — dynamic dispatch, reflection, and string-based invocation
|
|
209
|
+
can't be fully resolved. `impact` surfaces those flagged `resolved: false`, and
|
|
210
|
+
`dead_code` results are always candidates to verify.
|
|
211
|
+
- **No cross-repo edges** — entities outside the indexed repo don't appear.
|
|
212
|
+
- **Re-ingest after refactors** — the graph doesn't auto-update unless `watch` is running.
|