mcpField
P
Python SSH MCP

Python SSH MCP

本地服务
github.com/Nightreaver开发工具821 周前更新

关于 Python SSH MCP

Python SSH MCP 是基于 FastMCP 的服务端,为大模型提供受控的多主机 SSH 访问。访问分级、路径限制和审计日志便于运维人员控制可用操作。

主要功能

  1. 01四级可配置访问权限
  2. 02十组 SSH 工具
  3. 03路径白名单与严格 known_hosts
  4. 04读取文件时遮蔽秘密信息
  5. 05Docker、systemctl 和软件包工具
  6. 06哈希审计日志与运维钩子

适用场景

  1. 01对主机执行只读 SSH 检查
  2. 02将文件操作限制在获准路径
  3. 03运行指定的 Docker 或 systemctl 操作
  4. 04在不暴露秘密的情况下检查配置

MCP 相关

该服务通过 stdio 或 HTTP 向 MCP 客户端提供 SSH 和主机管理工具。运维人员可配置开放的权限级别和工具组。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"python-ssh": {
"command": "uvx",
"args": [
"git+https://github.com/Nightreaver/python-ssh-mcp"
],
"env": {
"LOG_LEVEL": "<LOG_LEVEL>",
"ALLOW_LOW_ACCESS_TOOLS": "<ALLOW_LOW_ACCESS_TOOLS>",
"ALLOW_DANGEROUS_TOOLS": "<ALLOW_DANGEROUS_TOOLS>",
"ALLOW_SUDO": "<ALLOW_SUDO>"
}
}
}
}
启动命令uvx 'git+https://github.com/Nightreaver/python-ssh-mcp'
需要配置的环境变量
LOG_LEVEL
ALLOW_LOW_ACCESS_TOOLS
ALLOW_DANGEROUS_TOOLS
ALLOW_SUDO

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypigit+https://github.com/Nightreaver/python-ssh-mcp

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

Python SSH MCP

Python FastMCP License Tests

一个基于 Python 和 FastMCP 构建的 SSH MCP 服务。目标:让大模型能够通过 SSH 访问多台主机,同时对其可执行和不可执行的操作进行精细控制。配置选项刻意设计得非常丰富——如果你只需要一个 ssh_exec 工具,这些选项可能有些过头;但当你开始连接多台主机,或将 Agent 的访问限制到特定路径、命令和可见性级别时,它们就很有价值。如果这里没有你需要的工具,请提交 issue。

目前已实现: 10 个分组共 100 个工具,1649 项单元测试通过,另有 6 项基于 Docker 化 sshd 的集成测试,以及一个可选择启用的 tests/e2e/ 测试套件,可使用操作员实际的 hosts.toml 测试每个工具。默认严格使用 known_hosts;所有涉及路径的工具均受路径允许列表约束;审计日志使用 SHA-256 哈希;支持操作员自行接入钩子。提供密钥脱敏策略,让大模型能够读取配置文件而看不到其中的密钥(使用 HMAC-SHA256 哈希标记;redact_paths_globs 支持 block/warn/audit_only 绕过模式)。5 个涉及路径的 sudo 级别工具在 sudo 下也遵循路径策略(read/read_redacted/write/edit/sftp_list)。在 upload/deploy/download/sudo_write 上提供本地磁盘流式传输模式,让大文件绕过大模型的 base64 通道。大多数工具返回带类型的 Pydantic 结果,使 MCP 客户端在 tools/list 中看到实际的 schema(而非通用的 object);少数确实会生成合并或双峰负载的工具仍使用 dict[str, Any],并在函数处说明原因。全面支持 POSIX SSH 目标;Windows SSH 目标支持 SFTP、文件操作以及通过 PowerShell -EncodedCommand 实现的 ssh_file_hash(参见 ADR-0023);可通过 SSH_DOCKER_CMD / 每台主机的 docker_cmd 将 Docker CLI 替换为 Podman。

目录

本文内容:

快速开始

  • 安装 python-ssh-mcp
  • 编写你的第一条 hosts.toml 配置(操作演示 §3)
  • 设置你的 MCP 客户端(Claude Desktop、Claude Code、Cursor 等)
  • 让大模型对目标主机运行 ssh_host_ping——端到端验证 Agent、known_hosts 和连接池
  • 启用所需的级别标志(ALLOW_LOW_ACCESS_TOOLS、ALLOW_DANGEROUS_TOOLS、ALLOW_SUDO),即可解锁文件操作、执行命令和 sudo——参见 CONFIGURATION.md → 访问级别

CONFIGURATION.md — 配置更多主机、访问级别、允许列表/阻止列表、工具分组、Docker/Podman、每台主机的 SSH 身份、known_hosts 管理以及 sudo。 ADVANCED.md — 操作手册(FastMCP Skills)、钩子、可观测性、测试、密钥轮换、架构和贡献指南。

功能

  • 符合 MCP 规范的服务,通过 stdio 暴露 SSH(也可根据需要使用 HTTP);传输层直接使用 MCP,无需适配层。
  • 四级访问模型——read / low-access / dangerous / sudo。每个级别都通过独立的环境标志切换,并由 FastMCP Visibility 转换强制执行。默认:只读。
  • 十个与访问级别正交的工具组(host、session、sftp-read、file-ops、exec、sudo、shell、docker、systemctl、pkg)。SSH_ENABLED_GROUPS 可将目录精简到特定助手实际需要的内容。
  • 100 个工具:完整的逐工具参考请参阅 TOOLS.md。亮点:
    • 只读探测(ping、主机信息、磁盘使用情况、进程、告警、已知主机验证、用户信息、主机备注、服务器信息)
    • mcp://ssh-mcp/server-info 资源 + ssh_server_info 回退工具——服务器身份 + 功能范围,让大模型(或操作员)无需搜索目录即可自行了解“这是哪个版本的服务器 / 解锁了哪些访问级别 / 有多少工具可见”(v1.5.0)
    • SFTP 读取(list、stat、download、find、file_hash),并通过远程 realpath 限制路径
    • ssh_read_redacted——读取配置文件(.env、.yml 等)时,将机密替换为内联 HMAC-SHA256 哈希标记,让大模型获取结构信息,但绝不会看到明文(v1.4.0)
    • 低权限文件操作(cp、mv、mkdir、delete、delete_folder、edit、patch、upload、deploy、link、transfer)——优先使用 SFTP,并采用原子写入。upload/deploy/sftp_download 支持使用 local_path= 流式传输大文件,无需经过 base64 往返(v1.3.0)
    • Exec 级别支持逐次调用超时、流式变体、跨主机广播,以及默认启用的速查表,可识别 cat/tee/sudo cat/… 并转用相应的原生工具
    • Sudo 级别——ssh_sudo_exec 加上五个 sudo 级别的路径工具(ssh_sudo_read、_read_redacted、_write、_edit、_sftp_list),确保 root 所有的文件仍受路径策略约束,而不是通过原始 sudo cat 绕过策略(v1.4.0)。密码通过 stdin 传递,绝不放入 argv;启动时会直接拒绝环境变量中的密码
    • 27 个 Docker 工具(ps、logs、inspect、stats、events、system_df、images、volumes、compose up/down/logs/…、容器生命周期管理、exec、run、prune)
    • 17 个 systemctl 工具(读取 + 生命周期变更)以及 8 个 journalctl/list 辅助工具
    • 9 个 APT/软件包工具——读取(apt_list、apt_search、apt_show、apt_show_holds)+ 变更(apt_install、apt_upgrade、apt_remove、apt_autoremove、apt_mark)。非 Debian 主机会清晰地返回 PlatformNotSupported
    • 支持跟踪当前工作目录的持久 Shell 会话(无远程 PTY,使用哨兵标记跟踪状态)
  • 严格的 known_hosts——不自动接受密钥;未知密钥或不匹配的密钥都会导致操作失败。
  • 所有操作均受路径限制——每个涉及路径的工具都会通过远程 realpath(Windows 上使用 SFTP realpath)规范化路径并检查允许列表,同时允许使用 restricted_paths 为敏感区域设置例外。
  • hosts.toml 中的按主机策略——用户、密钥、允许列表、sudo 模式、平台、代理链、告警阈值、持久会话退出选项。
  • 支持将 Windows 作为 SSH 目标,用于 SFTP + 文件操作(参阅 ADR-0023);仅支持 POSIX 的工具会拒绝 Windows 目标,并清晰地通过 PlatformNotSupported 指明缺少的功能。
  • 审计日志——每次工具调用(所有访问级别)记录一行 JSON;路径/命令使用 SHA-256 哈希,error 字段仅记录异常类(完整文本仅在本地 DEBUG 级别保留)。
  • 操作员钩子:通过 SSH_HOOKS_MODULE 导入任意模块,以处理 STARTUP / SHUTDOWN / PRE_TOOL_CALL / POST_TOOL_CALL 事件。每个钩子都有超时上限,并隔离异常;待处理任务堆积时会发出积压警告。
  • 通过 FastMCP Skills 提供运行手册——每个工具都有对应的 SKILL.md 文件,按需为大模型提供限定范围的操作指南。
  • BM25 工具搜索(可选)——当 50 个以上的 schema 开始占用过多上下文时,以 search_tools + call_tool 取代 tools/list。
  • 启动时记录工具目录概览(按访问级别和工具组统计数量),让操作员准确了解将向大模型提供哪些工具。

安装

Python SSH MCP 是一个标准的 PEP 621 Python 包(使用 hatchling 构建后端)。你可以使用 自己偏好的安装器;推荐使用 uv:

uv sync                      # create .venv + install runtime deps + dev extras
uv run ssh-mcp               # start the server on stdio

# Or without syncing a venv first — build + run in an ephemeral environment:
uvx --from . ssh-mcp

# Plain pip also works (PEP 517):
pip install -e ".[dev]"
ssh-mcp

# FastMCP shortcuts (once the package is installed):
fastmcp dev inspector        # dev UI: MCP Inspector + hot reload; auto-finds fastmcp.json
fastmcp run                  # run the server; auto-finds fastmcp.json
fastmcp run -t http -p 8000  # HTTP transport instead of stdio

可选依赖组:

  • .[tasks] — 添加 Redis 客户端(redis>=5.0.0),用于生产环境任务后端。FastMCP tasks 运行时本身(默认使用内存,由 docket 提供)是通过 fastmcp[tasks] 引入的必需依赖,无论如何都会安装;只有在将 FASTMCP_DOCKET_URL 指向真实的 Redis 时,才需要安装此额外依赖(在生产环境中,当 ALLOW_DANGEROUS_TOOLS=true 时,重启可能导致任务丢失;参见 [_warn_task_backend](src/ssh_mcp/lifespan.py#L25)。
  • .[telemetry] — OpenTelemetry 发行版和 OTLP 导出器。
  • .[dev] — pytest、ruff、mypy。

MCP 客户端(Claude Desktop、Claude Code、Cursor)通过 fastmcp.json 发现服务。

客户端设置

每个主流 MCP 客户端都接受一段 JSON 配置,用于告知其如何启动服务。配置格式统一采用 mcpServers 对象;不同客户端之间只有文件路径不同。选择你的客户端,将配置粘贴到对应文件,然后重启客户端,以重新启动子进程。

提示: 如果项目中保留了 fastmcp.json 的 deployment.env 块,它会无条件覆盖客户端环境变量;请勿将分层标志放入该块,而应通过客户端配置或 .env 设置。如果代码变更后客户端似乎仍在使用过期的子进程,请参见故障排除——大多数客户端会启动并管理服务子进程,因此仅在终端侧重启并不足够。

基础配置(适用于 Claude Desktop、Cursor、Windsurf、Kilocode——大多数客户端都使用这种格式):

{
  "mcpServers": {
    "ssh-mcp": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/Nightreaver/python-ssh-mcp", "ssh-mcp"],
      "env": {
        "LOG_LEVEL": "INFO",
        "ALLOW_LOW_ACCESS_TOOLS": "false",
        "ALLOW_DANGEROUS_TOOLS": "false",
        "ALLOW_SUDO": "false"
      }
    }
  }
}

uvx --from <path> ssh-mcp 会在由 uv 管理的临时环境中构建并运行服务;客户端无需持久化的 venv。 另一种方式:如果你已有一个将 fastmcp 加入 PATH 的 venv,可以将配置替换为 "command": "fastmcp"、"args": ["run", "<path-to-clone>/fastmcp.json"]。

授予助手相应能力时,逐步启用 ALLOW_* 标志。默认保持只读,并仅在需要时开启 exec/sudo 权限层。

Claude Desktop

配置文件:

  • macOS:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json
  • Linux:~/.config/Claude/claude_desktop_config.json

粘贴基础配置。完全退出 Claude Desktop(托盘图标 → 退出),然后重新启动——重新加载不会重新启动 MCP 子进程。

Claude Code

使用命令行,无需编辑 JSON:

claude mcp add --transport stdio ssh-mcp -- uvx --from git+https://github.com/Nightreaver/python-ssh-mcp ssh-mcp

如需控制作用范围:--scope user(全局)、--scope project(将 .mcp.json 提交到当前仓库)、--scope local(默认,仅限此项目)。环境变量可通过重复使用 --env KEY=VALUE 标志设置,也可以事后编辑 ~/.claude/mcp.json。

Cursor

配置文件:

  • 全局:~/.cursor/mcp.json
  • 每个工作区:<workspace>/.cursor/mcp.json

格式与基础配置中的 mcpServers 相同。Cursor 会在下次聊天会话时载入配置变更;无需完全重启。

VS Code(GitHub Copilot Chat / Agent Mode)

VS Code 的 MCP 支持(1.102+)使用略有不同的键。配置文件:

  • 每个工作区:<workspace>/.vscode/mcp.json
  • 全局用户设置:settings.json → "mcp.servers"

工作区 .vscode/mcp.json:

{
  "servers": {
    "ssh-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "git+https://github.com/Nightreaver/python-ssh-mcp", "ssh-mcp"],
      "env": {
        "LOG_LEVEL": "INFO",
        "ALLOW_LOW_ACCESS_TOOLS": "false",
        "ALLOW_DANGEROUS_TOOLS": "false",
        "ALLOW_SUDO": "false"
      }
    }
  }
}

请注意,顶层键是 servers(而非 mcpServers),且每个条目都带有 "type": "stdio" 标识。重新加载 VS Code 窗口(Developer: Reload Window)以重新启动子进程。

Windsurf(Codeium)

配置文件:~/.codeium/windsurf/mcp_config.json。格式与基础配置中的 mcpServers 相同。编辑后重启 Windsurf。

Kilocode

配置文件:~/.kilocode/mcp.json(或 Kilocode 安装目录中的对应文件——扩展文档列出了确切路径)。格式与基础配置中的 mcpServers 相同。编辑后重新加载 VS Code 窗口。

Continue.dev

配置文件:~/.continue/config.json。Continue 使用嵌套键:

{
  "experimental": {
    "modelContextProtocolServers": [
      {
        "transport": {
          "type": "stdio",
          "command": "uvx",
          "args": ["--from", "git+https://github.com/Nightreaver/python-ssh-mcp", "ssh-mcp"]
        }
      }
    ]
  }
}

注意:这里使用的是对象列表,而不是命名映射。环境变量应放在 transport 块中。

Zed

通过命令面板配置:assistant: configure context servers, 或编辑 ~/.config/zed/settings.json:

{
  "context_servers": {
    "ssh-mcp": {
      "source": "custom",
      "command": {
        "path": "uvx",
        "args": ["--from", "git+https://github.com/Nightreaver/python-ssh-mcp", "ssh-mcp"],
        "env": {}
      }
    }
  }
}
MCP Inspector(开发 UI)

在将服务接入实际客户端之前,可先调试服务:

fastmcp dev inspector

自动检测 fastmcp.json,启动附带实时 MCP Inspector 的 Web UI。源文件变更时会热重载。


演练 — 5 分钟内接入你的第一个主机

最快的路径:Agent 身份验证 + 一个主机 + 只读权限级别。分为五步:

1. 将密钥加载到 Agent
  • Linux/macOS: ssh-add ~/.ssh/id_ed25519
  • Windows: 启动 Pageant 并加载 .ppk(或运行 ssh-agent + ssh-add)

验证 Agent 是否可访问:

uv run python -c "import asyncio; from ssh_mcp.ssh.agent import list_agent_fingerprints; print(asyncio.run(list_agent_fingerprints()))"

你应该会看到一行或多行 SHA256:...。复制你打算使用的那一行,稍后会用到。

2. 固定目标主机的密钥(信任前务必验证)

默认启用严格的 known_hosts 验证(不会自动接受)。固定密钥分为三个步骤——切勿将 ssh-keyscan 的输出直接追加到 known_hosts。

# 2a. Scan to a scratch file. This does NOT trust anything yet.
ssh-keyscan -t ed25519,ecdsa,rsa web01.example.com > /tmp/web01.hostkey

# 2b. Print the fingerprint and compare OUT-OF-BAND.
ssh-keygen -lf /tmp/web01.hostkey
# → 256 SHA256:abc123... web01.example.com (ED25519)

将该 SHA256:... 与可信来源进行比对,该来源不能是刚才扫描所用的网络:主机的配置工具输出、控制台会话、terraform 输出,或系统管理员发来的 Signal 消息。**如果不匹配,请停止。**拼写错误或中间人攻击(MITM)可能会导致恶意密钥被固定为受信任密钥。

# 2c. Only after the out-of-band fingerprint matches, append and clean up.
cat /tmp/web01.hostkey >> ~/.ssh/known_hosts
rm /tmp/web01.hostkey

如果 known_hosts 缺失、为空或内容不匹配,MCP 服务将拒绝连接。

3. 编写 hosts.toml

复制带注释的入门模板并进行编辑:

cp hosts.toml.example hosts.toml
# Replace the SHA256:REPLACE-WITH-... fingerprints with yours from step 1.

也可以从头编写——最精简的可用配置块:

[defaults]
user = "deploy"

[defaults.auth]
method = "agent"
identity_fingerprint = "SHA256:<paste-your-fingerprint-here>"
identities_only = true

[hosts.web01]
hostname = "web01.example.com"
path_allowlist = ["/opt/app", "/var/log"]

有关堡垒机/代理跳转、每台主机的密钥覆盖,以及磁盘密钥 + 密钥链密码短语模式,请参阅 hosts.toml.example。有关多主机配置示例(堡垒机、按角色区分的密钥、旧版主机),请参阅 CONFIGURATION.md → 配置更多主机。

从 ~/.ssh/config 继承配置

如果你已经维护了一份内容丰富的 ~/.ssh/config(包含主机别名、ProxyJump、IdentityFile,以及针对旧设备的 Ciphers/MACs 覆盖设置),可将 SSH_CONFIG_FILE 指向该文件,并跳过在 hosts.toml 中重复设置这些字段:

SSH_CONFIG_FILE=~/.ssh/config

优先级:hosts.toml 始终优先生效。~/.ssh/config 只会补充你未针对每台主机设置的字段——OpenSSH 配置不能扩大 path_allowlist、command_allowlist 或主机阻止列表所允许的范围。启动日志会显示 ssh_config: honoring <abs-path>(如果文件缺失,则显示 WARNING),以便立即发现配置错误。

4. 编写 .env
# Start locked down — only read-only tools are active.
ALLOW_LOW_ACCESS_TOOLS=false
ALLOW_DANGEROUS_TOOLS=false
ALLOW_SUDO=false

# Optional safety rail
SSH_HOSTS_BLOCKLIST=
5. 端到端验证
uv run ssh-mcp

通过 MCP 客户端(或快速启动的 Python shell)调用:

from ssh_mcp.server import mcp_server
# tools: ssh_host_ping, ssh_host_info, ssh_sftp_list, ssh_find, ...

ssh_host_ping(host="web01") 应返回 {reachable: true, auth_ok: true, latency_ms: N, ...}。

如果失败,请参阅故障排除。


故障排除

no SSH agent reachable

Agent 的查找顺序为:hosts.toml 中显式设置的 identity_agent → SSH_AUTH_SOCK 环境变量 → Windows 自动检测(Pageant/OpenSSH pipe)。请检查:

# Unix / macOS
echo $SSH_AUTH_SOCK
ssh-add -l

# Windows (PowerShell)
Get-Process Pageant -ErrorAction SilentlyContinue
uv run python -c "import asyncio; from ssh_mcp.ssh.agent import list_agent_fingerprints; print(asyncio.run(list_agent_fingerprints()))"
identity 'SHA256:...' not found in agent

hosts.toml 中的指纹与 Agent 提供的任何密钥都不匹配。列出实际加载的密钥:

uv run python -c "import asyncio; from ssh_mcp.ssh.agent import list_agent_fingerprints; [print(fp) for fp in asyncio.run(list_agent_fingerprints())]"

将显示的某个指纹复制到 identity_fingerprint。

HostKeyMismatch / UnknownHost

主机密钥可能已更改(轮换或 MITM),也可能是 known_hosts 中缺少对应条目。**不要让大模型绕过此验证,也不要在未经验证的情况下使用 >> 将扫描结果直接写入 known_hosts。**请按照演练第 2 步中的三个步骤操作:

ssh-keyscan -t ed25519,ecdsa <host> > /tmp/h.hostkey
ssh-keygen -lf /tmp/h.hostkey                     # compare fingerprint out-of-band
cat /tmp/h.hostkey >> ~/.ssh/known_hosts && rm /tmp/h.hostkey
HostNotAllowed

该主机不在 hosts.toml 中,也不在 SSH_HOSTS_ALLOWLIST 中。解析时会先将输入作为 hosts.<alias> 键查找,然后与 hosts.*.hostname 匹配,最后检查环境变量允许列表。请添加 hosts.toml 条目,或将主机名原文添加到 SSH_HOSTS_ALLOWLIST。

HostBlocked

拒绝规则优先——请检查 SSH_HOSTS_BLOCKLIST。这是有意为之;如果误加了屏蔽条目,可以将其移除,但请先向添加该条目的操作员确认。

PathNotAllowed

解析后的(规范化)路径不在任何 path_allowlist 根目录下。请检查:

  • 路径是否正确?低访问权限工具会在检查前解析符号链接,因此,即使符号链接本身位于 /opt/app 中,若其指向该目录之外,也会被拒绝。
  • hosts.<name>.path_allowlist 是否涵盖了目标路径?
command_allowlist is empty but ALLOW_DANGEROUS_TOOLS=true

如果启用 exec,却没有限定允许执行的命令,加载器会发出警告。请设置 SSH_COMMAND_ALLOWLIST,或为每台主机设置空的 command_allowlist(显式设置即表示无限制)。

MCP 客户端中看不到工具
  • 检查权限级别:ALLOW_LOW_ACCESS_TOOLS / ALLOW_DANGEROUS_TOOLS / ALLOW_SUDO 默认均为拒绝。
  • 检查分组:SSH_ENABLED_GROUPS(留空 = 全部;显式设置 = 筛选)。
  • 重启 MCP 客户端——工具列表会按 MCP 服务版本缓存。

查询审计日志

每次工具调用都会向 Python 日志记录器 ssh_mcp.audit 写入一行 JSON——包括只读权限级别的工具(自 v1.4.0 起,所有权限级别都会进行审计)。进程内没有用于查询审计日志的工具——这是有意为之(INC-052):如果大模型可以读取自己的审计轨迹,遭到入侵或越狱的 Agent 就能自行监控被抓到的行为,并据此调整规避方式。审计数据只单向流向操作员。

请在自己的日志配置中,将 ssh_mcp.audit 接入你选择的接收端(文件、Loki、Splunk、Datadog、journald 等)。如需本地调试或快速排查事件,可将日志写入文件并使用 jq 查询:

# In your own bootstrap (or a custom run_server wrapper)
import logging
h = logging.FileHandler("/var/log/ssh-mcp/audit.jsonl")
h.setFormatter(logging.Formatter("%(message)s"))
logging.getLogger("ssh_mcp.audit").addHandler(h)

每一行都是一个紧凑的 JSON 对象。架构如下:

字段类型说明
tsfloatUnix 纪元秒数
correlation_idstr16 位十六进制字符;与 ssh_mcp.audit 上的 DEBUG 级别完整错误日志对应
toolstrMCP 工具名称(例如 ssh_exec_run、ssh_broadcast)
tierstrread / low-access / dangerous / sudo
hoststr解析后的主机名(对于 ssh_broadcast 等扇出工具则为 ?)
resultstrok / error
duration_msint工具调用的实际耗时
path_hashstr规范化路径的 sha256:<16hex>(工具访问路径时)
command_hashstr脱敏后命令的 sha256:<16hex>(工具运行命令时)
exit_codeint适用时提供
errorstr仅包含异常类名——完整文本仅记录在 DEBUG 级别(INC-008)

实用的 jq 用法:

# All errors in the last hour, sorted by tool
jq -r 'select(.result == "error") | "\(.ts) \(.tool) \(.host) \(.error)"' \
  /var/log/ssh-mcp/audit.jsonl | sort -k2

# Slowest dangerous-tier calls (top 20 by duration_ms)
jq 'select(.tier == "dangerous")' /var/log/ssh-mcp/audit.jsonl \
  | jq -s 'sort_by(-.duration_ms) | .[:20] | .[] | {tool, host, duration_ms}'

# Count by tool to see what the LLM is actually using
jq -r '.tool' /var/log/ssh-mcp/audit.jsonl | sort | uniq -c | sort -rn

# Trace one specific call end-to-end via correlation_id
jq 'select(.correlation_id == "a1b2c3d4e5f6abcd")' /var/log/ssh-mcp/audit.jsonl

command_hash 和 path_hash 字段是用于去重的辅助信息,而非隐私保护措施——对于常见命令和规范化路径,较短的 SHA-256 前缀很容易通过彩虹表破解。如果审计日志的机密性很重要,请通过传输加密(使用 TLS 连接到日志后端)和对接收端本身实施访问控制来保障。

免责声明

Python SSH MCP 是本地基础设施,可让大模型(或任何 MCP 客户端)通过 SSH 在远程系统上执行命令。**使用风险自负。**默认拒绝的权限级别标志和严格的 known_hosts 强制检查可以防范明显的操作陷阱,但没有任何软件能保护那些不了解影响范围却将所有标志都设为 true 的操作员。

在生产环境中启用危险或 sudo 权限级别之前,请阅读 DECISIONS.md。请定期审查 ssh_mcp.audit JSON 日志。如有疑问,请保持权限级别关闭。

本项目与任何 SSH、FastMCP 或 MCP 提供商均无关联,也未获其认可。


支持

构建和维护此 MCP 服务需要投入大量时间和精力,即使有 AI 的帮助也是如此。如果这个 SSH MCP 让你的工作流和生活更加轻松,请考虑支持我:

如有问题、疑问或反馈,请提交 GitHub issue。如果你觉得 Python SSH MCP 有用,请考虑为仓库点个 Star——这确实很有帮助。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。