Skip to content

Commit e52bb47

Browse files
authored
1 parent b84fb5b commit e52bb47

File tree

5 files changed

+23
-10
lines changed

5 files changed

+23
-10
lines changed

src/vs/workbench/api/browser/mainThreadMcp.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Severity from '../../../base/common/severity.js';
1313
import { URI, UriComponents } from '../../../base/common/uri.js';
1414
import * as nls from '../../../nls.js';
1515
import { IDialogService, IPromptButton } from '../../../platform/dialogs/common/dialogs.js';
16+
import { ExtensionIdentifier } from '../../../platform/extensions/common/extensions.js';
1617
import { LogLevel } from '../../../platform/log/common/log.js';
1718
import { IMcpMessageTransport, IMcpRegistry } from '../../contrib/mcp/common/mcpRegistryTypes.js';
1819
import { McpCollectionDefinition, McpConnectionState, McpServerDefinition, McpServerLaunch, McpServerTransportType } from '../../contrib/mcp/common/mcpTypes.js';
@@ -91,6 +92,7 @@ export class MainThreadMcp extends Disposable implements MainThreadMcpShape {
9192
const serverDefinitions = observableValue<readonly McpServerDefinition[]>('mcpServers', servers);
9293
const handle = this._mcpRegistry.registerCollection({
9394
...collection,
95+
source: new ExtensionIdentifier(collection.extensionId),
9496
resolveServerLanch: collection.canResolveLaunch ? (async def => {
9597
const r = await this._proxy.$resolveMcpLaunch(collection.id, def.label);
9698
return r ? McpServerLaunch.fromSerialized(r) : undefined;

src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ import { assertType } from '../../../../../base/common/types.js';
1212
import { generateUuid } from '../../../../../base/common/uuid.js';
1313
import { localize } from '../../../../../nls.js';
1414
import { ICommandService } from '../../../../../platform/commands/common/commands.js';
15+
import { ExtensionIdentifier } from '../../../../../platform/extensions/common/extensions.js';
1516
import { ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js';
1617
import { IQuickInputButton, IQuickInputService, IQuickPickItem, IQuickPickSeparator } from '../../../../../platform/quickinput/common/quickInput.js';
1718
import { IEditorService } from '../../../../services/editor/common/editorService.js';
18-
import { IExtensionsWorkbenchService } from '../../../extensions/common/extensions.js';
19+
import { ExtensionEditorTab, IExtensionsWorkbenchService } from '../../../extensions/common/extensions.js';
1920
import { McpCommandIds } from '../../../mcp/common/mcpCommandIds.js';
2021
import { IMcpRegistry } from '../../../mcp/common/mcpRegistryTypes.js';
21-
import { IMcpServer, IMcpService, McpConnectionState } from '../../../mcp/common/mcpTypes.js';
22+
import { IMcpServer, IMcpService, IMcpWorkbenchService, McpConnectionState, McpServerEditorTab } from '../../../mcp/common/mcpTypes.js';
2223
import { ILanguageModelToolsService, IToolData, ToolDataSource, ToolSet } from '../../common/languageModelToolsService.js';
2324
import { ConfigureToolSets } from '../tools/toolSetsContribution.js';
2425

@@ -59,8 +60,9 @@ export async function showToolsPicker(
5960
const mcpService = accessor.get(IMcpService);
6061
const mcpRegistry = accessor.get(IMcpRegistry);
6162
const commandService = accessor.get(ICommandService);
62-
const extensionWorkbenchService = accessor.get(IExtensionsWorkbenchService);
63+
const extensionsWorkbenchService = accessor.get(IExtensionsWorkbenchService);
6364
const editorService = accessor.get(IEditorService);
65+
const mcpWorkbenchService = accessor.get(IMcpWorkbenchService);
6466
const toolsService = accessor.get(ILanguageModelToolsService);
6567

6668
const mcpServerByTool = new Map<string, IMcpServer>();
@@ -88,7 +90,7 @@ export async function showToolsPicker(
8890

8991
const addMcpPick: CallbackPick = { type: 'item', label: localize('addServer', "Add MCP Server..."), iconClass: ThemeIcon.asClassName(Codicon.add), pickable: false, run: () => commandService.executeCommand(McpCommandIds.AddConfiguration) };
9092
const configureToolSetsPick: CallbackPick = { type: 'item', label: localize('configToolSet', "Configure Tool Sets..."), iconClass: ThemeIcon.asClassName(Codicon.gear), pickable: false, run: () => commandService.executeCommand(ConfigureToolSets.ID) };
91-
const addExpPick: CallbackPick = { type: 'item', label: localize('addExtension', "Install Extension..."), iconClass: ThemeIcon.asClassName(Codicon.add), pickable: false, run: () => extensionWorkbenchService.openSearch('@tag:language-model-tools') };
93+
const addExpPick: CallbackPick = { type: 'item', label: localize('addExtension', "Install Extension..."), iconClass: ThemeIcon.asClassName(Codicon.add), pickable: false, run: () => extensionsWorkbenchService.openSearch('@tag:language-model-tools') };
9294
const addPick: CallbackPick = {
9395
type: 'item', label: localize('addAny', "Add More Tools..."), iconClass: ThemeIcon.asClassName(Codicon.add), pickable: false, run: async () => {
9496
const pick = await quickPickService.pick(
@@ -143,7 +145,13 @@ export async function showToolsPicker(
143145
toolBuckets.set(key, bucket);
144146

145147
const collection = mcpRegistry.collections.get().find(c => c.id === mcpServer.collection.id);
146-
if (collection?.presentation?.origin) {
148+
if (collection?.source) {
149+
buttons.push({
150+
iconClass: ThemeIcon.asClassName(Codicon.settingsGear),
151+
tooltip: localize('configMcpCol', "Configure {0}", collection.label),
152+
action: () => collection.source ? collection.source instanceof ExtensionIdentifier ? extensionsWorkbenchService.open(collection.source.value, { tab: ExtensionEditorTab.Features, feature: 'mcp' }) : mcpWorkbenchService.open(collection.source, { tab: McpServerEditorTab.Configuration }) : undefined
153+
});
154+
} else if (collection?.presentation?.origin) {
147155
buttons.push({
148156
iconClass: ThemeIcon.asClassName(Codicon.settingsGear),
149157
tooltip: localize('configMcpCol', "Configure {0}", collection.label),

src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ export class ExtensionMcpDiscovery extends Disposable implements IMcpDiscovery {
9292
isCached: !!serverDefs,
9393
load: () => this._activateExtensionServers(coll.id),
9494
removed: () => extensionCollections.deleteAndDispose(id),
95-
}
95+
},
96+
source: collections.description.identifier
9697
});
9798

9899
extensionCollections.set(id, dispo);

src/vs/workbench/contrib/mcp/common/discovery/installedMcpServersDiscovery.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { URI } from '../../../../../base/common/uri.js';
99
import { ConfigurationTarget } from '../../../../../platform/configuration/common/configuration.js';
1010
import { StorageScope } from '../../../../../platform/storage/common/storage.js';
1111
import { IMcpRegistry } from '../mcpRegistryTypes.js';
12-
import { McpServerDefinition, McpServerTransportType, IMcpWorkbenchService, IMcpConfigPath } from '../mcpTypes.js';
12+
import { McpServerDefinition, McpServerTransportType, IMcpWorkbenchService, IMcpConfigPath, IWorkbenchMcpServer } from '../mcpTypes.js';
1313
import { IMcpDiscovery } from './mcpDiscovery.js';
1414
import { mcpConfigurationSection } from '../mcpConfiguration.js';
1515
import { posix as pathPosix, win32 as pathWin32, sep as pathSep } from '../../../../../base/common/path.js';
@@ -58,7 +58,7 @@ export class InstalledMcpServersDiscovery extends Disposable implements IMcpDisc
5858
private async sync(): Promise<void> {
5959
try {
6060
const remoteEnv = await this.remoteAgentService.getEnvironment();
61-
const collections = new Map<string, [IMcpConfigPath | undefined, McpServerDefinition[]]>();
61+
const collections = new Map<string, [IMcpConfigPath | undefined, McpServerDefinition[], IWorkbenchMcpServer]>();
6262
const mcpConfigPathInfos = new ResourceMap<Promise<IMcpConfigPath & { locations: Map<string, Location> } | undefined>>();
6363
for (const server of this.mcpWorkbenchService.local) {
6464
if (!server.local) {
@@ -81,7 +81,7 @@ export class InstalledMcpServersDiscovery extends Disposable implements IMcpDisc
8181

8282
let definitions = collections.get(collectionId);
8383
if (!definitions) {
84-
definitions = [mcpConfigPath, []];
84+
definitions = [mcpConfigPath, [], server];
8585
collections.set(collectionId, definitions);
8686
}
8787

@@ -135,7 +135,7 @@ export class InstalledMcpServersDiscovery extends Disposable implements IMcpDisc
135135
for (const [id, [mcpConfigPath, serverDefinitions]] of collections) {
136136
this.collectionDisposables.deleteAndDispose(id);
137137
this.collectionDisposables.set(id, this.mcpRegistry.registerCollection({
138-
id: id,
138+
id,
139139
label: mcpConfigPath?.label ?? '',
140140
presentation: {
141141
order: serverDefinitions[0]?.presentation?.order,

src/vs/workbench/contrib/mcp/common/mcpTypes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ export interface McpCollectionDefinition {
7171
removed?(): void;
7272
};
7373

74+
readonly source?: IWorkbenchMcpServer | ExtensionIdentifier;
75+
7476
readonly presentation?: {
7577
/** Sort order of the collection. */
7678
readonly order?: number;

0 commit comments

Comments
 (0)