From bb0c9a711c61319631d5b6acc3ce0d92c31b1555 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=BF=20corey?= Date: Thu, 5 Mar 2026 14:53:21 -0800 Subject: [PATCH 1/2] feat(glyph): Use MCPJungle as gateway --- hosts/glyph/services/default.nix | 1 + hosts/glyph/services/mcpjungle.nix | 35 +++++++++++++++++++++++++++++ modules/home/development.nix | 1 + overlays/custom-packages.nix | 3 +++ packages/mcpjungle/package.nix | 36 ++++++++++++++++++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 hosts/glyph/services/mcpjungle.nix create mode 100644 packages/mcpjungle/package.nix diff --git a/hosts/glyph/services/default.nix b/hosts/glyph/services/default.nix index 931b3e86..8265d595 100644 --- a/hosts/glyph/services/default.nix +++ b/hosts/glyph/services/default.nix @@ -8,6 +8,7 @@ ./dns.nix ./filebrowser.nix ./jellyfin.nix + ./mcpjungle.nix ./nfs.nix ./prometheus.nix ./samba.nix diff --git a/hosts/glyph/services/mcpjungle.nix b/hosts/glyph/services/mcpjungle.nix new file mode 100644 index 00000000..89c8dfcb --- /dev/null +++ b/hosts/glyph/services/mcpjungle.nix @@ -0,0 +1,35 @@ +{pkgs, ...}: { + users.users.mcpjungle = { + isSystemUser = true; + group = "mcpjungle"; + }; + users.groups.mcpjungle = {}; + + systemd.services.mcpjungle = { + description = "MCPJungle MCP Gateway"; + after = ["network.target"]; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + ExecStart = "${pkgs.mcpjungle}/bin/mcpjungle start --port 8090"; + User = "mcpjungle"; + Group = "mcpjungle"; + WorkingDirectory = "/var/lib/mcpjungle"; + StateDirectory = "mcpjungle"; + Restart = "on-failure"; + RestartSec = 5; + + # Hardening + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectHome = true; + ProtectSystem = "strict"; + ReadWritePaths = ["/var/lib/mcpjungle"]; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictSUIDSGID = true; + }; + }; +} diff --git a/modules/home/development.nix b/modules/home/development.nix index 63ec24ac..d5f87ee8 100644 --- a/modules/home/development.nix +++ b/modules/home/development.nix @@ -56,6 +56,7 @@ in { "Bash(git show *)" "Bash(git add *)" "Bash(git branch *)" + "Bash(gh api:*)" "Bash(mkdir *)" "Bash(* --version)" "Bash(* --help *)" diff --git a/overlays/custom-packages.nix b/overlays/custom-packages.nix index c8694841..9e7515bc 100644 --- a/overlays/custom-packages.nix +++ b/overlays/custom-packages.nix @@ -13,6 +13,9 @@ self: super: { # FileBrowser quantum fork filebrowser-quantum = super.callPackage ./../packages/filebrowser-quantum/package.nix {}; + # MCP Gateway + mcpjungle = super.callPackage ./../packages/mcpjungle/package.nix {}; + # Mochi spaced repetition software mochi = super.callPackage ./../packages/mochi/package.nix {}; diff --git a/packages/mcpjungle/package.nix b/packages/mcpjungle/package.nix new file mode 100644 index 00000000..03218a35 --- /dev/null +++ b/packages/mcpjungle/package.nix @@ -0,0 +1,36 @@ +{ + lib, + fetchFromGitHub, + buildGoModule, +}: +buildGoModule rec { + pname = "mcpjungle"; + version = "0.3.5"; + + src = fetchFromGitHub { + owner = "mcpjungle"; + repo = "mcpjungle"; + rev = version; + hash = "sha256-Q/ASyI6DygmYa284wk2pmYgVtPKRummnyh60v+Ri7bU="; + }; + + vendorHash = "sha256-pvCDf7Y+LiIOiZ0O/bJMzkf75o7HQbYpF01yFY4J9Yg="; + + # Tests require HOME to exist (tilde expansion); skip in sandbox + doCheck = false; + + env.CGO_ENABLED = 0; + + ldflags = [ + "-s" + "-w" + "-X github.com/mcpjungle/mcpjungle/pkg/version.Version=${version}" + ]; + + meta = with lib; { + description = "Self-hosted MCP Gateway"; + homepage = "https://github.com/mcpjungle/mcpjungle"; + license = licenses.mit; + mainProgram = "mcpjungle"; + }; +} From 46f44fe65b073be37641ce7350b78fa4106d6393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=9C=BF=20corey?= Date: Thu, 5 Mar 2026 16:26:44 -0800 Subject: [PATCH 2/2] enable mcpjungle via service module --- hosts/glyph/services/default.nix | 3 +- hosts/glyph/services/mcpjungle.nix | 35 ----------------- modules/nixos/default.nix | 1 + modules/nixos/llm/default.nix | 5 +++ modules/nixos/llm/mcpjungle.nix | 60 ++++++++++++++++++++++++++++++ 5 files changed, 68 insertions(+), 36 deletions(-) delete mode 100644 hosts/glyph/services/mcpjungle.nix create mode 100644 modules/nixos/llm/default.nix create mode 100644 modules/nixos/llm/mcpjungle.nix diff --git a/hosts/glyph/services/default.nix b/hosts/glyph/services/default.nix index 8265d595..2c5344c2 100644 --- a/hosts/glyph/services/default.nix +++ b/hosts/glyph/services/default.nix @@ -8,7 +8,6 @@ ./dns.nix ./filebrowser.nix ./jellyfin.nix - ./mcpjungle.nix ./nfs.nix ./prometheus.nix ./samba.nix @@ -60,4 +59,6 @@ enable = true; extraUpFlags = ["--ssh"]; }; + + services.mcpjungle.enable = true; } diff --git a/hosts/glyph/services/mcpjungle.nix b/hosts/glyph/services/mcpjungle.nix deleted file mode 100644 index 89c8dfcb..00000000 --- a/hosts/glyph/services/mcpjungle.nix +++ /dev/null @@ -1,35 +0,0 @@ -{pkgs, ...}: { - users.users.mcpjungle = { - isSystemUser = true; - group = "mcpjungle"; - }; - users.groups.mcpjungle = {}; - - systemd.services.mcpjungle = { - description = "MCPJungle MCP Gateway"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - - serviceConfig = { - ExecStart = "${pkgs.mcpjungle}/bin/mcpjungle start --port 8090"; - User = "mcpjungle"; - Group = "mcpjungle"; - WorkingDirectory = "/var/lib/mcpjungle"; - StateDirectory = "mcpjungle"; - Restart = "on-failure"; - RestartSec = 5; - - # Hardening - NoNewPrivileges = true; - PrivateDevices = true; - PrivateTmp = true; - ProtectHome = true; - ProtectSystem = "strict"; - ReadWritePaths = ["/var/lib/mcpjungle"]; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectControlGroups = true; - RestrictSUIDSGID = true; - }; - }; -} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 29e27779..dedc1b46 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -1,6 +1,7 @@ # NixOS-specific configuration modules { imports = [ + ./llm ./web ./filebrowser-quantum.nix ./users.nix diff --git a/modules/nixos/llm/default.nix b/modules/nixos/llm/default.nix new file mode 100644 index 00000000..f31ba072 --- /dev/null +++ b/modules/nixos/llm/default.nix @@ -0,0 +1,5 @@ +{ + imports = [ + ./mcpjungle.nix + ]; +} diff --git a/modules/nixos/llm/mcpjungle.nix b/modules/nixos/llm/mcpjungle.nix new file mode 100644 index 00000000..9800a600 --- /dev/null +++ b/modules/nixos/llm/mcpjungle.nix @@ -0,0 +1,60 @@ +{ + config, + pkgs, + lib, + ... +}: let + cfg = config.services.mcpjungle; +in { + options.services.mcpjungle = { + enable = lib.mkEnableOption "MCPJungle MCP Gateway"; + + package = lib.mkPackageOption pkgs "mcpjungle" {}; + + port = lib.mkOption { + type = lib.types.port; + default = 8090; + description = "Port for the HTTP server to listen on."; + }; + + openFirewall = lib.mkEnableOption "opening firewall ports for MCPJungle"; + }; + + config = lib.mkIf cfg.enable { + users.users.mcpjungle = { + isSystemUser = true; + group = "mcpjungle"; + }; + users.groups.mcpjungle = {}; + + systemd.services.mcpjungle = { + description = "MCPJungle MCP Gateway"; + after = ["network.target"]; + wantedBy = ["multi-user.target"]; + + serviceConfig = { + ExecStart = "${lib.getExe cfg.package} start --port ${toString cfg.port}"; + User = "mcpjungle"; + Group = "mcpjungle"; + WorkingDirectory = "/var/lib/mcpjungle"; + StateDirectory = "mcpjungle"; + Restart = "on-failure"; + RestartSec = 5; + + # Hardening + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + ProtectHome = true; + ProtectSystem = "strict"; + ReadWritePaths = ["/var/lib/mcpjungle"]; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectControlGroups = true; + RestrictSUIDSGID = true; + }; + }; + + networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [cfg.port]; + }; +}