mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-08 17:19:48 +01:00
Enable GH Mcp registry in stable behind a preview setting (#268830)
* Enable GH Mcp registry in stable behind a preview setting * add icon
This commit is contained in:
committed by
GitHub
parent
fdbeb852cf
commit
aadbd769df
@@ -244,6 +244,7 @@ export interface IAllowedMcpServersService {
|
||||
|
||||
export const mcpAccessConfig = 'chat.mcp.access';
|
||||
export const mcpGalleryServiceUrlConfig = 'chat.mcp.gallery.serviceUrl';
|
||||
export const mcpGalleryServiceEnablementConfig = 'chat.mcp.gallery.enabled';
|
||||
export const mcpAutoStartConfig = 'chat.mcp.autostart';
|
||||
|
||||
export const enum McpAutoStartValue {
|
||||
|
||||
@@ -20,7 +20,7 @@ import { Extensions as ConfigurationExtensions, ConfigurationScope, IConfigurati
|
||||
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
|
||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { McpAccessValue, McpAutoStartValue, mcpAccessConfig, mcpAutoStartConfig, mcpGalleryServiceUrlConfig } from '../../../../platform/mcp/common/mcpManagement.js';
|
||||
import { McpAccessValue, McpAutoStartValue, mcpAccessConfig, mcpAutoStartConfig, mcpGalleryServiceEnablementConfig, mcpGalleryServiceUrlConfig } from '../../../../platform/mcp/common/mcpManagement.js';
|
||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||
import { EditorPaneDescriptor, IEditorPaneRegistry } from '../../../browser/editor.js';
|
||||
import { Extensions, IConfigurationMigrationRegistry } from '../../../common/configuration.js';
|
||||
@@ -456,6 +456,13 @@ configurationRegistry.registerConfiguration({
|
||||
default: Object.fromEntries(allDiscoverySources.map(k => [k, false])),
|
||||
markdownDescription: nls.localize('mcp.discovery.enabled', "Configures discovery of Model Context Protocol servers from configuration from various other applications."),
|
||||
},
|
||||
[mcpGalleryServiceEnablementConfig]: {
|
||||
type: 'boolean',
|
||||
default: false,
|
||||
tags: ['preview'],
|
||||
description: nls.localize('chat.mcp.gallery.enabled', "Enables the default Marketplace for Model Context Protocol (MCP) servers."),
|
||||
included: product.quality === 'stable'
|
||||
},
|
||||
[mcpGalleryServiceUrlConfig]: {
|
||||
type: 'string',
|
||||
description: nls.localize('mcp.gallery.serviceUrl', "Configure the MCP Gallery service URL to connect to"),
|
||||
|
||||
@@ -33,7 +33,7 @@ import { McpSamplingService } from '../common/mcpSamplingService.js';
|
||||
import { McpService } from '../common/mcpService.js';
|
||||
import { IMcpElicitationService, IMcpSamplingService, IMcpService, IMcpWorkbenchService } from '../common/mcpTypes.js';
|
||||
import { McpAddContextContribution } from './mcpAddContextContribution.js';
|
||||
import { AddConfigurationAction, BrowseMcpServersPageCommand, EditStoredInput, ListMcpServerCommand, McpBrowseCommand, McpBrowseResourcesCommand, McpConfigureSamplingModels, McpConfirmationServerOptionsCommand, MCPServerActionRendering, McpServerOptionsCommand, McpStartPromptingServerCommand, OpenRemoteUserMcpResourceCommand, OpenUserMcpResourceCommand, OpenWorkspaceFolderMcpResourceCommand, OpenWorkspaceMcpResourceCommand, RemoveStoredInput, ResetMcpCachedTools, ResetMcpTrustCommand, RestartServer, ShowConfiguration, ShowInstalledMcpServersCommand, ShowOutput, StartServer, StopServer } from './mcpCommands.js';
|
||||
import { AddConfigurationAction, EditStoredInput, ListMcpServerCommand, McpBrowseCommand, McpBrowseResourcesCommand, McpConfigureSamplingModels, McpConfirmationServerOptionsCommand, MCPServerActionRendering, McpServerOptionsCommand, McpStartPromptingServerCommand, OpenRemoteUserMcpResourceCommand, OpenUserMcpResourceCommand, OpenWorkspaceFolderMcpResourceCommand, OpenWorkspaceMcpResourceCommand, RemoveStoredInput, ResetMcpCachedTools, ResetMcpTrustCommand, RestartServer, ShowConfiguration, ShowInstalledMcpServersCommand, ShowOutput, StartServer, StopServer } from './mcpCommands.js';
|
||||
import { McpDiscovery } from './mcpDiscovery.js';
|
||||
import { McpElicitationService } from './mcpElicitationService.js';
|
||||
import { McpLanguageFeatures } from './mcpLanguageFeatures.js';
|
||||
@@ -76,7 +76,6 @@ registerAction2(ShowOutput);
|
||||
registerAction2(RestartServer);
|
||||
registerAction2(ShowConfiguration);
|
||||
registerAction2(McpBrowseCommand);
|
||||
registerAction2(BrowseMcpServersPageCommand);
|
||||
registerAction2(OpenUserMcpResourceCommand);
|
||||
registerAction2(OpenRemoteUserMcpResourceCommand);
|
||||
registerAction2(OpenWorkspaceMcpResourceCommand);
|
||||
|
||||
@@ -32,11 +32,8 @@ import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextke
|
||||
import { IFileService } from '../../../../platform/files/common/files.js';
|
||||
import { nativeHoverDelegate } from '../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService, ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { McpGalleryManifestStatus } from '../../../../platform/mcp/common/mcpGalleryManifest.js';
|
||||
import { mcpAutoStartConfig, McpAutoStartValue } from '../../../../platform/mcp/common/mcpManagement.js';
|
||||
import { observableConfigValue } from '../../../../platform/observable/common/platformObservableUtils.js';
|
||||
import { IOpenerService } from '../../../../platform/opener/common/opener.js';
|
||||
import { IProductService } from '../../../../platform/product/common/productService.js';
|
||||
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from '../../../../platform/quickinput/common/quickInput.js';
|
||||
import { StorageScope } from '../../../../platform/storage/common/storage.js';
|
||||
import { defaultCheckboxStyles } from '../../../../platform/theme/browser/defaultStyles.js';
|
||||
@@ -65,7 +62,7 @@ import { TEXT_FILE_EDITOR_ID } from '../../files/common/files.js';
|
||||
import { McpCommandIds } from '../common/mcpCommandIds.js';
|
||||
import { McpContextKeys } from '../common/mcpContextKeys.js';
|
||||
import { IMcpRegistry } from '../common/mcpRegistryTypes.js';
|
||||
import { HasInstalledMcpServersContext, IMcpSamplingService, IMcpServer, IMcpServerStartOpts, IMcpService, InstalledMcpServersViewId, LazyCollectionState, McpCapability, McpCollectionDefinition, McpConnectionState, McpDefinitionReference, mcpPromptPrefix, McpServerCacheState, McpServersGalleryStatusContext, McpStartServerInteraction } from '../common/mcpTypes.js';
|
||||
import { HasInstalledMcpServersContext, IMcpSamplingService, IMcpServer, IMcpServerStartOpts, IMcpService, InstalledMcpServersViewId, LazyCollectionState, McpCapability, McpCollectionDefinition, McpConnectionState, McpDefinitionReference, mcpPromptPrefix, McpServerCacheState, McpStartServerInteraction } from '../common/mcpTypes.js';
|
||||
import { McpAddConfigurationCommand } from './mcpCommandsAddConfiguration.js';
|
||||
import { McpResourceQuickAccess, McpResourceQuickPick } from './mcpResourceQuickAccess.js';
|
||||
import './media/mcpServerAction.css';
|
||||
@@ -848,11 +845,17 @@ export class McpBrowseCommand extends Action2 {
|
||||
super({
|
||||
id: McpCommandIds.Browse,
|
||||
title: localize2('mcp.command.browse', "MCP Servers"),
|
||||
tooltip: localize2('mcp.command.browse.tooltip', "Browse MCP Servers"),
|
||||
category,
|
||||
icon: Codicon.globe,
|
||||
menu: [{
|
||||
id: extensionsFilterSubMenu,
|
||||
group: '1_predefined',
|
||||
order: 1,
|
||||
}, {
|
||||
id: MenuId.ViewTitle,
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', InstalledMcpServersViewId)),
|
||||
group: 'navigation',
|
||||
}],
|
||||
});
|
||||
}
|
||||
@@ -865,32 +868,11 @@ export class McpBrowseCommand extends Action2 {
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: McpCommandIds.Browse,
|
||||
title: localize2('mcp.command.browse.mcp', "Browse Servers"),
|
||||
title: localize2('mcp.command.browse.mcp', "Browse MCP Servers"),
|
||||
category
|
||||
},
|
||||
});
|
||||
|
||||
export class BrowseMcpServersPageCommand extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: McpCommandIds.BrowsePage,
|
||||
title: localize2('mcp.command.open', "Browse MCP Servers"),
|
||||
icon: Codicon.globe,
|
||||
menu: [{
|
||||
id: MenuId.ViewTitle,
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.equals('view', InstalledMcpServersViewId), McpServersGalleryStatusContext.isEqualTo(McpGalleryManifestStatus.Unavailable)),
|
||||
group: 'navigation',
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
async run(accessor: ServicesAccessor) {
|
||||
const productService = accessor.get(IProductService);
|
||||
const openerService = accessor.get(IOpenerService);
|
||||
return openerService.open(productService.quality === 'insider' ? 'https://code.visualstudio.com/insider/mcp' : 'https://code.visualstudio.com/mcp');
|
||||
}
|
||||
}
|
||||
|
||||
export class ShowInstalledMcpServersCommand extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
|
||||
@@ -12,7 +12,7 @@ import { combinedDisposable, Disposable, DisposableStore, dispose, IDisposable,
|
||||
import { DelayedPagedModel, IPagedModel, PagedModel } from '../../../../base/common/paging.js';
|
||||
import { localize, localize2 } from '../../../../nls.js';
|
||||
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
|
||||
import { ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { ContextKeyDefinedExpr, ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
|
||||
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
|
||||
import { IHoverService } from '../../../../platform/hover/browser/hover.js';
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
@@ -24,15 +24,15 @@ import { IThemeService } from '../../../../platform/theme/common/themeService.js
|
||||
import { getLocationBasedViewColors } from '../../../browser/parts/views/viewPane.js';
|
||||
import { IViewletViewOptions } from '../../../browser/parts/views/viewsViewlet.js';
|
||||
import { IViewDescriptorService, IViewsRegistry, ViewContainerLocation, Extensions as ViewExtensions } from '../../../common/views.js';
|
||||
import { HasInstalledMcpServersContext, IMcpWorkbenchService, InstalledMcpServersViewId, IWorkbenchMcpServer, McpServerContainers, McpServerEnablementState, McpServerInstallState } from '../common/mcpTypes.js';
|
||||
import { HasInstalledMcpServersContext, IMcpWorkbenchService, InstalledMcpServersViewId, IWorkbenchMcpServer, McpServerContainers, McpServerEnablementState, McpServerInstallState, McpServersGalleryStatusContext } from '../common/mcpTypes.js';
|
||||
import { DropDownAction, InstallAction, InstallingLabelAction, ManageMcpServerAction, McpServerStatusAction } from './mcpServerActions.js';
|
||||
import { PublisherWidget, StarredWidget, McpServerIconWidget, McpServerHoverWidget, McpServerScopeBadgeWidget } from './mcpServerWidgets.js';
|
||||
import { ActionRunner, IAction, Separator } from '../../../../base/common/actions.js';
|
||||
import { IActionViewItemOptions } from '../../../../base/browser/ui/actionbar/actionViewItems.js';
|
||||
import { IAllowedMcpServersService } from '../../../../platform/mcp/common/mcpManagement.js';
|
||||
import { IAllowedMcpServersService, mcpGalleryServiceEnablementConfig, mcpGalleryServiceUrlConfig } from '../../../../platform/mcp/common/mcpManagement.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { ThemeIcon } from '../../../../base/common/themables.js';
|
||||
import { IProductService } from '../../../../platform/product/common/productService.js';
|
||||
|
||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||
import { IWorkbenchContribution } from '../../../common/contributions.js';
|
||||
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
|
||||
@@ -50,9 +50,11 @@ import { IWorkbenchLayoutService, Position } from '../../../services/layout/brow
|
||||
import { mcpServerIcon } from './mcpServerIcons.js';
|
||||
import { IPagedRenderer } from '../../../../base/browser/ui/list/listPaging.js';
|
||||
import { IMcpGalleryManifestService, McpGalleryManifestStatus } from '../../../../platform/mcp/common/mcpGalleryManifest.js';
|
||||
import { IPreferencesService } from '../../../services/preferences/common/preferences.js';
|
||||
import { ProductQualityContext } from '../../../../platform/contextkey/common/contextkeys.js';
|
||||
|
||||
export interface McpServerListViewOptions {
|
||||
showWelcomeOnEmpty?: boolean;
|
||||
showWelcome?: boolean;
|
||||
}
|
||||
|
||||
interface IQueryResult {
|
||||
@@ -82,9 +84,9 @@ export class McpServersListView extends AbstractExtensionsListView<IWorkbenchMcp
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
|
||||
@IOpenerService openerService: IOpenerService,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
@IMcpWorkbenchService private readonly mcpWorkbenchService: IMcpWorkbenchService,
|
||||
@IMcpGalleryManifestService protected readonly mcpGalleryManifestService: IMcpGalleryManifestService,
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
|
||||
) {
|
||||
super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, hoverService);
|
||||
@@ -186,9 +188,12 @@ export class McpServersListView extends AbstractExtensionsListView<IWorkbenchMcp
|
||||
this.input = undefined;
|
||||
}
|
||||
|
||||
this.input = await this.query(query.trim());
|
||||
if (this.mpcViewOptions.showWelcome) {
|
||||
this.input = { model: new PagedModel([]), disposables: new DisposableStore(), showWelcomeContent: true };
|
||||
} else {
|
||||
this.input = await this.query(query.trim());
|
||||
}
|
||||
|
||||
this.input.showWelcomeContent = !!this.mpcViewOptions.showWelcomeOnEmpty && this.mcpGalleryManifestService.mcpGalleryManifestStatus === McpGalleryManifestStatus.Unavailable && this.input.model.length === 0;
|
||||
this.renderInput();
|
||||
|
||||
if (this.input.onDidChangeModel) {
|
||||
@@ -197,7 +202,6 @@ export class McpServersListView extends AbstractExtensionsListView<IWorkbenchMcp
|
||||
return;
|
||||
}
|
||||
this.input.model = model;
|
||||
this.input.showWelcomeContent = !!this.mpcViewOptions.showWelcomeOnEmpty && this.mcpGalleryManifestService.mcpGalleryManifestStatus === McpGalleryManifestStatus.Unavailable && this.input.model.length === 0;
|
||||
this.renderInput();
|
||||
}));
|
||||
}
|
||||
@@ -232,7 +236,7 @@ export class McpServersListView extends AbstractExtensionsListView<IWorkbenchMcp
|
||||
|
||||
const description = dom.append(welcomeContent, dom.$('.mcp-welcome-description'));
|
||||
const markdownResult = this._register(renderMarkdown(new MarkdownString(
|
||||
localize('mcp.welcome.descriptionWithLink', "Extend agent mode by installing MCP servers to bring extra tools for connecting to databases, invoking APIs and performing specialized tasks."),
|
||||
localize('mcp.welcome.descriptionWithLink', "Browse and install MCP servers directly from VS Code to extend agent mode with extra tools for connecting to databases, invoking APIs and performing specialized tasks."),
|
||||
{ isTrusted: true }
|
||||
), {
|
||||
actionHandler: (content: string) => {
|
||||
@@ -241,15 +245,16 @@ export class McpServersListView extends AbstractExtensionsListView<IWorkbenchMcp
|
||||
}));
|
||||
description.appendChild(markdownResult.element);
|
||||
|
||||
// Browse button
|
||||
const buttonContainer = dom.append(welcomeContent, dom.$('.mcp-welcome-button-container'));
|
||||
const button = this._register(new Button(buttonContainer, {
|
||||
title: localize('mcp.welcome.browseButton', "Browse MCP Servers"),
|
||||
title: localize('mcp.welcome.enableGalleryButton', "Enable MCP Servers Marketplace"),
|
||||
...defaultButtonStyles
|
||||
}));
|
||||
button.label = localize('mcp.welcome.browseButton', "Browse MCP Servers");
|
||||
button.label = localize('mcp.welcome.enableGalleryButton', "Enable MCP Servers Marketplace");
|
||||
|
||||
this._register(button.onDidClick(() => this.openerService.open(URI.parse(this.productService.quality === 'insider' ? 'https://code.visualstudio.com/insider/mcp' : 'https://code.visualstudio.com/mcp'))));
|
||||
this._register(button.onDidClick(() => this.preferencesService.openSettings({
|
||||
query: `@id:${mcpGalleryServiceEnablementConfig}`,
|
||||
})));
|
||||
}
|
||||
|
||||
private async query(query: string): Promise<IQueryResult> {
|
||||
@@ -443,7 +448,7 @@ export class McpServersViewsContribution extends Disposable implements IWorkbenc
|
||||
{
|
||||
id: InstalledMcpServersViewId,
|
||||
name: localize2('mcp-installed', "MCP Servers - Installed"),
|
||||
ctorDescriptor: new SyncDescriptor(McpServersListView, [{ showWelcomeOnEmpty: false }]),
|
||||
ctorDescriptor: new SyncDescriptor(McpServersListView, [{}]),
|
||||
when: ContextKeyExpr.and(DefaultViewsContext, HasInstalledMcpServersContext),
|
||||
weight: 40,
|
||||
order: 4,
|
||||
@@ -452,8 +457,8 @@ export class McpServersViewsContribution extends Disposable implements IWorkbenc
|
||||
{
|
||||
id: 'workbench.views.mcp.default.marketplace',
|
||||
name: localize2('mcp', "MCP Servers"),
|
||||
ctorDescriptor: new SyncDescriptor(DefaultBrowseMcpServersView, [{ showWelcomeOnEmpty: true }]),
|
||||
when: ContextKeyExpr.and(DefaultViewsContext, HasInstalledMcpServersContext.toNegated(), ChatContextKeys.Setup.hidden.negate()),
|
||||
ctorDescriptor: new SyncDescriptor(DefaultBrowseMcpServersView, [{}]),
|
||||
when: ContextKeyExpr.and(DefaultViewsContext, HasInstalledMcpServersContext.toNegated(), ChatContextKeys.Setup.hidden.negate(), McpServersGalleryStatusContext.isEqualTo(McpGalleryManifestStatus.Available), ContextKeyExpr.or(ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceUrlConfig}`), ProductQualityContext.notEqualsTo('stable'), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceEnablementConfig}`))),
|
||||
weight: 40,
|
||||
order: 4,
|
||||
canToggleVisibility: true
|
||||
@@ -461,8 +466,23 @@ export class McpServersViewsContribution extends Disposable implements IWorkbenc
|
||||
{
|
||||
id: 'workbench.views.mcp.marketplace',
|
||||
name: localize2('mcp', "MCP Servers"),
|
||||
ctorDescriptor: new SyncDescriptor(McpServersListView, [{ showWelcomeOnEmpty: true }]),
|
||||
when: ContextKeyExpr.and(SearchMcpServersContext),
|
||||
ctorDescriptor: new SyncDescriptor(McpServersListView, [{}]),
|
||||
when: ContextKeyExpr.and(SearchMcpServersContext, McpServersGalleryStatusContext.isEqualTo(McpGalleryManifestStatus.Available), ContextKeyExpr.or(ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceUrlConfig}`), ProductQualityContext.notEqualsTo('stable'), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceEnablementConfig}`))),
|
||||
},
|
||||
{
|
||||
id: 'workbench.views.mcp.default.welcomeView',
|
||||
name: localize2('mcp', "MCP Servers"),
|
||||
ctorDescriptor: new SyncDescriptor(DefaultBrowseMcpServersView, [{ showWelcome: true }]),
|
||||
when: ContextKeyExpr.and(DefaultViewsContext, HasInstalledMcpServersContext.toNegated(), ChatContextKeys.Setup.hidden.negate(), McpServersGalleryStatusContext.isEqualTo(McpGalleryManifestStatus.Available), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceUrlConfig}`).negate(), ProductQualityContext.isEqualTo('stable'), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceEnablementConfig}`).negate()),
|
||||
weight: 40,
|
||||
order: 4,
|
||||
canToggleVisibility: false
|
||||
},
|
||||
{
|
||||
id: 'workbench.views.mcp.welcomeView',
|
||||
name: localize2('mcp', "MCP Servers"),
|
||||
ctorDescriptor: new SyncDescriptor(McpServersListView, [{ showWelcome: true }]),
|
||||
when: ContextKeyExpr.and(SearchMcpServersContext, McpServersGalleryStatusContext.isEqualTo(McpGalleryManifestStatus.Available), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceUrlConfig}`).negate(), ProductQualityContext.isEqualTo('stable'), ContextKeyDefinedExpr.create(`config.${mcpGalleryServiceEnablementConfig}`).negate()),
|
||||
}
|
||||
], VIEW_CONTAINER);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user