claude-code: reject disabled mcp servers instead of dropping
Filtering disabled shared servers out of `.mcp.json` (#9457) collapsed "present but disabled" and "absent" into the same output, so a server set `enabled = false` for OpenCode could no longer remain present in Claude Code. `.mcp.json` has no per-server `enabled` field, but settings.json does via `disabledMcpjsonServers`. Keep disabled servers in `.mcp.json` and list them under `disabledMcpjsonServers` (merged with any user-set value). This honors the disabled intent without dropping the server, and covers both shared and Claude Code-native servers.
This commit is contained in:
parent
1ac720f007
commit
062581938b
4 changed files with 74 additions and 6 deletions
|
|
@ -38,10 +38,15 @@ let
|
|||
];
|
||||
};
|
||||
|
||||
transformedMcpServers = lib.optionalAttrs (cfg.enableMcpIntegration && config.programs.mcp.enable) (
|
||||
lib.mapAttrs transformMcpServer (
|
||||
lib.filterAttrs (_: isMcpServerEnabled) config.programs.mcp.servers
|
||||
)
|
||||
# Shared MCP servers participate only when both integrations are enabled.
|
||||
sharedMcpServers = lib.optionalAttrs (
|
||||
cfg.enableMcpIntegration && config.programs.mcp.enable
|
||||
) config.programs.mcp.servers;
|
||||
|
||||
transformedMcpServers = lib.mapAttrs transformMcpServer sharedMcpServers;
|
||||
|
||||
disabledMcpServerNames = lib.attrNames (
|
||||
lib.filterAttrs (_: server: !(isMcpServerEnabled server)) (sharedMcpServers // cfg.mcpServers)
|
||||
);
|
||||
|
||||
mkContentOption =
|
||||
|
|
@ -111,6 +116,12 @@ in
|
|||
Note: Settings defined in {option}`programs.mcp.servers` are merged
|
||||
with {option}`programs.claude-code.mcpServers`, with Claude Code servers
|
||||
taking precedence.
|
||||
|
||||
Servers marked disabled (via `enabled = false` or `disabled = true`)
|
||||
are still written to {file}`.mcp.json` but rejected through
|
||||
`disabledMcpjsonServers` in {file}`settings.json`, since Claude Code
|
||||
has no per-server `enabled` field. This keeps a disabled server
|
||||
present (and re-enableable) instead of dropping it.
|
||||
'';
|
||||
};
|
||||
|
||||
|
|
@ -701,7 +712,7 @@ in
|
|||
};
|
||||
|
||||
file = lib.mkMerge [
|
||||
(lib.mkIf (cfg.settings != { } || cfg.marketplaces != { }) {
|
||||
(lib.mkIf (cfg.settings != { } || cfg.marketplaces != { } || disabledMcpServerNames != [ ]) {
|
||||
"${cfg.configDir}/settings.json".source = jsonFormat.generate "claude-code-settings.json" (
|
||||
cfg.settings
|
||||
// {
|
||||
|
|
@ -710,6 +721,11 @@ in
|
|||
// optionalAttrs (cfg.marketplaces != { }) {
|
||||
extraKnownMarketplaces = lib.mapAttrs mkMarketplaceEntry cfg.marketplaces;
|
||||
}
|
||||
// optionalAttrs (disabledMcpServerNames != [ ]) {
|
||||
disabledMcpjsonServers = lib.unique (
|
||||
(cfg.settings.disabledMcpjsonServers or [ ]) ++ disabledMcpServerNames
|
||||
);
|
||||
}
|
||||
);
|
||||
})
|
||||
(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"mcpServers": {
|
||||
"customTransport": {
|
||||
"customOption": "value",
|
||||
"timeout": 5000,
|
||||
"type": "websocket",
|
||||
"url": "wss://example.com/mcp"
|
||||
},
|
||||
"database": {
|
||||
"args": [
|
||||
"-y",
|
||||
"@bytebase/dbhub",
|
||||
"--dsn",
|
||||
"postgresql://user:pass@localhost:5432/db"
|
||||
],
|
||||
"command": "npx",
|
||||
"env": {
|
||||
"DATABASE_URL": "postgresql://user:pass@localhost:5432/db"
|
||||
},
|
||||
"type": "stdio"
|
||||
},
|
||||
"disabled-server": {
|
||||
"args": [
|
||||
"test"
|
||||
],
|
||||
"command": "echo",
|
||||
"type": "stdio"
|
||||
},
|
||||
"filesystem": {
|
||||
"args": [
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-filesystem",
|
||||
"/tmp"
|
||||
],
|
||||
"command": "npx",
|
||||
"type": "stdio"
|
||||
},
|
||||
"github": {
|
||||
"type": "http",
|
||||
"url": "https://api.githubcopilot.com/mcp/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"$schema": "https://json.schemastore.org/claude-code-settings.json",
|
||||
"disabledMcpjsonServers": [
|
||||
"disabled-server"
|
||||
]
|
||||
}
|
||||
|
|
@ -79,7 +79,10 @@
|
|||
pluginDir=$(grep -o -- '--plugin-dir /nix/store/[^ ]*' "$wrapperPath")
|
||||
pluginDir="''${pluginDir#--plugin-dir }"
|
||||
assertFileContent "$pluginDir/.claude-plugin/plugin.json" ${./expected-plugin-manifest.json}
|
||||
assertFileContent "$pluginDir/.mcp.json" ${./expected-mcp-plugin.json}
|
||||
assertFileContent "$pluginDir/.mcp.json" ${./expected-mcp-integration-plugin.json}
|
||||
assertPathNotExists "$pluginDir/.lsp.json"
|
||||
|
||||
settingsPath="$TESTED/home-files/.claude/settings.json"
|
||||
assertFileContent "$settingsPath" ${./expected-mcp-settings.json}
|
||||
'';
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue