@hypothesi/tauri-mcp-server 0.8.3 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -2
- package/dist/api.d.ts +2 -0
- package/dist/api.js +2 -0
- package/dist/config.d.ts +35 -0
- package/dist/driver/app-discovery.d.ts +75 -0
- package/dist/driver/element-picker.d.ts +42 -0
- package/dist/driver/element-picker.js +272 -0
- package/dist/driver/plugin-client.d.ts +100 -0
- package/dist/driver/plugin-commands.d.ts +163 -0
- package/dist/driver/protocol.d.ts +128 -0
- package/dist/driver/script-manager.d.ts +91 -0
- package/dist/driver/scripts/aria-api-loader.d.ts +17 -0
- package/dist/driver/scripts/element-picker.js +395 -0
- package/dist/driver/scripts/html2canvas-loader.d.ts +25 -0
- package/dist/driver/scripts/index.d.ts +37 -0
- package/dist/driver/scripts/index.js +1 -0
- package/dist/driver/session-manager.d.ts +76 -0
- package/dist/driver/webview-executor.d.ts +122 -0
- package/dist/driver/webview-interactions.d.ts +349 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -119
- package/dist/logger.d.ts +16 -0
- package/dist/manager/mobile.d.ts +6 -0
- package/dist/monitor/logs.d.ts +32 -0
- package/dist/prompts-registry.d.ts +30 -0
- package/dist/prompts-registry.js +46 -0
- package/dist/server.d.ts +13 -0
- package/dist/server.js +110 -0
- package/dist/tools-registry.d.ts +73 -0
- package/dist/tools-registry.js +51 -0
- package/dist/types/window.d.ts +30 -0
- package/dist/version.d.ts +15 -0
- package/package.json +9 -1
|
@@ -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>;
|
package/dist/index.d.ts
ADDED
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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
package/dist/logger.d.ts
ADDED
|
@@ -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,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>;
|
package/dist/prompts-registry.js
CHANGED
|
@@ -91,6 +91,28 @@ Once changes are approved and made:
|
|
|
91
91
|
- The plugin only runs in debug builds so it won't affect production
|
|
92
92
|
- The WebSocket server binds to \`0.0.0.0:9223\` by default
|
|
93
93
|
- For localhost-only access, use \`Builder::new().bind_address("127.0.0.1").build()\``;
|
|
94
|
+
const SELECT_ELEMENT_PROMPT = (message) => {
|
|
95
|
+
const lines = [
|
|
96
|
+
'The user wants to visually select an element in their running Tauri app so they can discuss it with you.',
|
|
97
|
+
'',
|
|
98
|
+
'Follow these steps:',
|
|
99
|
+
'',
|
|
100
|
+
'1. **Ensure a session is active** - Use `driver_session` with action "start" if not already connected',
|
|
101
|
+
'',
|
|
102
|
+
'2. **Activate the element picker** - Call `webview_select_element` to show the picker overlay in the app.',
|
|
103
|
+
'The user will see a blue highlight following their cursor and can click to select an element.',
|
|
104
|
+
'They can press Escape or click X to cancel.',
|
|
105
|
+
'',
|
|
106
|
+
'3. **Review the result** - You will receive the element\'s metadata (tag, id, classes, CSS selector, XPath,',
|
|
107
|
+
'bounding rect, attributes, computed styles, parent chain) and an annotated screenshot with the element highlighted.',
|
|
108
|
+
'',
|
|
109
|
+
'4. **Respond to the user** - Use the element context and screenshot to address their request.',
|
|
110
|
+
];
|
|
111
|
+
if (message) {
|
|
112
|
+
lines.push('', '## User\'s Message About the Element', '', message);
|
|
113
|
+
}
|
|
114
|
+
return lines.join('\n');
|
|
115
|
+
};
|
|
94
116
|
/**
|
|
95
117
|
* Complete registry of all available prompts
|
|
96
118
|
*/
|
|
@@ -114,6 +136,30 @@ export const PROMPTS = [
|
|
|
114
136
|
];
|
|
115
137
|
},
|
|
116
138
|
},
|
|
139
|
+
{
|
|
140
|
+
name: 'select',
|
|
141
|
+
description: 'Visually select an element in the running Tauri app. ' +
|
|
142
|
+
'Activates a picker overlay — click an element to send its metadata and an annotated screenshot to the agent. ' +
|
|
143
|
+
'Optionally include a message describing what you want to do with the element.',
|
|
144
|
+
arguments: [
|
|
145
|
+
{
|
|
146
|
+
name: 'message',
|
|
147
|
+
description: 'What you want to discuss or do with the selected element (e.g. "this button should be green instead of blue")',
|
|
148
|
+
required: false,
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
handler: (args) => {
|
|
152
|
+
return [
|
|
153
|
+
{
|
|
154
|
+
role: 'user',
|
|
155
|
+
content: {
|
|
156
|
+
type: 'text',
|
|
157
|
+
text: SELECT_ELEMENT_PROMPT(args.message),
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
];
|
|
161
|
+
},
|
|
162
|
+
},
|
|
117
163
|
{
|
|
118
164
|
name: 'setup',
|
|
119
165
|
description: 'Set up or update the MCP Bridge plugin in a Tauri project. ' +
|
package/dist/server.d.ts
ADDED
|
@@ -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>;
|