gdep-mcp 0.1.7 → 0.1.11

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/README.md CHANGED
@@ -1,76 +1,76 @@
1
- # gdep-mcp
2
-
3
- > MCP server for [gdep](https://github.com/pirua-game/gdep) — Game Codebase Analysis Tool
4
-
5
- Enables Claude Desktop, Cursor, and other MCP-compatible AI agents to analyze game projects
6
- (Unity, Unreal Engine 5, C++, C#) using gdep.
7
-
8
- ## Install
9
-
10
- ```bash
11
- npm install -g gdep-mcp
12
- ```
13
-
14
- Automatically installs the `gdep` Python package and `mcp[cli]` dependencies.
15
-
16
- ## Usage
17
-
18
- Add to your AI agent config:
19
-
20
- **Claude Desktop** (`claude_desktop_config.json`):
21
- ```json
22
- {
23
- "mcpServers": {
24
- "gdep": {
25
- "command": "gdep-mcp"
26
- }
27
- }
28
- }
29
- ```
30
-
31
- **Cursor** (`.cursor/mcp.json`):
32
- ```json
33
- {
34
- "mcpServers": {
35
- "gdep": {
36
- "command": "gdep-mcp"
37
- }
38
- }
39
- }
40
- ```
41
-
42
- > Each tool accepts `project_path` as a call parameter — no path needed in the config.
43
-
44
- ## Requirements
45
-
46
- - Node.js 18+
47
- - Python 3.11+
48
- - .NET Runtime 8.0+ (for C#/Unity analysis)
49
-
50
- ## Available Tools (13)
51
-
52
- | Tool | Description |
53
- |------|-------------|
54
- | `get_project_context` | Project overview — call first |
55
- | `analyze_impact_and_risk` | Change impact + lint |
56
- | `trace_gameplay_flow` | Call chain tracing (C++→BP) |
57
- | `inspect_architectural_health` | Tech debt diagnosis |
58
- | `explore_class_semantics` | Class structure + AI summary |
59
- | `execute_gdep_cli` | Raw CLI access |
60
- | `find_unity_event_bindings` | Unity Inspector bindings |
61
- | `analyze_unity_animator` | Unity Animator state machine |
62
- | `analyze_ue5_gas` | UE5 GAS full analysis |
63
- | `analyze_ue5_behavior_tree` | BehaviorTree structure |
64
- | `analyze_ue5_state_tree` | StateTree structure |
65
- | `analyze_ue5_animation` | ABP + Montage analysis |
66
- | `analyze_ue5_blueprint_mapping` | C++ → Blueprint mapping |
67
-
68
- ## Links
69
-
70
- - [GitHub Repository](https://github.com/pirua-game/gdep)
71
- - [Full Documentation](https://github.com/pirua-game/gdep/blob/main/README.md)
72
- - [Benchmark](https://github.com/pirua-game/gdep/blob/main/docs/BENCHMARK.md)
73
-
74
- ## License
75
-
76
- Apache-2.0
1
+ # gdep-mcp
2
+
3
+ > MCP server for [gdep](https://github.com/pirua-game/gdep) — Game Codebase Analysis Tool
4
+
5
+ Enables Claude Desktop, Cursor, and other MCP-compatible AI agents to analyze game projects
6
+ (Unity, Unreal Engine 5, C++, C#) using gdep.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ npm install -g gdep-mcp
12
+ ```
13
+
14
+ Automatically installs the `gdep` Python package and `mcp[cli]` dependencies.
15
+
16
+ ## Usage
17
+
18
+ Add to your AI agent config:
19
+
20
+ **Claude Desktop** (`claude_desktop_config.json`):
21
+ ```json
22
+ {
23
+ "mcpServers": {
24
+ "gdep": {
25
+ "command": "gdep-mcp"
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ **Cursor** (`.cursor/mcp.json`):
32
+ ```json
33
+ {
34
+ "mcpServers": {
35
+ "gdep": {
36
+ "command": "gdep-mcp"
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ > Each tool accepts `project_path` as a call parameter — no path needed in the config.
43
+
44
+ ## Requirements
45
+
46
+ - Node.js 18+
47
+ - Python 3.11+
48
+ - .NET Runtime 8.0+ (for C#/Unity analysis)
49
+
50
+ ## Available Tools (13)
51
+
52
+ | Tool | Description |
53
+ |------|-------------|
54
+ | `get_project_context` | Project overview — call first |
55
+ | `analyze_impact_and_risk` | Change impact + lint |
56
+ | `trace_gameplay_flow` | Call chain tracing (C++→BP) |
57
+ | `inspect_architectural_health` | Tech debt diagnosis |
58
+ | `explore_class_semantics` | Class structure + AI summary |
59
+ | `execute_gdep_cli` | Raw CLI access |
60
+ | `find_unity_event_bindings` | Unity Inspector bindings |
61
+ | `analyze_unity_animator` | Unity Animator state machine |
62
+ | `analyze_ue5_gas` | UE5 GAS full analysis |
63
+ | `analyze_ue5_behavior_tree` | BehaviorTree structure |
64
+ | `analyze_ue5_state_tree` | StateTree structure |
65
+ | `analyze_ue5_animation` | ABP + Montage analysis |
66
+ | `analyze_ue5_blueprint_mapping` | C++ → Blueprint mapping |
67
+
68
+ ## Links
69
+
70
+ - [GitHub Repository](https://github.com/pirua-game/gdep)
71
+ - [Full Documentation](https://github.com/pirua-game/gdep/blob/main/README.md)
72
+ - [Benchmark](https://github.com/pirua-game/gdep/blob/main/docs/BENCHMARK.md)
73
+
74
+ ## License
75
+
76
+ Apache-2.0
package/bin/gdep-mcp.js CHANGED
@@ -5,26 +5,38 @@
5
5
  * Usage: gdep-mcp
6
6
  */
7
7
 
8
- const { spawn, execSync } = require('child_process');
8
+ const { spawn, spawnSync } = require('child_process');
9
9
  const os = require('os');
10
10
  const fs = require('fs');
11
11
  const path = require('path');
12
12
 
13
13
  const isWin = os.platform() === 'win32';
14
14
 
15
- // ── Find Python 3.11+ (same logic as postinstall) ─────────────
15
+ // ── Find Python 3.11+ ─────────────────────────────────────────
16
+ // Returns { exe: string, extraArgs: string[] } or null.
17
+ // Uses array-based spawnSync to avoid shell interpretation issues
18
+ // with paths containing spaces.
16
19
  function findPython() {
17
20
  const candidates = isWin
18
- ? ['py -3.11', 'py -3.12', 'py -3.13', 'python3.11', 'python3', 'python']
19
- : ['python3.11', 'python3.12', 'python3.13', 'python3', 'python'];
21
+ ? [['py', '-3.11'], ['py', '-3.12'], ['py', '-3.13'], ['python3.11'], ['python3'], ['python']]
22
+ : [['python3.11'], ['python3.12'], ['python3.13'], ['python3'], ['python']];
20
23
 
21
- for (const cmd of candidates) {
24
+ for (const parts of candidates) {
22
25
  try {
23
- const ver = execSync(`${cmd} --version`, { encoding: 'utf8', stdio: ['pipe','pipe','pipe'] }).trim();
26
+ const args = [...parts.slice(1), '--version'];
27
+ const result = spawnSync(parts[0], args, {
28
+ encoding: 'utf8',
29
+ stdio: ['pipe', 'pipe', 'pipe'],
30
+ timeout: 5000,
31
+ });
32
+ if (result.status !== 0) continue;
33
+ const ver = (result.stdout || '').trim();
24
34
  const m = ver.match(/Python (\d+)\.(\d+)/);
25
35
  if (m) {
26
36
  const [, major, minor] = m.map(Number);
27
- if (major === 3 && minor >= 11) return cmd;
37
+ if (major === 3 && minor >= 11) {
38
+ return { exe: parts[0], extraArgs: parts.slice(1) };
39
+ }
28
40
  }
29
41
  } catch {}
30
42
  }
@@ -32,41 +44,39 @@ function findPython() {
32
44
  }
33
45
 
34
46
  // ── Find gdep MCP server.py via pip show ──────────────────────
35
- function findServerScript(pyCmd) {
47
+ function findServerScript(py) {
36
48
  try {
37
- const pipShow = execSync(`${pyCmd} -m pip show gdep`, { encoding: 'utf8', stdio: ['pipe','pipe','pipe'] });
38
- const m = pipShow.match(/Location: (.+)/);
49
+ const result = spawnSync(py.exe, [...py.extraArgs, '-m', 'pip', 'show', 'gdep'], {
50
+ encoding: 'utf8',
51
+ stdio: ['pipe', 'pipe', 'pipe'],
52
+ timeout: 10000,
53
+ });
54
+ const out = result.stdout || '';
55
+ const m = out.match(/Location: (.+)/);
39
56
  if (m) {
40
57
  const candidate = path.join(m[1].trim(), 'gdep_mcp', 'server.py');
41
58
  if (fs.existsSync(candidate)) return candidate;
42
- // Also try gdep-mcp subdir
43
- const candidate2 = path.join(m[1].trim(), 'gdep', 'gdep-mcp', 'server.py');
44
- if (fs.existsSync(candidate2)) return candidate2;
45
59
  }
46
60
  } catch {}
47
61
  return null;
48
62
  }
49
63
 
50
- const pyCmd = findPython();
51
- if (!pyCmd) {
64
+ const py = findPython();
65
+ if (!py) {
52
66
  console.error('Python 3.11+ not found. Install gdep manually:');
53
67
  console.error(' pip install gdep "mcp[cli]"');
54
68
  process.exit(1);
55
69
  }
56
70
 
57
- // Split "py -3.11" into ["py", "-3.11"]
58
- const cmdParts = pyCmd.split(' ');
59
- const pyExe = cmdParts[0];
60
- const pyExtraArgs= cmdParts.slice(1);
61
-
62
- const serverScript = findServerScript(pyCmd);
71
+ const serverScript = findServerScript(py);
63
72
  const spawnArgs = serverScript
64
- ? [...pyExtraArgs, serverScript]
65
- : [...pyExtraArgs, '-m', 'gdep_mcp.server'];
73
+ ? [...py.extraArgs, serverScript]
74
+ : [...py.extraArgs, '-m', 'gdep_mcp.server'];
66
75
 
67
- const child = spawn(pyExe, spawnArgs, {
76
+ // shell: false — safe for paths with spaces (e.g. C:\Users\xxx yyy\...)
77
+ const child = spawn(py.exe, spawnArgs, {
68
78
  stdio: 'inherit',
69
- shell: isWin,
79
+ shell: false,
70
80
  env: { ...process.env, PYTHONUTF8: '1' },
71
81
  });
72
82
 
@@ -13,30 +13,41 @@ const YELLOW= '\x1b[33m';
13
13
  const CYAN = '\x1b[36m';
14
14
  const RESET = '\x1b[0m';
15
15
 
16
- function ok(msg) { console.log(`${GREEN}✓${RESET} ${msg}`); }
17
- function warn(msg) { console.log(`${YELLOW}⚠${RESET} ${msg}`); }
18
- function info(msg) { console.log(`${CYAN}→${RESET} ${msg}`); }
16
+ function ok(msg) { console.log(`${GREEN}\u2713${RESET} ${msg}`); }
17
+ function warn(msg) { console.log(`${YELLOW}\u26A0${RESET} ${msg}`); }
18
+ function info(msg) { console.log(`${CYAN}\u2192${RESET} ${msg}`); }
19
19
 
20
20
  console.log(`\n${BOLD}gdep-mcp postinstall${RESET}\n`);
21
21
 
22
- // ── 1. Find Python 3.11+ ──────────────────────────────────────
23
- // Try candidates in order: py -3.11 (Windows launcher), python3.11, python3, python
24
22
  const isWin = os.platform() === 'win32';
23
+
24
+ // ── 1. Find Python 3.11+ ──────────────────────────────────────
25
+ // Array-based spawnSync to avoid shell interpretation issues
26
+ // with paths containing spaces (e.g. C:\Users\xxx yyy\...).
25
27
  const candidates = isWin
26
- ? ['py -3.11', 'py -3.12', 'py -3.13', 'python3.11', 'python3', 'python']
27
- : ['python3.11', 'python3.12', 'python3.13', 'python3', 'python'];
28
+ ? [['py', '-3.11'], ['py', '-3.12'], ['py', '-3.13'], ['python3.11'], ['python3'], ['python']]
29
+ : [['python3.11'], ['python3.12'], ['python3.13'], ['python3'], ['python']];
28
30
 
29
- let pyCmd = null;
31
+ let pyExe = null;
32
+ let pyExtraArgs = [];
30
33
  let pyVersion = null;
31
34
 
32
- for (const cmd of candidates) {
35
+ for (const parts of candidates) {
33
36
  try {
34
- const ver = execSync(`${cmd} --version`, { encoding: 'utf8', stdio: ['pipe','pipe','pipe'] }).trim();
37
+ const args = [...parts.slice(1), '--version'];
38
+ const result = spawnSync(parts[0], args, {
39
+ encoding: 'utf8',
40
+ stdio: ['pipe', 'pipe', 'pipe'],
41
+ timeout: 5000,
42
+ });
43
+ if (result.status !== 0) continue;
44
+ const ver = (result.stdout || '').trim();
35
45
  const m = ver.match(/Python (\d+)\.(\d+)/);
36
46
  if (m) {
37
47
  const [, major, minor] = m.map(Number);
38
48
  if (major === 3 && minor >= 11) {
39
- pyCmd = cmd;
49
+ pyExe = parts[0];
50
+ pyExtraArgs = parts.slice(1);
40
51
  pyVersion = ver;
41
52
  break;
42
53
  }
@@ -44,27 +55,26 @@ for (const cmd of candidates) {
44
55
  } catch {}
45
56
  }
46
57
 
47
- if (!pyCmd) {
58
+ if (!pyExe) {
48
59
  warn('Python 3.11+ not found. Please install it and run manually:');
49
60
  warn(' pip install gdep "mcp[cli]"');
50
61
  warn(' Download: https://www.python.org/downloads/');
51
62
  process.exit(0);
52
63
  }
53
64
 
54
- ok(`Python found: ${pyVersion} (using: ${pyCmd})`);
65
+ ok(`Python found: ${pyVersion} (using: ${pyExe}${pyExtraArgs.length ? ' ' + pyExtraArgs.join(' ') : ''})`);
55
66
 
56
67
  // ── 2. pip install gdep + mcp[cli] ────────────────────────────
57
68
  info('Installing gdep and mcp[cli]...');
58
69
 
59
- // For "py -3.11" style commands, split into args
60
- const cmdParts = pyCmd.split(' ');
61
- const pipArgs = [...cmdParts.slice(1), '-m', 'pip', 'install', '--upgrade', 'gdep', 'mcp[cli]'];
70
+ const pipArgs = [...pyExtraArgs, '-m', 'pip', 'install', '--upgrade', 'gdep', 'mcp[cli]'];
62
71
 
63
- const result = spawnSync(cmdParts[0], pipArgs, { stdio: 'inherit', shell: isWin });
72
+ // shell: false safe for paths with spaces
73
+ const result = spawnSync(pyExe, pipArgs, { stdio: 'inherit', shell: false });
64
74
 
65
75
  if (result.status !== 0) {
66
76
  warn('pip install failed. Try manually:');
67
- warn(` ${pyCmd} -m pip install gdep "mcp[cli]"`);
77
+ warn(` ${pyExe}${pyExtraArgs.length ? ' ' + pyExtraArgs.join(' ') : ''} -m pip install gdep "mcp[cli]"`);
68
78
  process.exit(0);
69
79
  }
70
80
 
@@ -72,27 +82,31 @@ ok('gdep and mcp[cli] installed!');
72
82
 
73
83
  // ── 3. Check gdep is on PATH ──────────────────────────────────
74
84
  try {
75
- execSync('gdep --help', { stdio: 'pipe' });
76
- ok('gdep command is available on PATH.');
85
+ const check = spawnSync('gdep', ['--help'], { stdio: 'pipe', timeout: 10000 });
86
+ if (check.status === 0) {
87
+ ok('gdep command is available on PATH.');
88
+ } else {
89
+ throw new Error('non-zero exit');
90
+ }
77
91
  } catch {
78
92
  warn('gdep was installed but is not on PATH.');
79
93
  warn('Add the Python Scripts folder to your PATH, e.g.:');
80
94
  if (isWin) {
81
- // Try to find the actual scripts path
82
95
  try {
83
- const scripts = execSync(`${pyCmd} -c "import sysconfig; print(sysconfig.get_path('scripts'))"`,
84
- { encoding: 'utf8', stdio: ['pipe','pipe','pipe'] }).trim();
85
- warn(` ${scripts}`);
96
+ const scripts = spawnSync(pyExe, [...pyExtraArgs, '-c',
97
+ 'import sysconfig; print(sysconfig.get_path("scripts"))'],
98
+ { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] });
99
+ if (scripts.stdout) warn(` ${scripts.stdout.trim()}`);
86
100
  } catch {}
87
- warn(' (System Properties Environment Variables Path)');
101
+ warn(' (System Properties \u2192 Environment Variables \u2192 Path)');
88
102
  } else {
89
103
  warn(' export PATH="$PATH:$(python3 -m site --user-base)/bin"');
90
104
  }
91
105
  }
92
106
 
93
- // ── 3. Print config ───────────────────────────────────────────
107
+ // ── 4. Print config ───────────────────────────────────────────
94
108
  console.log(`
95
- ${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
109
+ ${BOLD}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${RESET}
96
110
  ${GREEN}${BOLD} gdep-mcp ready!${RESET}
97
111
 
98
112
  Add to Claude Desktop (claude_desktop_config.json):
@@ -107,5 +121,5 @@ ${CYAN}{
107
121
 
108
122
  Each tool call passes project_path as a parameter.
109
123
 
110
- ${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}
124
+ ${BOLD}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${RESET}
111
125
  `);
package/package.json CHANGED
@@ -1,26 +1,26 @@
1
- {
2
- "name": "gdep-mcp",
3
- "version": "0.1.7",
4
- "description": "MCP server for gdep — Game Codebase Analysis Tool (Unity/UE5/C++/C#)",
5
- "keywords": ["mcp", "game", "unity", "unreal", "ue5", "dependency", "analysis", "claude", "cursor", "ai"],
6
- "author": "pirua-game",
7
- "license": "Apache-2.0",
8
- "repository": {
9
- "type": "git",
10
- "url": "https://github.com/pirua-game/gdep.git"
11
- },
12
- "homepage": "https://github.com/pirua-game/gdep",
13
- "bin": {
14
- "gdep-mcp": "./bin/gdep-mcp.js"
15
- },
16
- "scripts": {
17
- "postinstall": "node bin/postinstall.js"
18
- },
19
- "engines": {
20
- "node": ">=18"
21
- },
22
- "files": [
23
- "bin/",
24
- "README.md"
25
- ]
26
- }
1
+ {
2
+ "name": "gdep-mcp",
3
+ "version": "0.1.11",
4
+ "description": "MCP server for gdep — Game Codebase Analysis Tool (Unity/UE5/C++/C#)",
5
+ "keywords": ["mcp", "game", "unity", "unreal", "ue5", "dependency", "analysis", "claude", "cursor", "ai"],
6
+ "author": "pirua-game",
7
+ "license": "Apache-2.0",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/pirua-game/gdep.git"
11
+ },
12
+ "homepage": "https://github.com/pirua-game/gdep",
13
+ "bin": {
14
+ "gdep-mcp": "./bin/gdep-mcp.js"
15
+ },
16
+ "scripts": {
17
+ "postinstall": "node bin/postinstall.js"
18
+ },
19
+ "engines": {
20
+ "node": ">=18"
21
+ },
22
+ "files": [
23
+ "bin/",
24
+ "README.md"
25
+ ]
26
+ }