Files
mcp-servers/docs/ssh-mcp.md
T
2026-10-22 17:12:12 +02:00

1.9 KiB

ssh-mcp Home Manager Module

homeManagerModules.ssh-mcp exposes services.ssh-mcp.instances.<name>. Each instance renders its own SSH host policy and known_hosts file under ~/.config/ssh-mcp/<instance>/.

Import

home-manager.sharedModules = [
  mcp-servers.homeManagerModules.ssh-mcp
];

Example

services.ssh-mcp.instances.admin = {
  enable = true;
  description = "Read-only systemd/journalctl over SSH";

  defaults = {
    user = "ai-agent";
    port = 22;
    platform = "linux";
    persistentSession = false;
    auth = {
      method = "key";
      key = "/run/secrets/ssh_ai_agent_key";
    };
  };

  hosts = {
    perlis.hostname = "100.64.0.4";
    ravel.hostname = "100.64.0.19";
  };

  knownHosts = {
    "100.64.0.4" = "ssh-ed25519 AAAA...";
    "100.64.0.19" = "ssh-ed25519 AAAA...";
  };

  settings = {
    enabledGroups = [ "host" "systemctl" ];
    allowLowAccessTools = false;
    allowDangerousTools = false;
    allowSudo = false;
  };
};

Gateway integration

Each instance exposes gatewayBackend, a plain attrset shaped like a services.mcp-gateway.backends.<name> entry:

services.mcp-gateway.backends = {
  ssh-mcp = config.services.ssh-mcp.instances.admin.gatewayBackend;
  ssh-mcp-media = config.services.ssh-mcp.instances.media.gatewayBackend;
};

Read-only paths are also available:

  • config.services.ssh-mcp.instances.<name>.hostsFile
  • config.services.ssh-mcp.instances.<name>.knownHostsFile

Notes

  • The default package is pkgs.python-ssh-mcp, so apply mcp-servers.overlays.default on the host or set package explicitly.
  • SSH_ENABLED_GROUPS is server-wide, not per-host. Run separate instances when different catalogs are needed.
  • Tier flags (allowLowAccessTools, allowDangerousTools, allowSudo) are hard security gates. Group filters only change what is advertised.
  • Empty path or command allowlists mean denied, not unrestricted.