add context keys and control tools command placement based on MCP servers being around

This commit is contained in:
Johannes 2025-03-11 20:15:46 +01:00
parent 0e01b1cc94
commit 7d2f5bb1ae
No known key found for this signature in database
GPG Key ID: 6DEF802A22264FCA
4 changed files with 51 additions and 2 deletions

View File

@ -2005,6 +2005,10 @@ export class RawContextKey<T extends ContextKeyValue> extends ContextKeyDefinedE
public notEqualsTo(value: any): ContextKeyExpression {
return ContextKeyNotEqualsExpr.create(this.key, value);
}
public greater(value: any): ContextKeyExpression {
return ContextKeyGreaterExpr.create(this.key, value);
}
}
export type ContextKeyValue = null | undefined | boolean | number | string

View File

@ -22,6 +22,7 @@ import { McpDiscovery } from './mcpDiscovery.js';
import { AttachMCPToolsAction, AttachMCPToolsActionRendering, ListMcpServerCommand, McpServerOptionsCommand } from './mcpCommands.js';
import { registerAction2 } from '../../../../platform/actions/common/actions.js';
import { McpContextKeysController } from '../common/mcpContextKeys.js';
registerSingleton(IMcpRegistry, McpRegistry, InstantiationType.Delayed);
registerSingleton(IMcpService, McpService, InstantiationType.Delayed);
@ -30,6 +31,7 @@ mcpDiscoveryRegistry.register(new SyncDescriptor(RemoteNativeMpcDiscovery));
mcpDiscoveryRegistry.register(new SyncDescriptor(ConfigMcpDiscovery));
registerWorkbenchContribution2('mcpDiscovery', McpDiscovery, WorkbenchPhase.AfterRestored);
registerWorkbenchContribution2('mcpContextKeys', McpContextKeysController, WorkbenchPhase.BlockRestore);
registerAction2(ListMcpServerCommand);
registerAction2(McpServerOptionsCommand);

View File

@ -25,6 +25,7 @@ import { IWorkbenchContribution } from '../../../common/contributions.js';
import { CHAT_CATEGORY } from '../../chat/browser/actions/chatActions.js';
import { ChatAgentLocation } from '../../chat/common/chatAgents.js';
import { ChatContextKeys } from '../../chat/common/chatContextKeys.js';
import { McpContextKeys } from '../common/mcpContextKeys.js';
import { IMcpService, IMcpTool, McpConnectionState } from '../common/mcpTypes.js';
// acroynms do not get localized
@ -178,9 +179,15 @@ export class AttachMCPToolsAction extends Action2 {
icon: Codicon.tools,
f1: false,
category: CHAT_CATEGORY,
precondition: ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession),
precondition: ContextKeyExpr.and(
McpContextKeys.serverCount.greater(0),
ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession)
),
menu: {
when: ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession),
when: ContextKeyExpr.and(
McpContextKeys.serverCount.greater(0),
ChatContextKeys.location.isEqualTo(ChatAgentLocation.EditingSession)
),
id: MenuId.ChatInputAttachmentToolbar,
group: 'navigation'
},

View File

@ -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 { Disposable } from '../../../../base/common/lifecycle.js';
import { autorun } from '../../../../base/common/observable.js';
import { localize } from '../../../../nls.js';
import { IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
import { IWorkbenchContribution } from '../../../common/contributions.js';
import { IMcpService } from './mcpTypes.js';
export namespace McpContextKeys {
export const serverCount = new RawContextKey<number>('mcp.serverCount', undefined, { type: 'number', description: localize('mcp.serverCount.description', "Context key that has the number of registered MCP servers") });
}
export class McpContextKeysController extends Disposable implements IWorkbenchContribution {
public static readonly ID = 'workbench.contrib.mcp.contextKey';
constructor(
@IMcpService mcpService: IMcpService,
@IContextKeyService contextKeyService: IContextKeyService
) {
super();
const ctxServerCount = McpContextKeys.serverCount.bindTo(contextKeyService);
this._store.add(autorun(r => {
ctxServerCount.set(mcpService.servers.read(r).length);
}));
}
}