Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/test/mcp/src/automationTools/editor.ts
3520 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { McpServer, RegisteredTool } from '@modelcontextprotocol/sdk/server/mcp.js';
7
import { ApplicationService } from '../application';
8
import { z } from 'zod';
9
10
/**
11
* Editor Management Tools
12
*/
13
export function applyEditorTools(server: McpServer, appService: ApplicationService): RegisteredTool[] {
14
const tools: RegisteredTool[] = [];
15
// Playwright can probably figure this one out
16
// server.tool(
17
// 'vscode_automation_editor_open_file',
18
// 'Open a file in the VS Code editor through quick open',
19
// {
20
// fileName: z.string().describe('Name of the file to open (partial names work)')
21
// },
22
// async (args) => {
23
// const { fileName } = args;
24
// await app.workbench.quickaccess.openFileQuickAccessAndWait(fileName, fileName);
25
// return {
26
// content: [{
27
// type: 'text' as const,
28
// text: `Opened file: ${fileName}`
29
// }]
30
// };
31
// }
32
// );
33
34
// This one is critical as Playwright had trouble typing in monaco
35
tools.push(server.tool(
36
'vscode_automation_editor_type_text',
37
'Type text in the currently active editor',
38
{
39
text: z.string().describe('The text to type'),
40
filename: z.string().describe('Filename to target specific editor')
41
},
42
async (args) => {
43
const { text, filename } = args;
44
const app = await appService.getOrCreateApplication();
45
await app.workbench.editor.waitForTypeInEditor(filename, text);
46
return {
47
content: [{
48
type: 'text' as const,
49
text: `Typed text: "${text}"`
50
}]
51
};
52
}
53
));
54
55
// Doesn't seem particularly useful
56
// server.tool(
57
// 'vscode_automation_editor_get_selection',
58
// 'Get the current selection in the editor',
59
// {
60
// filename: z.string().describe('Filename to target specific editor')
61
// },
62
// async (args) => {
63
// const { filename } = args;
64
// return new Promise((resolve, reject) => {
65
// const selectionHandler = (selection: { selectionStart: number; selectionEnd: number }) => {
66
// resolve({
67
// content: [{
68
// type: 'text' as const,
69
// text: `Selection: start=${selection.selectionStart}, end=${selection.selectionEnd}`
70
// }]
71
// });
72
// return true;
73
// };
74
75
// app.workbench.editor.waitForEditorSelection(filename, selectionHandler).catch(reject);
76
// });
77
// }
78
// );
79
80
// Doesn't seem particularly useful
81
// server.tool(
82
// 'vscode_automation_editor_go_to_definition',
83
// 'Go to definition of symbol at current cursor position',
84
// {
85
// filename: z.string().describe('File containing the symbol'),
86
// term: z.string().describe('The symbol/term to go to definition for'),
87
// line: z.number().describe('Line number where the symbol is located')
88
// },
89
// async (args) => {
90
// const { filename, term, line } = args;
91
// await app.workbench.editor.gotoDefinition(filename, term, line);
92
// return {
93
// content: [{
94
// type: 'text' as const,
95
// text: `Navigated to definition of "${term}" in ${filename} at line ${line}`
96
// }]
97
// };
98
// }
99
// );
100
101
// Playwright can probably figure this one out
102
// server.tool(
103
// 'vscode_automation_editor_peek_definition',
104
// 'Peek definition of symbol at current cursor position',
105
// {
106
// filename: z.string().describe('File containing the symbol'),
107
// term: z.string().describe('The symbol/term to peek definition for'),
108
// line: z.number().describe('Line number where the symbol is located')
109
// },
110
// async (args) => {
111
// const { filename, term, line } = args;
112
// await app.workbench.editor.peekDefinition(filename, term, line);
113
// return {
114
// content: [{
115
// type: 'text' as const,
116
// text: `Peeked definition of "${term}" in ${filename} at line ${line}`
117
// }]
118
// };
119
// }
120
// );
121
122
// Playwright can probably figure this one out
123
// server.tool(
124
// 'vscode_automation_editor_rename_symbol',
125
// 'Rename a symbol in the editor',
126
// {
127
// filename: z.string().describe('File containing the symbol'),
128
// line: z.number().describe('Line number where the symbol is located'),
129
// oldName: z.string().describe('Current name of the symbol'),
130
// newName: z.string().describe('New name for the symbol')
131
// },
132
// async (args) => {
133
// const { filename, line, oldName, newName } = args;
134
// await app.workbench.editor.rename(filename, line, oldName, newName);
135
// return {
136
// content: [{
137
// type: 'text' as const,
138
// text: `Renamed "${oldName}" to "${newName}" in ${filename} at line ${line}`
139
// }]
140
// };
141
// }
142
// );
143
144
// Playwright can probably figure this one out
145
// server.tool(
146
// 'vscode_automation_editor_find_references',
147
// 'Find all references to a symbol',
148
// {
149
// filename: z.string().describe('File containing the symbol'),
150
// term: z.string().describe('The symbol/term to find references for'),
151
// line: z.number().describe('Line number where the symbol is located')
152
// },
153
// async (args) => {
154
// const { filename, term, line } = args;
155
// await app.workbench.editor.findReferences(filename, term, line);
156
// return {
157
// content: [{
158
// type: 'text' as const,
159
// text: `Found references for "${term}" in ${filename} at line ${line}`
160
// }]
161
// };
162
// }
163
// );
164
165
// Editor File Management Tools
166
tools.push(server.tool(
167
'vscode_automation_editor_new_untitled_file',
168
'Create a new untitled file',
169
async () => {
170
const app = await appService.getOrCreateApplication();
171
await app.workbench.editors.newUntitledFile();
172
return {
173
content: [{
174
type: 'text' as const,
175
text: 'Created new untitled file'
176
}]
177
};
178
}
179
));
180
181
tools.push(server.tool(
182
'vscode_automation_editor_save_file',
183
'Save the currently active file',
184
async () => {
185
const app = await appService.getOrCreateApplication();
186
await app.workbench.editors.saveOpenedFile();
187
return {
188
content: [{
189
type: 'text' as const,
190
text: 'Saved active file'
191
}]
192
};
193
}
194
));
195
196
// Playwright can probably figure this out
197
// server.tool(
198
// 'vscode_automation_editor_select_tab',
199
// 'Select a specific tab by filename',
200
// {
201
// fileName: z.string().describe('Name of the file tab to select')
202
// },
203
// async (args) => {
204
// const { fileName } = args;
205
// await app.workbench.editors.selectTab(fileName);
206
// return {
207
// content: [{
208
// type: 'text' as const,
209
// text: `Selected tab: ${fileName}`
210
// }]
211
// };
212
// }
213
// );
214
215
// Playwright can probably figure this out
216
// server.tool(
217
// 'vscode_automation_editor_wait_for_tab',
218
// 'Wait for a specific tab to appear',
219
// {
220
// fileName: z.string().describe('Name of the file tab to wait for'),
221
// isDirty: z.boolean().optional().describe('Whether to wait for the tab to be dirty (unsaved)')
222
// },
223
// async (args) => {
224
// const { fileName, isDirty = false } = args;
225
// await app.workbench.editors.waitForTab(fileName, isDirty);
226
// return {
227
// content: [{
228
// type: 'text' as const,
229
// text: `Tab appeared: ${fileName}${isDirty ? ' (dirty)' : ''}`
230
// }]
231
// };
232
// }
233
// );
234
235
// Playwright can probably figure this out
236
// server.tool(
237
// 'vscode_automation_editor_wait_for_focus',
238
// 'Wait for an editor to have focus',
239
// {
240
// fileName: z.string().describe('Name of the file to wait for focus'),
241
// retryCount: z.number().optional().describe('Number of retries')
242
// },
243
// async (args) => {
244
// const { fileName, retryCount } = args;
245
// await app.workbench.editors.waitForEditorFocus(fileName, retryCount);
246
// return {
247
// content: [{
248
// type: 'text' as const,
249
// text: `Editor has focus: ${fileName}`
250
// }]
251
// };
252
// }
253
// );
254
255
return tools;
256
}
257
258