project-graph-mcp 2.1.3 → 2.1.5

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/GUIDE.md ADDED
@@ -0,0 +1,237 @@
1
+ # Project Graph MCP — Usage Guide
2
+
3
+ ## Quick Start Workflow
4
+ 1. `get_ai_context({ path: "src/" })` → boot AI context (skeleton + docs)
5
+ 2. `get_focus_zone({ recentFiles: ["src/parser.js"] })` → enriched context for area of interest
6
+ 3. Make code changes
7
+ 4. `invalidate_cache()` → always after edits
8
+ 5. `analyze({ action: "analysis_summary", path: "src/" })` → verify quality
9
+
10
+ ## Two-Tier Context Model
11
+ Project Graph MCP operates on a dual-layer context model designed for token efficiency and high context awareness:
12
+ - **Skeleton (Overview)**: Provides a high-level map of the whole project (2-5K tokens). It includes file paths, exported symbols, and structural relationships without the implementation details.
13
+ - **Focus Zone (Detailed)**: When drilling into specific areas, agents receive the full context for those files (1-3K tokens per file), including implementation and associated `.ctx` documentation.
14
+
15
+ The key insight: agents read the whole project cheaply via the skeleton, then drill into specific files with full context when needed.
16
+
17
+ ## Navigation
18
+ Use the `navigate` tool to explore the codebase structure and dependencies.
19
+
20
+ ```javascript
21
+ // Expand a specific symbol to see its definition
22
+ navigate({ action: "expand", symbol: "MyClass" });
23
+
24
+ // Find where a specific file or symbol is imported/used
25
+ navigate({ action: "usages", path: "src/parser.js" });
26
+
27
+ // Get dependencies of a specific file
28
+ navigate({ action: "deps", path: "src/core/workspace.js" });
29
+
30
+ // Trace the call chain for a function
31
+ navigate({ action: "call_chain", symbol: "processData" });
32
+
33
+ // List sub-projects or modules
34
+ navigate({ action: "sub_projects" });
35
+ ```
36
+
37
+ ## Analysis
38
+ Use the `analyze` tool to inspect code quality, find issues, and gather metrics.
39
+
40
+ ```javascript
41
+ // Get a comprehensive summary of codebase health
42
+ analyze({ action: "analysis_summary", path: "src/" });
43
+
44
+ // Find dead or unused code
45
+ analyze({ action: "dead_code", path: "src/" });
46
+
47
+ // Detect potentially duplicate or similar functions
48
+ analyze({ action: "similar_functions", path: "src/" });
49
+
50
+ // Identify complex files requiring refactoring
51
+ analyze({ action: "complexity", path: "src/" });
52
+
53
+ // Find unusually large files
54
+ analyze({ action: "large_files", path: "src/" });
55
+
56
+ // Check for outdated framework patterns
57
+ analyze({ action: "outdated_patterns", path: "src/" });
58
+
59
+ // Find undocumented code blocks
60
+ analyze({ action: "undocumented", path: "src/" });
61
+
62
+ // Run a full suite of analysis checks
63
+ analyze({ action: "full_analysis", path: "src/" });
64
+ ```
65
+
66
+ ## Compact Code
67
+ Use the `compact` tool to compress and expand codebase files, enforce compact mode standards, and configure how code is presented to the AI.
68
+
69
+ ### Compact Mode Standards
70
+ Compact mode enforces 5 style rules for maximum token efficiency:
71
+ - **`missing-ctx-header`**: Every `.js` file must start with `// @ctx .context/path/to/file.ctx`
72
+ - **`missing-ctx-file`**: Every `.js` file must have a corresponding `.ctx` documentation file
73
+ - **`multi-line-imports`**: All imports must be on a single line
74
+ - **`indented-lines`**: No indentation — all code must be flat (terser-minified)
75
+ - **`long-names`**: All identifiers (const/let/var/function) must be ≤2 chars — `.ctx` provides readability
76
+ - **`incomplete-ctx`**: Every export must be documented in `.ctx`, no `{DESCRIBE}` placeholders allowed
77
+
78
+ ### .pgignore
79
+ File exclusions are configured via `.pgignore` (created automatically if missing):
80
+ ```
81
+ # Third-party vendored code
82
+ vendor/
83
+
84
+ # Generated files
85
+ .context/
86
+ .expanded/
87
+ ```
88
+
89
+ ### Bidirectional Workflow
90
+ The compact pipeline works in both directions:
91
+ 1. **Compact (fix:true)**: Parses readable code → generates `.ctx` with full signatures → minifies with terser
92
+ 2. **Expand**: Reads `.ctx` → restores JSDoc, readable names, and formatting
93
+
94
+ ```javascript
95
+ // Validate compact mode compliance (read-only check)
96
+ compact({ action: "validate_pipeline", path: "." });
97
+
98
+ // Auto-fix all style violations + generate .ctx documentation
99
+ compact({ action: "validate_pipeline", path: ".", fix: true });
100
+
101
+ // Compact a single file
102
+ compact({ action: "compact_file", path: "src/parser.js" });
103
+
104
+ // Apply a targeted edit to a compacted file
105
+ compact({ action: "edit", path: "src/parser.js", symbol: "parseFile", code: "..." });
106
+
107
+ // Compact all files in a directory
108
+ compact({ action: "compact_all", path: "src/" });
109
+
110
+ // Format and beautify a file
111
+ compact({ action: "beautify", path: "src/index.js" });
112
+
113
+ // Expand a previously compacted file to its full content
114
+ compact({ action: "expand_file", path: "src/parser.js" });
115
+
116
+ // Expand the entire project back to full source
117
+ compact({ action: "expand_project" });
118
+
119
+ // Get current compaction mode settings
120
+ compact({ action: "get_mode" });
121
+
122
+ // Set compaction mode: 1 (compact, recommended) or 2 (full)
123
+ compact({ action: "set_mode", mode: 1 });
124
+ ```
125
+
126
+ ## Documentation (.ctx)
127
+ Use the `docs` tool to manage and interact with project context (`.ctx`) files.
128
+
129
+ ```javascript
130
+ // Get documentation for a specific file
131
+ docs({ action: "get", path: "src/core/workspace.js" });
132
+
133
+ // Generate missing documentation for a directory
134
+ docs({ action: "generate", path: "src/utils/" });
135
+
136
+ // Check for stale or outdated documentation
137
+ docs({ action: "check_stale", path: "src/" });
138
+
139
+ // Validate interface and API contracts
140
+ docs({ action: "validate_contracts", path: "src/" });
141
+ ```
142
+
143
+ ## Database Analysis
144
+ Use the `db` tool to analyze database schemas and queries within the code.
145
+
146
+ ```javascript
147
+ // Extract the inferred database schema
148
+ db({ action: "schema", path: "src/" });
149
+
150
+ // Find where specific database tables are accessed
151
+ db({ action: "table_usage", table: "users" });
152
+
153
+ // Identify defined tables that are never queried
154
+ db({ action: "dead_tables", path: "src/" });
155
+ ```
156
+
157
+ ## Testing
158
+ Use the `testing` tool to manage and track test states and annotations.
159
+
160
+ ```javascript
161
+ // List tests marked as pending or TODO
162
+ testing({ action: "pending", path: "tests/" });
163
+
164
+ // Mark specific tests as passing
165
+ testing({ action: "pass", testIds: ["test-123"] });
166
+
167
+ // Mark specific tests as failing
168
+ testing({ action: "fail", testIds: ["test-456"] });
169
+
170
+ // Get a summary of current test statuses
171
+ testing({ action: "summary", path: "tests/" });
172
+
173
+ // Reset all test statuses
174
+ testing({ action: "reset" });
175
+ ```
176
+
177
+ ## JSDoc
178
+ Use the `jsdoc` tool to manage JSDoc comments and type annotations.
179
+
180
+ ```javascript
181
+ // Check for inconsistencies between JSDoc and actual code
182
+ jsdoc({ action: "check_consistency", path: "src/" });
183
+
184
+ // Validate JSDoc types
185
+ jsdoc({ action: "check_types", path: "src/" });
186
+
187
+ // Generate missing JSDoc comments
188
+ jsdoc({ action: "generate", path: "src/core/" });
189
+ ```
190
+
191
+ ## Filters
192
+ Use the `filters` tool to configure which files the MCP server includes or ignores.
193
+
194
+ ```javascript
195
+ // Get current active filters
196
+ filters({ action: "get" });
197
+
198
+ // Set specific inclusion/exclusion patterns
199
+ filters({ action: "set", includes: ["src/**/*.js"], excludes: ["tests/"] });
200
+
201
+ // Add patterns to the exclusion list
202
+ filters({ action: "add_excludes", patterns: ["dist/", "build/"] });
203
+
204
+ // Remove patterns from the exclusion list
205
+ filters({ action: "remove_excludes", patterns: ["tests/"] });
206
+
207
+ // Reset filters to default
208
+ filters({ action: "reset" });
209
+ ```
210
+
211
+ ## Custom Rules
212
+ Manage custom linting or architectural rules specific to the project.
213
+
214
+ ```javascript
215
+ // Retrieve all custom rules
216
+ get_custom_rules();
217
+
218
+ // Define a new custom rule
219
+ set_custom_rule({ name: "no-console", description: "Disallow console.log", pattern: "console\\.log" });
220
+
221
+ // Check codebase against defined custom rules
222
+ check_custom_rules({ path: "src/" });
223
+ ```
224
+
225
+ ## Self-Discovery Tools
226
+ Agents can use these tools to learn about the workspace and available workflows.
227
+
228
+ ```javascript
229
+ // Read a specific section of this usage guide
230
+ get_usage_guide({ topic: "navigation" });
231
+
232
+ // Retrieve project-specific coding guidelines and agent rules
233
+ get_agent_instructions();
234
+
235
+ // Fetch framework or library documentation referenced in the project
236
+ get_framework_reference({ path: "src/" });
237
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "project-graph-mcp",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "type": "module",
5
5
  "description": "MCP server for AI agents — project graph, code quality analysis, visual web explorer. JS, TS, Python, Go.",
6
6
  "main": "src/network/server.js",
@@ -13,6 +13,7 @@
13
13
  "vendor/",
14
14
  "rules/",
15
15
  "docs/",
16
+ "GUIDE.md",
16
17
  "CONFIGURATION.md",
17
18
  "README.md",
18
19
  "LICENSE"
@@ -1,6 +1,6 @@
1
1
  // @ctx .context/src/network/web-server.ctx
2
2
  import e from"node:http";import t from"node:fs";import o from"node:path";import n from"node:crypto";import{fileURLToPath as a}from"node:url";import{WebSocketServer as s}from"ws";import{createServer as i}from"../mcp/mcp-server.js";import c from"../core/event-bus.js";import{registerService as r}from"./local-gateway.js";import{expandFile as l}from"../compact/expand.js";import{setRoots as _setRoots}from"../core/workspace.js";
3
- const d=o.dirname(a(import.meta.url)),p=o.join(d,"..",".."),m=o.join(p,"web"),h={"symbiote-node":o.join(p,"node_modules","symbiote-node"),symbiote:o.join(p,"node_modules","@symbiotejs","symbiote")},f={".html":"text/html",".js":"text/javascript",".mjs":"text/javascript",".css":"text/css",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon",".woff2":"font/woff2"};
3
+ const d=o.dirname(a(import.meta.url)),p=o.join(d,"..","..");function _rv(k,n){const a=o.join(p,"node_modules",n||k);if(t.existsSync(a))return a;const b=o.join(p,"..","..","node_modules",n||k);if(t.existsSync(b))return b;const c=o.join(p,"..",n||k);return t.existsSync(c)?c:a}const m=o.join(p,"web"),h={"symbiote-node":_rv("symbiote-node"),symbiote:_rv("symbiote",o.join("@symbiotejs","symbiote"))},f={".html":"text/html",".js":"text/javascript",".mjs":"text/javascript",".css":"text/css",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon",".woff2":"font/woff2"};
4
4
  function g(e,n){const a=o.normalize(e).replace(/^(\.\.[/\\])+/,""),s=a.match(/^[/\\]?vendor[/\\]([^/\\]+)[/\\]?(.*)/);let i,c;if(s&&h[s[1]]?(c=h[s[1]],i=o.join(c,s[2]||"index.js")):(c=m,i=o.join(m,"/"===a?"index.html":a)),!i.startsWith(c))return n.writeHead(403),void n.end("Forbidden");if(t.existsSync(i)&&t.statSync(i).isDirectory()&&(i=o.join(i,"index.html")),!t.existsSync(i))return n.writeHead(404),void n.end("Not Found");const r=o.extname(i),l=f[r]||"application/octet-stream",d=t.readFileSync(i);n.writeHead(200,{"Content-Type":l,"Cache-Control":"no-cache, no-store, must-revalidate"}),n.end(d)}
5
5
  function u(e){return n.createHash("sha1").update(e+"258EAFA5-E914-47DA-95CA-5AB5ADF35C70").digest("base64")}
6
6
  function y(e){const t=Buffer.from(e,"utf8"),o=t.length;let n;return o<126?(n=Buffer.alloc(2),n[0]=129,n[1]=o):o<65536?(n=Buffer.alloc(4),n[0]=129,n[1]=126,n.writeUInt16BE(o,2)):(n=Buffer.alloc(10),n[0]=129,n[1]=127,n.writeBigUInt64BE(BigInt(o),2)),Buffer.concat([n,t])}