minode-mcp-setup 1.0.0

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 +171 -0
  2. package/package.json +17 -0
package/bin/cli.js ADDED
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { execSync, spawn } = require('child_process');
5
+ const https = require('https');
6
+ const http = require('http');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const os = require('os');
10
+
11
+ const SITE = 'https://minode.site';
12
+ const DEST = path.join(os.homedir(), 'Desktop', 'cheatengine-mcp-bridge');
13
+ const ZIP_URL = `${SITE}/cheatengine-mcp-bridge.zip`;
14
+ const ZIP_TMP = path.join(os.tmpdir(), 'cheatengine-mcp-bridge.zip');
15
+
16
+ /* ── 컬러 출력 (chalk 없이 ANSI) */
17
+ const c = {
18
+ green: s => `\x1b[32m${s}\x1b[0m`,
19
+ yellow: s => `\x1b[33m${s}\x1b[0m`,
20
+ cyan: s => `\x1b[36m${s}\x1b[0m`,
21
+ red: s => `\x1b[31m${s}\x1b[0m`,
22
+ bold: s => `\x1b[1m${s}\x1b[0m`,
23
+ };
24
+
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)); }
30
+
31
+ /* ── 명령 실행 */
32
+ function run(cmd, opts = {}) {
33
+ return execSync(cmd, { stdio: opts.silent ? 'pipe' : 'inherit', ...opts });
34
+ }
35
+
36
+ function hasCmd(cmd) {
37
+ try { run(`${cmd} --version`, { silent: true }); return true; }
38
+ catch { return false; }
39
+ }
40
+
41
+ /* ── 파일 다운로드 */
42
+ function download(url, dest) {
43
+ return new Promise((resolve, reject) => {
44
+ const file = fs.createWriteStream(dest);
45
+ const get = url.startsWith('https') ? https.get : http.get;
46
+ get(url, res => {
47
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
48
+ file.close();
49
+ return download(res.headers.location, dest).then(resolve).catch(reject);
50
+ }
51
+ res.pipe(file);
52
+ file.on('finish', () => file.close(resolve));
53
+ }).on('error', e => { fs.unlink(dest, () => {}); reject(e); });
54
+ });
55
+ }
56
+
57
+ /* ── zip 압축 해제 (PowerShell 사용) */
58
+ function extractZip(zipPath, outDir) {
59
+ run(`powershell -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${outDir}' -Force"`, { silent: true });
60
+ }
61
+
62
+ /* ── 메뉴 */
63
+ 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];
72
+
73
+ 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('');
79
+ return;
80
+ }
81
+
82
+ if (cmd === 'puppeteer') await setupPuppeteer();
83
+ else if (cmd === 'ce-install') await installCE();
84
+ else if (cmd === 'ce-start') await startCE();
85
+ else { err(`알 수 없는 명령: ${cmd}`); process.exit(1); }
86
+ }
87
+
88
+ /* ── Puppeteer MCP */
89
+ async function setupPuppeteer() {
90
+ info('Puppeteer MCP 서버 시작 중...');
91
+
92
+ // 글로벌 설치 확인
93
+ const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim();
94
+ const puppeteerJs = path.join(npmRoot, '@modelcontextprotocol', 'server-puppeteer', 'dist', 'index.js');
95
+
96
+ if (!fs.existsSync(puppeteerJs)) {
97
+ info('패키지 설치 중...');
98
+ run('npm install -g @modelcontextprotocol/server-puppeteer');
99
+ }
100
+ ok('패키지 확인 완료');
101
+
102
+ process.env.PUPPETEER_LAUNCH_OPTIONS = JSON.stringify({ headless: true, args: ['--no-sandbox'] });
103
+ process.env.ALLOW_DANGEROUS = 'true';
104
+
105
+ info('MCP 서버 시작 (포트 8013)...');
106
+ const proc = spawn('npx', ['-y', 'mcp-proxy', '--port', '8013', '--', 'node', puppeteerJs], {
107
+ stdio: 'inherit', env: process.env, shell: true,
108
+ });
109
+ proc.on('exit', code => process.exit(code));
110
+ }
111
+
112
+ /* ── Cheat Engine MCP 설치 */
113
+ async function installCE() {
114
+ info('Cheat Engine MCP 설치 시작...');
115
+
116
+ // Python 확인
117
+ if (!hasCmd('python')) {
118
+ err('Python이 설치되지 않았습니다.');
119
+ log('설치: https://www.python.org/downloads/');
120
+ process.exit(1);
121
+ }
122
+ ok(`Python: ${execSync('python --version', { encoding: 'utf8' }).trim()}`);
123
+
124
+ // 패키지 다운로드
125
+ const pyScript = path.join(DEST, 'MCP_Server', 'mcp_cheatengine.py');
126
+ if (!fs.existsSync(pyScript)) {
127
+ info(`다운로드 중: ${ZIP_URL}`);
128
+ await download(ZIP_URL, ZIP_TMP);
129
+ ok('다운로드 완료');
130
+
131
+ info('압축 해제 중...');
132
+ fs.mkdirSync(DEST, { recursive: true });
133
+ extractZip(ZIP_TMP, path.dirname(DEST));
134
+ ok('압축 해제 완료');
135
+ } else {
136
+ ok('패키지 이미 설치됨');
137
+ }
138
+
139
+ // pip 설치
140
+ const req = path.join(DEST, 'MCP_Server', 'requirements.txt');
141
+ if (fs.existsSync(req)) {
142
+ info('Python 의존성 설치 중...');
143
+ run(`pip install -r "${req}"`);
144
+ ok('설치 완료');
145
+ }
146
+
147
+ log('');
148
+ ok('설치 완료! 아래 명령어로 서버를 시작하세요:');
149
+ log(c.cyan(' npx minode-mcp-setup ce-start'));
150
+ }
151
+
152
+ /* ── Cheat Engine MCP 시작 */
153
+ async function startCE() {
154
+ const pyScript = path.join(DEST, 'MCP_Server', 'mcp_cheatengine.py');
155
+ if (!fs.existsSync(pyScript)) {
156
+ err('설치되지 않았습니다. 먼저 설치를 실행하세요:');
157
+ log(c.cyan(' npx minode-mcp-setup ce-install'));
158
+ process.exit(1);
159
+ }
160
+
161
+ info('Cheat Engine MCP 서버 시작 (포트 8015)...');
162
+ info('Cheat Engine Lua 브릿지가 실행 중인지 확인하세요.');
163
+ log('');
164
+
165
+ const proc = spawn('npx', ['-y', 'mcp-proxy', '--port', '8015', '--', 'python', pyScript], {
166
+ stdio: 'inherit', shell: true,
167
+ });
168
+ proc.on('exit', code => process.exit(code));
169
+ }
170
+
171
+ main().catch(e => { err(e.message); process.exit(1); });
package/package.json ADDED
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "minode-mcp-setup",
3
+ "version": "1.0.0",
4
+ "description": "Minode AI - MCP 서버 자동 설치 및 실행 도구",
5
+ "bin": {
6
+ "minode-mcp-setup": "./bin/cli.js"
7
+ },
8
+ "dependencies": {
9
+ "chalk": "^4.1.2",
10
+ "inquirer": "^8.2.6",
11
+ "execa": "^5.1.1"
12
+ },
13
+ "engines": { "node": ">=18.0.0" },
14
+ "keywords": ["mcp", "puppeteer", "cheatengine", "minode"],
15
+ "author": "minode",
16
+ "license": "MIT"
17
+ }