@hypothesi/tauri-mcp-server 0.11.0 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +67 -0
- package/dist/driver/element-picker.js +22 -41
- package/dist/driver/scripts/html2canvas-loader.d.ts +2 -0
- package/dist/driver/scripts/html2canvas-loader.js +20 -19
- package/dist/driver/scripts/index.js +11 -8
- package/dist/prompts-registry.js +1 -67
- package/dist/tools-registry.js +1 -71
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SETUP_INSTRUCTIONS: string;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { PLUGIN_VERSION_CARGO } from './version.js';
|
|
2
|
+
export const SETUP_INSTRUCTIONS = `Help me set up or update the MCP Bridge plugin in my Tauri project.
|
|
3
|
+
|
|
4
|
+
## IMPORTANT: Do Not Act Without Permission
|
|
5
|
+
|
|
6
|
+
**You must NOT make any changes to files without my explicit approval.**
|
|
7
|
+
|
|
8
|
+
1. First, examine my project to understand its current state
|
|
9
|
+
2. Then, present a clear summary of what changes are needed
|
|
10
|
+
3. Wait for my approval before making ANY modifications
|
|
11
|
+
4. Only proceed with changes after I confirm
|
|
12
|
+
|
|
13
|
+
## Prerequisites Check
|
|
14
|
+
|
|
15
|
+
First, verify this is a Tauri v2 project:
|
|
16
|
+
- Look for \`src-tauri/\` directory and \`tauri.conf.json\`
|
|
17
|
+
- If this is NOT a Tauri project, stop and let me know this setup only applies to Tauri apps
|
|
18
|
+
|
|
19
|
+
## What to Check
|
|
20
|
+
|
|
21
|
+
Examine these files and report what needs to be added or updated:
|
|
22
|
+
|
|
23
|
+
### 1. Rust Plugin Dependency
|
|
24
|
+
Check \`src-tauri/Cargo.toml\` for \`tauri-plugin-mcp-bridge\`. If missing or outdated, note that it needs:
|
|
25
|
+
\`\`\`toml
|
|
26
|
+
[dependencies]
|
|
27
|
+
tauri-plugin-mcp-bridge = "${PLUGIN_VERSION_CARGO}"
|
|
28
|
+
\`\`\`
|
|
29
|
+
|
|
30
|
+
### 2. Plugin Registration
|
|
31
|
+
Check \`src-tauri/src/lib.rs\` or \`src-tauri/src/main.rs\` for plugin registration. It should have:
|
|
32
|
+
\`\`\`rust
|
|
33
|
+
#[cfg(debug_assertions)]
|
|
34
|
+
{
|
|
35
|
+
builder = builder.plugin(tauri_plugin_mcp_bridge::init());
|
|
36
|
+
}
|
|
37
|
+
\`\`\`
|
|
38
|
+
|
|
39
|
+
### 3. Global Tauri Setting
|
|
40
|
+
Check \`src-tauri/tauri.conf.json\` for \`withGlobalTauri: true\` under the \`app\` section.
|
|
41
|
+
**This is required** - without it, the MCP bridge cannot communicate with the webview.
|
|
42
|
+
|
|
43
|
+
### 4. Plugin Permissions
|
|
44
|
+
Check \`src-tauri/capabilities/default.json\` (or similar) for \`"mcp-bridge:default"\` permission.
|
|
45
|
+
|
|
46
|
+
## Your Response Format
|
|
47
|
+
|
|
48
|
+
After examining the project, respond with:
|
|
49
|
+
|
|
50
|
+
1. **Current State**: What's already configured correctly
|
|
51
|
+
2. **Changes Needed**: A numbered list of specific changes required
|
|
52
|
+
3. **Ask for Permission**: "May I proceed with these changes?"
|
|
53
|
+
|
|
54
|
+
Only after I say yes should you make any modifications.
|
|
55
|
+
|
|
56
|
+
## After Setup
|
|
57
|
+
|
|
58
|
+
Once changes are approved and made:
|
|
59
|
+
1. Run the Tauri app in development mode (\`cargo tauri dev\`)
|
|
60
|
+
2. Use \`driver_session\` with action "start" to connect
|
|
61
|
+
3. Use \`driver_session\` with action "status" to verify
|
|
62
|
+
|
|
63
|
+
## Notes
|
|
64
|
+
|
|
65
|
+
- The plugin only runs in debug builds so it won't affect production
|
|
66
|
+
- The WebSocket server binds to \`0.0.0.0:9223\` by default
|
|
67
|
+
- For localhost-only access, use \`Builder::new().bind_address("127.0.0.1").build()\``;
|
|
@@ -10,7 +10,7 @@ import { executeInWebview, executeAsyncInWebview } from './webview-executor.js';
|
|
|
10
10
|
import { ensureSessionAndConnect } from './plugin-client.js';
|
|
11
11
|
import { SCRIPTS, buildScript } from './scripts/index.js';
|
|
12
12
|
import { WindowTargetSchema } from './webview-interactions.js';
|
|
13
|
-
import { getHtml2CanvasSource, HTML2CANVAS_SCRIPT_ID, } from './scripts/html2canvas-loader.js';
|
|
13
|
+
import { getHtml2CanvasSource, HTML2CANVAS_SCRIPT_ID, HTML2CANVAS_RESOLVER_SCRIPT, HTML2CANVAS_OPTIONS_SCRIPT, } from './scripts/html2canvas-loader.js';
|
|
14
14
|
import { registerScript, isScriptRegistered } from './script-manager.js';
|
|
15
15
|
// ============================================================================
|
|
16
16
|
// Schemas
|
|
@@ -114,28 +114,14 @@ async function captureElementScreenshot(cssSelector, windowId, appIdentifier) {
|
|
|
114
114
|
const escapedSelector = cssSelector.replace(/\\/g, '\\\\').replace(/'/g, '\\\'');
|
|
115
115
|
// Build a script that captures just the element with html2canvas
|
|
116
116
|
const captureScript = `
|
|
117
|
-
|
|
118
|
-
(typeof window !== 'undefined' && window.html2canvas) ? window.html2canvas :
|
|
119
|
-
(typeof self !== 'undefined' && self.html2canvas) ? self.html2canvas :
|
|
120
|
-
(typeof globalThis !== 'undefined' && globalThis.html2canvas) ? globalThis.html2canvas : null;
|
|
121
|
-
|
|
122
|
-
if (!html2canvasFn) {
|
|
123
|
-
throw new Error('html2canvas not loaded');
|
|
124
|
-
}
|
|
117
|
+
${HTML2CANVAS_RESOLVER_SCRIPT}
|
|
125
118
|
|
|
126
119
|
const el = document.querySelector('${escapedSelector}');
|
|
127
120
|
if (!el) {
|
|
128
121
|
throw new Error('Element not found for screenshot');
|
|
129
122
|
}
|
|
130
123
|
|
|
131
|
-
const canvas = await html2canvasFn(el, {
|
|
132
|
-
backgroundColor: null,
|
|
133
|
-
scale: window.devicePixelRatio || 1,
|
|
134
|
-
logging: false,
|
|
135
|
-
useCORS: true,
|
|
136
|
-
allowTaint: false,
|
|
137
|
-
imageTimeout: 5000,
|
|
138
|
-
});
|
|
124
|
+
const canvas = await html2canvasFn(el, ${HTML2CANVAS_OPTIONS_SCRIPT});
|
|
139
125
|
|
|
140
126
|
if (!canvas) {
|
|
141
127
|
throw new Error('html2canvas returned null canvas');
|
|
@@ -168,6 +154,23 @@ async function captureElementScreenshot(cssSelector, windowId, appIdentifier) {
|
|
|
168
154
|
return null;
|
|
169
155
|
}
|
|
170
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Common helper to format an element and capture its screenshot.
|
|
159
|
+
*/
|
|
160
|
+
async function buildElementContent(element, windowId, appIdentifier) {
|
|
161
|
+
const content = [];
|
|
162
|
+
// Add formatted metadata
|
|
163
|
+
content.push({ type: 'text', text: formatElementMetadata(element) });
|
|
164
|
+
// Capture element-only screenshot (no picker overlays visible)
|
|
165
|
+
const screenshot = await captureElementScreenshot(element.cssSelector, windowId, appIdentifier);
|
|
166
|
+
if (screenshot) {
|
|
167
|
+
content.push(screenshot);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
content.push({ type: 'text', text: '(Element screenshot capture failed)' });
|
|
171
|
+
}
|
|
172
|
+
return content;
|
|
173
|
+
}
|
|
171
174
|
// ============================================================================
|
|
172
175
|
// selectElement - Agent-initiated picker
|
|
173
176
|
// ============================================================================
|
|
@@ -217,18 +220,7 @@ export async function selectElement(options) {
|
|
|
217
220
|
}
|
|
218
221
|
// Clean up all picker UI BEFORE taking the screenshot
|
|
219
222
|
await cleanupPickerHighlights(windowId, appIdentifier);
|
|
220
|
-
|
|
221
|
-
// Add formatted metadata
|
|
222
|
-
content.push({ type: 'text', text: formatElementMetadata(element) });
|
|
223
|
-
// Capture element-only screenshot (no picker overlays visible)
|
|
224
|
-
const screenshot = await captureElementScreenshot(element.cssSelector, windowId, appIdentifier);
|
|
225
|
-
if (screenshot) {
|
|
226
|
-
content.push(screenshot);
|
|
227
|
-
}
|
|
228
|
-
else {
|
|
229
|
-
content.push({ type: 'text', text: '(Element screenshot capture failed)' });
|
|
230
|
-
}
|
|
231
|
-
return content;
|
|
223
|
+
return buildElementContent(element, windowId, appIdentifier);
|
|
232
224
|
}
|
|
233
225
|
// ============================================================================
|
|
234
226
|
// getPointedElement - Retrieve user-pointed element
|
|
@@ -257,16 +249,5 @@ export async function getPointedElement(options) {
|
|
|
257
249
|
catch {
|
|
258
250
|
return [{ type: 'text', text: `Failed to parse pointed element data: ${raw.substring(0, 200)}` }];
|
|
259
251
|
}
|
|
260
|
-
|
|
261
|
-
// Add formatted metadata
|
|
262
|
-
content.push({ type: 'text', text: formatElementMetadata(element) });
|
|
263
|
-
// Capture element-only screenshot (no overlays)
|
|
264
|
-
const screenshot = await captureElementScreenshot(element.cssSelector, windowId, appIdentifier);
|
|
265
|
-
if (screenshot) {
|
|
266
|
-
content.push(screenshot);
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
content.push({ type: 'text', text: '(Element screenshot capture failed)' });
|
|
270
|
-
}
|
|
271
|
-
return content;
|
|
252
|
+
return buildElementContent(element, windowId, appIdentifier);
|
|
272
253
|
}
|
|
@@ -13,6 +13,8 @@ export declare const HTML2CANVAS_SCRIPT_ID = "__mcp_html2canvas__";
|
|
|
13
13
|
* Loaded lazily and cached.
|
|
14
14
|
*/
|
|
15
15
|
export declare function getHtml2CanvasSource(): string;
|
|
16
|
+
export declare const HTML2CANVAS_RESOLVER_SCRIPT = "\n // Get the html2canvas function (may be on window, self, or globalThis)\n const html2canvasFn = typeof html2canvas !== 'undefined' ? html2canvas :\n (typeof window !== 'undefined' && window.html2canvas) ? window.html2canvas :\n (typeof self !== 'undefined' && self.html2canvas) ? self.html2canvas :\n (typeof globalThis !== 'undefined' && globalThis.html2canvas) ? globalThis.html2canvas : null;\n\n if (!html2canvasFn) {\n throw new Error('html2canvas not loaded');\n }\n";
|
|
17
|
+
export declare const HTML2CANVAS_OPTIONS_SCRIPT = "{\n backgroundColor: null,\n scale: window.devicePixelRatio || 1,\n logging: false,\n useCORS: true,\n allowTaint: false,\n imageTimeout: 5000,\n }";
|
|
16
18
|
/**
|
|
17
19
|
* Build a script that captures a screenshot using html2canvas.
|
|
18
20
|
* Assumes html2canvas is already loaded (either via script manager or inline).
|
|
@@ -30,13 +30,7 @@ export function getHtml2CanvasSource() {
|
|
|
30
30
|
}
|
|
31
31
|
return html2canvasProSource;
|
|
32
32
|
}
|
|
33
|
-
|
|
34
|
-
* Build a script that captures a screenshot using html2canvas.
|
|
35
|
-
* Assumes html2canvas is already loaded (either via script manager or inline).
|
|
36
|
-
*/
|
|
37
|
-
export function buildScreenshotCaptureScript(format, quality) {
|
|
38
|
-
// Note: This script is wrapped by executeAsyncInWebview, so we don't need an IIFE
|
|
39
|
-
return `
|
|
33
|
+
export const HTML2CANVAS_RESOLVER_SCRIPT = `
|
|
40
34
|
// Get the html2canvas function (may be on window, self, or globalThis)
|
|
41
35
|
const html2canvasFn = typeof html2canvas !== 'undefined' ? html2canvas :
|
|
42
36
|
(typeof window !== 'undefined' && window.html2canvas) ? window.html2canvas :
|
|
@@ -44,27 +38,34 @@ export function buildScreenshotCaptureScript(format, quality) {
|
|
|
44
38
|
(typeof globalThis !== 'undefined' && globalThis.html2canvas) ? globalThis.html2canvas : null;
|
|
45
39
|
|
|
46
40
|
if (!html2canvasFn) {
|
|
47
|
-
throw new Error('html2canvas not loaded
|
|
41
|
+
throw new Error('html2canvas not loaded');
|
|
48
42
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const element = document.documentElement;
|
|
52
|
-
if (!element) {
|
|
53
|
-
throw new Error('document.documentElement is null');
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Configure html2canvas options
|
|
57
|
-
const options = {
|
|
43
|
+
`;
|
|
44
|
+
export const HTML2CANVAS_OPTIONS_SCRIPT = `{
|
|
58
45
|
backgroundColor: null,
|
|
59
46
|
scale: window.devicePixelRatio || 1,
|
|
60
47
|
logging: false,
|
|
61
48
|
useCORS: true,
|
|
62
49
|
allowTaint: false,
|
|
63
50
|
imageTimeout: 5000,
|
|
64
|
-
}
|
|
51
|
+
}`;
|
|
52
|
+
/**
|
|
53
|
+
* Build a script that captures a screenshot using html2canvas.
|
|
54
|
+
* Assumes html2canvas is already loaded (either via script manager or inline).
|
|
55
|
+
*/
|
|
56
|
+
export function buildScreenshotCaptureScript(format, quality) {
|
|
57
|
+
// Note: This script is wrapped by executeAsyncInWebview, so we don't need an IIFE
|
|
58
|
+
return `
|
|
59
|
+
${HTML2CANVAS_RESOLVER_SCRIPT}
|
|
60
|
+
|
|
61
|
+
// Capture the entire document
|
|
62
|
+
const element = document.documentElement;
|
|
63
|
+
if (!element) {
|
|
64
|
+
throw new Error('document.documentElement is null');
|
|
65
|
+
}
|
|
65
66
|
|
|
66
67
|
// Capture the webview
|
|
67
|
-
const canvas = await html2canvasFn(element,
|
|
68
|
+
const canvas = await html2canvasFn(element, ${HTML2CANVAS_OPTIONS_SCRIPT});
|
|
68
69
|
if (!canvas) {
|
|
69
70
|
throw new Error('html2canvas returned null canvas');
|
|
70
71
|
}
|
|
@@ -106,17 +106,20 @@ export function buildKeyEventScript(action, key, modifiers = []) {
|
|
|
106
106
|
|
|
107
107
|
const activeElement = document.activeElement || document.body;
|
|
108
108
|
|
|
109
|
+
const modStr = modifiers.length ? ' with ' + modifiers.join('+') : '';
|
|
110
|
+
const dispatch = (type) => activeElement.dispatchEvent(new KeyboardEvent(type, eventOptions));
|
|
111
|
+
|
|
109
112
|
if (action === 'press') {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return 'Pressed key: ' + key +
|
|
113
|
+
dispatch('keydown');
|
|
114
|
+
dispatch('keypress');
|
|
115
|
+
dispatch('keyup');
|
|
116
|
+
return 'Pressed key: ' + key + modStr;
|
|
114
117
|
} else if (action === 'down') {
|
|
115
|
-
|
|
116
|
-
return 'Key down: ' + key +
|
|
118
|
+
dispatch('keydown');
|
|
119
|
+
return 'Key down: ' + key + modStr;
|
|
117
120
|
} else if (action === 'up') {
|
|
118
|
-
|
|
119
|
-
return 'Key up: ' + key +
|
|
121
|
+
dispatch('keyup');
|
|
122
|
+
return 'Key up: ' + key + modStr;
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
throw new Error('Unknown action: ' + action);
|
package/dist/prompts-registry.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Single source of truth for all MCP prompt definitions
|
|
3
3
|
* Prompts are user-controlled templates that appear as slash commands in MCP clients
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { SETUP_INSTRUCTIONS as SETUP_PROMPT } from './constants.js';
|
|
6
6
|
const FIX_WEBVIEW_ERRORS_PROMPT = `I need help finding and fixing JavaScript errors in my Tauri app's webview.
|
|
7
7
|
|
|
8
8
|
Please follow these steps:
|
|
@@ -25,72 +25,6 @@ Please follow these steps:
|
|
|
25
25
|
If no errors are found, let me know the app is running cleanly.
|
|
26
26
|
|
|
27
27
|
If the session fails to start, help me troubleshoot the connection (is the app running? is the MCP bridge plugin installed?).`;
|
|
28
|
-
const SETUP_PROMPT = `Help me set up or update the MCP Bridge plugin in my Tauri project.
|
|
29
|
-
|
|
30
|
-
## IMPORTANT: Do Not Act Without Permission
|
|
31
|
-
|
|
32
|
-
**You must NOT make any changes to files without my explicit approval.**
|
|
33
|
-
|
|
34
|
-
1. First, examine my project to understand its current state
|
|
35
|
-
2. Then, present a clear summary of what changes are needed
|
|
36
|
-
3. Wait for my approval before making ANY modifications
|
|
37
|
-
4. Only proceed with changes after I confirm
|
|
38
|
-
|
|
39
|
-
## Prerequisites Check
|
|
40
|
-
|
|
41
|
-
First, verify this is a Tauri v2 project:
|
|
42
|
-
- Look for \`src-tauri/\` directory and \`tauri.conf.json\`
|
|
43
|
-
- If this is NOT a Tauri project, stop and let me know this setup only applies to Tauri apps
|
|
44
|
-
|
|
45
|
-
## What to Check
|
|
46
|
-
|
|
47
|
-
Examine these files and report what needs to be added or updated:
|
|
48
|
-
|
|
49
|
-
### 1. Rust Plugin Dependency
|
|
50
|
-
Check \`src-tauri/Cargo.toml\` for \`tauri-plugin-mcp-bridge\`. If missing or outdated, note that it needs:
|
|
51
|
-
\`\`\`toml
|
|
52
|
-
[dependencies]
|
|
53
|
-
tauri-plugin-mcp-bridge = "${PLUGIN_VERSION_CARGO}"
|
|
54
|
-
\`\`\`
|
|
55
|
-
|
|
56
|
-
### 2. Plugin Registration
|
|
57
|
-
Check \`src-tauri/src/lib.rs\` or \`src-tauri/src/main.rs\` for plugin registration. It should have:
|
|
58
|
-
\`\`\`rust
|
|
59
|
-
#[cfg(debug_assertions)]
|
|
60
|
-
{
|
|
61
|
-
builder = builder.plugin(tauri_plugin_mcp_bridge::init());
|
|
62
|
-
}
|
|
63
|
-
\`\`\`
|
|
64
|
-
|
|
65
|
-
### 3. Global Tauri Setting
|
|
66
|
-
Check \`src-tauri/tauri.conf.json\` for \`withGlobalTauri: true\` under the \`app\` section.
|
|
67
|
-
**This is required** - without it, the MCP bridge cannot communicate with the webview.
|
|
68
|
-
|
|
69
|
-
### 4. Plugin Permissions
|
|
70
|
-
Check \`src-tauri/capabilities/default.json\` (or similar) for \`"mcp-bridge:default"\` permission.
|
|
71
|
-
|
|
72
|
-
## Your Response Format
|
|
73
|
-
|
|
74
|
-
After examining the project, respond with:
|
|
75
|
-
|
|
76
|
-
1. **Current State**: What's already configured correctly
|
|
77
|
-
2. **Changes Needed**: A numbered list of specific changes required
|
|
78
|
-
3. **Ask for Permission**: "May I proceed with these changes?"
|
|
79
|
-
|
|
80
|
-
Only after I say yes should you make any modifications.
|
|
81
|
-
|
|
82
|
-
## After Setup
|
|
83
|
-
|
|
84
|
-
Once changes are approved and made:
|
|
85
|
-
1. Run the Tauri app in development mode (\`cargo tauri dev\`)
|
|
86
|
-
2. Use \`driver_session\` with action "start" to connect
|
|
87
|
-
3. Use \`driver_session\` with action "status" to verify
|
|
88
|
-
|
|
89
|
-
## Notes
|
|
90
|
-
|
|
91
|
-
- The plugin only runs in debug builds so it won't affect production
|
|
92
|
-
- The WebSocket server binds to \`0.0.0.0:9223\` by default
|
|
93
|
-
- For localhost-only access, use \`Builder::new().bind_address("127.0.0.1").build()\``;
|
|
94
28
|
const SELECT_ELEMENT_PROMPT = (message) => {
|
|
95
29
|
const lines = [
|
|
96
30
|
'The user wants to visually select an element in their running Tauri app so they can discuss it with you.',
|
package/dist/tools-registry.js
CHANGED
|
@@ -9,7 +9,7 @@ import { readLogs, ReadLogsSchema } from './monitor/logs.js';
|
|
|
9
9
|
import { executeIPCCommand, manageIPCMonitoring, getIPCEvents, emitTestEvent, getBackendState, manageWindow, ExecuteIPCCommandSchema, ManageIPCMonitoringSchema, GetIPCEventsSchema, EmitTestEventSchema, GetBackendStateSchema, ManageWindowSchema, } from './driver/plugin-commands.js';
|
|
10
10
|
import { interact, screenshot, keyboard, waitFor, getStyles, executeJavaScript, findElement, domSnapshot, InteractSchema, ScreenshotSchema, KeyboardSchema, WaitForSchema, GetStylesSchema, ExecuteJavaScriptSchema, FindElementSchema, DomSnapshotSchema, } from './driver/webview-interactions.js';
|
|
11
11
|
import { selectElement, getPointedElement, SelectElementSchema, GetPointedElementSchema, } from './driver/element-picker.js';
|
|
12
|
-
import {
|
|
12
|
+
import { SETUP_INSTRUCTIONS } from './constants.js';
|
|
13
13
|
/**
|
|
14
14
|
* Standard multi-app description for webview tools.
|
|
15
15
|
*/
|
|
@@ -24,76 +24,6 @@ export const TOOL_CATEGORIES = {
|
|
|
24
24
|
UI_AUTOMATION: 'UI Automation & WebView Interaction',
|
|
25
25
|
IPC_PLUGIN: 'IPC & Plugin Tools (via MCP Bridge)',
|
|
26
26
|
};
|
|
27
|
-
// Setup instructions for the MCP Bridge plugin
|
|
28
|
-
const SETUP_INSTRUCTIONS = `# MCP Bridge Plugin Setup Instructions
|
|
29
|
-
|
|
30
|
-
Use these instructions to set up or update the MCP Bridge plugin in a Tauri v2 project.
|
|
31
|
-
|
|
32
|
-
## IMPORTANT: Do Not Act Without Permission
|
|
33
|
-
|
|
34
|
-
**You must NOT make any changes to files without the user's explicit approval.**
|
|
35
|
-
|
|
36
|
-
1. First, examine the project to understand its current state
|
|
37
|
-
2. Then, present a clear summary of what changes are needed
|
|
38
|
-
3. Wait for user approval before making ANY modifications
|
|
39
|
-
4. Only proceed with changes after they confirm
|
|
40
|
-
|
|
41
|
-
## Prerequisites Check
|
|
42
|
-
|
|
43
|
-
First, verify this is a Tauri v2 project:
|
|
44
|
-
- Look for \`src-tauri/\` directory and \`tauri.conf.json\`
|
|
45
|
-
- If this is NOT a Tauri project, stop and let the user know this setup only applies to Tauri apps
|
|
46
|
-
|
|
47
|
-
## What to Check
|
|
48
|
-
|
|
49
|
-
Examine these files and report what needs to be added or updated:
|
|
50
|
-
|
|
51
|
-
### 1. Rust Plugin Dependency
|
|
52
|
-
Check \`src-tauri/Cargo.toml\` for \`tauri-plugin-mcp-bridge\`. If missing or outdated, note that it needs:
|
|
53
|
-
\`\`\`toml
|
|
54
|
-
[dependencies]
|
|
55
|
-
tauri-plugin-mcp-bridge = "${PLUGIN_VERSION_CARGO}"
|
|
56
|
-
\`\`\`
|
|
57
|
-
|
|
58
|
-
### 2. Plugin Registration
|
|
59
|
-
Check \`src-tauri/src/lib.rs\` or \`src-tauri/src/main.rs\` for plugin registration. It should have:
|
|
60
|
-
\`\`\`rust
|
|
61
|
-
#[cfg(debug_assertions)]
|
|
62
|
-
{
|
|
63
|
-
builder = builder.plugin(tauri_plugin_mcp_bridge::init());
|
|
64
|
-
}
|
|
65
|
-
\`\`\`
|
|
66
|
-
|
|
67
|
-
### 3. Global Tauri Setting
|
|
68
|
-
Check \`src-tauri/tauri.conf.json\` for \`withGlobalTauri: true\` under the \`app\` section.
|
|
69
|
-
**This is required** - without it, the MCP bridge cannot communicate with the webview.
|
|
70
|
-
|
|
71
|
-
### 4. Plugin Permissions
|
|
72
|
-
Check \`src-tauri/capabilities/default.json\` (or similar) for \`"mcp-bridge:default"\` permission.
|
|
73
|
-
|
|
74
|
-
## Response Format
|
|
75
|
-
|
|
76
|
-
After examining the project, respond with:
|
|
77
|
-
|
|
78
|
-
1. **Current State**: What's already configured correctly
|
|
79
|
-
2. **Changes Needed**: A numbered list of specific changes required
|
|
80
|
-
3. **Ask for Permission**: "May I proceed with these changes?"
|
|
81
|
-
|
|
82
|
-
Only after the user says yes should you make any modifications.
|
|
83
|
-
|
|
84
|
-
## After Setup
|
|
85
|
-
|
|
86
|
-
Once changes are approved and made:
|
|
87
|
-
1. Run the Tauri app in development mode (\`cargo tauri dev\`)
|
|
88
|
-
2. Use \`driver_session\` with action "start" to connect
|
|
89
|
-
3. Use \`driver_session\` with action "status" to verify
|
|
90
|
-
|
|
91
|
-
## Notes
|
|
92
|
-
|
|
93
|
-
- The plugin only runs in debug builds so it won't affect production
|
|
94
|
-
- The WebSocket server binds to \`0.0.0.0:9223\` by default
|
|
95
|
-
- For localhost-only access, use \`Builder::new().bind_address("127.0.0.1").build()\`
|
|
96
|
-
`;
|
|
97
27
|
/**
|
|
98
28
|
* Complete registry of all available tools
|
|
99
29
|
* This is the single source of truth for tool definitions
|
package/package.json
CHANGED