mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 11:36:05 +01:00
opencode: add mcp module integration
This commit is contained in:
parent
083b20c1a0
commit
c740351870
6 changed files with 202 additions and 8 deletions
|
|
@ -16,6 +16,35 @@ let
|
|||
cfg = config.programs.opencode;
|
||||
|
||||
jsonFormat = pkgs.formats.json { };
|
||||
|
||||
transformMcpServer = name: server: {
|
||||
name = name;
|
||||
value = {
|
||||
enabled = !(server.disabled or false);
|
||||
}
|
||||
// (
|
||||
if server ? url then
|
||||
{
|
||||
type = "remote";
|
||||
url = server.url;
|
||||
}
|
||||
// (lib.optionalAttrs (server ? headers) { headers = server.headers; })
|
||||
else if server ? command then
|
||||
{
|
||||
type = "local";
|
||||
command = [ server.command ] ++ (server.args or [ ]);
|
||||
}
|
||||
// (lib.optionalAttrs (server ? env) { environment = server.env; })
|
||||
else
|
||||
{ }
|
||||
);
|
||||
};
|
||||
|
||||
transformedMcpServers =
|
||||
if cfg.enableMcpIntegration && config.programs.mcp.enable && config.programs.mcp.servers != { } then
|
||||
lib.listToAttrs (lib.mapAttrsToList transformMcpServer config.programs.mcp.servers)
|
||||
else
|
||||
{ };
|
||||
in
|
||||
{
|
||||
meta.maintainers = with lib.maintainers; [ delafthi ];
|
||||
|
|
@ -25,6 +54,20 @@ in
|
|||
|
||||
package = mkPackageOption pkgs "opencode" { nullable = true; };
|
||||
|
||||
enableMcpIntegration = mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to integrate the MCP servers config from
|
||||
{option}`programs.mcp.servers` into
|
||||
{option}`programs.opencode.settings.mcp`.
|
||||
|
||||
Note: Settings defined in {option}`programs.mcp.servers` are merged
|
||||
with {option}`programs.opencode.settings.mcp`, with OpenCode settings
|
||||
taking precedence.
|
||||
'';
|
||||
};
|
||||
|
||||
settings = mkOption {
|
||||
inherit (jsonFormat) type;
|
||||
default = { };
|
||||
|
|
@ -147,7 +190,7 @@ in
|
|||
Custom themes for opencode. The attribute name becomes the theme
|
||||
filename, and the value is either:
|
||||
- An attribute set, that is converted to a json
|
||||
- A path to a file conaining the content
|
||||
- A path to a file containing the content
|
||||
Themes are stored in {file}`$XDG_CONFIG_HOME/opencode/themes/` directory.
|
||||
Set `programs.opencode.settings.theme` to enable the custom theme.
|
||||
See <https://opencode.ai/docs/themes/> for the documentation.
|
||||
|
|
@ -159,13 +202,21 @@ in
|
|||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||
|
||||
xdg.configFile = {
|
||||
"opencode/config.json" = mkIf (cfg.settings != { }) {
|
||||
source = jsonFormat.generate "config.json" (
|
||||
{
|
||||
"$schema" = "https://opencode.ai/config.json";
|
||||
}
|
||||
// cfg.settings
|
||||
);
|
||||
"opencode/config.json" = mkIf (cfg.settings != { } || transformedMcpServers != { }) {
|
||||
source =
|
||||
let
|
||||
# Merge MCP servers: transformed servers + user settings, with user settings taking precedence
|
||||
mergedMcpServers = transformedMcpServers // (cfg.settings.mcp or { });
|
||||
# Merge all settings
|
||||
mergedSettings =
|
||||
cfg.settings // (lib.optionalAttrs (mergedMcpServers != { }) { mcp = mergedMcpServers; });
|
||||
in
|
||||
jsonFormat.generate "config.json" (
|
||||
{
|
||||
"$schema" = "https://opencode.ai/config.json";
|
||||
}
|
||||
// mergedSettings
|
||||
);
|
||||
};
|
||||
|
||||
"opencode/AGENTS.md" = (
|
||||
|
|
|
|||
|
|
@ -11,4 +11,6 @@
|
|||
opencode-mixed-content = ./mixed-content.nix;
|
||||
opencode-themes-inline = ./themes-inline.nix;
|
||||
opencode-themes-path = ./themes-path.nix;
|
||||
opencode-mcp-integration = ./mcp-integration.nix;
|
||||
opencode-mcp-integration-with-override = ./mcp-integration-with-override.nix;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"context7": {
|
||||
"enabled": true,
|
||||
"headers": {
|
||||
"CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}"
|
||||
},
|
||||
"type": "remote",
|
||||
"url": "https://mcp.context7.com/mcp"
|
||||
},
|
||||
"custom-server": {
|
||||
"enabled": true,
|
||||
"type": "remote",
|
||||
"url": "https://example.com"
|
||||
},
|
||||
"everything": {
|
||||
"command": [
|
||||
"custom-command"
|
||||
],
|
||||
"enabled": false,
|
||||
"type": "local"
|
||||
}
|
||||
},
|
||||
"model": "anthropic/claude-sonnet-4-20250514",
|
||||
"theme": "opencode"
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
programs.mcp = {
|
||||
enable = true;
|
||||
servers = {
|
||||
everything = {
|
||||
command = "npx";
|
||||
args = [
|
||||
"-y"
|
||||
"@modelcontextprotocol/server-everything"
|
||||
];
|
||||
};
|
||||
context7 = {
|
||||
url = "https://mcp.context7.com/mcp";
|
||||
headers = {
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.opencode = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
settings = {
|
||||
theme = "opencode";
|
||||
model = "anthropic/claude-sonnet-4-20250514";
|
||||
# User's custom MCP settings should override generated ones
|
||||
mcp = {
|
||||
everything = {
|
||||
enabled = false; # Override to disable
|
||||
command = [ "custom-command" ];
|
||||
type = "local";
|
||||
};
|
||||
custom-server = {
|
||||
enabled = true;
|
||||
type = "remote";
|
||||
url = "https://example.com";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/opencode/config.json
|
||||
assertFileContent home-files/.config/opencode/config.json \
|
||||
${./mcp-integration-with-override.json}
|
||||
'';
|
||||
}
|
||||
30
tests/modules/programs/opencode/mcp-integration.json
Normal file
30
tests/modules/programs/opencode/mcp-integration.json
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"context7": {
|
||||
"enabled": true,
|
||||
"headers": {
|
||||
"CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}"
|
||||
},
|
||||
"type": "remote",
|
||||
"url": "https://mcp.context7.com/mcp"
|
||||
},
|
||||
"disabled-server": {
|
||||
"command": [
|
||||
"echo",
|
||||
"test"
|
||||
],
|
||||
"enabled": false,
|
||||
"type": "local"
|
||||
},
|
||||
"everything": {
|
||||
"command": [
|
||||
"npx",
|
||||
"-y",
|
||||
"@modelcontextprotocol/server-everything"
|
||||
],
|
||||
"enabled": true,
|
||||
"type": "local"
|
||||
}
|
||||
}
|
||||
}
|
||||
36
tests/modules/programs/opencode/mcp-integration.nix
Normal file
36
tests/modules/programs/opencode/mcp-integration.nix
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
programs.mcp = {
|
||||
enable = true;
|
||||
servers = {
|
||||
everything = {
|
||||
command = "npx";
|
||||
args = [
|
||||
"-y"
|
||||
"@modelcontextprotocol/server-everything"
|
||||
];
|
||||
};
|
||||
context7 = {
|
||||
url = "https://mcp.context7.com/mcp";
|
||||
headers = {
|
||||
CONTEXT7_API_KEY = "{env:CONTEXT7_API_KEY}";
|
||||
};
|
||||
};
|
||||
disabled-server = {
|
||||
command = "echo";
|
||||
args = [ "test" ];
|
||||
disabled = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
programs.opencode = {
|
||||
enable = true;
|
||||
enableMcpIntegration = true;
|
||||
};
|
||||
|
||||
nmt.script = ''
|
||||
assertFileExists home-files/.config/opencode/config.json
|
||||
assertFileContent home-files/.config/opencode/config.json \
|
||||
${./mcp-integration.json}
|
||||
'';
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue