mobilecoder-mcp 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.
- package/dist/adapters/cli-adapter.d.ts +13 -0
- package/dist/adapters/cli-adapter.d.ts.map +1 -0
- package/dist/adapters/cli-adapter.js +62 -0
- package/dist/adapters/cli-adapter.js.map +1 -0
- package/dist/agent.d.ts +10 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +63 -0
- package/dist/agent.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +175 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-handler.d.ts +3 -0
- package/dist/mcp-handler.d.ts.map +1 -0
- package/dist/mcp-handler.js +317 -0
- package/dist/mcp-handler.js.map +1 -0
- package/dist/security.d.ts +52 -0
- package/dist/security.d.ts.map +1 -0
- package/dist/security.js +307 -0
- package/dist/security.js.map +1 -0
- package/dist/tool-detector.d.ts +18 -0
- package/dist/tool-detector.d.ts.map +1 -0
- package/dist/tool-detector.js +130 -0
- package/dist/tool-detector.js.map +1 -0
- package/dist/webrtc.d.ts +20 -0
- package/dist/webrtc.d.ts.map +1 -0
- package/dist/webrtc.js +152 -0
- package/dist/webrtc.js.map +1 -0
- package/package.json +35 -0
- package/src/adapters/cli-adapter.ts +73 -0
- package/src/agent.ts +71 -0
- package/src/index.ts +162 -0
- package/src/mcp-handler.ts +324 -0
- package/src/security.ts +294 -0
- package/src/tool-detector.ts +110 -0
- package/src/webrtc.ts +156 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface CLIResult {
|
|
2
|
+
output: string;
|
|
3
|
+
exitCode: number | null;
|
|
4
|
+
}
|
|
5
|
+
export declare class CLIAdapter {
|
|
6
|
+
private process;
|
|
7
|
+
private onOutputCallback?;
|
|
8
|
+
constructor();
|
|
9
|
+
execute(command: string, args?: string[], cwd?: string): void;
|
|
10
|
+
onOutput(callback: (data: string) => void): void;
|
|
11
|
+
kill(): void;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=cli-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-adapter.d.ts","sourceRoot":"","sources":["../../src/adapters/cli-adapter.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,qBAAa,UAAU;IACnB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,gBAAgB,CAAC,CAAyB;;IAIlD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,EAAE,GAAG,GAAE,MAAsB,GAAG,IAAI;IAgDhF,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIhD,IAAI,IAAI,IAAI;CAMf"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLIAdapter = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const os_1 = require("os");
|
|
6
|
+
class CLIAdapter {
|
|
7
|
+
process = null;
|
|
8
|
+
onOutputCallback;
|
|
9
|
+
constructor() { }
|
|
10
|
+
execute(command, args = [], cwd = process.cwd()) {
|
|
11
|
+
const isWindows = (0, os_1.platform)() === 'win32';
|
|
12
|
+
const shell = isWindows ? 'powershell.exe' : '/bin/bash';
|
|
13
|
+
const shellArgs = isWindows ? ['-c', `${command} ${args.join(' ')}`] : ['-c', `${command} ${args.join(' ')}`];
|
|
14
|
+
console.log(`[CLI] Executing: ${command} ${args.join(' ')}`);
|
|
15
|
+
try {
|
|
16
|
+
this.process = (0, child_process_1.spawn)(shell, shellArgs, {
|
|
17
|
+
cwd,
|
|
18
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
19
|
+
env: process.env
|
|
20
|
+
});
|
|
21
|
+
this.process.stdout?.on('data', (data) => {
|
|
22
|
+
const output = data.toString();
|
|
23
|
+
if (this.onOutputCallback) {
|
|
24
|
+
this.onOutputCallback(output);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
this.process.stderr?.on('data', (data) => {
|
|
28
|
+
const output = data.toString();
|
|
29
|
+
if (this.onOutputCallback) {
|
|
30
|
+
this.onOutputCallback(output);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
this.process.on('error', (error) => {
|
|
34
|
+
if (this.onOutputCallback) {
|
|
35
|
+
this.onOutputCallback(`Error: ${error.message}\n`);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
this.process.on('close', (code) => {
|
|
39
|
+
if (this.onOutputCallback) {
|
|
40
|
+
this.onOutputCallback(`\n[Process exited with code ${code}]`);
|
|
41
|
+
}
|
|
42
|
+
this.process = null;
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
if (this.onOutputCallback) {
|
|
47
|
+
this.onOutputCallback(`Failed to start process: ${error.message}\n`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
onOutput(callback) {
|
|
52
|
+
this.onOutputCallback = callback;
|
|
53
|
+
}
|
|
54
|
+
kill() {
|
|
55
|
+
if (this.process) {
|
|
56
|
+
this.process.kill();
|
|
57
|
+
this.process = null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
exports.CLIAdapter = CLIAdapter;
|
|
62
|
+
//# sourceMappingURL=cli-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../src/adapters/cli-adapter.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { WebRTCConnection } from './webrtc';
|
|
2
|
+
export declare class UniversalAgent {
|
|
3
|
+
private webrtc;
|
|
4
|
+
private cliAdapter;
|
|
5
|
+
private activeTool;
|
|
6
|
+
constructor(webrtc: WebRTCConnection);
|
|
7
|
+
start(): Promise<void>;
|
|
8
|
+
private handleMessage;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAI5C,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,UAAU,CAAwB;gBAE9B,MAAM,EAAE,gBAAgB;IAK9B,KAAK;IAkCX,OAAO,CAAC,aAAa;CAsBxB"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UniversalAgent = void 0;
|
|
4
|
+
const mcp_handler_1 = require("./mcp-handler");
|
|
5
|
+
const cli_adapter_1 = require("./adapters/cli-adapter");
|
|
6
|
+
class UniversalAgent {
|
|
7
|
+
webrtc;
|
|
8
|
+
cliAdapter;
|
|
9
|
+
activeTool = 'mcp';
|
|
10
|
+
constructor(webrtc) {
|
|
11
|
+
this.webrtc = webrtc;
|
|
12
|
+
this.cliAdapter = new cli_adapter_1.CLIAdapter();
|
|
13
|
+
}
|
|
14
|
+
async start() {
|
|
15
|
+
console.log('š Universal Agent starting...');
|
|
16
|
+
// Initialize MCP Server (Cursor integration)
|
|
17
|
+
// We run this in parallel because it sets up its own listeners
|
|
18
|
+
// Note: In the future, we might want to wrap this better
|
|
19
|
+
(0, mcp_handler_1.setupMCPServer)(this.webrtc).catch(err => {
|
|
20
|
+
console.error('Failed to start MCP server:', err);
|
|
21
|
+
});
|
|
22
|
+
// Initialize CLI Adapter listeners
|
|
23
|
+
this.cliAdapter.onOutput((data) => {
|
|
24
|
+
this.webrtc.send({
|
|
25
|
+
type: 'cli_output',
|
|
26
|
+
data: data,
|
|
27
|
+
timestamp: Date.now()
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
// Override the WebRTC message handler to route commands
|
|
31
|
+
// We need to be careful not to conflict with mcp-handler's listeners
|
|
32
|
+
// Currently mcp-handler adds its own listener. SimplePeer supports multiple listeners.
|
|
33
|
+
this.webrtc.onMessage((message) => {
|
|
34
|
+
this.handleMessage(message);
|
|
35
|
+
});
|
|
36
|
+
try {
|
|
37
|
+
await this.webrtc.connect();
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error('Failed to connect WebRTC:', error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
handleMessage(message) {
|
|
44
|
+
// console.log('Universal Agent received:', message);
|
|
45
|
+
if (message.type === 'switch_tool') {
|
|
46
|
+
this.activeTool = message.tool;
|
|
47
|
+
console.log(`š Switched active tool to: ${this.activeTool}`);
|
|
48
|
+
this.webrtc.send({
|
|
49
|
+
type: 'system',
|
|
50
|
+
message: `Switched to ${this.activeTool}`
|
|
51
|
+
});
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (message.type === 'cli_command') {
|
|
55
|
+
const command = message.command;
|
|
56
|
+
console.log(`š» Received CLI command: ${command}`);
|
|
57
|
+
this.cliAdapter.execute(command);
|
|
58
|
+
}
|
|
59
|
+
// MCP commands are handled by mcp-handler.ts directly via its own listener
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.UniversalAgent = UniversalAgent;
|
|
63
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":";;;AACA,+CAA+C;AAC/C,wDAAoD;AAEpD,MAAa,cAAc;IACf,MAAM,CAAmB;IACzB,UAAU,CAAa;IACvB,UAAU,GAAkB,KAAK,CAAC;IAE1C,YAAY,MAAwB;QAChC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,wBAAU,EAAE,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,KAAK;QACP,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;QAE9C,6CAA6C;QAC7C,+DAA+D;QAC/D,yDAAyD;QACzD,IAAA,4BAAc,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YACpC,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,IAAI;gBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACxB,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,wDAAwD;QACxD,qEAAqE;QACrE,uFAAuF;QAEvF,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;YAC9B,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAChC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;QACtD,CAAC;IACL,CAAC;IAEO,aAAa,CAAC,OAAY;QAC9B,qDAAqD;QAErD,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAE9D,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,eAAe,IAAI,CAAC,UAAU,EAAE;aAC5C,CAAC,CAAC;YACH,OAAO;QACX,CAAC;QAED,IAAI,OAAO,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;YACnD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC;QAED,2EAA2E;IAC/E,CAAC;CACJ;AAlED,wCAkEC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const qrcode = __importStar(require("qrcode-terminal"));
|
|
42
|
+
const agent_1 = require("./agent");
|
|
43
|
+
const webrtc_1 = require("./webrtc");
|
|
44
|
+
const program = new commander_1.Command();
|
|
45
|
+
program
|
|
46
|
+
.name('mobile-coder-mcp')
|
|
47
|
+
.description('MCP server for MobileCoderMCP - enables mobile to desktop coding')
|
|
48
|
+
.version('1.0.0');
|
|
49
|
+
program
|
|
50
|
+
.command('init')
|
|
51
|
+
.description('Initialize connection, generate QR code and start the agent')
|
|
52
|
+
.option('-s, --signaling <url>', 'Signaling server URL', 'https://mcp-signal.workers.dev')
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
const code = generateConnectionCode();
|
|
55
|
+
console.log('\nš± MobileCoder MCP - Quick Setup');
|
|
56
|
+
console.log('================================');
|
|
57
|
+
console.log(`\nš Your Pairing Code: ${code}`);
|
|
58
|
+
console.log('Scan the QR code below with your mobile device to connect:\n');
|
|
59
|
+
// Generate QR code in terminal
|
|
60
|
+
// We use the full URL if we want to deep link, or just the code
|
|
61
|
+
const pairingUrl = `https://mobilecoder-mcp.app/connect?code=${code}`;
|
|
62
|
+
qrcode.generate(pairingUrl, { small: true });
|
|
63
|
+
console.log('\nš Configuring IDEs...');
|
|
64
|
+
await autoConfigureIDEs(code, options.signaling);
|
|
65
|
+
console.log('\nš Starting Universal Agent...');
|
|
66
|
+
const webrtc = new webrtc_1.WebRTCConnection(code, options.signaling);
|
|
67
|
+
const agent = new agent_1.UniversalAgent(webrtc);
|
|
68
|
+
await agent.start();
|
|
69
|
+
});
|
|
70
|
+
program
|
|
71
|
+
.command('start')
|
|
72
|
+
.description('Start the Universal Agent with an existing code')
|
|
73
|
+
.option('-c, --code <code>', 'Connection code')
|
|
74
|
+
.option('-s, --signaling <url>', 'Signaling server URL', 'https://mcp-signal.workers.dev')
|
|
75
|
+
.action(async (options) => {
|
|
76
|
+
if (!options.code) {
|
|
77
|
+
console.error('ā Error: Connection code is required');
|
|
78
|
+
console.log(' Use: mobile-coder-mcp start --code=YOUR_CODE');
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
console.log('š Starting Universal Agent...');
|
|
82
|
+
console.log(` Connection code: ${options.code}`);
|
|
83
|
+
console.log(` Signaling server: ${options.signaling}\n`);
|
|
84
|
+
const webrtc = new webrtc_1.WebRTCConnection(options.code, options.signaling);
|
|
85
|
+
const agent = new agent_1.UniversalAgent(webrtc);
|
|
86
|
+
await agent.start();
|
|
87
|
+
});
|
|
88
|
+
program
|
|
89
|
+
.command('reset')
|
|
90
|
+
.description('Reset connection and remove config from all IDEs')
|
|
91
|
+
.option('-i, --ide <ide>', 'IDE to reset (cursor, windsurf, vscode, all)', 'all')
|
|
92
|
+
.action(async (options) => {
|
|
93
|
+
console.log('š Resetting MobileCoderMCP...\n');
|
|
94
|
+
const configs = {
|
|
95
|
+
cursor: path.join(os.homedir(), '.cursor', 'mcp.json'),
|
|
96
|
+
windsurf: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
|
|
97
|
+
vscode: path.join(os.homedir(), '.vscode', 'mcp.json'),
|
|
98
|
+
};
|
|
99
|
+
const ide = options.ide.toLowerCase();
|
|
100
|
+
if (ide === 'all') {
|
|
101
|
+
for (const [name, configPath] of Object.entries(configs)) {
|
|
102
|
+
await removeFromConfig(configPath, 'mobile-coder');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else if (configs[ide]) {
|
|
106
|
+
await removeFromConfig(configs[ide], 'mobile-coder');
|
|
107
|
+
}
|
|
108
|
+
console.log('ā
Configuration reset complete\n');
|
|
109
|
+
});
|
|
110
|
+
program.parse();
|
|
111
|
+
function generateConnectionCode() {
|
|
112
|
+
return Math.random().toString(36).substring(2, 8).toUpperCase();
|
|
113
|
+
}
|
|
114
|
+
async function autoConfigureIDEs(code, signalingUrl) {
|
|
115
|
+
const configs = {
|
|
116
|
+
cursor: path.join(os.homedir(), '.cursor', 'mcp.json'),
|
|
117
|
+
windsurf: path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),
|
|
118
|
+
vscode: path.join(os.homedir(), '.vscode', 'mcp.json'),
|
|
119
|
+
};
|
|
120
|
+
for (const [name, configPath] of Object.entries(configs)) {
|
|
121
|
+
try {
|
|
122
|
+
await configureIDE(configPath, name, code, signalingUrl);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
// Ignore if IDE config dir doesn't exist
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
async function configureIDE(configPath, ideName, code, signalingUrl) {
|
|
130
|
+
const configDir = path.dirname(configPath);
|
|
131
|
+
if (!fs.existsSync(configDir)) {
|
|
132
|
+
return; // Skip if IDE is not installed/configured
|
|
133
|
+
}
|
|
134
|
+
let config = { mcpServers: {} };
|
|
135
|
+
if (fs.existsSync(configPath)) {
|
|
136
|
+
try {
|
|
137
|
+
config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
console.warn(`ā ļø Could not read existing ${ideName} config, creating new one`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!config.mcpServers) {
|
|
144
|
+
config.mcpServers = {};
|
|
145
|
+
}
|
|
146
|
+
// We assume the user has mobile-coder-mcp installed globally or via npx
|
|
147
|
+
// In npx context, we use the command name directly
|
|
148
|
+
config.mcpServers['mobile-coder'] = {
|
|
149
|
+
command: 'npx',
|
|
150
|
+
args: ['mobile-coder-mcp', 'start', '--code', code, '--signaling', signalingUrl],
|
|
151
|
+
env: {
|
|
152
|
+
MCP_CONNECTION_CODE: code,
|
|
153
|
+
MCP_SIGNALING_URL: signalingUrl
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
157
|
+
console.log(` ā
${ideName.charAt(0).toUpperCase() + ideName.slice(1)} linked.`);
|
|
158
|
+
}
|
|
159
|
+
async function removeFromConfig(configPath, serverName) {
|
|
160
|
+
if (!fs.existsSync(configPath)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
165
|
+
if (config.mcpServers && config.mcpServers[serverName]) {
|
|
166
|
+
delete config.mcpServers[serverName];
|
|
167
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
168
|
+
console.log(` ā
Removed from ${path.basename(configPath)}`);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (e) {
|
|
172
|
+
console.warn(`ā ļø Could not update ${configPath}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../src/mcp-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAkB5C,wBAAsB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4N5E"}
|