docker-flutter-ios-simulator-mcp 0.1.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 (80) hide show
  1. package/CLAUDE.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +370 -0
  4. package/dist/flutter/log-buffer.d.ts +14 -0
  5. package/dist/flutter/log-buffer.d.ts.map +1 -0
  6. package/dist/flutter/log-buffer.js +49 -0
  7. package/dist/flutter/log-buffer.js.map +1 -0
  8. package/dist/flutter/process.d.ts +30 -0
  9. package/dist/flutter/process.d.ts.map +1 -0
  10. package/dist/flutter/process.js +241 -0
  11. package/dist/flutter/process.js.map +1 -0
  12. package/dist/flutter/types.d.ts +31 -0
  13. package/dist/flutter/types.d.ts.map +1 -0
  14. package/dist/flutter/types.js +2 -0
  15. package/dist/flutter/types.js.map +1 -0
  16. package/dist/index.d.ts +3 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +207 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/server.d.ts +3 -0
  21. package/dist/server.d.ts.map +1 -0
  22. package/dist/server.js +18 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/session/manager.d.ts +74 -0
  25. package/dist/session/manager.d.ts.map +1 -0
  26. package/dist/session/manager.js +209 -0
  27. package/dist/session/manager.js.map +1 -0
  28. package/dist/session/state.d.ts +14 -0
  29. package/dist/session/state.d.ts.map +1 -0
  30. package/dist/session/state.js +42 -0
  31. package/dist/session/state.js.map +1 -0
  32. package/dist/session/types.d.ts +26 -0
  33. package/dist/session/types.d.ts.map +1 -0
  34. package/dist/session/types.js +2 -0
  35. package/dist/session/types.js.map +1 -0
  36. package/dist/simulator/idb.d.ts +42 -0
  37. package/dist/simulator/idb.d.ts.map +1 -0
  38. package/dist/simulator/idb.js +127 -0
  39. package/dist/simulator/idb.js.map +1 -0
  40. package/dist/simulator/simctl.d.ts +9 -0
  41. package/dist/simulator/simctl.d.ts.map +1 -0
  42. package/dist/simulator/simctl.js +96 -0
  43. package/dist/simulator/simctl.js.map +1 -0
  44. package/dist/simulator/types.d.ts +25 -0
  45. package/dist/simulator/types.d.ts.map +1 -0
  46. package/dist/simulator/types.js +2 -0
  47. package/dist/simulator/types.js.map +1 -0
  48. package/dist/tools/flutter-commands.d.ts +128 -0
  49. package/dist/tools/flutter-commands.d.ts.map +1 -0
  50. package/dist/tools/flutter-commands.js +275 -0
  51. package/dist/tools/flutter-commands.js.map +1 -0
  52. package/dist/tools/index.d.ts +3 -0
  53. package/dist/tools/index.d.ts.map +1 -0
  54. package/dist/tools/index.js +499 -0
  55. package/dist/tools/index.js.map +1 -0
  56. package/dist/tools/session.d.ts +38 -0
  57. package/dist/tools/session.d.ts.map +1 -0
  58. package/dist/tools/session.js +40 -0
  59. package/dist/tools/session.js.map +1 -0
  60. package/dist/tools/simulator-ui.d.ts +102 -0
  61. package/dist/tools/simulator-ui.d.ts.map +1 -0
  62. package/dist/tools/simulator-ui.js +117 -0
  63. package/dist/tools/simulator-ui.js.map +1 -0
  64. package/dist/tools/simulator.d.ts +7 -0
  65. package/dist/tools/simulator.d.ts.map +1 -0
  66. package/dist/tools/simulator.js +8 -0
  67. package/dist/tools/simulator.js.map +1 -0
  68. package/dist/transport.d.ts +4 -0
  69. package/dist/transport.d.ts.map +1 -0
  70. package/dist/transport.js +20 -0
  71. package/dist/transport.js.map +1 -0
  72. package/dist/utils/exec.d.ts +29 -0
  73. package/dist/utils/exec.d.ts.map +1 -0
  74. package/dist/utils/exec.js +109 -0
  75. package/dist/utils/exec.js.map +1 -0
  76. package/dist/utils/logger.d.ts +17 -0
  77. package/dist/utils/logger.d.ts.map +1 -0
  78. package/dist/utils/logger.js +60 -0
  79. package/dist/utils/logger.js.map +1 -0
  80. package/package.json +76 -0
@@ -0,0 +1,102 @@
1
+ import { z } from 'zod';
2
+ export declare const uiTapSchema: z.ZodObject<{
3
+ sessionId: z.ZodString;
4
+ x: z.ZodNumber;
5
+ y: z.ZodNumber;
6
+ duration: z.ZodOptional<z.ZodNumber>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ sessionId: string;
9
+ x: number;
10
+ y: number;
11
+ duration?: number | undefined;
12
+ }, {
13
+ sessionId: string;
14
+ x: number;
15
+ y: number;
16
+ duration?: number | undefined;
17
+ }>;
18
+ export declare const uiTypeSchema: z.ZodObject<{
19
+ sessionId: z.ZodString;
20
+ text: z.ZodString;
21
+ }, "strip", z.ZodTypeAny, {
22
+ sessionId: string;
23
+ text: string;
24
+ }, {
25
+ sessionId: string;
26
+ text: string;
27
+ }>;
28
+ export declare const uiSwipeSchema: z.ZodObject<{
29
+ sessionId: z.ZodString;
30
+ x_start: z.ZodNumber;
31
+ y_start: z.ZodNumber;
32
+ x_end: z.ZodNumber;
33
+ y_end: z.ZodNumber;
34
+ duration: z.ZodOptional<z.ZodNumber>;
35
+ }, "strip", z.ZodTypeAny, {
36
+ sessionId: string;
37
+ x_start: number;
38
+ y_start: number;
39
+ x_end: number;
40
+ y_end: number;
41
+ duration?: number | undefined;
42
+ }, {
43
+ sessionId: string;
44
+ x_start: number;
45
+ y_start: number;
46
+ x_end: number;
47
+ y_end: number;
48
+ duration?: number | undefined;
49
+ }>;
50
+ export declare const uiDescribeAllSchema: z.ZodObject<{
51
+ sessionId: z.ZodString;
52
+ }, "strip", z.ZodTypeAny, {
53
+ sessionId: string;
54
+ }, {
55
+ sessionId: string;
56
+ }>;
57
+ export declare const uiDescribePointSchema: z.ZodObject<{
58
+ sessionId: z.ZodString;
59
+ x: z.ZodNumber;
60
+ y: z.ZodNumber;
61
+ }, "strip", z.ZodTypeAny, {
62
+ sessionId: string;
63
+ x: number;
64
+ y: number;
65
+ }, {
66
+ sessionId: string;
67
+ x: number;
68
+ y: number;
69
+ }>;
70
+ export declare const screenshotSchema: z.ZodObject<{
71
+ sessionId: z.ZodString;
72
+ }, "strip", z.ZodTypeAny, {
73
+ sessionId: string;
74
+ }, {
75
+ sessionId: string;
76
+ }>;
77
+ export declare function handleUiTap(args: z.infer<typeof uiTapSchema>): Promise<{
78
+ success: boolean;
79
+ message: string;
80
+ }>;
81
+ export declare function handleUiType(args: z.infer<typeof uiTypeSchema>): Promise<{
82
+ success: boolean;
83
+ message: string;
84
+ }>;
85
+ export declare function handleUiSwipe(args: z.infer<typeof uiSwipeSchema>): Promise<{
86
+ success: boolean;
87
+ message: string;
88
+ }>;
89
+ export declare function handleUiDescribeAll(args: z.infer<typeof uiDescribeAllSchema>): Promise<{
90
+ accessibility_tree: string;
91
+ }>;
92
+ export declare function handleUiDescribePoint(args: z.infer<typeof uiDescribePointSchema>): Promise<{
93
+ accessibility_info: string;
94
+ }>;
95
+ export declare function handleScreenshot(args: z.infer<typeof screenshotSchema>): Promise<{
96
+ success: boolean;
97
+ path: string;
98
+ imageData: string;
99
+ format: string;
100
+ message: string;
101
+ }>;
102
+ //# sourceMappingURL=simulator-ui.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulator-ui.d.ts","sourceRoot":"","sources":["../../src/tools/simulator-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;EAKtB,CAAC;AAEH,eAAO,MAAM,YAAY;;;;;;;;;EAGvB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;EAOxB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;EAE9B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAIhC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;EAE3B,CAAC;AAEH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,GAChC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAkBhD;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,GACjC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAchD;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,GAClC,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBhD;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,GACxC,OAAO,CAAC;IAAE,kBAAkB,EAAE,MAAM,CAAA;CAAE,CAAC,CAazC;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,GAC1C,OAAO,CAAC;IAAE,kBAAkB,EAAE,MAAM,CAAA;CAAE,CAAC,CAazC;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,GACrC,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAiBD"}
@@ -0,0 +1,117 @@
1
+ import { z } from 'zod';
2
+ import { sessionManager } from '../session/manager.js';
3
+ import * as idb from '../simulator/idb.js';
4
+ import { logger } from '../utils/logger.js';
5
+ export const uiTapSchema = z.object({
6
+ sessionId: z.string().describe('Session ID'),
7
+ x: z.number().describe('X coordinate'),
8
+ y: z.number().describe('Y coordinate'),
9
+ duration: z.number().optional().describe('Duration in seconds for long press'),
10
+ });
11
+ export const uiTypeSchema = z.object({
12
+ sessionId: z.string().describe('Session ID'),
13
+ text: z.string().describe('Text to type'),
14
+ });
15
+ export const uiSwipeSchema = z.object({
16
+ sessionId: z.string().describe('Session ID'),
17
+ x_start: z.number().describe('Start X coordinate'),
18
+ y_start: z.number().describe('Start Y coordinate'),
19
+ x_end: z.number().describe('End X coordinate'),
20
+ y_end: z.number().describe('End Y coordinate'),
21
+ duration: z.number().optional().describe('Swipe duration in seconds'),
22
+ });
23
+ export const uiDescribeAllSchema = z.object({
24
+ sessionId: z.string().describe('Session ID'),
25
+ });
26
+ export const uiDescribePointSchema = z.object({
27
+ sessionId: z.string().describe('Session ID'),
28
+ x: z.number().describe('X coordinate'),
29
+ y: z.number().describe('Y coordinate'),
30
+ });
31
+ export const screenshotSchema = z.object({
32
+ sessionId: z.string().describe('Session ID'),
33
+ });
34
+ export async function handleUiTap(args) {
35
+ logger.info('Tool: ui_tap', args);
36
+ const session = sessionManager.getSession(args.sessionId);
37
+ if (!session) {
38
+ throw new Error(`Session not found: ${args.sessionId}`);
39
+ }
40
+ await idb.tap(session.simulatorUdid, {
41
+ x: args.x,
42
+ y: args.y,
43
+ duration: args.duration,
44
+ });
45
+ return {
46
+ success: true,
47
+ message: `Tapped at (${String(args.x)}, ${String(args.y)})${args.duration ? ` for ${String(args.duration)}s` : ''}`,
48
+ };
49
+ }
50
+ export async function handleUiType(args) {
51
+ logger.info('Tool: ui_type', args);
52
+ const session = sessionManager.getSession(args.sessionId);
53
+ if (!session) {
54
+ throw new Error(`Session not found: ${args.sessionId}`);
55
+ }
56
+ await idb.typeText(session.simulatorUdid, args.text);
57
+ return {
58
+ success: true,
59
+ message: `Typed ${String(args.text.length)} characters`,
60
+ };
61
+ }
62
+ export async function handleUiSwipe(args) {
63
+ logger.info('Tool: ui_swipe', args);
64
+ const session = sessionManager.getSession(args.sessionId);
65
+ if (!session) {
66
+ throw new Error(`Session not found: ${args.sessionId}`);
67
+ }
68
+ await idb.swipe(session.simulatorUdid, {
69
+ x_start: args.x_start,
70
+ y_start: args.y_start,
71
+ x_end: args.x_end,
72
+ y_end: args.y_end,
73
+ duration: args.duration,
74
+ });
75
+ return {
76
+ success: true,
77
+ message: `Swiped from (${String(args.x_start)}, ${String(args.y_start)}) to (${String(args.x_end)}, ${String(args.y_end)})`,
78
+ };
79
+ }
80
+ export async function handleUiDescribeAll(args) {
81
+ logger.info('Tool: ui_describe_all', args);
82
+ const session = sessionManager.getSession(args.sessionId);
83
+ if (!session) {
84
+ throw new Error(`Session not found: ${args.sessionId}`);
85
+ }
86
+ const tree = await idb.describeAll(session.simulatorUdid);
87
+ return {
88
+ accessibility_tree: tree,
89
+ };
90
+ }
91
+ export async function handleUiDescribePoint(args) {
92
+ logger.info('Tool: ui_describe_point', args);
93
+ const session = sessionManager.getSession(args.sessionId);
94
+ if (!session) {
95
+ throw new Error(`Session not found: ${args.sessionId}`);
96
+ }
97
+ const info = await idb.describePoint(session.simulatorUdid, args.x, args.y);
98
+ return {
99
+ accessibility_info: info,
100
+ };
101
+ }
102
+ export async function handleScreenshot(args) {
103
+ logger.info('Tool: screenshot', args);
104
+ const session = sessionManager.getSession(args.sessionId);
105
+ if (!session) {
106
+ throw new Error(`Session not found: ${args.sessionId}`);
107
+ }
108
+ const result = await idb.screenshot(session.simulatorUdid);
109
+ return {
110
+ success: true,
111
+ path: result.path,
112
+ imageData: result.imageData,
113
+ format: result.format,
114
+ message: `Screenshot captured (${String(result.imageData.length)} bytes base64)`,
115
+ };
116
+ }
117
+ //# sourceMappingURL=simulator-ui.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulator-ui.js","sourceRoot":"","sources":["../../src/tools/simulator-ui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAClC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC5C,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACtC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACtC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;CAC/E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC5C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;CAC1C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC5C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAClD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IAClD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC9C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC;IAC9C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2BAA2B,CAAC;CACtE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;IAC5C,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;IACtC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;CACvC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;CAC7C,CAAC,CAAC;AAEH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAiC;IAEjC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;IAElC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE;QACnC,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,CAAC,EAAE,IAAI,CAAC,CAAC;QACT,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,cAAc,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;KACpH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAkC;IAElC,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAEnC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IAErD,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,SAAS,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAmC;IAEnC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;IAEpC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE;QACrC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE,gBAAgB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG;KAC5H,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAAyC;IAEzC,MAAM,CAAC,IAAI,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE1D,OAAO;QACL,kBAAkB,EAAE,IAAI;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAA2C;IAE3C,MAAM,CAAC,IAAI,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IAE5E,OAAO;QACL,kBAAkB,EAAE,IAAI;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAsC;IAQtC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAE3D,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,wBAAwB,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB;KACjF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare function handleSimulatorList(): Promise<{
2
+ deviceTypes: Array<{
3
+ name: string;
4
+ identifier: string;
5
+ }>;
6
+ }>;
7
+ //# sourceMappingURL=simulator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulator.d.ts","sourceRoot":"","sources":["../../src/tools/simulator.ts"],"names":[],"mappings":"AAGA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC;IACnD,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1D,CAAC,CAMD"}
@@ -0,0 +1,8 @@
1
+ import { listDeviceTypes } from '../simulator/simctl.js';
2
+ import { logger } from '../utils/logger.js';
3
+ export async function handleSimulatorList() {
4
+ logger.info('Tool: simulator_list');
5
+ const deviceTypes = await listDeviceTypes();
6
+ return { deviceTypes };
7
+ }
8
+ //# sourceMappingURL=simulator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulator.js","sourceRoot":"","sources":["../../src/tools/simulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,CAAC,KAAK,UAAU,mBAAmB;IAGvC,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAEpC,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAE5C,OAAO,EAAE,WAAW,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
+ import { Express } from 'express';
3
+ export declare function setupTransport(app: Express): StreamableHTTPServerTransport;
4
+ //# sourceMappingURL=transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,6BAA6B,CAsB1E"}
@@ -0,0 +1,20 @@
1
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
2
+ import { logger } from './utils/logger.js';
3
+ export function setupTransport(app) {
4
+ logger.debug('Setting up Streamable HTTP transport');
5
+ const transport = new StreamableHTTPServerTransport({
6
+ sessionIdGenerator: undefined,
7
+ });
8
+ app.post('/mcp', (req, res) => {
9
+ void transport.handleRequest(req, res, req.body);
10
+ });
11
+ app.get('/mcp', (req, res) => {
12
+ void transport.handleRequest(req, res);
13
+ });
14
+ app.delete('/mcp', (req, res) => {
15
+ void transport.handleRequest(req, res);
16
+ });
17
+ logger.debug('Streamable HTTP transport routes registered');
18
+ return transport;
19
+ }
20
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAEnG,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAE3C,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAErD,MAAM,SAAS,GAAG,IAAI,6BAA6B,CAAC;QAClD,kBAAkB,EAAE,SAAS;KAC9B,CAAC,CAAC;IAEH,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5B,KAAK,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC3B,KAAK,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC9B,KAAK,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAE5D,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface ExecResult {
2
+ stdout: string;
3
+ stderr: string;
4
+ exitCode: number;
5
+ }
6
+ export interface ExecOptions {
7
+ cwd?: string;
8
+ timeout?: number;
9
+ env?: NodeJS.ProcessEnv;
10
+ maxBuffer?: number;
11
+ }
12
+ export declare function exec(command: string, options?: ExecOptions): Promise<ExecResult>;
13
+ /**
14
+ * Execute a file with arguments (safer than exec - no shell injection)
15
+ */
16
+ export declare function execFile(command: string, args?: string[], options?: ExecOptions): Promise<ExecResult>;
17
+ export interface SpawnStreamOptions extends ExecOptions {
18
+ onStdout?: (data: string) => void;
19
+ onStderr?: (data: string) => void;
20
+ onExit?: (code: number | null, signal: string | null) => void;
21
+ }
22
+ export interface SpawnedProcess {
23
+ pid: number | undefined;
24
+ stdin: NodeJS.WritableStream;
25
+ kill: (signal?: NodeJS.Signals) => boolean;
26
+ wait: () => Promise<number>;
27
+ }
28
+ export declare function spawnStreaming(command: string, args: string[], options?: SpawnStreamOptions): SpawnedProcess;
29
+ //# sourceMappingURL=exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,IAAI,CACxB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CA0CrB;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC,CA0CrB;AAED,MAAM,WAAW,kBAAmB,SAAQ,WAAW;IACrD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAC/D;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC,cAAc,CAAC;IAC7B,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,OAAO,KAAK,OAAO,CAAC;IAC3C,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B;AAED,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,kBAAuB,GAC/B,cAAc,CAqChB"}
@@ -0,0 +1,109 @@
1
+ import { exec as nodeExec, execFile as nodeExecFile, spawn } from 'child_process';
2
+ import { promisify } from 'util';
3
+ import { logger } from './logger.js';
4
+ const execAsync = promisify(nodeExec);
5
+ const execFileAsync = promisify(nodeExecFile);
6
+ export async function exec(command, options = {}) {
7
+ const { cwd, timeout = 30000, env, maxBuffer = 10 * 1024 * 1024 } = options;
8
+ logger.debug('Executing command', { command, cwd });
9
+ try {
10
+ const { stdout, stderr } = await execAsync(command, {
11
+ cwd,
12
+ timeout,
13
+ env: { ...process.env, ...env },
14
+ maxBuffer,
15
+ });
16
+ return {
17
+ stdout,
18
+ stderr,
19
+ exitCode: 0,
20
+ };
21
+ }
22
+ catch (error) {
23
+ if (error && typeof error === 'object' && 'code' in error) {
24
+ const execError = error;
25
+ const stdout = typeof execError.stdout === 'string'
26
+ ? execError.stdout
27
+ : execError.stdout?.toString() ?? '';
28
+ const stderr = typeof execError.stderr === 'string'
29
+ ? execError.stderr
30
+ : execError.stderr?.toString() ?? '';
31
+ return {
32
+ stdout,
33
+ stderr,
34
+ exitCode: execError.code ?? 1,
35
+ };
36
+ }
37
+ throw error;
38
+ }
39
+ }
40
+ /**
41
+ * Execute a file with arguments (safer than exec - no shell injection)
42
+ */
43
+ export async function execFile(command, args = [], options = {}) {
44
+ const { cwd, timeout = 30000, env, maxBuffer = 10 * 1024 * 1024 } = options;
45
+ logger.debug('Executing file', { command, args, cwd });
46
+ try {
47
+ const { stdout, stderr } = await execFileAsync(command, args, {
48
+ cwd,
49
+ timeout,
50
+ env: { ...process.env, ...env },
51
+ maxBuffer,
52
+ });
53
+ return {
54
+ stdout,
55
+ stderr,
56
+ exitCode: 0,
57
+ };
58
+ }
59
+ catch (error) {
60
+ if (error && typeof error === 'object' && 'code' in error) {
61
+ const execError = error;
62
+ const stdout = typeof execError.stdout === 'string'
63
+ ? execError.stdout
64
+ : execError.stdout?.toString() ?? '';
65
+ const stderr = typeof execError.stderr === 'string'
66
+ ? execError.stderr
67
+ : execError.stderr?.toString() ?? '';
68
+ return {
69
+ stdout,
70
+ stderr,
71
+ exitCode: execError.code ?? 1,
72
+ };
73
+ }
74
+ throw error;
75
+ }
76
+ }
77
+ export function spawnStreaming(command, args, options = {}) {
78
+ const { cwd, env, onStdout, onStderr, onExit } = options;
79
+ logger.debug('Spawning process', { command, args, cwd });
80
+ const child = spawn(command, args, {
81
+ cwd,
82
+ env: { ...process.env, ...env },
83
+ stdio: ['pipe', 'pipe', 'pipe'],
84
+ });
85
+ child.stdout.on('data', (data) => {
86
+ const str = data.toString();
87
+ logger.debug('Process stdout', { pid: child.pid, data: str });
88
+ onStdout?.(str);
89
+ });
90
+ child.stderr.on('data', (data) => {
91
+ const str = data.toString();
92
+ logger.debug('Process stderr', { pid: child.pid, data: str });
93
+ onStderr?.(str);
94
+ });
95
+ const waitPromise = new Promise((resolve) => {
96
+ child.on('exit', (code, signal) => {
97
+ logger.debug('Process exited', { pid: child.pid, code, signal });
98
+ onExit?.(code, signal);
99
+ resolve(code ?? 1);
100
+ });
101
+ });
102
+ return {
103
+ pid: child.pid,
104
+ stdin: child.stdin,
105
+ kill: (signal) => child.kill(signal),
106
+ wait: () => waitPromise,
107
+ };
108
+ }
109
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ declare class Logger {
3
+ private level;
4
+ private levelPriority;
5
+ constructor(level?: LogLevel);
6
+ setLevel(level: LogLevel): void;
7
+ private shouldLog;
8
+ private formatLog;
9
+ private log;
10
+ debug(message: string, context?: Record<string, unknown>): void;
11
+ info(message: string, context?: Record<string, unknown>): void;
12
+ warn(message: string, context?: Record<string, unknown>): void;
13
+ error(message: string, context?: Record<string, unknown>): void;
14
+ }
15
+ export declare const logger: Logger;
16
+ export {};
17
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AASpD,cAAM,MAAM;IACV,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,aAAa,CAKnB;gBAEU,KAAK,GAAE,QAAiB;IAIpC,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,SAAS;IAOjB,OAAO,CAAC,GAAG;IAuBX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGhE;AAGD,eAAO,MAAM,MAAM,QAAuB,CAAC"}
@@ -0,0 +1,60 @@
1
+ class Logger {
2
+ level;
3
+ levelPriority = {
4
+ debug: 0,
5
+ info: 1,
6
+ warn: 2,
7
+ error: 3,
8
+ };
9
+ constructor(level = 'info') {
10
+ this.level = level;
11
+ }
12
+ setLevel(level) {
13
+ this.level = level;
14
+ }
15
+ shouldLog(level) {
16
+ return this.levelPriority[level] >= this.levelPriority[this.level];
17
+ }
18
+ formatLog(entry) {
19
+ const contextStr = entry.context !== undefined
20
+ ? ` ${JSON.stringify(entry.context)}`
21
+ : '';
22
+ return `[${entry.timestamp}] ${entry.level.toUpperCase()}: ${entry.message}${contextStr}`;
23
+ }
24
+ log(level, message, context) {
25
+ if (!this.shouldLog(level)) {
26
+ return;
27
+ }
28
+ const entry = {
29
+ timestamp: new Date().toISOString(),
30
+ level,
31
+ message,
32
+ context,
33
+ };
34
+ const formatted = this.formatLog(entry);
35
+ if (level === 'error') {
36
+ console.error(formatted);
37
+ }
38
+ else if (level === 'warn') {
39
+ console.warn(formatted);
40
+ }
41
+ else {
42
+ console.log(formatted);
43
+ }
44
+ }
45
+ debug(message, context) {
46
+ this.log('debug', message, context);
47
+ }
48
+ info(message, context) {
49
+ this.log('info', message, context);
50
+ }
51
+ warn(message, context) {
52
+ this.log('warn', message, context);
53
+ }
54
+ error(message, context) {
55
+ this.log('error', message, context);
56
+ }
57
+ }
58
+ const logLevel = process.env.LOG_LEVEL ?? 'info';
59
+ export const logger = new Logger(logLevel);
60
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AASA,MAAM,MAAM;IACF,KAAK,CAAW;IAChB,aAAa,GAA6B;QAChD,KAAK,EAAE,CAAC;QACR,IAAI,EAAE,CAAC;QACP,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,CAAC;KACT,CAAC;IAEF,YAAY,QAAkB,MAAM;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,QAAQ,CAAC,KAAe;QACtB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEO,SAAS,CAAC,KAAe;QAC/B,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrE,CAAC;IAEO,SAAS,CAAC,KAAe;QAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS;YAC5C,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE;YACrC,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,IAAI,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;IAC5F,CAAC;IAEO,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,OAAiC;QAC7E,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAa;YACtB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK;YACL,OAAO;YACP,OAAO;SACR,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAExC,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;aAAM,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,OAAiC;QACtD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,OAAiC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,OAAiC;QACtD,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACtC,CAAC;CACF;AAED,MAAM,QAAQ,GAAI,OAAO,CAAC,GAAG,CAAC,SAAkC,IAAI,MAAM,CAAC;AAC3E,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "docker-flutter-ios-simulator-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server providing Flutter iOS development tooling for AI agents",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "docker-flutter-ios-simulator-mcp": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js",
14
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest",
15
+ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch",
16
+ "lint": "eslint src --ext .ts",
17
+ "typecheck": "tsc --noEmit",
18
+ "clean": "rm -rf dist build",
19
+ "prepublishOnly": "npm run clean && npm run build && npm run lint && npm run typecheck && npm test",
20
+ "prepare": "npm run build"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "flutter",
26
+ "ios",
27
+ "simulator",
28
+ "development",
29
+ "ai",
30
+ "agent",
31
+ "xcode",
32
+ "mobile",
33
+ "testing",
34
+ "automation"
35
+ ],
36
+ "author": "Nick Clifford <nick@nickclifford.com>",
37
+ "license": "MIT",
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "git+https://github.com/zafnz/docker-flutter-ios-simulator-mcp.git"
41
+ },
42
+ "bugs": {
43
+ "url": "https://github.com/zafnz/docker-flutter-ios-simulator-mcp/issues"
44
+ },
45
+ "homepage": "https://github.com/zafnz/docker-flutter-ios-simulator-mcp#readme",
46
+ "files": [
47
+ "dist",
48
+ "README.md",
49
+ "LICENSE",
50
+ "CLAUDE.md"
51
+ ],
52
+ "dependencies": {
53
+ "@modelcontextprotocol/sdk": "^1.0.4",
54
+ "express": "^4.21.2",
55
+ "uuid": "^11.0.3",
56
+ "zod": "^3.24.1"
57
+ },
58
+ "devDependencies": {
59
+ "@eslint/js": "^9.17.0",
60
+ "@types/express": "^4.17.21",
61
+ "@types/jest": "^29.5.14",
62
+ "@types/node": "^20.17.10",
63
+ "@types/uuid": "^9.0.8",
64
+ "@typescript-eslint/eslint-plugin": "^8.18.2",
65
+ "@typescript-eslint/parser": "^8.18.2",
66
+ "eslint": "^9.17.0",
67
+ "jest": "^29.7.0",
68
+ "ts-jest": "^29.2.5",
69
+ "ts-node": "^10.9.2",
70
+ "typescript": "^5.7.2",
71
+ "typescript-eslint": "^8.18.2"
72
+ },
73
+ "engines": {
74
+ "node": ">=18.0.0"
75
+ }
76
+ }