mobilecoder-mcp 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.
- package/.security.log +48 -0
- package/dist/adapters/cli-adapter.js +5 -9
- package/dist/adapters/cli-adapter.js.map +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +21 -9
- package/dist/agent.js.map +1 -1
- package/dist/index.js +30 -56
- package/dist/index.js.map +1 -1
- package/dist/mcp-handler.d.ts +1 -1
- package/dist/mcp-handler.d.ts.map +1 -1
- package/dist/mcp-handler.js +42 -77
- package/dist/mcp-handler.js.map +1 -1
- package/dist/security.d.ts +2 -0
- package/dist/security.d.ts.map +1 -1
- package/dist/security.js +83 -80
- package/dist/security.js.map +1 -1
- package/dist/tool-detector.js +7 -44
- package/dist/tool-detector.js.map +1 -1
- package/dist/webrtc.d.ts +12 -3
- package/dist/webrtc.d.ts.map +1 -1
- package/dist/webrtc.js +280 -80
- package/dist/webrtc.js.map +1 -1
- package/package.json +37 -35
- package/src/agent.ts +21 -3
- package/src/index.ts +172 -162
- package/src/mcp-handler.ts +14 -11
- package/src/security.ts +93 -42
- package/src/webrtc.ts +387 -156
- package/tsconfig.json +14 -7
package/.security.log
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{"timestamp":"2026-01-12T19:17:45.101Z","event":"mcp_server_started","details":{"timestamp":1768245465101},"severity":"low","pid":14972,"user":"unknown"}
|
|
2
|
+
{"timestamp":"2026-01-12T19:18:59.766Z","event":"mcp_server_started","details":{"timestamp":1768245539765},"severity":"low","pid":16832,"user":"unknown"}
|
|
3
|
+
{"timestamp":"2026-01-12T19:20:35.262Z","event":"mcp_server_started","details":{"timestamp":1768245635262},"severity":"low","pid":17300,"user":"unknown"}
|
|
4
|
+
{"timestamp":"2026-01-12T19:23:45.884Z","event":"mcp_server_started","details":{"timestamp":1768245825883},"severity":"low","pid":15984,"user":"unknown"}
|
|
5
|
+
{"timestamp":"2026-01-12T19:25:54.796Z","event":"mcp_server_started","details":{"timestamp":1768245954795},"severity":"low","pid":6320,"user":"unknown"}
|
|
6
|
+
{"timestamp":"2026-01-12T19:45:02.068Z","event":"mcp_server_started","details":{"timestamp":1768247102068},"severity":"low","pid":8744,"user":"unknown"}
|
|
7
|
+
{"timestamp":"2026-01-12T19:46:40.690Z","event":"mcp_server_error","details":{"error":"Unexpected token 'c', \"cd C:\\User\"... is not valid JSON"},"severity":"medium","pid":6320,"user":"unknown"}
|
|
8
|
+
{"timestamp":"2026-01-12T19:46:51.441Z","event":"mcp_server_started","details":{"timestamp":1768247211441},"severity":"low","pid":11664,"user":"unknown"}
|
|
9
|
+
{"timestamp":"2026-01-12T20:19:49.096Z","event":"mcp_server_started","details":{"timestamp":1768249189096},"severity":"low","pid":15940,"user":"unknown"}
|
|
10
|
+
{"timestamp":"2026-01-12T20:24:25.070Z","event":"mcp_server_started","details":{"timestamp":1768249465062},"severity":"low","pid":11640,"user":"unknown"}
|
|
11
|
+
{"timestamp":"2026-01-12T20:27:05.476Z","event":"mcp_server_started","details":{"timestamp":1768249625476},"severity":"low","pid":10024,"user":"unknown"}
|
|
12
|
+
{"timestamp":"2026-01-12T20:36:54.241Z","event":"mcp_server_started","details":{"timestamp":1768250214241},"severity":"low","pid":12872,"user":"unknown"}
|
|
13
|
+
{"timestamp":"2026-01-12T20:38:25.599Z","event":"mcp_server_started","details":{"timestamp":1768250305599},"severity":"low","pid":15384,"user":"unknown"}
|
|
14
|
+
{"timestamp":"2026-01-13T21:47:30.989Z","event":"mcp_server_started","details":{"timestamp":1768340850989},"severity":"low","pid":13352,"user":"unknown"}
|
|
15
|
+
{"timestamp":"2026-01-13T21:50:23.274Z","event":"mcp_server_started","details":{"timestamp":1768341023274},"severity":"low","pid":14428,"user":"unknown"}
|
|
16
|
+
{"timestamp":"2026-01-13T21:58:10.298Z","event":"mcp_server_started","details":{"timestamp":1768341490298},"severity":"low","pid":13820,"user":"unknown"}
|
|
17
|
+
{"timestamp":"2026-01-13T22:12:00.582Z","event":"mcp_server_started","details":{"timestamp":1768342320582},"severity":"low","pid":16044,"user":"unknown"}
|
|
18
|
+
{"timestamp":"2026-01-13T22:13:40.183Z","event":"mcp_server_started","details":{"timestamp":1768342420182},"severity":"low","pid":6168,"user":"unknown"}
|
|
19
|
+
{"timestamp":"2026-01-13T22:25:05.420Z","event":"mcp_server_started","details":{"timestamp":1768343105420},"severity":"low","pid":16768,"user":"unknown"}
|
|
20
|
+
{"timestamp":"2026-01-13T22:27:33.430Z","event":"mcp_server_started","details":{"timestamp":1768343253429},"severity":"low","pid":18144,"user":"unknown"}
|
|
21
|
+
{"timestamp":"2026-01-13T22:27:38.068Z","event":"mcp_server_error","details":{"error":"Unexpected token 'c', \"cd 'c:\\Use\"... is not valid JSON"},"severity":"medium","pid":18144,"user":"unknown"}
|
|
22
|
+
{"timestamp":"2026-01-14T20:35:12.421Z","event":"mcp_server_started","details":{"timestamp":1768422912421},"severity":"low","pid":10232,"user":"unknown"}
|
|
23
|
+
{"timestamp":"2026-01-14T21:09:01.773Z","event":"mcp_server_started","details":{"timestamp":1768424941772},"severity":"low","pid":6568,"user":"unknown"}
|
|
24
|
+
{"timestamp":"2026-01-14T21:17:47.740Z","event":"mcp_server_started","details":{"timestamp":1768425467739},"severity":"low","pid":7056,"user":"unknown"}
|
|
25
|
+
{"timestamp":"2026-01-14T21:46:04.721Z","event":"mcp_server_started","details":{"timestamp":1768427164721},"severity":"low","pid":13516,"user":"unknown"}
|
|
26
|
+
{"timestamp":"2026-01-14T21:49:52.141Z","event":"mcp_server_started","details":{"timestamp":1768427392141},"severity":"low","pid":5928,"user":"unknown"}
|
|
27
|
+
{"timestamp":"2026-01-15T17:47:58.492Z","event":"mcp_server_started","details":{"timestamp":1768499278492},"severity":"low","pid":13088,"user":"unknown"}
|
|
28
|
+
{"timestamp":"2026-01-15T17:50:01.661Z","event":"mcp_server_started","details":{"timestamp":1768499401661},"severity":"low","pid":6668,"user":"unknown"}
|
|
29
|
+
{"timestamp":"2026-01-15T18:03:20.923Z","event":"mcp_server_started","details":{"timestamp":1768500200922},"severity":"low","pid":13840,"user":"unknown"}
|
|
30
|
+
{"timestamp":"2026-01-15T18:04:20.452Z","event":"mcp_server_started","details":{"timestamp":1768500260451},"severity":"low","pid":3068,"user":"unknown"}
|
|
31
|
+
{"timestamp":"2026-01-15T18:06:16.394Z","event":"mcp_server_started","details":{"timestamp":1768500376394},"severity":"low","pid":11484,"user":"unknown"}
|
|
32
|
+
{"timestamp":"2026-01-15T18:09:50.431Z","event":"mcp_server_started","details":{"timestamp":1768500590431},"severity":"low","pid":9628,"user":"unknown"}
|
|
33
|
+
{"timestamp":"2026-01-16T18:58:44.667Z","event":"mcp_server_started","details":{"timestamp":1768589924667},"severity":"low","pid":15724,"user":"unknown"}
|
|
34
|
+
{"timestamp":"2026-01-16T18:58:50.370Z","event":"mcp_server_started","details":{"timestamp":1768589930370},"severity":"low","pid":16784,"user":"unknown"}
|
|
35
|
+
{"timestamp":"2026-01-16T19:04:23.658Z","event":"mcp_server_started","details":{"timestamp":1768590263657},"severity":"low","pid":4060,"user":"unknown"}
|
|
36
|
+
{"timestamp":"2026-01-19T19:04:53.877Z","event":"mcp_server_started","details":{"timestamp":1768849493877},"severity":"low","pid":10996,"user":"unknown"}
|
|
37
|
+
{"timestamp":"2026-01-19T19:05:08.692Z","event":"mcp_server_started","details":{"timestamp":1768849508692},"severity":"low","pid":8148,"user":"unknown"}
|
|
38
|
+
{"timestamp":"2026-01-19T19:05:32.721Z","event":"mcp_server_started","details":{"timestamp":1768849532721},"severity":"low","pid":14120,"user":"unknown"}
|
|
39
|
+
{"timestamp":"2026-01-19T19:55:48.328Z","event":"mcp_server_started","details":{"timestamp":1768852548328},"severity":"low","pid":15312,"user":"unknown"}
|
|
40
|
+
{"timestamp":"2026-01-19T21:18:55.224Z","event":"mcp_server_started","details":{"timestamp":1768857535224},"severity":"low","pid":14444,"user":"unknown"}
|
|
41
|
+
{"timestamp":"2026-01-20T17:05:53.653Z","event":"mcp_server_started","details":{"timestamp":1768928753653},"severity":"low","pid":8684,"user":"unknown"}
|
|
42
|
+
{"timestamp":"2026-01-20T18:50:01.944Z","event":"mcp_server_started","details":{"timestamp":1768935001944},"severity":"low","pid":1328,"user":"unknown"}
|
|
43
|
+
{"timestamp":"2026-01-20T20:32:12.756Z","event":"mcp_server_started","details":{"timestamp":1768941132756},"severity":"low","pid":14400,"user":"unknown"}
|
|
44
|
+
{"timestamp":"2026-01-20T20:43:09.314Z","event":"mcp_server_started","details":{"timestamp":1768941789314},"severity":"low","pid":12936,"user":"unknown"}
|
|
45
|
+
{"timestamp":"2026-01-20T20:47:06.818Z","event":"mcp_server_started","details":{"timestamp":1768942026818},"severity":"low","pid":13580,"user":"unknown"}
|
|
46
|
+
{"timestamp":"2026-01-24T20:19:47.199Z","event":"mcp_server_started","details":{"timestamp":1769285987199},"severity":"low","pid":9716,"user":"unknown"}
|
|
47
|
+
{"timestamp":"2026-01-24T20:24:33.021Z","event":"mobile_device_connected","details":{"timestamp":1769286273021},"severity":"low","pid":9716,"user":"unknown"}
|
|
48
|
+
{"timestamp":"2026-01-24T23:11:46.753Z","event":"mcp_server_started","details":{"timestamp":1769296306753},"severity":"low","pid":17644,"user":"unknown"}
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const child_process_1 = require("child_process");
|
|
5
|
-
const os_1 = require("os");
|
|
6
|
-
class CLIAdapter {
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { platform } from 'os';
|
|
3
|
+
export class CLIAdapter {
|
|
7
4
|
process = null;
|
|
8
5
|
onOutputCallback;
|
|
9
6
|
constructor() { }
|
|
10
7
|
execute(command, args = [], cwd = process.cwd()) {
|
|
11
|
-
const isWindows =
|
|
8
|
+
const isWindows = platform() === 'win32';
|
|
12
9
|
const shell = isWindows ? 'powershell.exe' : '/bin/bash';
|
|
13
10
|
const shellArgs = isWindows ? ['-c', `${command} ${args.join(' ')}`] : ['-c', `${command} ${args.join(' ')}`];
|
|
14
11
|
console.log(`[CLI] Executing: ${command} ${args.join(' ')}`);
|
|
15
12
|
try {
|
|
16
|
-
this.process =
|
|
13
|
+
this.process = spawn(shell, shellArgs, {
|
|
17
14
|
cwd,
|
|
18
15
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
19
16
|
env: process.env
|
|
@@ -58,5 +55,4 @@ class CLIAdapter {
|
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
}
|
|
61
|
-
exports.CLIAdapter = CLIAdapter;
|
|
62
58
|
//# sourceMappingURL=cli-adapter.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../src/adapters/cli-adapter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-adapter.js","sourceRoot":"","sources":["../../src/adapters/cli-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAgB,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AAO9B,MAAM,OAAO,UAAU;IACX,OAAO,GAAwB,IAAI,CAAC;IACpC,gBAAgB,CAA0B;IAElD,gBAAgB,CAAC;IAEjB,OAAO,CAAC,OAAe,EAAE,OAAiB,EAAE,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;QACrE,MAAM,SAAS,GAAG,QAAQ,EAAE,KAAK,OAAO,CAAC;QACzC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC;QACzD,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE9G,OAAO,CAAC,GAAG,CAAC,oBAAoB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7D,IAAI,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE;gBACnC,GAAG;gBACH,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBAC/B,GAAG,EAAE,OAAO,CAAC,GAAG;aACnB,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC/B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,gBAAgB,CAAC,UAAU,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;gBACvD,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC9B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxB,IAAI,CAAC,gBAAgB,CAAC,+BAA+B,IAAI,GAAG,CAAC,CAAC;gBAClE,CAAC;gBACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;YACxB,CAAC,CAAC,CAAC;QAEP,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACxB,IAAI,CAAC,gBAAgB,CAAC,4BAA4B,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;YACzE,CAAC;QACL,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,QAAgC;QACrC,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;IACrC,CAAC;IAED,IAAI;QACA,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACxB,CAAC;IACL,CAAC;CACJ"}
|
package/dist/agent.d.ts
CHANGED
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/C,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;CAwCxB"}
|
package/dist/agent.js
CHANGED
|
@@ -1,22 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const mcp_handler_1 = require("./mcp-handler");
|
|
5
|
-
const cli_adapter_1 = require("./adapters/cli-adapter");
|
|
6
|
-
class UniversalAgent {
|
|
1
|
+
import { setupMCPServer } from './mcp-handler.js';
|
|
2
|
+
import { CLIAdapter } from './adapters/cli-adapter.js';
|
|
3
|
+
export class UniversalAgent {
|
|
7
4
|
webrtc;
|
|
8
5
|
cliAdapter;
|
|
9
6
|
activeTool = 'mcp';
|
|
10
7
|
constructor(webrtc) {
|
|
11
8
|
this.webrtc = webrtc;
|
|
12
|
-
this.cliAdapter = new
|
|
9
|
+
this.cliAdapter = new CLIAdapter();
|
|
13
10
|
}
|
|
14
11
|
async start() {
|
|
15
12
|
console.log('🚀 Universal Agent starting...');
|
|
16
13
|
// Initialize MCP Server (Cursor integration)
|
|
17
14
|
// We run this in parallel because it sets up its own listeners
|
|
18
15
|
// Note: In the future, we might want to wrap this better
|
|
19
|
-
|
|
16
|
+
setupMCPServer(this.webrtc).catch(err => {
|
|
20
17
|
console.error('Failed to start MCP server:', err);
|
|
21
18
|
});
|
|
22
19
|
// Initialize CLI Adapter listeners
|
|
@@ -51,6 +48,22 @@ class UniversalAgent {
|
|
|
51
48
|
});
|
|
52
49
|
return;
|
|
53
50
|
}
|
|
51
|
+
if (message.type === 'switch_ide') {
|
|
52
|
+
console.log(`🖥️ Target IDE switched to: ${message.ide}`);
|
|
53
|
+
this.webrtc.send({
|
|
54
|
+
type: 'system',
|
|
55
|
+
message: `Target IDE: ${message.ide}`
|
|
56
|
+
});
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (message.type === 'switch_model') {
|
|
60
|
+
console.log(`🤖 AI Model preference: ${message.model}`);
|
|
61
|
+
this.webrtc.send({
|
|
62
|
+
type: 'system',
|
|
63
|
+
message: `Model: ${message.model}`
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
54
67
|
if (message.type === 'cli_command') {
|
|
55
68
|
const command = message.command;
|
|
56
69
|
console.log(`💻 Received CLI command: ${command}`);
|
|
@@ -59,5 +72,4 @@ class UniversalAgent {
|
|
|
59
72
|
// MCP commands are handled by mcp-handler.ts directly via its own listener
|
|
60
73
|
}
|
|
61
74
|
}
|
|
62
|
-
exports.UniversalAgent = UniversalAgent;
|
|
63
75
|
//# sourceMappingURL=agent.js.map
|
package/dist/agent.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,88 +1,62 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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();
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as path from 'path';
|
|
5
|
+
import * as os from 'os';
|
|
6
|
+
import * as crypto from 'crypto';
|
|
7
|
+
import { createRequire } from 'module';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const qrcode = require('qrcode-terminal');
|
|
10
|
+
import { UniversalAgent } from './agent.js';
|
|
11
|
+
import { WebRTCConnection } from './webrtc.js';
|
|
12
|
+
const program = new Command();
|
|
45
13
|
program
|
|
46
|
-
.name('
|
|
14
|
+
.name('mobilecoder-mcp')
|
|
47
15
|
.description('MCP server for MobileCoderMCP - enables mobile to desktop coding')
|
|
48
16
|
.version('1.0.0');
|
|
49
17
|
program
|
|
50
18
|
.command('init')
|
|
51
19
|
.description('Initialize connection, generate QR code and start the agent')
|
|
52
|
-
.option('-s, --signaling <url>', 'Signaling server URL', 'https://
|
|
20
|
+
.option('-s, --signaling <url>', 'Signaling server URL', process.env.MCP_SIGNALING_URL || 'https://api.mobilecoder.xyz/api')
|
|
21
|
+
.option('--debug', 'Enable debug logging', false)
|
|
53
22
|
.action(async (options) => {
|
|
54
23
|
const code = generateConnectionCode();
|
|
24
|
+
if (options.debug) {
|
|
25
|
+
console.log('🔍 Debug mode enabled');
|
|
26
|
+
}
|
|
55
27
|
console.log('\n📱 MobileCoder MCP - Quick Setup');
|
|
56
28
|
console.log('================================');
|
|
57
29
|
console.log(`\n🔑 Your Pairing Code: ${code}`);
|
|
58
30
|
console.log('Scan the QR code below with your mobile device to connect:\n');
|
|
59
31
|
// Generate QR code in terminal
|
|
60
|
-
//
|
|
61
|
-
const
|
|
32
|
+
// Use environment variable or default to the deployed URL
|
|
33
|
+
const webAppUrl = process.env.MOBILE_CODER_WEB_URL || 'https://mobilecoder.xyz';
|
|
34
|
+
const pairingUrl = `${webAppUrl}/connect?code=${code}`;
|
|
62
35
|
qrcode.generate(pairingUrl, { small: true });
|
|
63
36
|
console.log('\n🚀 Configuring IDEs...');
|
|
64
37
|
await autoConfigureIDEs(code, options.signaling);
|
|
65
38
|
console.log('\n🔌 Starting Universal Agent...');
|
|
66
|
-
const webrtc = new
|
|
67
|
-
const agent = new
|
|
39
|
+
const webrtc = new WebRTCConnection(code, options.signaling, options.debug);
|
|
40
|
+
const agent = new UniversalAgent(webrtc);
|
|
68
41
|
await agent.start();
|
|
69
42
|
});
|
|
70
43
|
program
|
|
71
44
|
.command('start')
|
|
72
45
|
.description('Start the Universal Agent with an existing code')
|
|
73
46
|
.option('-c, --code <code>', 'Connection code')
|
|
74
|
-
.option('-s, --signaling <url>', 'Signaling server URL', 'https://
|
|
47
|
+
.option('-s, --signaling <url>', 'Signaling server URL', process.env.MCP_SIGNALING_URL || 'https://api.mobilecoder.xyz/api')
|
|
48
|
+
.option('--debug', 'Enable debug logging', false)
|
|
75
49
|
.action(async (options) => {
|
|
76
50
|
if (!options.code) {
|
|
77
51
|
console.error('❌ Error: Connection code is required');
|
|
78
|
-
console.log(' Use:
|
|
52
|
+
console.log(' Use: mobilecoder-mcp start --code=YOUR_CODE');
|
|
79
53
|
process.exit(1);
|
|
80
54
|
}
|
|
81
55
|
console.log('🔌 Starting Universal Agent...');
|
|
82
56
|
console.log(` Connection code: ${options.code}`);
|
|
83
57
|
console.log(` Signaling server: ${options.signaling}\n`);
|
|
84
|
-
const webrtc = new
|
|
85
|
-
const agent = new
|
|
58
|
+
const webrtc = new WebRTCConnection(options.code, options.signaling, options.debug);
|
|
59
|
+
const agent = new UniversalAgent(webrtc);
|
|
86
60
|
await agent.start();
|
|
87
61
|
});
|
|
88
62
|
program
|
|
@@ -109,7 +83,7 @@ program
|
|
|
109
83
|
});
|
|
110
84
|
program.parse();
|
|
111
85
|
function generateConnectionCode() {
|
|
112
|
-
return
|
|
86
|
+
return crypto.randomBytes(3).toString('hex').toUpperCase();
|
|
113
87
|
}
|
|
114
88
|
async function autoConfigureIDEs(code, signalingUrl) {
|
|
115
89
|
const configs = {
|
|
@@ -143,11 +117,11 @@ async function configureIDE(configPath, ideName, code, signalingUrl) {
|
|
|
143
117
|
if (!config.mcpServers) {
|
|
144
118
|
config.mcpServers = {};
|
|
145
119
|
}
|
|
146
|
-
// We assume the user has
|
|
120
|
+
// We assume the user has mobilecoder-mcp installed globally or via npx
|
|
147
121
|
// In npx context, we use the command name directly
|
|
148
122
|
config.mcpServers['mobile-coder'] = {
|
|
149
123
|
command: 'npx',
|
|
150
|
-
args: ['
|
|
124
|
+
args: ['mobilecoder-mcp', 'start', '--code', code, '--signaling', signalingUrl],
|
|
151
125
|
env: {
|
|
152
126
|
MCP_CONNECTION_CODE: code,
|
|
153
127
|
MCP_SIGNALING_URL: signalingUrl
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-handler.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../src/mcp-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"mcp-handler.d.ts","sourceRoot":"","sources":["../src/mcp-handler.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAmB/C,wBAAsB,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4N5E"}
|
package/dist/mcp-handler.js
CHANGED
|
@@ -1,51 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.setupMCPServer = setupMCPServer;
|
|
37
|
-
const index_1 = require("@modelcontextprotocol/sdk/server/index");
|
|
38
|
-
const stdio_1 = require("@modelcontextprotocol/sdk/server/stdio");
|
|
39
|
-
const types_1 = require("@modelcontextprotocol/sdk/types");
|
|
40
|
-
const security_1 = require("./security");
|
|
41
|
-
const fs = __importStar(require("fs"));
|
|
42
|
-
const path = __importStar(require("path"));
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { validatePath, validateFile, validateCommand, sanitizeInput, sanitizePath, safeResolvePath, rateLimiters, securityLogger, generateSecureToken } from './security.js';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
43
7
|
// Queue to store commands received from mobile
|
|
44
8
|
const commandQueue = [];
|
|
45
|
-
async function setupMCPServer(webrtc) {
|
|
9
|
+
export async function setupMCPServer(webrtc) {
|
|
46
10
|
// Create MCP server
|
|
47
|
-
const server = new
|
|
48
|
-
name: '
|
|
11
|
+
const server = new Server({
|
|
12
|
+
name: 'mobilecoder-mcp',
|
|
49
13
|
version: '1.0.0',
|
|
50
14
|
}, {
|
|
51
15
|
capabilities: {
|
|
@@ -55,10 +19,10 @@ async function setupMCPServer(webrtc) {
|
|
|
55
19
|
// Set up error handling
|
|
56
20
|
server.onerror = (error) => {
|
|
57
21
|
console.error('[MCP Error]', error);
|
|
58
|
-
|
|
22
|
+
securityLogger.log('mcp_server_error', { error: error.message || 'Unknown error' }, 'medium');
|
|
59
23
|
};
|
|
60
24
|
// List available tools
|
|
61
|
-
server.setRequestHandler(
|
|
25
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
62
26
|
return {
|
|
63
27
|
tools: [
|
|
64
28
|
{
|
|
@@ -114,7 +78,7 @@ async function setupMCPServer(webrtc) {
|
|
|
114
78
|
};
|
|
115
79
|
});
|
|
116
80
|
// Handle tool calls from MCP (Claude/Cursor)
|
|
117
|
-
server.setRequestHandler(
|
|
81
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
118
82
|
const { name, arguments: args } = request.params;
|
|
119
83
|
if (name === 'get_next_command') {
|
|
120
84
|
const command = commandQueue.shift();
|
|
@@ -129,7 +93,7 @@ async function setupMCPServer(webrtc) {
|
|
|
129
93
|
return { content: [{ type: 'text', text: 'Error: Message is required' }], isError: true };
|
|
130
94
|
}
|
|
131
95
|
// Sanitize message content
|
|
132
|
-
const sanitizedMessage =
|
|
96
|
+
const sanitizedMessage = sanitizeInput(message);
|
|
133
97
|
// Check if message contains diff data
|
|
134
98
|
if (typeof args === 'object' && args.diff) {
|
|
135
99
|
webrtc.send({
|
|
@@ -150,7 +114,7 @@ async function setupMCPServer(webrtc) {
|
|
|
150
114
|
}
|
|
151
115
|
if (name === 'list_directory') {
|
|
152
116
|
try {
|
|
153
|
-
const requestId =
|
|
117
|
+
const requestId = generateSecureToken(16);
|
|
154
118
|
const fileList = await handleListDirectory(process.cwd(), args, requestId);
|
|
155
119
|
return { content: [{ type: 'text', text: JSON.stringify(fileList) }] };
|
|
156
120
|
}
|
|
@@ -160,7 +124,7 @@ async function setupMCPServer(webrtc) {
|
|
|
160
124
|
}
|
|
161
125
|
if (name === 'read_file') {
|
|
162
126
|
try {
|
|
163
|
-
const requestId =
|
|
127
|
+
const requestId = generateSecureToken(16);
|
|
164
128
|
const content = await handleReadFile(process.cwd(), args, requestId);
|
|
165
129
|
return { content: [{ type: 'text', text: content }] };
|
|
166
130
|
}
|
|
@@ -173,15 +137,15 @@ async function setupMCPServer(webrtc) {
|
|
|
173
137
|
// Connect WebRTC listeners
|
|
174
138
|
webrtc.onConnect(() => {
|
|
175
139
|
console.log('📱 [MCP] Mobile device connected');
|
|
176
|
-
|
|
140
|
+
securityLogger.log('mobile_device_connected', { timestamp: Date.now() }, 'low');
|
|
177
141
|
});
|
|
178
142
|
webrtc.onMessage(async (message) => {
|
|
179
143
|
// Handle command queueing
|
|
180
144
|
if (message.type === 'command' && message.text) {
|
|
181
|
-
const sanitizedCommand =
|
|
145
|
+
const sanitizedCommand = sanitizeInput(message.text);
|
|
182
146
|
// Rate limiting
|
|
183
|
-
if (!
|
|
184
|
-
|
|
147
|
+
if (!rateLimiters.commands.isAllowed('command')) {
|
|
148
|
+
securityLogger.logRateLimitExceeded('command', 'queue_command');
|
|
185
149
|
webrtc.send({
|
|
186
150
|
type: 'error',
|
|
187
151
|
data: 'Rate limit exceeded. Please try again later.',
|
|
@@ -190,9 +154,9 @@ async function setupMCPServer(webrtc) {
|
|
|
190
154
|
return;
|
|
191
155
|
}
|
|
192
156
|
// Command validation
|
|
193
|
-
const commandValidation =
|
|
157
|
+
const commandValidation = validateCommand(sanitizedCommand);
|
|
194
158
|
if (!commandValidation.valid) {
|
|
195
|
-
|
|
159
|
+
securityLogger.logBlockedCommand(sanitizedCommand, commandValidation.error || 'Unknown reason');
|
|
196
160
|
webrtc.send({
|
|
197
161
|
type: 'error',
|
|
198
162
|
data: 'Command blocked for security reasons.',
|
|
@@ -228,7 +192,7 @@ async function setupMCPServer(webrtc) {
|
|
|
228
192
|
}
|
|
229
193
|
catch (error) {
|
|
230
194
|
console.error(`❌ [MCP] Tool execution failed: ${error.message}`);
|
|
231
|
-
|
|
195
|
+
securityLogger.log('tool_execution_failed', { tool, error: error.message }, 'medium');
|
|
232
196
|
webrtc.send({
|
|
233
197
|
type: 'tool_result',
|
|
234
198
|
id: id,
|
|
@@ -240,32 +204,33 @@ async function setupMCPServer(webrtc) {
|
|
|
240
204
|
}
|
|
241
205
|
});
|
|
242
206
|
// Start MCP server with stdio transport
|
|
243
|
-
const transport = new
|
|
207
|
+
const transport = new StdioServerTransport();
|
|
244
208
|
await server.connect(transport);
|
|
245
209
|
console.log('✅ MCP Server initialized (stdio transport)');
|
|
246
|
-
|
|
210
|
+
securityLogger.log('mcp_server_started', { timestamp: Date.now() }, 'low');
|
|
247
211
|
}
|
|
248
212
|
// Helper functions for file system operations
|
|
249
213
|
async function handleListDirectory(cwd, args, requestId) {
|
|
250
214
|
const dirPath = args?.path || '.';
|
|
251
|
-
const sanitizedPath =
|
|
215
|
+
const sanitizedPath = sanitizePath(dirPath);
|
|
252
216
|
// Rate limiting
|
|
253
|
-
if (!
|
|
254
|
-
|
|
217
|
+
if (!rateLimiters.fileOperations.isAllowed(requestId || 'unknown')) {
|
|
218
|
+
securityLogger.logRateLimitExceeded(requestId || 'unknown', 'list_directory');
|
|
255
219
|
throw new Error('Rate limit exceeded for directory operations');
|
|
256
220
|
}
|
|
257
221
|
// Security validation
|
|
258
|
-
const pathValidation =
|
|
222
|
+
const pathValidation = validatePath(sanitizedPath, cwd);
|
|
259
223
|
if (!pathValidation.valid) {
|
|
260
|
-
|
|
224
|
+
securityLogger.logPathTraversal(sanitizedPath, path.resolve(cwd, sanitizedPath));
|
|
261
225
|
throw new Error(`Access denied: ${pathValidation.error}`);
|
|
262
226
|
}
|
|
263
227
|
try {
|
|
264
|
-
const
|
|
228
|
+
const resolvedPath = await safeResolvePath(cwd, sanitizedPath);
|
|
229
|
+
const stats = await fs.promises.stat(resolvedPath);
|
|
265
230
|
if (!stats.isDirectory()) {
|
|
266
231
|
throw new Error('Path is not a directory');
|
|
267
232
|
}
|
|
268
|
-
const files = await fs.promises.readdir(
|
|
233
|
+
const files = await fs.promises.readdir(resolvedPath, { withFileTypes: true });
|
|
269
234
|
const fileList = files.map((f) => ({
|
|
270
235
|
name: f.name,
|
|
271
236
|
isDirectory: f.isDirectory(),
|
|
@@ -281,7 +246,7 @@ async function handleListDirectory(cwd, args, requestId) {
|
|
|
281
246
|
return fileList;
|
|
282
247
|
}
|
|
283
248
|
catch (error) {
|
|
284
|
-
|
|
249
|
+
securityLogger.log('directory_list_error', { path: sanitizedPath, error: error.message }, 'medium');
|
|
285
250
|
throw new Error(`Error listing directory: ${error.message}`);
|
|
286
251
|
}
|
|
287
252
|
}
|
|
@@ -289,28 +254,28 @@ async function handleReadFile(cwd, args, requestId) {
|
|
|
289
254
|
const filePath = args?.path;
|
|
290
255
|
if (!filePath)
|
|
291
256
|
throw new Error('Path is required');
|
|
292
|
-
const sanitizedPath =
|
|
257
|
+
const sanitizedPath = sanitizePath(filePath);
|
|
293
258
|
// Rate limiting
|
|
294
|
-
if (!
|
|
295
|
-
|
|
259
|
+
if (!rateLimiters.fileOperations.isAllowed(requestId || 'unknown')) {
|
|
260
|
+
securityLogger.logRateLimitExceeded(requestId || 'unknown', 'read_file');
|
|
296
261
|
throw new Error('Rate limit exceeded for file operations');
|
|
297
262
|
}
|
|
298
263
|
// Security validation
|
|
299
|
-
const fileValidation =
|
|
264
|
+
const fileValidation = validateFile(sanitizedPath, cwd);
|
|
300
265
|
if (!fileValidation.valid) {
|
|
301
|
-
|
|
266
|
+
securityLogger.log('file_access_denied', { path: sanitizedPath, reason: fileValidation.error }, 'high');
|
|
302
267
|
throw new Error(`Access denied: ${fileValidation.error}`);
|
|
303
268
|
}
|
|
304
269
|
try {
|
|
305
|
-
const
|
|
306
|
-
const stats = await fs.promises.stat(
|
|
270
|
+
const resolvedPath = await safeResolvePath(cwd, sanitizedPath);
|
|
271
|
+
const stats = await fs.promises.stat(resolvedPath);
|
|
307
272
|
if (stats.isDirectory()) {
|
|
308
273
|
throw new Error('Path is a directory, not a file');
|
|
309
274
|
}
|
|
310
|
-
return await fs.promises.readFile(
|
|
275
|
+
return await fs.promises.readFile(resolvedPath, 'utf-8');
|
|
311
276
|
}
|
|
312
277
|
catch (error) {
|
|
313
|
-
|
|
278
|
+
securityLogger.log('file_read_error', { path: sanitizedPath, error: error.message }, 'medium');
|
|
314
279
|
throw new Error(`Error reading file: ${error.message}`);
|
|
315
280
|
}
|
|
316
281
|
}
|