minode-mcp-setup 1.0.0 → 1.0.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.
Files changed (2) hide show
  1. package/bin/cli.js +45 -49
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -8,12 +8,31 @@ const fs = require('fs');
8
8
  const path = require('path');
9
9
  const os = require('os');
10
10
 
11
- const SITE = 'https://minode.site';
12
- const DEST = path.join(os.homedir(), 'Desktop', 'cheatengine-mcp-bridge');
11
+ const SITE = 'https://minode.site';
13
12
  const ZIP_URL = `${SITE}/cheatengine-mcp-bridge.zip`;
14
13
  const ZIP_TMP = path.join(os.tmpdir(), 'cheatengine-mcp-bridge.zip');
15
14
 
16
- /* ── 컬러 출력 (chalk 없이 ANSI) */
15
+ /* ── 실제 바탕화면 경로 (레지스트리 읽기) */
16
+ function getDesktopPath() {
17
+ try {
18
+ const result = execSync(
19
+ 'reg query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders" /v Desktop',
20
+ { encoding: 'utf8', stdio: 'pipe' }
21
+ );
22
+ const match = result.match(/Desktop\s+REG_EXPAND_SZ\s+(.+)/);
23
+ if (match) {
24
+ // 환경변수 확장 (%USERPROFILE% 등)
25
+ const raw = match[1].trim();
26
+ return raw.replace(/%([^%]+)%/g, (_, k) => process.env[k] || `%${k}%`);
27
+ }
28
+ } catch {}
29
+ return path.join(os.homedir(), 'Desktop');
30
+ }
31
+
32
+ const DESKTOP = getDesktopPath();
33
+ const DEST = path.join(DESKTOP, 'cheatengine-mcp-bridge');
34
+
35
+ /* ── 컬러 출력 */
17
36
  const c = {
18
37
  green: s => `\x1b[32m${s}\x1b[0m`,
19
38
  yellow: s => `\x1b[33m${s}\x1b[0m`,
@@ -22,13 +41,10 @@ const c = {
22
41
  bold: s => `\x1b[1m${s}\x1b[0m`,
23
42
  };
24
43
 
25
- function log(msg) { console.log(msg); }
26
- function ok(msg) { log(c.green(' ' + msg)); }
27
- function info(msg) { log(c.cyan(' ' + msg)); }
28
- function warn(msg) { log(c.yellow('⚠ ' + msg)); }
29
- function err(msg) { log(c.red('✗ ' + msg)); }
44
+ function ok(msg) { console.log(c.green('✓ ' + msg)); }
45
+ function info(msg) { console.log(c.cyan(' ' + msg)); }
46
+ function err(msg) { console.log(c.red(' ' + msg)); }
30
47
 
31
- /* ── 명령 실행 */
32
48
  function run(cmd, opts = {}) {
33
49
  return execSync(cmd, { stdio: opts.silent ? 'pipe' : 'inherit', ...opts });
34
50
  }
@@ -38,7 +54,6 @@ function hasCmd(cmd) {
38
54
  catch { return false; }
39
55
  }
40
56
 
41
- /* ── 파일 다운로드 */
42
57
  function download(url, dest) {
43
58
  return new Promise((resolve, reject) => {
44
59
  const file = fs.createWriteStream(dest);
@@ -54,54 +69,43 @@ function download(url, dest) {
54
69
  });
55
70
  }
56
71
 
57
- /* ── zip 압축 해제 (PowerShell 사용) */
58
72
  function extractZip(zipPath, outDir) {
59
73
  run(`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${outDir}' -Force"`, { silent: true });
60
74
  }
61
75
 
62
- /* ── 메뉴 */
63
76
  async function main() {
64
- log('');
65
- log(c.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
66
- log(c.bold(' Minode AI — MCP 서버 설치 도구'));
67
- log(c.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
68
- log('');
69
-
70
- const args = process.argv.slice(2);
71
- const cmd = args[0];
77
+ console.log('');
78
+ console.log(c.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
79
+ console.log(c.bold(' Minode AI — MCP 서버 설치 도구'));
80
+ console.log(c.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
81
+ console.log('');
72
82
 
83
+ const cmd = process.argv[2];
73
84
  if (!cmd || cmd === 'menu') {
74
- log('사용법:');
75
- log(' npx minode-mcp-setup puppeteer Puppeteer MCP 시작');
76
- log(' npx minode-mcp-setup ce-install Cheat Engine MCP 설치');
77
- log(' npx minode-mcp-setup ce-start Cheat Engine MCP 시작');
78
- log('');
85
+ console.log('사용법:');
86
+ console.log(' npx minode-mcp-setup puppeteer Puppeteer MCP 시작');
87
+ console.log(' npx minode-mcp-setup ce-install Cheat Engine MCP 설치');
88
+ console.log(' npx minode-mcp-setup ce-start Cheat Engine MCP 시작');
79
89
  return;
80
90
  }
81
91
 
82
- if (cmd === 'puppeteer') await setupPuppeteer();
92
+ if (cmd === 'puppeteer') await setupPuppeteer();
83
93
  else if (cmd === 'ce-install') await installCE();
84
- else if (cmd === 'ce-start') await startCE();
94
+ else if (cmd === 'ce-start') await startCE();
85
95
  else { err(`알 수 없는 명령: ${cmd}`); process.exit(1); }
86
96
  }
87
97
 
88
- /* ── Puppeteer MCP */
89
98
  async function setupPuppeteer() {
90
99
  info('Puppeteer MCP 서버 시작 중...');
91
-
92
- // 글로벌 설치 확인
93
- const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
100
+ const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
94
101
  const puppeteerJs = path.join(npmRoot, '@modelcontextprotocol', 'server-puppeteer', 'dist', 'index.js');
95
-
96
102
  if (!fs.existsSync(puppeteerJs)) {
97
103
  info('패키지 설치 중...');
98
104
  run('npm install -g @modelcontextprotocol/server-puppeteer');
99
105
  }
100
106
  ok('패키지 확인 완료');
101
-
102
107
  process.env.PUPPETEER_LAUNCH_OPTIONS = JSON.stringify({ headless: true, args: ['--no-sandbox'] });
103
108
  process.env.ALLOW_DANGEROUS = 'true';
104
-
105
109
  info('MCP 서버 시작 (포트 8013)...');
106
110
  const proc = spawn('npx', ['-y', 'mcp-proxy', '--port', '8013', '--', 'node', puppeteerJs], {
107
111
  stdio: 'inherit', env: process.env, shell: true,
@@ -109,34 +113,29 @@ async function setupPuppeteer() {
109
113
  proc.on('exit', code => process.exit(code));
110
114
  }
111
115
 
112
- /* ── Cheat Engine MCP 설치 */
113
116
  async function installCE() {
114
117
  info('Cheat Engine MCP 설치 시작...');
118
+ info(`바탕화면 경로: ${DESKTOP}`);
115
119
 
116
- // Python 확인
117
120
  if (!hasCmd('python')) {
118
- err('Python이 설치되지 않았습니다.');
119
- log('설치: https://www.python.org/downloads/');
121
+ err('Python이 설치되지 않았습니다. 설치: https://www.python.org/downloads/');
120
122
  process.exit(1);
121
123
  }
122
124
  ok(`Python: ${execSync('python --version', { encoding: 'utf8' }).trim()}`);
123
125
 
124
- // 패키지 다운로드
125
126
  const pyScript = path.join(DEST, 'MCP_Server', 'mcp_cheatengine.py');
126
127
  if (!fs.existsSync(pyScript)) {
127
128
  info(`다운로드 중: ${ZIP_URL}`);
128
129
  await download(ZIP_URL, ZIP_TMP);
129
130
  ok('다운로드 완료');
130
-
131
131
  info('압축 해제 중...');
132
132
  fs.mkdirSync(DEST, { recursive: true });
133
- extractZip(ZIP_TMP, path.dirname(DEST));
133
+ extractZip(ZIP_TMP, DESKTOP);
134
134
  ok('압축 해제 완료');
135
135
  } else {
136
136
  ok('패키지 이미 설치됨');
137
137
  }
138
138
 
139
- // pip 설치
140
139
  const req = path.join(DEST, 'MCP_Server', 'requirements.txt');
141
140
  if (fs.existsSync(req)) {
142
141
  info('Python 의존성 설치 중...');
@@ -144,24 +143,21 @@ async function installCE() {
144
143
  ok('설치 완료');
145
144
  }
146
145
 
147
- log('');
146
+ console.log('');
148
147
  ok('설치 완료! 아래 명령어로 서버를 시작하세요:');
149
- log(c.cyan(' npx minode-mcp-setup ce-start'));
148
+ console.log(c.cyan(' npx minode-mcp-setup ce-start'));
150
149
  }
151
150
 
152
- /* ── Cheat Engine MCP 시작 */
153
151
  async function startCE() {
154
152
  const pyScript = path.join(DEST, 'MCP_Server', 'mcp_cheatengine.py');
155
153
  if (!fs.existsSync(pyScript)) {
156
154
  err('설치되지 않았습니다. 먼저 설치를 실행하세요:');
157
- log(c.cyan(' npx minode-mcp-setup ce-install'));
155
+ console.log(c.cyan(' npx minode-mcp-setup ce-install'));
158
156
  process.exit(1);
159
157
  }
160
-
161
158
  info('Cheat Engine MCP 서버 시작 (포트 8015)...');
162
159
  info('Cheat Engine Lua 브릿지가 실행 중인지 확인하세요.');
163
- log('');
164
-
160
+ console.log('');
165
161
  const proc = spawn('npx', ['-y', 'mcp-proxy', '--port', '8015', '--', 'python', pyScript], {
166
162
  stdio: 'inherit', shell: true,
167
163
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minode-mcp-setup",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Minode AI - MCP 서버 자동 설치 및 실행 도구",
5
5
  "bin": {
6
6
  "minode-mcp-setup": "./bin/cli.js"