From 9e4b005ff5d9fe7b945c451d98705b0cf7cc4f9e Mon Sep 17 00:00:00 2001 From: Dileep Yavanmandha Date: Tue, 28 Oct 2025 09:50:37 -0700 Subject: [PATCH] Adding goBack button --- .vscode/mcp.json | 15 ++++++ .../mcp/common/mcpResourceFilesystem.ts | 48 ++++++++++++++++++- .../contrib/mcp/common/mcpTypesUtils.ts | 47 +++++++++++++++++- 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/.vscode/mcp.json b/.vscode/mcp.json index ac49da4c655..70e8e8c134a 100644 --- a/.vscode/mcp.json +++ b/.vscode/mcp.json @@ -8,6 +8,21 @@ "start-stdio" ], "cwd": "${workspaceFolder}/test/mcp" + }, + "everything-server": { + "type": "stdio", + "command": "node", + "args": [ + "C:\\Users\\dileepy\\servers\\src\\everything\\dist\\index.js" + ], + "env": {} + }, + "my-mcp-server-612a332c": { + "type": "stdio", + "command": "node", + "args": [ + "C:\\\\Users\\\\dileepy\\\\servers\\\\src\\\\everything\\\\dist\\\\index.js" + ] } }, "inputs": [] diff --git a/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts b/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts index 8f23b085e7c..fb347e988b6 100644 --- a/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts +++ b/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.ts @@ -17,10 +17,12 @@ import { equalsIgnoreCase } from '../../../../base/common/strings.js'; import { URI } from '../../../../base/common/uri.js'; import { createFileSystemProviderError, FileChangeType, FileSystemProviderCapabilities, FileSystemProviderErrorCode, FileType, IFileChange, IFileDeleteOptions, IFileOverwriteOptions, IFileReadStreamOptions, IFileService, IFileSystemProviderWithFileAtomicReadCapability, IFileSystemProviderWithFileReadStreamCapability, IFileSystemProviderWithFileReadWriteCapability, IFileWriteOptions, IStat, IWatchOptions } from '../../../../platform/files/common/files.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; +import { NativeWebContentExtractorService } from '../../../../platform/webContentExtractor/electron-main/webContentExtractorService.js'; import { IWorkbenchContribution } from '../../../common/contributions.js'; import { McpServer } from './mcpServer.js'; import { McpServerRequestHandler } from './mcpServerRequestHandler.js'; -import { IMcpService, McpCapability, McpResourceURI } from './mcpTypes.js'; +import { IMcpService, McpCapability, McpResourceURI, McpServerLaunch } from './mcpTypes.js'; +import { downloadResourceContentForWebHostedResources } from './mcpTypesUtils.js'; import { MCP } from './modelContextProtocol.js'; const MOMENTARY_CACHE_DURATION = 3000; @@ -282,13 +284,57 @@ export class McpResourceFilesystem extends Disposable implements IWorkbenchContr private async _readURIInner(uri: URI, token?: CancellationToken): Promise { const { resourceURI, server } = this._decodeURI(uri); + + const webContent = await downloadResourceContentForWebHostedResources(resourceURI.toString(), server.connection.get()?.launchDefinition); + + + //check if the uri is valid + const res = await McpServer.callOn(server, r => r.readResource({ uri: resourceURI.toString() }, token), token); + + + + if (res && res.contents?.length > 0) { + res = res.contents.map(content => { + if (content.mimeType === 'text/html') { + //extract the text part only. + + } + return content; + }) + } + return { contents: res.contents, resourceURI, forSameURI: res.contents.filter(c => equalsUrlPath(c.uri, resourceURI)) }; } + + private async downloadResourceContentForWebHostedResources(uriString: string, launch?: McpServerLaunch): Promise { + + const uri = URI.parse(uriString); + + const extractHelper = this._instantiationService.createInstance(NativeWebContentExtractorService); + + if (uri.scheme === 'http' || (uri.scheme === 'https')) { + + // if (!!launch) { + // if (launch?.type !== McpServerTransportType.HTTP) { + // return false; + // } + // const expectedAuthority = launch.uri.authority.toLowerCase(); + // if (uri.authority.toLowerCase() !== expectedAuthority) { + // return false; + // } + // } + + const content = await extractHelper.extract([uri]); + return content ? content[0] : ''; + } + return ''; + } + } function equalsUrlPath(a: string, b: URL): boolean { diff --git a/src/vs/workbench/contrib/mcp/common/mcpTypesUtils.ts b/src/vs/workbench/contrib/mcp/common/mcpTypesUtils.ts index bbc69d6aa3a..0df349f9428 100644 --- a/src/vs/workbench/contrib/mcp/common/mcpTypesUtils.ts +++ b/src/vs/workbench/contrib/mcp/common/mcpTypesUtils.ts @@ -8,8 +8,9 @@ import { CancellationToken } from '../../../../base/common/cancellation.js'; import { CancellationError } from '../../../../base/common/errors.js'; import { DisposableStore } from '../../../../base/common/lifecycle.js'; import { autorun } from '../../../../base/common/observable.js'; +import { URI } from '../../../../base/common/uri.js'; import { ToolDataSource } from '../../chat/common/languageModelToolsService.js'; -import { IMcpServer, IMcpServerStartOpts, IMcpService, McpConnectionState, McpServerCacheState } from './mcpTypes.js'; +import { IMcpServer, IMcpServerStartOpts, IMcpService, McpConnectionState, McpServerCacheState, McpServerLaunch, McpServerTransportType } from './mcpTypes.js'; /** * Waits up to `timeout` for a server passing the filter to be discovered, @@ -91,3 +92,47 @@ export function mcpServerToSourceData(server: IMcpServer): ToolDataSource { definitionId: server.definition.id }; } + +/** + * Validates a URI string against the MCP server's launch configuration. + * Returns the validated URI if it passes security checks, or undefined with a debug message if it fails. + * + * Security rules: + * - data: URIs are always allowed + * - http/https: Only allowed for HTTP transport servers, and only if authority matches the launch URI + * - file: URIs are only allowed for stdio (local process) servers + * - All other schemes are rejected + */ +export function validateMcpUri(uriString: string, launch?: McpServerLaunch): boolean { + const uri = URI.parse(uriString); + + if (uri.scheme === 'data') { + return true; + } + + if (uri.scheme === 'http' || (uri.scheme === 'https')) { + + // if (!!launch) { + // if (launch?.type !== McpServerTransportType.HTTP) { + // return false; + // } + // const expectedAuthority = launch.uri.authority.toLowerCase(); + // if (uri.authority.toLowerCase() !== expectedAuthority) { + // return false; + // } + // } + + return true; + } + + if (uri.scheme === 'file') { + if (launch?.type !== McpServerTransportType.Stdio) { + return false; + } + + return true; + } + + return false; +} +