mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46: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;
|
cfg = config.programs.opencode;
|
||||||
|
|
||||||
jsonFormat = pkgs.formats.json { };
|
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
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = with lib.maintainers; [ delafthi ];
|
meta.maintainers = with lib.maintainers; [ delafthi ];
|
||||||
|
|
@ -25,6 +54,20 @@ in
|
||||||
|
|
||||||
package = mkPackageOption pkgs "opencode" { nullable = true; };
|
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 {
|
settings = mkOption {
|
||||||
inherit (jsonFormat) type;
|
inherit (jsonFormat) type;
|
||||||
default = { };
|
default = { };
|
||||||
|
|
@ -147,7 +190,7 @@ in
|
||||||
Custom themes for opencode. The attribute name becomes the theme
|
Custom themes for opencode. The attribute name becomes the theme
|
||||||
filename, and the value is either:
|
filename, and the value is either:
|
||||||
- An attribute set, that is converted to a json
|
- 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.
|
Themes are stored in {file}`$XDG_CONFIG_HOME/opencode/themes/` directory.
|
||||||
Set `programs.opencode.settings.theme` to enable the custom theme.
|
Set `programs.opencode.settings.theme` to enable the custom theme.
|
||||||
See <https://opencode.ai/docs/themes/> for the documentation.
|
See <https://opencode.ai/docs/themes/> for the documentation.
|
||||||
|
|
@ -159,13 +202,21 @@ in
|
||||||
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||||
|
|
||||||
xdg.configFile = {
|
xdg.configFile = {
|
||||||
"opencode/config.json" = mkIf (cfg.settings != { }) {
|
"opencode/config.json" = mkIf (cfg.settings != { } || transformedMcpServers != { }) {
|
||||||
source = jsonFormat.generate "config.json" (
|
source =
|
||||||
{
|
let
|
||||||
"$schema" = "https://opencode.ai/config.json";
|
# Merge MCP servers: transformed servers + user settings, with user settings taking precedence
|
||||||
}
|
mergedMcpServers = transformedMcpServers // (cfg.settings.mcp or { });
|
||||||
// cfg.settings
|
# 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" = (
|
"opencode/AGENTS.md" = (
|
||||||
|
|
|
||||||
|
|
@ -11,4 +11,6 @@
|
||||||
opencode-mixed-content = ./mixed-content.nix;
|
opencode-mixed-content = ./mixed-content.nix;
|
||||||
opencode-themes-inline = ./themes-inline.nix;
|
opencode-themes-inline = ./themes-inline.nix;
|
||||||
opencode-themes-path = ./themes-path.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