fix(coding-agent): filter disabled MCP completions

(cherry picked from commit 33886ad9691cf4d330cf1a645e19cae7681c8e94)
This commit is contained in:
can1357
2026-07-29 23:07:53 +02:00
parent 0617ff6e80
commit 2be93e7c84
3 changed files with 61 additions and 37 deletions
@@ -259,16 +259,11 @@ type MCPSearchParsed = {
* covers connections, pending connections, and discovered-but-not-yet-
* connected sources).
*
* When `includeDisabled` is true (the default), disabled-server entries
* are unioned in too — disabling a server only flips its config `enabled`
* flag, it doesn't remove the config entry, so a disabled server is still
* a valid `/mcp enable <name>` target. This also covers a discovered
* (non-config) server that was disabled: `loadAllMCPConfigs` filters it
* out of `getAllServerNames()`, but its name survives in
* `userConfig.disabledServers`. Callers whose target operation needs a
* live connection or config entry (`/mcp test`/`reconnect`/`reauth`/
* `unauth`) — which a disabled-only name can never satisfy — must pass
* `includeDisabled: false`.
* `includeDisabledOnly` controls names found only in
* `userConfig.disabledServers`, while `includeDisabledConfigured` controls
* config entries whose `enabled` flag is false. Both default to true because
* callers such as `/mcp list` need the complete union. Autocomplete callers
* must disable the categories their target operation cannot accept.
*
* This is the single source of truth for "every known server name": both
* `MCPCommandController#handleList()` and the `/mcp` slash-command argument
@@ -281,7 +276,8 @@ type MCPSearchParsed = {
export async function collectMcpServerNames(
ctx: InteractiveModeContext,
preloaded?: { userConfig: MCPConfigFile; projectConfig: MCPConfigFile },
includeDisabled = true,
includeDisabledOnly = true,
includeDisabledConfigured = true,
): Promise<string[]> {
let userConfig: MCPConfigFile;
let projectConfig: MCPConfigFile;
@@ -295,11 +291,17 @@ export async function collectMcpServerNames(
]);
}
const names = new Set<string>([
...Object.keys(userConfig.mcpServers ?? {}),
...Object.keys(projectConfig.mcpServers ?? {}),
...(includeDisabled ? (userConfig.disabledServers ?? []) : []),
]);
const names = new Set<string>(includeDisabledOnly ? (userConfig.disabledServers ?? []) : []);
const addConfiguredNames = (config: MCPConfigFile): void => {
const servers = config.mcpServers;
if (!servers) return;
for (const name in servers) {
const server = servers[name];
if (server && (includeDisabledConfigured || server.enabled !== false)) names.add(name);
}
};
addConfiguredNames(userConfig);
addConfiguredNames(projectConfig);
if (ctx.mcpManager) {
for (const name of ctx.mcpManager.getAllServerNames()) {
names.add(name);