-
Notifications
You must be signed in to change notification settings - Fork 37.3k
vscode mcp: support custom workspace path; enable restart tool #286297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
rebornix
commented
Jan 7, 2026
- optional workspace paths through MCP setup/start so the server can open a specific folder or workspace when requested
- enable reload tool to support window reload
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR enables MCP (Model Context Protocol) automation tools to support custom workspace paths and enables the restart tool for VS Code automation testing. The changes make workspace paths optional throughout the automation framework, allowing VS Code to open with the last used workspace or an empty window when no path is specified.
Key Changes:
- Enable the previously commented-out restart tool with support for optional workspace paths and extra CLI arguments
- Add optional
workspacePathparameter to the MCP start tool - Make
workspacePathoptional throughout the automation framework (Application, Code, electron, playwrightBrowser)
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| test/mcp/src/automationTools/core.ts | Uncommented and enabled the restart tool with optional workspace and extra arguments support |
| test/mcp/src/automation.ts | Added optional workspacePath parameter to the start tool with updated description |
| test/mcp/src/application.ts | Propagated workspacePath parameter through getApplication and ApplicationService methods |
| test/automation/src/playwrightBrowser.ts | Modified URL construction to conditionally include workspace path only when provided |
| test/automation/src/electron.ts | Made workspace path optional in electron args, added validation for remote scenarios |
| test/automation/src/code.ts | Changed workspacePath from required to optional in LaunchOptions interface |
| test/automation/src/application.ts | Changed _workspacePathOrFolder and its getter to return optional string |
| let url = `${endpoint}&payload=${payloadParam}`; | ||
| if (workspacePath) { | ||
| url = `${endpoint}&${workspacePath.endsWith('.code-workspace') ? 'workspace' : 'folder'}=${URI.file(workspacePath).path}&payload=${payloadParam}`; | ||
| } |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The URL construction logic is duplicating the endpoint and payloadParam concatenation. When workspacePath is provided, the entire URL is rebuilt from scratch with endpoint and payloadParam, but this duplicates the pattern from the line above. Consider simplifying this by starting with the base URL and conditionally adding the workspace portion in the middle.
| let url = `${endpoint}&payload=${payloadParam}`; | |
| if (workspacePath) { | |
| url = `${endpoint}&${workspacePath.endsWith('.code-workspace') ? 'workspace' : 'folder'}=${URI.file(workspacePath).path}&payload=${payloadParam}`; | |
| } | |
| let url = `${endpoint}&`; | |
| if (workspacePath) { | |
| const workspaceParam = workspacePath.endsWith('.code-workspace') ? 'workspace' : 'folder'; | |
| url += `${workspaceParam}=${URI.file(workspacePath).path}&`; | |
| } | |
| url += `payload=${payloadParam}`; |
| 'Restart VS Code with optional workspace or folder and extra command-line arguments', | ||
| { | ||
| workspaceOrFolder: z.string().optional().describe('Path to a workspace or folder to open on restart'), | ||
| extraArgs: z.array(z.string()).optional().describe('Extra CLI arguments to pass on restart') |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description says 'extra command-line arguments' but this is inconsistent with the parameter description on line 21 which says 'Extra CLI arguments'. Consider using consistent terminology throughout - either 'command-line arguments' or 'CLI arguments' in both places.
| extraArgs: z.array(z.string()).optional().describe('Extra CLI arguments to pass on restart') | |
| extraArgs: z.array(z.string()).optional().describe('Extra command-line arguments to pass on restart') |
| workspaceOrFolder: z.string().optional().describe('Path to a workspace or folder to open on restart'), | ||
| extraArgs: z.array(z.string()).optional().describe('Extra CLI arguments to pass on restart') | ||
| }, | ||
| async ({ workspaceOrFolder, extraArgs }) => { | ||
| const app = await appService.getOrCreateApplication(); | ||
| await app.restart({ workspaceOrFolder, extraArgs }); | ||
| const workspaceText = workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''; |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter name workspaceOrFolder is inconsistent with the workspacePath parameter used in the start tool (automation.ts line 24). Consider using consistent naming across both tools - either workspacePath or workspaceOrFolder - to avoid confusion for API consumers.
| workspaceOrFolder: z.string().optional().describe('Path to a workspace or folder to open on restart'), | |
| extraArgs: z.array(z.string()).optional().describe('Extra CLI arguments to pass on restart') | |
| }, | |
| async ({ workspaceOrFolder, extraArgs }) => { | |
| const app = await appService.getOrCreateApplication(); | |
| await app.restart({ workspaceOrFolder, extraArgs }); | |
| const workspaceText = workspaceOrFolder ? ` with workspace: ${workspaceOrFolder}` : ''; | |
| workspacePath: z.string().optional().describe('Path to a workspace or folder to open on restart'), | |
| extraArgs: z.array(z.string()).optional().describe('Extra CLI arguments to pass on restart') | |
| }, | |
| async ({ workspacePath, extraArgs }) => { | |
| const app = await appService.getOrCreateApplication(); | |
| await app.restart({ workspacePath, extraArgs }); | |
| const workspaceText = workspacePath ? ` with workspace: ${workspacePath}` : ''; |
| private _workspacePathOrFolder: string | undefined; | ||
| get workspacePathOrFolder(): string | undefined { | ||
| return this._workspacePathOrFolder; |
Copilot
AI
Jan 7, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type of _workspacePathOrFolder and its getter have been changed to optional, but the Application class still has a critical bug that affects the restart functionality being enabled in this PR. In the startApplication method (line 110), when launching with {...this.options, extraArgs: [...]}, the code spreads this.options which contains the original readonly workspacePath from construction time. However, when restart is called with a new workspace path, _start updates this._workspacePathOrFolder but this updated value is never passed to the launch function because this.options.workspacePath is readonly and unchanged.
To properly support workspace path changes during restart, the startApplication method needs to be updated to use this._workspacePathOrFolder instead of this.options.workspacePath.