fix(mcp): preserve user's enabled:false and apply disabled_mcps to all MCP sources

Commit 598a4389 refactored config-handler into separate modules but
dropped the disabledMcps parameter from loadMcpConfigs() and did not
handle the spread-order overwrite where .mcp.json MCPs (hardcoded
enabled:true) overwrote user's enabled:false from opencode.json.

Changes:
- Re-add disabledMcps parameter to loadMcpConfigs() in loader.ts
- Capture user's enabled:false MCPs before merge, restore after
- Pass disabled_mcps to loadMcpConfigs for .mcp.json filtering
- Delete disabled_mcps entries from final merged result
- Add 8 new tests covering both fixes
This commit is contained in:
edxeth
2026-02-10 15:26:17 +01:00
parent 260acdc140
commit 456bee9e10
4 changed files with 325 additions and 7 deletions
+44 -5
View File
@@ -3,19 +3,58 @@ import { loadMcpConfigs } from "../features/claude-code-mcp-loader";
import { createBuiltinMcps } from "../mcp";
import type { PluginComponents } from "./plugin-components-loader";
type McpEntry = Record<string, unknown>;
function captureUserDisabledMcps(
userMcp: Record<string, unknown> | undefined
): Set<string> {
const disabled = new Set<string>();
if (!userMcp) return disabled;
for (const [name, value] of Object.entries(userMcp)) {
if (
value &&
typeof value === "object" &&
"enabled" in value &&
(value as McpEntry).enabled === false
) {
disabled.add(name);
}
}
return disabled;
}
export async function applyMcpConfig(params: {
config: Record<string, unknown>;
pluginConfig: OhMyOpenCodeConfig;
pluginComponents: PluginComponents;
}): Promise<void> {
const disabledMcps = params.pluginConfig.disabled_mcps ?? [];
const userMcp = params.config.mcp as Record<string, unknown> | undefined;
const userDisabledMcps = captureUserDisabledMcps(userMcp);
const mcpResult = params.pluginConfig.claude_code?.mcp ?? true
? await loadMcpConfigs()
? await loadMcpConfigs(disabledMcps)
: { servers: {} };
params.config.mcp = {
...createBuiltinMcps(params.pluginConfig.disabled_mcps, params.pluginConfig),
...(params.config.mcp as Record<string, unknown>),
const merged = {
...createBuiltinMcps(disabledMcps, params.pluginConfig),
...(userMcp ?? {}),
...mcpResult.servers,
...params.pluginComponents.mcpServers,
};
} as Record<string, McpEntry>;
for (const name of userDisabledMcps) {
if (merged[name]) {
merged[name] = { ...merged[name], enabled: false };
}
}
const disabledSet = new Set(disabledMcps);
for (const name of disabledSet) {
delete merged[name];
}
params.config.mcp = merged;
}