2.home-manager/tests/modules/programs/claude-code/mcp-integration.nix
Austin Horstman 4fcef56c15 claude-code: load MCP config via plugin dir
Claude Code rejects `--mcp-config` once the Home Manager wrapper injects
it around subcommands, which breaks commands like `claude mcp list`.
Claude Code 2.1.76 fixed `--plugin-dir` so it no longer consumes
following subcommands, so use that path for the generated MCP config
instead.

Generate a plugin directory with a manifest and `.mcp.json`, wrap
`claude` with `--plugin-dir` before user arguments, and snapshot that
wrapper directly in the tests. Keep the existing LSP support in the
generated plugin directory as well, and add coverage for the combined
MCP+LSP case plus the MCP integration merge path.

Signed-off-by: Austin Horstman <khaneliman12@gmail.com>
2026-03-18 23:58:36 -05:00

82 lines
2.1 KiB
Nix

{ config, ... }:
{
programs = {
claude-code = {
package = config.lib.test.mkStubPackage {
name = "claude-code";
buildScript = ''
mkdir -p $out/bin
touch $out/bin/claude
chmod 755 $out/bin/claude
'';
};
enable = true;
enableMcpIntegration = true;
mcpServers = {
github = {
type = "http";
url = "https://api.githubcopilot.com/mcp/";
};
filesystem = {
type = "stdio";
command = "npx";
args = [
"-y"
"@modelcontextprotocol/server-filesystem"
"/tmp"
];
};
};
};
mcp = {
enable = true;
servers = {
filesystem = {
type = "stdio";
command = "npx";
args = [
"-y"
"@modelcontextprotocol/server-filesystem"
"/other-tmp"
];
};
database = {
command = "npx";
args = [
"-y"
"@bytebase/dbhub"
"--dsn"
"postgresql://user:pass@localhost:5432/db"
];
env = {
DATABASE_URL = "postgresql://user:pass@localhost:5432/db";
};
};
customTransport = {
type = "websocket";
url = "wss://example.com/mcp";
customOption = "value";
timeout = 5000;
};
};
};
};
nmt.script = ''
wrapperPath="$TESTED/home-path/bin/claude"
normalizedWrapper=$(normalizeStorePaths "$wrapperPath")
assertFileContent "$normalizedWrapper" ${./expected-mcp-wrapper}
pluginDir=$(grep -o -- '--plugin-dir /nix/store/[^ ]*' "$wrapperPath")
pluginDir="''${pluginDir#--plugin-dir }"
assertFileContent "$pluginDir/.claude-plugin/plugin.json" ${./expected-plugin-manifest.json}
assertFileRegex "$pluginDir/.mcp.json" '"github"'
assertFileRegex "$pluginDir/.mcp.json" '"database"'
assertFileRegex "$pluginDir/.mcp.json" '"/tmp"'
(! grep -q -- '/other-tmp' "$pluginDir/.mcp.json")
assertPathNotExists "$pluginDir/.lsp.json"
'';
}