diff --git a/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts index 87bc0f1cb16..ae32ea5de9b 100644 --- a/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts +++ b/src/vs/code/electron-utility/sharedProcess/sharedProcessMain.ts @@ -124,6 +124,11 @@ import { IExtensionGalleryManifestService } from '../../../platform/extensionMan import { ExtensionGalleryManifestIPCService } from '../../../platform/extensionManagement/common/extensionGalleryManifestServiceIpc.js'; import { ISharedWebContentExtractorService } from '../../../platform/webContentExtractor/common/webContentExtractor.js'; import { SharedWebContentExtractorService } from '../../../platform/webContentExtractor/node/sharedWebContentExtractorService.js'; +import { McpManagementService } from '../../../platform/mcp/node/mcpManagementService.js'; +import { IMcpGalleryService, IMcpManagementService } from '../../../platform/mcp/common/mcpManagement.js'; +import { IMcpResourceScannerService, McpResourceScannerService } from '../../../platform/mcp/common/mcpResourceScannerService.js'; +import { McpGalleryService } from '../../../platform/mcp/common/mcpGalleryService.js'; +import { McpManagementChannel } from '../../../platform/mcp/common/mcpManagementIpc.js'; class SharedProcessMain extends Disposable implements IClientConnectionFilter { @@ -334,6 +339,11 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { services.set(IAllowedExtensionsService, new SyncDescriptor(AllowedExtensionsService, undefined, true)); services.set(INativeServerExtensionManagementService, new SyncDescriptor(ExtensionManagementService, undefined, true)); + // MCP Management + services.set(IMcpGalleryService, new SyncDescriptor(McpGalleryService, undefined, true)); + services.set(IMcpResourceScannerService, new SyncDescriptor(McpResourceScannerService, undefined, true)); + services.set(IMcpManagementService, new SyncDescriptor(McpManagementService, undefined, true)); + // Extension Gallery services.set(IExtensionGalleryManifestService, new ExtensionGalleryManifestIPCService(this.server, productService)); services.set(IExtensionGalleryService, new SyncDescriptor(ExtensionGalleryService, undefined, true)); @@ -388,6 +398,10 @@ class SharedProcessMain extends Disposable implements IClientConnectionFilter { const channel = new ExtensionManagementChannel(accessor.get(IExtensionManagementService), () => null); this.server.registerChannel('extensions', channel); + // Mcp Management + const mcpManagementChannel = new McpManagementChannel(accessor.get(IMcpManagementService), () => null); + this.server.registerChannel('mcpManagement', mcpManagementChannel); + // Language Packs const languagePacksChannel = ProxyChannel.fromService(accessor.get(ILanguagePackService), this._store); this.server.registerChannel('languagePacks', languagePacksChannel); diff --git a/src/vs/code/node/cliProcessMain.ts b/src/vs/code/node/cliProcessMain.ts index 6c569ca4c8a..74a137b05b1 100644 --- a/src/vs/code/node/cliProcessMain.ts +++ b/src/vs/code/node/cliProcessMain.ts @@ -69,7 +69,7 @@ import { McpManagementCli } from '../../platform/mcp/common/mcpManagementCli.js' import { IExtensionGalleryManifestService } from '../../platform/extensionManagement/common/extensionGalleryManifest.js'; import { ExtensionGalleryManifestService } from '../../platform/extensionManagement/common/extensionGalleryManifestService.js'; import { IMcpGalleryService, IMcpManagementService } from '../../platform/mcp/common/mcpManagement.js'; -import { McpManagementService } from '../../platform/mcp/common/mcpManagementService.js'; +import { McpManagementService } from '../../platform/mcp/node/mcpManagementService.js'; import { IMcpResourceScannerService, McpResourceScannerService } from '../../platform/mcp/common/mcpResourceScannerService.js'; import { McpGalleryService } from '../../platform/mcp/common/mcpGalleryService.js'; diff --git a/src/vs/platform/mcp/common/mcpManagementService.ts b/src/vs/platform/mcp/common/mcpManagementService.ts index 566c43ead1e..84466d3893d 100644 --- a/src/vs/platform/mcp/common/mcpManagementService.ts +++ b/src/vs/platform/mcp/common/mcpManagementService.ts @@ -386,11 +386,12 @@ export abstract class AbstractMcpResourceManagementService extends Disposable im abstract installFromGallery(server: IGalleryMcpServer, options?: InstallOptions): Promise; abstract updateMetadata(local: ILocalMcpServer, server: IGalleryMcpServer, profileLocation: URI): Promise; protected abstract getLocalServerInfo(name: string, mcpServerConfig: IMcpServerConfiguration): Promise; + protected abstract installFromUri(uri: URI, options?: Omit): Promise; } export class McpUserResourceManagementService extends AbstractMcpResourceManagementService implements IMcpManagementService { - private readonly mcpLocation: URI; + protected readonly mcpLocation: URI; constructor( mcpResource: URI, @@ -498,13 +499,18 @@ export class McpUserResourceManagementService extends AbstractMcpResourceManagem return storedMcpServerInfo; } - private getLocation(name: string, version?: string): URI { + protected getLocation(name: string, version?: string): URI { name = name.replace('/', '.'); return this.uriIdentityService.extUri.joinPath(this.mcpLocation, version ? `${name}-${version}` : name); } + protected override installFromUri(uri: URI, options?: Omit): Promise { + throw new Error('Method not supported.'); + } + } + export class McpManagementService extends Disposable implements IMcpManagementService { readonly _serviceBrand: undefined; @@ -528,7 +534,7 @@ export class McpManagementService extends Disposable implements IMcpManagementSe constructor( @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, - @IInstantiationService private readonly instantiationService: IInstantiationService, + @IInstantiationService protected readonly instantiationService: IInstantiationService, ) { super(); } @@ -537,7 +543,7 @@ export class McpManagementService extends Disposable implements IMcpManagementSe let mcpResourceManagementService = this.mcpResourceManagementServices.get(mcpResource); if (!mcpResourceManagementService) { const disposables = new DisposableStore(); - const service = disposables.add(this.instantiationService.createInstance(McpUserResourceManagementService, mcpResource)); + const service = disposables.add(this.createMcpResourceManagementService(mcpResource)); disposables.add(service.onInstallMcpServer(e => this._onInstallMcpServer.fire(e))); disposables.add(service.onDidInstallMcpServers(e => this._onDidInstallMcpServers.fire(e))); disposables.add(service.onDidUpdateMcpServers(e => this._onDidUpdateMcpServers.fire(e))); @@ -578,4 +584,8 @@ export class McpManagementService extends Disposable implements IMcpManagementSe super.dispose(); } + protected createMcpResourceManagementService(mcpResource: URI): McpUserResourceManagementService { + return this.instantiationService.createInstance(McpUserResourceManagementService, mcpResource); + } + } diff --git a/src/vs/platform/mcp/node/mcpManagementService.ts b/src/vs/platform/mcp/node/mcpManagementService.ts new file mode 100644 index 00000000000..13a417d03b2 --- /dev/null +++ b/src/vs/platform/mcp/node/mcpManagementService.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { URI } from '../../../base/common/uri.js'; +import { IEnvironmentService } from '../../environment/common/environment.js'; +import { IFileService } from '../../files/common/files.js'; +import { ILogService } from '../../log/common/log.js'; +import { IUriIdentityService } from '../../uriIdentity/common/uriIdentity.js'; +import { IMcpGalleryService, IMcpManagementService } from '../common/mcpManagement.js'; +import { McpUserResourceManagementService as CommonMcpUserResourceManagementService, McpManagementService as CommonMcpManagementService } from '../common/mcpManagementService.js'; +import { IMcpResourceScannerService } from '../common/mcpResourceScannerService.js'; + + +export class McpUserResourceManagementService extends CommonMcpUserResourceManagementService { + constructor( + mcpResource: URI, + @IMcpGalleryService mcpGalleryService: IMcpGalleryService, + @IFileService fileService: IFileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + @ILogService logService: ILogService, + @IMcpResourceScannerService mcpResourceScannerService: IMcpResourceScannerService, + @IEnvironmentService environmentService: IEnvironmentService + ) { + super(mcpResource, mcpGalleryService, fileService, uriIdentityService, logService, mcpResourceScannerService, environmentService); + } +} + +export class McpManagementService extends CommonMcpManagementService implements IMcpManagementService { + protected override createMcpResourceManagementService(mcpResource: URI): McpUserResourceManagementService { + return this.instantiationService.createInstance(McpUserResourceManagementService, mcpResource); + } +} diff --git a/src/vs/server/node/serverServices.ts b/src/vs/server/node/serverServices.ts index bdb0dcb629f..c4f5bc2ce92 100644 --- a/src/vs/server/node/serverServices.ts +++ b/src/vs/server/node/serverServices.ts @@ -86,7 +86,7 @@ import { NativeMcpDiscoveryHelperService } from '../../platform/mcp/node/nativeM import { IExtensionGalleryManifestService } from '../../platform/extensionManagement/common/extensionGalleryManifest.js'; import { ExtensionGalleryManifestIPCService } from '../../platform/extensionManagement/common/extensionGalleryManifestServiceIpc.js'; import { IMcpGalleryService, IMcpManagementService } from '../../platform/mcp/common/mcpManagement.js'; -import { McpManagementService } from '../../platform/mcp/common/mcpManagementService.js'; +import { McpManagementService } from '../../platform/mcp/node/mcpManagementService.js'; import { McpGalleryService } from '../../platform/mcp/common/mcpGalleryService.js'; import { IMcpResourceScannerService, McpResourceScannerService } from '../../platform/mcp/common/mcpResourceScannerService.js'; import { McpManagementChannel } from '../../platform/mcp/common/mcpManagementIpc.js'; diff --git a/src/vs/workbench/services/mcp/browser/mcpWorkbenchManagementService.ts b/src/vs/workbench/services/mcp/browser/mcpWorkbenchManagementService.ts new file mode 100644 index 00000000000..1b7256ce155 --- /dev/null +++ b/src/vs/workbench/services/mcp/browser/mcpWorkbenchManagementService.ts @@ -0,0 +1,34 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; +import { IUserDataProfileService } from '../../../services/userDataProfile/common/userDataProfile.js'; +import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; +import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js'; +import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js'; +import { IRemoteAgentService } from '../../remote/common/remoteAgentService.js'; +import { IUserDataProfilesService } from '../../../../platform/userDataProfile/common/userDataProfile.js'; +import { IRemoteUserDataProfilesService } from '../../userDataProfile/common/remoteUserDataProfiles.js'; +import { WorkbenchMcpManagementService as BaseWorkbenchMcpManagementService, IWorkbenchMcpManagementService } from '../common/mcpWorkbenchManagementService.js'; +import { McpManagementService } from '../../../../platform/mcp/common/mcpManagementService.js'; + +export class WorkbenchMcpManagementService extends BaseWorkbenchMcpManagementService { + + constructor( + @IUserDataProfileService userDataProfileService: IUserDataProfileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + @IWorkspaceContextService workspaceContextService: IWorkspaceContextService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, + @IRemoteUserDataProfilesService remoteUserDataProfilesService: IRemoteUserDataProfilesService, + @IInstantiationService instantiationService: IInstantiationService, + ) { + const mMcpManagementService = instantiationService.createInstance(McpManagementService); + super(mMcpManagementService, userDataProfileService, uriIdentityService, workspaceContextService, remoteAgentService, userDataProfilesService, remoteUserDataProfilesService, instantiationService); + this._register(mMcpManagementService); + } +} + +registerSingleton(IWorkbenchMcpManagementService, WorkbenchMcpManagementService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts b/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts index d01429d53c0..f70a1ba04c5 100644 --- a/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts +++ b/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.ts @@ -5,9 +5,8 @@ import { Disposable, DisposableStore, IDisposable } from '../../../../base/common/lifecycle.js'; import { ILocalMcpServer, IMcpManagementService, IGalleryMcpServer, InstallOptions, InstallMcpServerEvent, UninstallMcpServerEvent, DidUninstallMcpServerEvent, InstallMcpServerResult, IInstallableMcpServer, IMcpGalleryService, UninstallOptions } from '../../../../platform/mcp/common/mcpManagement.js'; -import { createDecorator, IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; +import { IInstantiationService, refineServiceDecorator } from '../../../../platform/instantiation/common/instantiation.js'; import { IUserDataProfileService } from '../../../services/userDataProfile/common/userDataProfile.js'; -import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { Emitter, Event } from '../../../../base/common/event.js'; import { IMcpResourceScannerService, McpResourceTarget } from '../../../../platform/mcp/common/mcpResourceScannerService.js'; import { isWorkspaceFolder, IWorkspaceContextService, IWorkspaceFolder, IWorkspaceFoldersChangeEvent } from '../../../../platform/workspace/common/workspace.js'; @@ -43,7 +42,9 @@ export interface IWorkbenchMcpServerInstallResult extends InstallMcpServerResult readonly local?: IWorkbenchLocalMcpServer; } +export const IWorkbenchMcpManagementService = refineServiceDecorator(IMcpManagementService); export interface IWorkbenchMcpManagementService extends IMcpManagementService { + readonly _serviceBrand: undefined; readonly onDidInstallMcpServers: Event; @@ -55,12 +56,10 @@ export interface IWorkbenchMcpManagementService extends IMcpManagementService { readonly onDidChangeProfile: Event; getInstalled(): Promise; - install(server: IInstallableMcpServer, options?: IWorkbencMcpServerInstallOptions): Promise; + install(server: IInstallableMcpServer | URI, options?: IWorkbencMcpServerInstallOptions): Promise; } -export const IWorkbenchMcpManagementService = createDecorator('workbenchMcpManagementService'); - -class WorkbenchMcpManagementService extends Disposable implements IWorkbenchMcpManagementService { +export class WorkbenchMcpManagementService extends Disposable implements IWorkbenchMcpManagementService { readonly _serviceBrand: undefined; @@ -101,10 +100,10 @@ class WorkbenchMcpManagementService extends Disposable implements IWorkbenchMcpM private readonly remoteMcpManagementService: IMcpManagementService | undefined; constructor( + private readonly mcpManagementService: IMcpManagementService, @IUserDataProfileService private readonly userDataProfileService: IUserDataProfileService, @IUriIdentityService private readonly uriIdentityService: IUriIdentityService, @IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService, - @IMcpManagementService private readonly mcpManagementService: IMcpManagementService, @IRemoteAgentService remoteAgentService: IRemoteAgentService, @IUserDataProfilesService private readonly userDataProfilesService: IUserDataProfilesService, @IRemoteUserDataProfilesService private readonly remoteUserDataProfilesService: IRemoteUserDataProfilesService, @@ -379,6 +378,10 @@ class WorkspaceMcpResourceManagementService extends AbstractMcpResourceManagemen throw new Error('Not supported'); } + protected override installFromUri(): Promise { + throw new Error('Not supported'); + } + protected override async getLocalServerInfo(): Promise { return undefined; } @@ -568,5 +571,3 @@ class WorkspaceMcpManagementService extends Disposable implements IMcpManagement super.dispose(); } } - -registerSingleton(IWorkbenchMcpManagementService, WorkbenchMcpManagementService, InstantiationType.Delayed); diff --git a/src/vs/workbench/services/mcp/electron-browser/mcpWorkbenchManagementService.ts b/src/vs/workbench/services/mcp/electron-browser/mcpWorkbenchManagementService.ts new file mode 100644 index 00000000000..6989b92cfd7 --- /dev/null +++ b/src/vs/workbench/services/mcp/electron-browser/mcpWorkbenchManagementService.ts @@ -0,0 +1,36 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; +import { IUserDataProfileService } from '../../../services/userDataProfile/common/userDataProfile.js'; +import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; +import { IWorkspaceContextService } from '../../../../platform/workspace/common/workspace.js'; +import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js'; +import { IRemoteAgentService } from '../../remote/common/remoteAgentService.js'; +import { McpManagementChannelClient } from '../../../../platform/mcp/common/mcpManagementIpc.js'; +import { IUserDataProfilesService } from '../../../../platform/userDataProfile/common/userDataProfile.js'; +import { IRemoteUserDataProfilesService } from '../../userDataProfile/common/remoteUserDataProfiles.js'; +import { WorkbenchMcpManagementService as BaseWorkbenchMcpManagementService, IWorkbenchMcpManagementService } from '../common/mcpWorkbenchManagementService.js'; +import { ISharedProcessService } from '../../../../platform/ipc/electron-browser/services.js'; + +export class WorkbenchMcpManagementService extends BaseWorkbenchMcpManagementService { + + constructor( + @IUserDataProfileService userDataProfileService: IUserDataProfileService, + @IUriIdentityService uriIdentityService: IUriIdentityService, + @IWorkspaceContextService workspaceContextService: IWorkspaceContextService, + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + @IUserDataProfilesService userDataProfilesService: IUserDataProfilesService, + @IRemoteUserDataProfilesService remoteUserDataProfilesService: IRemoteUserDataProfilesService, + @IInstantiationService instantiationService: IInstantiationService, + @ISharedProcessService sharedProcessService: ISharedProcessService, + ) { + const mcpManagementService = new McpManagementChannelClient(sharedProcessService.getChannel('mcpManagement')); + super(mcpManagementService, userDataProfileService, uriIdentityService, workspaceContextService, remoteAgentService, userDataProfilesService, remoteUserDataProfilesService, instantiationService); + this._register(mcpManagementService); + } +} + +registerSingleton(IWorkbenchMcpManagementService, WorkbenchMcpManagementService, InstantiationType.Delayed); diff --git a/src/vs/workbench/workbench.common.main.ts b/src/vs/workbench/workbench.common.main.ts index 750087f2e72..924f024d86e 100644 --- a/src/vs/workbench/workbench.common.main.ts +++ b/src/vs/workbench/workbench.common.main.ts @@ -83,7 +83,6 @@ import './services/notebook/common/notebookDocumentService.js'; import './services/commands/common/commandService.js'; import './services/themes/browser/workbenchThemeService.js'; import './services/label/common/labelService.js'; -import './services/mcp/common/mcpWorkbenchManagementService.js'; import './services/extensions/common/extensionManifestPropertiesService.js'; import './services/extensionManagement/common/extensionGalleryService.js'; import './services/extensionManagement/browser/extensionEnablementService.js'; @@ -157,9 +156,8 @@ import { ExtensionStorageService, IExtensionStorageService } from '../platform/e import { IUserDataSyncLogService } from '../platform/userDataSync/common/userDataSync.js'; import { UserDataSyncLogService } from '../platform/userDataSync/common/userDataSyncLog.js'; import { AllowedExtensionsService } from '../platform/extensionManagement/common/allowedExtensionsService.js'; -import { IMcpGalleryService, IMcpManagementService } from '../platform/mcp/common/mcpManagement.js'; +import { IMcpGalleryService } from '../platform/mcp/common/mcpManagement.js'; import { McpGalleryService } from '../platform/mcp/common/mcpGalleryService.js'; -import { McpManagementService } from '../platform/mcp/common/mcpManagementService.js'; registerSingleton(IUserDataSyncLogService, UserDataSyncLogService, InstantiationType.Delayed); registerSingleton(IAllowedExtensionsService, AllowedExtensionsService, InstantiationType.Delayed); @@ -176,7 +174,6 @@ registerSingleton(ITextResourceConfigurationService, TextResourceConfigurationSe registerSingleton(IDownloadService, DownloadService, InstantiationType.Delayed); registerSingleton(IOpenerService, OpenerService, InstantiationType.Delayed); registerSingleton(IMcpGalleryService, McpGalleryService, InstantiationType.Delayed); -registerSingleton(IMcpManagementService, McpManagementService, InstantiationType.Delayed); //#endregion diff --git a/src/vs/workbench/workbench.desktop.main.ts b/src/vs/workbench/workbench.desktop.main.ts index c9df215ea42..af84852ebd2 100644 --- a/src/vs/workbench/workbench.desktop.main.ts +++ b/src/vs/workbench/workbench.desktop.main.ts @@ -53,6 +53,7 @@ import './services/keybinding/electron-browser/nativeKeyboardLayout.js'; import './services/path/electron-browser/pathService.js'; import './services/themes/electron-browser/nativeHostColorSchemeService.js'; import './services/extensionManagement/electron-browser/extensionManagementService.js'; +import './services/mcp/electron-browser/mcpWorkbenchManagementService.js'; import './services/encryption/electron-browser/encryptionService.js'; import './services/browserElements/electron-browser/browserElementsService.js'; import './services/secrets/electron-browser/secretStorageService.js'; diff --git a/src/vs/workbench/workbench.web.main.internal.ts b/src/vs/workbench/workbench.web.main.internal.ts index 460c888e390..eae3a102dee 100644 --- a/src/vs/workbench/workbench.web.main.internal.ts +++ b/src/vs/workbench/workbench.web.main.internal.ts @@ -43,6 +43,7 @@ import './services/extensionManagement/browser/extensionsProfileScannerService.j import './services/extensions/browser/extensionsScannerService.js'; import './services/extensionManagement/browser/webExtensionsScannerService.js'; import './services/extensionManagement/common/extensionManagementServerService.js'; +import './services/mcp/browser/mcpWorkbenchManagementService.js'; import './services/extensionManagement/browser/extensionGalleryManifestService.js'; import './services/telemetry/browser/telemetryService.js'; import './services/url/browser/urlService.js';