78 lines
1.9 KiB
Markdown
78 lines
1.9 KiB
Markdown
# 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
|
|
|
|
```nix
|
|
home-manager.sharedModules = [
|
|
mcp-servers.homeManagerModules.ssh-mcp
|
|
];
|
|
```
|
|
|
|
## Example
|
|
|
|
```nix
|
|
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:
|
|
|
|
```nix
|
|
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.
|