[POC] Browser tools in Copilot CLI - MCP Version#314570
Draft
Conversation
Contributor
Screenshot ChangesBase: Changed (12) |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an “internal MCP server” concept to the MCP gateway so VS Code can expose in-process tools (starting with the Browser “open page” tool) to external MCP clients like Copilot CLI via the existing gateway channel.
Changes:
- Introduces an
InternalMcpServerRegistryservice for registering virtual/in-process MCP servers and tools. - Extends
McpGatewayToolBrokerChannelto list and invoke tools from internal servers alongside real MCP servers. - Adds an Electron workbench contribution that registers a
vscode-internal:browserMCP server backed byILanguageModelToolsServiceand adds tests for the new internal-server behavior.
Show a summary per file
| File | Description |
|---|---|
| src/vs/workbench/contrib/mcp/test/common/mcpGatewayToolBrokerChannel.test.ts | Adds coverage for listing/using internal MCP servers and tool routing. |
| src/vs/workbench/contrib/mcp/electron-browser/mcpGatewayToolBrokerContribution.ts | Wires IInternalMcpServerRegistry into the gateway tool broker channel registration (desktop). |
| src/vs/workbench/contrib/mcp/common/mcpGatewayToolBrokerChannel.ts | Implements internal-server support in list/notify/invoke flows. |
| src/vs/workbench/contrib/mcp/common/internalMcpToolUtils.ts | Adds conversion utility from internal IToolResult to MCP CallToolResult. |
| src/vs/workbench/contrib/mcp/common/internalMcpServerRegistry.ts | New registry/service contracts + implementation for internal MCP servers/tools. |
| src/vs/workbench/contrib/mcp/browser/mcpGatewayToolBrokerContribution.ts | Wires IInternalMcpServerRegistry into the gateway tool broker channel registration (web/remote). |
| src/vs/workbench/contrib/mcp/browser/mcp.contribution.ts | Registers IInternalMcpServerRegistry singleton in the MCP workbench contribution. |
| src/vs/workbench/contrib/browserView/electron-browser/tools/browserTools.contribution.ts | Registers the new Browser MCP server workbench contribution. |
| src/vs/workbench/contrib/browserView/electron-browser/tools/browserMcpServerContribution.ts | Implements vscode-internal:browser internal MCP server and bridges to ILanguageModelToolsService. |
Copilot's findings
- Files reviewed: 9/9 changed files
- Comments generated: 7
Comment on lines
+76
to
+83
| next.push({ | ||
| definition: { | ||
| name: data.id, | ||
| description: data.modelDescription, | ||
| inputSchema: data.inputSchema as MCP.Tool['inputSchema'], | ||
| }, | ||
| invoke: (args, _ctx, token) => this._invokeTool(data.id, args, token), | ||
| }); |
Comment on lines
+269
to
+275
| const internalTool = this._findInternalTool(internalServer, name); | ||
| if (!internalTool) { | ||
| throw new Error(`Unknown tool '${name}' on internal server '${serverId}'`); | ||
| } | ||
| const sessionResource = chatSessionResource ? URI.parse(chatSessionResource) : undefined; | ||
| const result = await internalTool.invoke(args, { chatSessionResource: sessionResource }, token); | ||
| this._logService.debug(`[McpGateway][ToolBroker] Internal tool '${name}' on '${serverId}' completed (isError=${result.isError ?? false}, content blocks=${result.content.length})`); |
Comment on lines
+114
to
+115
| const next = this._servers.get().filter(s => s !== server); | ||
| if (next.length !== this._servers.get().length) { |
Comment on lines
+20
to
+21
| * - `data` parts with any other mime type are dropped (with a warning text | ||
| * block) since MCP has no generic binary content type — the model would |
Comment on lines
53
to
58
| constructor( | ||
| private readonly _mcpService: IMcpService, | ||
| private readonly _logService: ILogService, | ||
| private readonly _startupGracePeriodMs = 5000, | ||
| private readonly _internalServerRegistry: IInternalMcpServerRegistry | undefined = undefined, | ||
| ) { |
Comment on lines
240
to
+246
| private async _listToolsForServer(serverId: string): Promise<readonly MCP.Tool[]> { | ||
| const internalServer = this._getInternalServerById(serverId); | ||
| if (internalServer) { | ||
| const tools = internalServer.tools.get().map(t => t.definition); | ||
| this._logService.debug(`[McpGateway][ToolBroker] listToolsForServer (internal) '${serverId}': ${tools.length} tool(s)`); | ||
| return tools; | ||
| } |
Comment on lines
+274
to
+276
| const result = await internalTool.invoke(args, { chatSessionResource: sessionResource }, token); | ||
| this._logService.debug(`[McpGateway][ToolBroker] Internal tool '${name}' on '${serverId}' completed (isError=${result.isError ?? false}, content blocks=${result.content.length})`); | ||
| return result; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
exposes open_browser_page tool to Copilot CLI chat sessions via MCP