|
5 | 5 |
|
6 | 6 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; |
7 | 7 | import { Application } from '../../../automation'; |
8 | | -import { z } from 'zod'; |
9 | 8 |
|
10 | 9 | /** |
11 | 10 | * Core Application Management Tools |
12 | 11 | */ |
13 | 12 | export function applyCoreTools(server: McpServer, app: Application) { |
| 13 | + // A dummy start tool just so that the model has something to hold on to. |
14 | 14 | server.tool( |
15 | | - 'vscode_automation_restart', |
16 | | - 'Restart VS Code with optional workspace or folder and extra arguments', |
17 | | - { |
18 | | - workspaceOrFolder: z.string().optional().describe('Optional path to workspace or folder to open'), |
19 | | - extraArgs: z.array(z.string()).optional().describe('Optional extra command line arguments') |
20 | | - }, |
21 | | - async (args) => { |
22 | | - const { workspaceOrFolder, extraArgs } = args; |
23 | | - await app.restart({ workspaceOrFolder, extraArgs }); |
24 | | - return { |
25 | | - content: [{ |
26 | | - type: 'text' as const, |
27 | | - text: `VS Code restarted successfully${workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''}` |
28 | | - }] |
29 | | - }; |
30 | | - } |
31 | | - ); |
32 | | - |
33 | | - server.tool( |
34 | | - 'vscode_automation_stop', |
35 | | - 'Stop the VS Code application', |
| 15 | + 'vscode_automation_start', |
| 16 | + 'Start VS Code Build', |
| 17 | + {}, |
36 | 18 | async () => { |
37 | | - await app.stop(); |
38 | 19 | return { |
39 | 20 | content: [{ |
40 | 21 | type: 'text' as const, |
41 | | - text: 'VS Code stopped successfully' |
| 22 | + text: `VS Code started successfully` |
42 | 23 | }] |
43 | 24 | }; |
44 | 25 | } |
45 | 26 | ); |
| 27 | + // Playwright keeps using this as a start... maybe it needs some massaging |
| 28 | + // server.tool( |
| 29 | + // 'vscode_automation_restart', |
| 30 | + // 'Restart VS Code with optional workspace or folder and extra arguments', |
| 31 | + // { |
| 32 | + // workspaceOrFolder: z.string().optional().describe('Optional path to workspace or folder to open'), |
| 33 | + // extraArgs: z.array(z.string()).optional().describe('Optional extra command line arguments') |
| 34 | + // }, |
| 35 | + // async (args) => { |
| 36 | + // const { workspaceOrFolder, extraArgs } = args; |
| 37 | + // await app.restart({ workspaceOrFolder, extraArgs }); |
| 38 | + // return { |
| 39 | + // content: [{ |
| 40 | + // type: 'text' as const, |
| 41 | + // text: `VS Code restarted successfully${workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''}` |
| 42 | + // }] |
| 43 | + // }; |
| 44 | + // } |
| 45 | + // ); |
46 | 46 |
|
47 | | - server.tool( |
48 | | - 'vscode_automation_get_quality', |
49 | | - 'Get the quality/build type of VS Code (Dev, Insiders, Stable, etc.)', |
50 | | - async () => { |
51 | | - const info = { |
52 | | - quality: app.quality, |
53 | | - remote: app.remote, |
54 | | - web: app.web, |
55 | | - workspacePathOrFolder: app.workspacePathOrFolder, |
56 | | - extensionsPath: app.extensionsPath, |
57 | | - userDataPath: app.userDataPath |
58 | | - }; |
59 | | - return { |
60 | | - content: [{ |
61 | | - type: 'text' as const, |
62 | | - text: `VS Code Info:\n${JSON.stringify(info, null, 2)}` |
63 | | - }] |
64 | | - }; |
65 | | - } |
66 | | - ); |
| 47 | + // I don't think Playwright needs this |
| 48 | + // server.tool( |
| 49 | + // 'vscode_automation_stop', |
| 50 | + // 'Stop the VS Code application', |
| 51 | + // async () => { |
| 52 | + // await app.stop(); |
| 53 | + // return { |
| 54 | + // content: [{ |
| 55 | + // type: 'text' as const, |
| 56 | + // text: 'VS Code stopped successfully' |
| 57 | + // }] |
| 58 | + // }; |
| 59 | + // } |
| 60 | + // ); |
67 | 61 |
|
68 | | - server.tool( |
69 | | - 'vscode_automation_wait_for_element', |
70 | | - 'Wait for a UI element to appear using CSS selector - prefer using specific workbench methods when available', |
71 | | - { |
72 | | - selector: z.string().describe('CSS selector for the element to wait for'), |
73 | | - timeout: z.number().optional().default(20).describe('Timeout in seconds (default: 20)') |
74 | | - }, |
75 | | - async (args) => { |
76 | | - const { selector, timeout = 20 } = args; |
77 | | - const retryCount = Math.floor((timeout * 1000) / 100); // 100ms intervals |
78 | | - const element = await app.code.waitForElement(selector, undefined, retryCount); |
79 | | - return { |
80 | | - content: [{ |
81 | | - type: 'text' as const, |
82 | | - text: `Element found: ${selector} (${!!element ? 'success' : 'not found'})` |
83 | | - }] |
84 | | - }; |
85 | | - } |
86 | | - ); |
| 62 | + // This doesn't seem particularly useful |
| 63 | + // server.tool( |
| 64 | + // 'vscode_automation_get_quality', |
| 65 | + // 'Get the quality/build type of VS Code (Dev, Insiders, Stable, etc.)', |
| 66 | + // async () => { |
| 67 | + // const info = { |
| 68 | + // quality: app.quality, |
| 69 | + // remote: app.remote, |
| 70 | + // web: app.web, |
| 71 | + // workspacePathOrFolder: app.workspacePathOrFolder, |
| 72 | + // extensionsPath: app.extensionsPath, |
| 73 | + // userDataPath: app.userDataPath |
| 74 | + // }; |
| 75 | + // return { |
| 76 | + // content: [{ |
| 77 | + // type: 'text' as const, |
| 78 | + // text: `VS Code Info:\n${JSON.stringify(info, null, 2)}` |
| 79 | + // }] |
| 80 | + // }; |
| 81 | + // } |
| 82 | + // ); |
87 | 83 |
|
88 | | - server.tool( |
89 | | - 'vscode_automation_click_element', |
90 | | - 'Click on a UI element - prefer using specific workbench methods when available', |
91 | | - { |
92 | | - selector: z.string().describe('CSS selector for the element to click'), |
93 | | - xOffset: z.number().optional().describe('Optional X offset from element center'), |
94 | | - yOffset: z.number().optional().describe('Optional Y offset from element center') |
95 | | - }, |
96 | | - async (args) => { |
97 | | - const { selector, xOffset, yOffset } = args; |
98 | | - await app.code.waitAndClick(selector, xOffset, yOffset); |
99 | | - return { |
100 | | - content: [{ |
101 | | - type: 'text' as const, |
102 | | - text: `Clicked element: ${selector}${xOffset !== undefined ? ` (offset: ${xOffset}, ${yOffset})` : ''}` |
103 | | - }] |
104 | | - }; |
105 | | - } |
106 | | - ); |
| 84 | + // This doesn't seem particularly useful |
| 85 | + // server.tool( |
| 86 | + // 'vscode_automation_wait_for_element', |
| 87 | + // 'Wait for a UI element to appear using CSS selector - prefer using specific workbench methods when available', |
| 88 | + // { |
| 89 | + // selector: z.string().describe('CSS selector for the element to wait for'), |
| 90 | + // timeout: z.number().optional().default(20).describe('Timeout in seconds (default: 20)') |
| 91 | + // }, |
| 92 | + // async (args) => { |
| 93 | + // const { selector, timeout = 20 } = args; |
| 94 | + // const retryCount = Math.floor((timeout * 1000) / 100); // 100ms intervals |
| 95 | + // const element = await app.code.waitForElement(selector, undefined, retryCount); |
| 96 | + // return { |
| 97 | + // content: [{ |
| 98 | + // type: 'text' as const, |
| 99 | + // text: `Element found: ${selector} (${!!element ? 'success' : 'not found'})` |
| 100 | + // }] |
| 101 | + // }; |
| 102 | + // } |
| 103 | + // ); |
107 | 104 |
|
108 | | - server.tool( |
109 | | - 'vscode_automation_send_keybinding', |
110 | | - 'Send a keybinding to VS Code (e.g., ctrl+shift+p, cmd+s)', |
111 | | - { |
112 | | - keybinding: z.string().describe('The keybinding to send (e.g., ctrl+shift+p, cmd+s, escape)'), |
113 | | - waitSelector: z.string().optional().describe('Optional CSS selector to wait for after sending the keybinding') |
114 | | - }, |
115 | | - async (args) => { |
116 | | - const { keybinding, waitSelector } = args; |
117 | | - await app.code.dispatchKeybinding(keybinding, async () => { |
118 | | - if (waitSelector) { |
119 | | - await app.code.waitForElement(waitSelector); |
120 | | - } |
121 | | - }); |
122 | | - return { |
123 | | - content: [{ |
124 | | - type: 'text' as const, |
125 | | - text: `Sent keybinding: ${keybinding}${waitSelector ? ` (waited for: ${waitSelector})` : ''}` |
126 | | - }] |
127 | | - }; |
128 | | - } |
129 | | - ); |
| 105 | + // Defer to Playwright's tool |
| 106 | + // server.tool( |
| 107 | + // 'vscode_automation_click_element', |
| 108 | + // 'Click on a UI element - prefer using specific workbench methods when available', |
| 109 | + // { |
| 110 | + // selector: z.string().describe('CSS selector for the element to click'), |
| 111 | + // xOffset: z.number().optional().describe('Optional X offset from element center'), |
| 112 | + // yOffset: z.number().optional().describe('Optional Y offset from element center') |
| 113 | + // }, |
| 114 | + // async (args) => { |
| 115 | + // const { selector, xOffset, yOffset } = args; |
| 116 | + // await app.code.waitAndClick(selector, xOffset, yOffset); |
| 117 | + // return { |
| 118 | + // content: [{ |
| 119 | + // type: 'text' as const, |
| 120 | + // text: `Clicked element: ${selector}${xOffset !== undefined ? ` (offset: ${xOffset}, ${yOffset})` : ''}` |
| 121 | + // }] |
| 122 | + // }; |
| 123 | + // } |
| 124 | + // ); |
130 | 125 |
|
131 | | - server.tool( |
132 | | - 'vscode_automation_get_text_content', |
133 | | - 'Get text content from a UI element using CSS selector', |
134 | | - { |
135 | | - selector: z.string().describe('CSS selector for the element'), |
136 | | - expectedText: z.string().optional().describe('Optional expected text to wait for') |
137 | | - }, |
138 | | - async (args) => { |
139 | | - const { selector, expectedText } = args; |
140 | | - const text = await app.code.waitForTextContent(selector, expectedText); |
141 | | - return { |
142 | | - content: [{ |
143 | | - type: 'text' as const, |
144 | | - text: `Text content from ${selector}: "${text}"` |
145 | | - }] |
146 | | - }; |
147 | | - } |
148 | | - ); |
| 126 | + // Defer to Playwright's tool |
| 127 | + // server.tool( |
| 128 | + // 'vscode_automation_send_keybinding', |
| 129 | + // 'Send a keybinding to VS Code (e.g., ctrl+shift+p, cmd+s)', |
| 130 | + // { |
| 131 | + // keybinding: z.string().describe('The keybinding to send (e.g., ctrl+shift+p, cmd+s, escape)'), |
| 132 | + // waitSelector: z.string().optional().describe('Optional CSS selector to wait for after sending the keybinding') |
| 133 | + // }, |
| 134 | + // async (args) => { |
| 135 | + // const { keybinding, waitSelector } = args; |
| 136 | + // await app.code.dispatchKeybinding(keybinding, async () => { |
| 137 | + // if (waitSelector) { |
| 138 | + // await app.code.waitForElement(waitSelector); |
| 139 | + // } |
| 140 | + // }); |
| 141 | + // return { |
| 142 | + // content: [{ |
| 143 | + // type: 'text' as const, |
| 144 | + // text: `Sent keybinding: ${keybinding}${waitSelector ? ` (waited for: ${waitSelector})` : ''}` |
| 145 | + // }] |
| 146 | + // }; |
| 147 | + // } |
| 148 | + // ); |
| 149 | + |
| 150 | + // Defer to Playwright's tool |
| 151 | + // server.tool( |
| 152 | + // 'vscode_automation_get_text_content', |
| 153 | + // 'Get text content from a UI element using CSS selector', |
| 154 | + // { |
| 155 | + // selector: z.string().describe('CSS selector for the element'), |
| 156 | + // expectedText: z.string().optional().describe('Optional expected text to wait for') |
| 157 | + // }, |
| 158 | + // async (args) => { |
| 159 | + // const { selector, expectedText } = args; |
| 160 | + // const text = await app.code.waitForTextContent(selector, expectedText); |
| 161 | + // return { |
| 162 | + // content: [{ |
| 163 | + // type: 'text' as const, |
| 164 | + // text: `Text content from ${selector}: "${text}"` |
| 165 | + // }] |
| 166 | + // }; |
| 167 | + // } |
| 168 | + // ); |
149 | 169 | } |
0 commit comments