From 8440fc1c9a4c6320335bfce365e30a90563ffe96 Mon Sep 17 00:00:00 2001 From: Harald Hoyer Date: Tue, 27 May 2025 17:28:53 +0200 Subject: [PATCH] feat(nixos): add CrateDocs MCP service module - Introduced a NixOS module for configuring the CrateDocs MCP server. - Added options for enabling the service, setting the port, user, and group. - Configured a hardened systemd service with security restrictions. --- config.nix | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 1 + 2 files changed, 68 insertions(+) create mode 100644 config.nix diff --git a/config.nix b/config.nix new file mode 100644 index 0000000..5ac15ea --- /dev/null +++ b/config.nix @@ -0,0 +1,67 @@ +{ config, lib, pkgs, ... }: +let + cfg = config.services.cratedocs-mcp; +in +{ + options.services.cratedocs-mcp = { + enable = lib.mkEnableOption "CrateDocs MCP server"; + + port = lib.mkOption { + type = lib.types.int; + default = 3000; + description = "Port to listen on for HTTP/SSE server"; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "cratedocs-mcp"; + description = "User to run the service as"; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "cratedocs-mcp"; + description = "Group to run the service as"; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services.cratedocs-mcp = { + description = "CrateDocs MCP server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + ExecStart = "${lib.getExe pkgs.cratedocs-mcp} --port ${toString cfg.port}"; + Restart = "always"; + User = cfg.user; + Group = cfg.group; + DynamicUser = true; + StateDirectory = "cratedocs-mcp"; + CacheDirectory = "cratedocs-mcp"; + + # Security hardening + PrivateTmp = true; + ProtectSystem = "strict"; + ProtectHome = true; + NoNewPrivileges = true; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; + SystemCallFilter = "@system-service"; + SystemCallErrorNumber = "EPERM"; + }; + }; + }; +} \ No newline at end of file diff --git a/flake.nix b/flake.nix index 6fd8e11..75f39f3 100644 --- a/flake.nix +++ b/flake.nix @@ -42,5 +42,6 @@ default = cratedocs-mcp; }; }; + nixosModules.default = import ./config.nix; }; }