@hypothesi/tauri-mcp-server 0.9.0 → 0.11.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.
@@ -0,0 +1,349 @@
1
+ import { z } from 'zod';
2
+ import { ScreenshotResult } from './webview-executor.js';
3
+ /**
4
+ * Base schema mixin for tools that can target a specific window and app.
5
+ * All webview tools extend this to support multi-window and multi-app scenarios.
6
+ */
7
+ export declare const WindowTargetSchema: z.ZodObject<{
8
+ windowId: z.ZodOptional<z.ZodString>;
9
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ windowId?: string | undefined;
12
+ appIdentifier?: string | number | undefined;
13
+ }, {
14
+ windowId?: string | undefined;
15
+ appIdentifier?: string | number | undefined;
16
+ }>;
17
+ export declare const InteractSchema: z.ZodObject<{
18
+ windowId: z.ZodOptional<z.ZodString>;
19
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
20
+ } & {
21
+ action: z.ZodEnum<["click", "double-click", "long-press", "scroll", "swipe", "focus"]>;
22
+ selector: z.ZodOptional<z.ZodString>;
23
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
24
+ x: z.ZodOptional<z.ZodNumber>;
25
+ y: z.ZodOptional<z.ZodNumber>;
26
+ duration: z.ZodOptional<z.ZodNumber>;
27
+ scrollX: z.ZodOptional<z.ZodNumber>;
28
+ scrollY: z.ZodOptional<z.ZodNumber>;
29
+ fromX: z.ZodOptional<z.ZodNumber>;
30
+ fromY: z.ZodOptional<z.ZodNumber>;
31
+ toX: z.ZodOptional<z.ZodNumber>;
32
+ toY: z.ZodOptional<z.ZodNumber>;
33
+ }, "strip", z.ZodTypeAny, {
34
+ action: "swipe" | "focus" | "click" | "double-click" | "long-press" | "scroll";
35
+ strategy: "css" | "text" | "xpath";
36
+ windowId?: string | undefined;
37
+ appIdentifier?: string | number | undefined;
38
+ selector?: string | undefined;
39
+ x?: number | undefined;
40
+ y?: number | undefined;
41
+ duration?: number | undefined;
42
+ scrollX?: number | undefined;
43
+ scrollY?: number | undefined;
44
+ fromX?: number | undefined;
45
+ fromY?: number | undefined;
46
+ toX?: number | undefined;
47
+ toY?: number | undefined;
48
+ }, {
49
+ action: "swipe" | "focus" | "click" | "double-click" | "long-press" | "scroll";
50
+ windowId?: string | undefined;
51
+ appIdentifier?: string | number | undefined;
52
+ selector?: string | undefined;
53
+ strategy?: "css" | "text" | "xpath" | undefined;
54
+ x?: number | undefined;
55
+ y?: number | undefined;
56
+ duration?: number | undefined;
57
+ scrollX?: number | undefined;
58
+ scrollY?: number | undefined;
59
+ fromX?: number | undefined;
60
+ fromY?: number | undefined;
61
+ toX?: number | undefined;
62
+ toY?: number | undefined;
63
+ }>;
64
+ export declare const ScreenshotSchema: z.ZodObject<{
65
+ windowId: z.ZodOptional<z.ZodString>;
66
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
67
+ } & {
68
+ format: z.ZodDefault<z.ZodOptional<z.ZodEnum<["png", "jpeg"]>>>;
69
+ quality: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
70
+ filePath: z.ZodOptional<z.ZodString>;
71
+ maxWidth: z.ZodOptional<z.ZodNumber>;
72
+ }, "strip", z.ZodTypeAny, {
73
+ format: "png" | "jpeg";
74
+ quality: number;
75
+ windowId?: string | undefined;
76
+ appIdentifier?: string | number | undefined;
77
+ maxWidth?: number | undefined;
78
+ filePath?: string | undefined;
79
+ }, {
80
+ format?: "png" | "jpeg" | undefined;
81
+ quality?: number | undefined;
82
+ windowId?: string | undefined;
83
+ appIdentifier?: string | number | undefined;
84
+ maxWidth?: number | undefined;
85
+ filePath?: string | undefined;
86
+ }>;
87
+ export declare const KeyboardSchema: z.ZodObject<{
88
+ windowId: z.ZodOptional<z.ZodString>;
89
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
90
+ } & {
91
+ action: z.ZodEnum<["type", "press", "down", "up"]>;
92
+ selector: z.ZodOptional<z.ZodString>;
93
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
94
+ text: z.ZodOptional<z.ZodString>;
95
+ key: z.ZodOptional<z.ZodString>;
96
+ modifiers: z.ZodOptional<z.ZodArray<z.ZodEnum<["Control", "Alt", "Shift", "Meta"]>, "many">>;
97
+ }, "strip", z.ZodTypeAny, {
98
+ action: "type" | "press" | "down" | "up";
99
+ strategy: "css" | "text" | "xpath";
100
+ text?: string | undefined;
101
+ windowId?: string | undefined;
102
+ appIdentifier?: string | number | undefined;
103
+ selector?: string | undefined;
104
+ key?: string | undefined;
105
+ modifiers?: ("Control" | "Alt" | "Shift" | "Meta")[] | undefined;
106
+ }, {
107
+ action: "type" | "press" | "down" | "up";
108
+ text?: string | undefined;
109
+ windowId?: string | undefined;
110
+ appIdentifier?: string | number | undefined;
111
+ selector?: string | undefined;
112
+ strategy?: "css" | "text" | "xpath" | undefined;
113
+ key?: string | undefined;
114
+ modifiers?: ("Control" | "Alt" | "Shift" | "Meta")[] | undefined;
115
+ }>;
116
+ export declare const WaitForSchema: z.ZodObject<{
117
+ windowId: z.ZodOptional<z.ZodString>;
118
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
119
+ } & {
120
+ type: z.ZodEnum<["selector", "text", "ipc-event"]>;
121
+ value: z.ZodString;
122
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
123
+ timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
124
+ }, "strip", z.ZodTypeAny, {
125
+ value: string;
126
+ type: "text" | "selector" | "ipc-event";
127
+ strategy: "css" | "text" | "xpath";
128
+ timeout: number;
129
+ windowId?: string | undefined;
130
+ appIdentifier?: string | number | undefined;
131
+ }, {
132
+ value: string;
133
+ type: "text" | "selector" | "ipc-event";
134
+ windowId?: string | undefined;
135
+ appIdentifier?: string | number | undefined;
136
+ strategy?: "css" | "text" | "xpath" | undefined;
137
+ timeout?: number | undefined;
138
+ }>;
139
+ export declare const GetStylesSchema: z.ZodObject<{
140
+ windowId: z.ZodOptional<z.ZodString>;
141
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
142
+ } & {
143
+ selector: z.ZodString;
144
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
145
+ properties: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
146
+ multiple: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
147
+ }, "strip", z.ZodTypeAny, {
148
+ selector: string;
149
+ strategy: "css" | "text" | "xpath";
150
+ multiple: boolean;
151
+ windowId?: string | undefined;
152
+ appIdentifier?: string | number | undefined;
153
+ properties?: string[] | undefined;
154
+ }, {
155
+ selector: string;
156
+ windowId?: string | undefined;
157
+ appIdentifier?: string | number | undefined;
158
+ strategy?: "css" | "text" | "xpath" | undefined;
159
+ properties?: string[] | undefined;
160
+ multiple?: boolean | undefined;
161
+ }>;
162
+ export declare const ExecuteJavaScriptSchema: z.ZodObject<{
163
+ windowId: z.ZodOptional<z.ZodString>;
164
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
165
+ } & {
166
+ script: z.ZodString;
167
+ args: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>;
168
+ }, "strip", z.ZodTypeAny, {
169
+ script: string;
170
+ windowId?: string | undefined;
171
+ appIdentifier?: string | number | undefined;
172
+ args?: unknown[] | undefined;
173
+ }, {
174
+ script: string;
175
+ windowId?: string | undefined;
176
+ appIdentifier?: string | number | undefined;
177
+ args?: unknown[] | undefined;
178
+ }>;
179
+ export declare const FocusElementSchema: z.ZodObject<{
180
+ windowId: z.ZodOptional<z.ZodString>;
181
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
182
+ } & {
183
+ selector: z.ZodString;
184
+ }, "strip", z.ZodTypeAny, {
185
+ selector: string;
186
+ windowId?: string | undefined;
187
+ appIdentifier?: string | number | undefined;
188
+ }, {
189
+ selector: string;
190
+ windowId?: string | undefined;
191
+ appIdentifier?: string | number | undefined;
192
+ }>;
193
+ export declare const FindElementSchema: z.ZodObject<{
194
+ windowId: z.ZodOptional<z.ZodString>;
195
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
196
+ } & {
197
+ selector: z.ZodString;
198
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
199
+ }, "strip", z.ZodTypeAny, {
200
+ selector: string;
201
+ strategy: "css" | "text" | "xpath";
202
+ windowId?: string | undefined;
203
+ appIdentifier?: string | number | undefined;
204
+ }, {
205
+ selector: string;
206
+ windowId?: string | undefined;
207
+ appIdentifier?: string | number | undefined;
208
+ strategy?: "css" | "text" | "xpath" | undefined;
209
+ }>;
210
+ export declare const GetConsoleLogsSchema: z.ZodObject<{
211
+ windowId: z.ZodOptional<z.ZodString>;
212
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
213
+ } & {
214
+ filter: z.ZodOptional<z.ZodString>;
215
+ since: z.ZodOptional<z.ZodString>;
216
+ }, "strip", z.ZodTypeAny, {
217
+ filter?: string | undefined;
218
+ windowId?: string | undefined;
219
+ appIdentifier?: string | number | undefined;
220
+ since?: string | undefined;
221
+ }, {
222
+ filter?: string | undefined;
223
+ windowId?: string | undefined;
224
+ appIdentifier?: string | number | undefined;
225
+ since?: string | undefined;
226
+ }>;
227
+ export declare const DomSnapshotSchema: z.ZodObject<{
228
+ windowId: z.ZodOptional<z.ZodString>;
229
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
230
+ } & {
231
+ type: z.ZodEnum<["accessibility", "structure"]>;
232
+ selector: z.ZodOptional<z.ZodString>;
233
+ strategy: z.ZodDefault<z.ZodEnum<["css", "xpath", "text"]>>;
234
+ }, "strip", z.ZodTypeAny, {
235
+ type: "accessibility" | "structure";
236
+ strategy: "css" | "text" | "xpath";
237
+ windowId?: string | undefined;
238
+ appIdentifier?: string | number | undefined;
239
+ selector?: string | undefined;
240
+ }, {
241
+ type: "accessibility" | "structure";
242
+ windowId?: string | undefined;
243
+ appIdentifier?: string | number | undefined;
244
+ selector?: string | undefined;
245
+ strategy?: "css" | "text" | "xpath" | undefined;
246
+ }>;
247
+ export declare function interact(options: {
248
+ action: string;
249
+ selector?: string;
250
+ strategy?: string;
251
+ x?: number;
252
+ y?: number;
253
+ duration?: number;
254
+ scrollX?: number;
255
+ scrollY?: number;
256
+ fromX?: number;
257
+ fromY?: number;
258
+ toX?: number;
259
+ toY?: number;
260
+ windowId?: string;
261
+ appIdentifier?: string | number;
262
+ }): Promise<string>;
263
+ export interface ScreenshotOptions {
264
+ quality?: number;
265
+ format?: 'png' | 'jpeg';
266
+ windowId?: string;
267
+ filePath?: string;
268
+ appIdentifier?: string | number;
269
+ maxWidth?: number;
270
+ }
271
+ export interface ScreenshotFileResult {
272
+ filePath: string;
273
+ format: 'png' | 'jpeg';
274
+ }
275
+ export declare function screenshot(options?: ScreenshotOptions): Promise<ScreenshotResult | ScreenshotFileResult>;
276
+ export interface KeyboardOptions {
277
+ action: string;
278
+ selectorOrKey?: string;
279
+ strategy?: string;
280
+ textOrModifiers?: string | string[];
281
+ modifiers?: string[];
282
+ windowId?: string;
283
+ appIdentifier?: string | number;
284
+ }
285
+ export declare function keyboard(options: KeyboardOptions): Promise<string>;
286
+ export interface WaitForOptions {
287
+ type: string;
288
+ value: string;
289
+ strategy?: string;
290
+ timeout?: number;
291
+ windowId?: string;
292
+ appIdentifier?: string | number;
293
+ }
294
+ export declare function waitFor(options: WaitForOptions): Promise<string>;
295
+ export interface GetStylesOptions {
296
+ selector: string;
297
+ strategy?: string;
298
+ properties?: string[];
299
+ multiple?: boolean;
300
+ windowId?: string;
301
+ appIdentifier?: string | number;
302
+ }
303
+ export declare function getStyles(options: GetStylesOptions): Promise<string>;
304
+ export interface ExecuteJavaScriptOptions {
305
+ script: string;
306
+ args?: unknown[];
307
+ windowId?: string;
308
+ appIdentifier?: string | number;
309
+ }
310
+ export declare function executeJavaScript(options: ExecuteJavaScriptOptions): Promise<string>;
311
+ export interface FocusElementOptions {
312
+ selector: string;
313
+ strategy?: string;
314
+ windowId?: string;
315
+ appIdentifier?: string | number;
316
+ }
317
+ export declare function focusElement(options: FocusElementOptions): Promise<string>;
318
+ export interface FindElementOptions {
319
+ selector: string;
320
+ strategy: string;
321
+ windowId?: string;
322
+ appIdentifier?: string | number;
323
+ }
324
+ /**
325
+ * Find an element using various selector strategies.
326
+ */
327
+ export declare function findElement(options: FindElementOptions): Promise<string>;
328
+ export interface GetConsoleLogsOptions {
329
+ filter?: string;
330
+ since?: string;
331
+ windowId?: string;
332
+ appIdentifier?: string | number;
333
+ }
334
+ /**
335
+ * Get console logs from the webview.
336
+ */
337
+ export declare function getConsoleLogs(options?: GetConsoleLogsOptions): Promise<string>;
338
+ export interface DomSnapshotOptions {
339
+ type: 'accessibility' | 'structure';
340
+ selector?: string;
341
+ strategy?: string;
342
+ windowId?: string;
343
+ appIdentifier?: string | number;
344
+ }
345
+ /**
346
+ * Generate a structured DOM snapshot for AI consumption.
347
+ * Uses aria-api for comprehensive, spec-compliant accessibility computation.
348
+ */
349
+ export declare function domSnapshot(options: DomSnapshotOptions): Promise<string>;
@@ -22,7 +22,8 @@ export const WindowTargetSchema = z.object({
22
22
  * Defaults to 'css' for backward compatibility.
23
23
  */
24
24
  const selectorStrategyField = z.enum(['css', 'xpath', 'text']).default('css').describe('Selector strategy: "css" (default) for CSS selectors, "xpath" for XPath expressions, ' +
25
- '"text" to find elements containing the given text. Ref IDs (e.g., "ref=e3") work with any strategy.');
25
+ '"text" to find elements by text content, with fallback to placeholder, aria-label, ' +
26
+ 'and title attributes. Ref IDs (e.g., "ref=e3") work with any strategy.');
26
27
  // ============================================================================
27
28
  // Schemas
28
29
  // ============================================================================
@@ -154,10 +155,8 @@ export async function screenshot(options = {}) {
154
155
  if (!imageContent || imageContent.type !== 'image') {
155
156
  throw new Error('Screenshot capture failed: no image data');
156
157
  }
157
- // Decode base64 and write to file
158
- const buffer = Buffer.from(imageContent.data, 'base64');
159
158
  const resolvedPath = resolve(filePath);
160
- await writeFile(resolvedPath, buffer);
159
+ await writeFile(resolvedPath, imageContent.data, 'base64');
161
160
  return { filePath: resolvedPath, format };
162
161
  }
163
162
  return result;
@@ -295,7 +294,7 @@ export async function domSnapshot(options) {
295
294
  const { type, selector, strategy, windowId, appIdentifier } = options;
296
295
  // Only load aria-api for accessibility snapshots
297
296
  if (type === 'accessibility') {
298
- await ensureAriaApiLoaded(windowId);
297
+ await ensureAriaApiLoaded(windowId, appIdentifier);
299
298
  }
300
299
  // Then execute the snapshot script
301
300
  const script = buildScript(SCRIPTS.domSnapshot, { type, selector: selector ?? null, strategy: strategy ?? 'css' });
@@ -311,11 +310,11 @@ export async function domSnapshot(options) {
311
310
  * Ensure aria-api library is loaded in the webview.
312
311
  * Uses the script manager to inject the library if not already present.
313
312
  */
314
- async function ensureAriaApiLoaded(windowId) {
313
+ async function ensureAriaApiLoaded(windowId, appIdentifier) {
315
314
  const { getAriaApiSource, ARIA_API_SCRIPT_ID: ariaApiScriptId } = await import('./scripts/aria-api-loader.js');
316
315
  const { registerScript, isScriptRegistered } = await import('./script-manager.js');
317
- if (await isScriptRegistered(ariaApiScriptId)) {
316
+ if (await isScriptRegistered(ariaApiScriptId, appIdentifier)) {
318
317
  return;
319
318
  }
320
- await registerScript(ariaApiScriptId, 'inline', getAriaApiSource(), windowId);
319
+ await registerScript(ariaApiScriptId, 'inline', getAriaApiSource(), windowId, appIdentifier);
321
320
  }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js CHANGED
@@ -1,132 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4
- import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
5
- import { zodToJsonSchema } from 'zod-to-json-schema';
6
2
  import { readFileSync } from 'fs';
7
3
  import { fileURLToPath } from 'url';
8
4
  import { dirname, join } from 'path';
9
- // Import the single source of truth for all tools and prompts
10
- import { TOOLS, TOOL_MAP } from './tools-registry.js';
11
- import { PROMPTS, PROMPT_MAP } from './prompts-registry.js';
12
- import { createMcpLogger } from './logger.js';
5
+ import { startStdioServer } from './server.js';
13
6
  /* eslint-disable no-process-exit */
14
7
  // Read version from package.json
15
8
  const currentDir = dirname(fileURLToPath(import.meta.url));
16
9
  const packageJson = JSON.parse(readFileSync(join(currentDir, '..', 'package.json'), 'utf-8'));
17
10
  const VERSION = packageJson.version;
18
- const serverLogger = createMcpLogger('SERVER');
19
- // Initialize server
20
- const server = new Server({
21
- name: 'mcp-server-tauri',
22
- version: VERSION,
23
- }, {
24
- capabilities: {
25
- tools: {},
26
- prompts: {},
27
- },
28
- });
29
- // Handle connection errors gracefully - don't crash on broken pipe
30
- server.onerror = (error) => {
31
- // Ignore broken pipe errors - they happen when the client disconnects
32
- const message = error instanceof Error ? error.message : String(error);
33
- if (message.includes('broken pipe') || message.includes('EPIPE')) {
34
- // Client disconnected, exit gracefully
35
- process.exit(0);
36
- }
37
- // For other errors, log to stderr (will be captured by MCP client)
38
- serverLogger.error(message);
39
- };
40
- // Handle connection close - exit gracefully
41
- server.onclose = () => {
42
- process.exit(0);
43
- };
44
- // Tool list handler - generated from registry
45
- server.setRequestHandler(ListToolsRequestSchema, async () => {
46
- return {
47
- tools: TOOLS.map((tool) => {
48
- return {
49
- name: tool.name,
50
- description: tool.description,
51
- inputSchema: zodToJsonSchema(tool.schema),
52
- annotations: tool.annotations,
53
- };
54
- }),
55
- };
56
- });
57
- /**
58
- * Convert a ToolResult to MCP content array.
59
- * Handles string (legacy), single content, and content arrays.
60
- */
61
- function toolResultToContent(result) {
62
- // Legacy string result - convert to text content
63
- if (typeof result === 'string') {
64
- return [{ type: 'text', text: result }];
65
- }
66
- // Array of content items
67
- if (Array.isArray(result)) {
68
- return result.map(contentToMcp);
69
- }
70
- // Single content item
71
- return [contentToMcp(result)];
72
- }
73
- /**
74
- * Convert a single ToolContent to MCP format.
75
- */
76
- function contentToMcp(content) {
77
- if (content.type === 'text') {
78
- return { type: 'text', text: content.text };
79
- }
80
- // Image content
81
- return { type: 'image', data: content.data, mimeType: content.mimeType };
82
- }
83
- // Tool call handler - generated from registry
84
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
85
- try {
86
- const tool = TOOL_MAP.get(request.params.name);
87
- if (!tool) {
88
- throw new Error(`Unknown tool: ${request.params.name}`);
89
- }
90
- const output = await tool.handler(request.params.arguments);
91
- return { content: toolResultToContent(output) };
92
- }
93
- catch (error) {
94
- const message = error instanceof Error ? error.message : String(error);
95
- return {
96
- content: [{ type: 'text', text: `Error: ${message}` }],
97
- isError: true,
98
- };
99
- }
100
- });
101
- // Prompt list handler - generated from registry
102
- server.setRequestHandler(ListPromptsRequestSchema, async () => {
103
- return {
104
- prompts: PROMPTS.map((prompt) => {
105
- return {
106
- name: prompt.name,
107
- description: prompt.description,
108
- arguments: prompt.arguments,
109
- };
110
- }),
111
- };
112
- });
113
- // Get prompt handler - returns prompt messages for a specific prompt
114
- server.setRequestHandler(GetPromptRequestSchema, async (request) => {
115
- const prompt = PROMPT_MAP.get(request.params.name);
116
- if (!prompt) {
117
- throw new Error(`Unknown prompt: ${request.params.name}`);
118
- }
119
- const args = (request.params.arguments || {});
120
- return {
121
- description: prompt.description,
122
- messages: prompt.handler(args),
123
- };
124
- });
125
- // Start server
126
11
  async function main() {
127
- const transport = new StdioServerTransport();
128
- await server.connect(transport);
129
- // Don't log to stderr - it interferes with MCP protocol
12
+ await startStdioServer({
13
+ name: 'mcp-server-tauri',
14
+ version: VERSION,
15
+ });
130
16
  }
131
17
  main().catch(() => {
132
18
  // Don't log errors to stderr - just exit silently
@@ -0,0 +1,16 @@
1
+ export interface McpLogger {
2
+ info: (...args: unknown[]) => void;
3
+ warn: (...args: unknown[]) => void;
4
+ error: (...args: unknown[]) => void;
5
+ }
6
+ /**
7
+ * Creates a logger that writes to stderr only.
8
+ *
9
+ * IMPORTANT: MCP uses stdio for JSON-RPC communication. The server sends
10
+ * JSON responses over stdout, and the client parses them. Any non-JSON
11
+ * output to stdout (like console.log) will corrupt the protocol and cause
12
+ * parsing errors like "invalid character 'M' looking for beginning of value".
13
+ *
14
+ * All logging MUST go to stderr to avoid interfering with MCP communication.
15
+ */
16
+ export declare function createMcpLogger(scope: string): McpLogger;
@@ -0,0 +1,6 @@
1
+ import { z } from 'zod';
2
+ export declare const ListDevicesSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
3
+ export declare function listDevices(): Promise<{
4
+ android: string[];
5
+ ios: string[];
6
+ }>;
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod';
2
+ export declare const ReadLogsSchema: z.ZodObject<{
3
+ source: z.ZodEnum<["console", "android", "ios", "system"]>;
4
+ lines: z.ZodDefault<z.ZodNumber>;
5
+ filter: z.ZodOptional<z.ZodString>;
6
+ since: z.ZodOptional<z.ZodString>;
7
+ windowId: z.ZodOptional<z.ZodString>;
8
+ appIdentifier: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodNumber]>>;
9
+ }, "strip", z.ZodTypeAny, {
10
+ lines: number;
11
+ source: "android" | "ios" | "console" | "system";
12
+ filter?: string | undefined;
13
+ windowId?: string | undefined;
14
+ appIdentifier?: string | number | undefined;
15
+ since?: string | undefined;
16
+ }, {
17
+ source: "android" | "ios" | "console" | "system";
18
+ filter?: string | undefined;
19
+ lines?: number | undefined;
20
+ windowId?: string | undefined;
21
+ appIdentifier?: string | number | undefined;
22
+ since?: string | undefined;
23
+ }>;
24
+ export interface ReadLogsOptions {
25
+ source: 'console' | 'android' | 'ios' | 'system';
26
+ lines?: number;
27
+ filter?: string;
28
+ since?: string;
29
+ windowId?: string;
30
+ appIdentifier?: string | number;
31
+ }
32
+ export declare function readLogs(options: ReadLogsOptions): Promise<string>;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Single source of truth for all MCP prompt definitions
3
+ * Prompts are user-controlled templates that appear as slash commands in MCP clients
4
+ */
5
+ export interface PromptArgument {
6
+ name: string;
7
+ description: string;
8
+ required?: boolean;
9
+ }
10
+ export interface PromptMessage {
11
+ role: 'user' | 'assistant';
12
+ content: {
13
+ type: 'text';
14
+ text: string;
15
+ };
16
+ }
17
+ export interface PromptDefinition {
18
+ name: string;
19
+ description: string;
20
+ arguments?: PromptArgument[];
21
+ handler: (args: Record<string, string>) => PromptMessage[];
22
+ }
23
+ /**
24
+ * Complete registry of all available prompts
25
+ */
26
+ export declare const PROMPTS: PromptDefinition[];
27
+ /**
28
+ * Create a Map for fast prompt lookup by name
29
+ */
30
+ export declare const PROMPT_MAP: Map<string, PromptDefinition>;
@@ -0,0 +1,13 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ export interface McpServerInfo {
3
+ name: string;
4
+ version: string;
5
+ }
6
+ export interface CliToolDefinition {
7
+ name: string;
8
+ description: string;
9
+ inputSchema: Record<string, unknown>;
10
+ }
11
+ export declare function getCliToolDefinitions(): CliToolDefinition[];
12
+ export declare function createMcpServer(info: McpServerInfo): Server;
13
+ export declare function startStdioServer(info: McpServerInfo): Promise<void>;