import * as vscode from "vscode"; import { Event } from "../../../base/common/event.js"; import { Disposable, DisposableMap, IDisposable } from "../../../base/common/lifecycle.js"; import { IAuthorizationProtectedResourceMetadata, IAuthorizationServerMetadata } from "../../../base/common/oauth.js"; import { URI, UriComponents } from "../../../base/common/uri.js"; import { IExtensionDescription } from "../../../platform/extensions/common/extensions.js"; import { LogLevel } from "../../../platform/log/common/log.js"; import { ILogService } from "../../../platform/log/common/log.service.js"; import { McpServerDefinition, McpServerLaunch, McpServerTransportHTTP } from "../../contrib/mcp/common/mcpTypes.js"; import { ExtHostMcpShape, IAuthMetadataSource, IStartMcpOptions, MainThreadMcpShape } from "./extHost.protocol.js"; import { IExtHostInitDataService } from "./extHostInitDataService.js"; import { IExtHostRpcService } from "./extHostRpcService.js"; import { IExtHostVariableResolverProvider } from "./extHostVariableResolverService.js"; import { IExtHostWorkspace } from "./extHostWorkspace.js"; export declare const IExtHostMpcService: import("../../../platform/instantiation/common/instantiation.js").ServiceIdentifier; export interface IExtHostMpcService extends ExtHostMcpShape { registerMcpConfigurationProvider(extension: IExtensionDescription, id: string, provider: vscode.McpServerDefinitionProvider): IDisposable; /** Event that fires when the set of MCP server definitions changes. */ readonly onDidChangeMcpServerDefinitions: Event; /** Returns all MCP server definitions known to the editor. */ readonly mcpServerDefinitions: readonly vscode.McpServerDefinition[]; /** Starts an MCP gateway that exposes MCP servers via an HTTP endpoint. */ startMcpGateway(): Promise; } export declare class ExtHostMcpService extends Disposable implements IExtHostMpcService { protected readonly _logService: ILogService; private readonly _extHostInitData; protected readonly _workspaceService: IExtHostWorkspace; private readonly _variableResolver; protected _proxy: MainThreadMcpShape; private readonly _initialProviderPromises; protected readonly _sseEventSources: DisposableMap; private readonly _unresolvedMcpServers; private readonly _onDidChangeMcpServerDefinitions; readonly onDidChangeMcpServerDefinitions: Event; private _mcpServerDefinitions; constructor(extHostRpc: IExtHostRpcService, _logService: ILogService, _extHostInitData: IExtHostInitDataService, _workspaceService: IExtHostWorkspace, _variableResolver: IExtHostVariableResolverProvider); /** Returns all MCP server definitions known to the editor. */ get mcpServerDefinitions(): readonly vscode.McpServerDefinition[]; /** Called by main thread to notify that MCP server definitions have changed. */ $onDidChangeMcpServerDefinitions(servers: McpServerDefinition.Serialized[]): void; $startMcp(id: number, opts: IStartMcpOptions): void; protected _startMcp(id: number, launch: McpServerLaunch, _defaultCwd?: URI, errorOnUserInteraction?: boolean): void; $substituteVariables(_workspaceFolder: UriComponents | undefined, value: T): Promise; $stopMcp(id: number): void; private _didClose; $sendMessage(id: number, message: string): void; $waitForInitialCollectionProviders(): Promise; $resolveMcpLaunch(collectionId: string, label: string): Promise; /** {@link vscode.lm.registerMcpServerDefinitionProvider} */ registerMcpConfigurationProvider(extension: IExtensionDescription, id: string, provider: vscode.McpServerDefinitionProvider): IDisposable; /** {@link vscode.lm.startMcpGateway} */ startMcpGateway(): Promise; } /** * Implementation of both MCP HTTP Streaming as well as legacy SSE. * * The first request will POST to the endpoint, assuming HTTP streaming. If the * server is legacy SSE, it should return some 4xx status in that case, * and we'll automatically fall back to SSE and res */ export declare class McpHTTPHandle extends Disposable { private readonly _id; private readonly _launch; private readonly _proxy; private readonly _logService; private readonly _errorOnUserInteraction?; private readonly _requestSequencer; private readonly _postEndpoint; private _mode; private readonly _cts; private readonly _abortCtrl; private _authMetadata?; private _didSendClose; constructor(_id: number, _launch: McpServerTransportHTTP, _proxy: MainThreadMcpShape, _logService: ILogService, _errorOnUserInteraction?: boolean | undefined); send(message: string): Promise; close(): Promise; private _closeSession; private _send; /** * Sends a streamable-HTTP request. * 1. Posts to the endpoint * 2. Updates internal state as needed. Falls back to SSE if appropriate. * 3. If the response body is empty, JSON, or a JSON stream, handle it appropriately. */ private _sendStreamableHttp; private _sseFallbackWithMessage; private _handleSuccessfulStreamableHttp; /** * Attaches the SSE backchannel that streamable HTTP servers can use * for async notifications. This is a "MAY" support, so if the server gives * us a 4xx code, we'll stop trying to connect.. */ private _attachStreamableBackchannel; /** * Starts a legacy SSE attachment, where the SSE response is the session lifetime. * Unlike `_attachStreamableBackchannel`, this fails the server if it disconnects. */ private _attachSSE; /** * Sends a legacy SSE message to the server. The response is always empty and * is otherwise received in {@link _attachSSE}'s loop. */ private _sendLegacySSE; /** Generic handle to pipe a response into an SSE parser. */ private _doSSE; private _addAuthHeader; private _log; private _getErrText; /** * Helper method to perform fetch with authentication retry logic. * If the initial request returns an auth error and we don't have auth metadata, * it will populate the auth metadata and retry once. * If we already have auth metadata, check if the scopes changed and update them. */ private _fetchWithAuthRetry; private _fetch; protected _fetchInternal(url: string, init?: CommonRequestInit): Promise; } interface MinimalRequestInit { method: string; headers: Record; body?: Uint8Array; } export interface CommonRequestInit extends MinimalRequestInit { signal?: AbortSignal; redirect?: RequestRedirect; } export interface CommonResponse { status: number; statusText: string; headers: Headers; body?: ReadableStream | null; url: string; json(): Promise; text(): Promise; } /** * Logger callback type for AuthMetadata operations. */ export type AuthMetadataLogger = (level: LogLevel, message: string) => void; /** * Interface for authentication metadata that can be updated when scopes change. */ export interface IAuthMetadata { readonly authorizationServer: URI; readonly serverMetadata: IAuthorizationServerMetadata; readonly resourceMetadata: IAuthorizationProtectedResourceMetadata | undefined; readonly scopes: string[] | undefined; /** Telemetry data about how auth metadata was discovered */ readonly telemetry: IAuthMetadataSource; /** * Updates the scopes based on the WWW-Authenticate header in the response. * @param response The HTTP response containing potential scope challenges * @returns true if scopes were updated, false otherwise */ update(responseHeaders: Headers): boolean; } /** * Concrete implementation of IAuthMetadata that manages OAuth authentication metadata. * Consumers should use {@link createAuthMetadata} to create instances. */ declare class AuthMetadata implements IAuthMetadata { readonly authorizationServer: URI; readonly serverMetadata: IAuthorizationServerMetadata; readonly resourceMetadata: IAuthorizationProtectedResourceMetadata | undefined; readonly telemetry: IAuthMetadataSource; private readonly _log; private _scopes; constructor(authorizationServer: URI, serverMetadata: IAuthorizationServerMetadata, resourceMetadata: IAuthorizationProtectedResourceMetadata | undefined, scopes: string[] | undefined, telemetry: IAuthMetadataSource, _log: AuthMetadataLogger); get scopes(): string[] | undefined; update(responseHeaders: Headers): boolean; private _parseScopesFromResponse; } /** * Options for creating AuthMetadata. */ export interface ICreateAuthMetadataOptions { /** Headers to include when fetching metadata from the same origin as the resource server */ sameOriginHeaders?: Record; /** Fetch function to use for HTTP requests */ fetch: (url: string, init: MinimalRequestInit) => Promise; /** Logger function for diagnostic output */ log: AuthMetadataLogger; } /** * Creates an AuthMetadata instance by discovering OAuth metadata from the server. * * This function: * 1. Parses the WWW-Authenticate header for resource_metadata and scope challenges * 2. Fetches OAuth protected resource metadata from well-known URIs or the challenge URL * 3. Fetches authorization server metadata * 4. Falls back to default metadata if discovery fails * * @param resourceUrl The resource server URL * @param wwwAuthenticateValue The value of the WWW-Authenticate header from the original HTTP response * @param options Configuration options including headers, fetch function, and logger * @returns A new AuthMetadata instance */ export declare function createAuthMetadata(resourceUrl: string, initialResponseHeaders: Headers, options: ICreateAuthMetadataOptions): Promise; export {};