关于 JumpServer Bastion (jms)
JumpServer v4 堡垒机的命令行客户端和 MCP 服务,面向需要访问已授权资产的运维人员及 AI Agent。它通过连接池复用会话,并提供本地审计记录。
主要功能
- 01列出并搜索已授权资产
- 02远程执行命令和交互式 Shell
- 03上传、下载及资产间传输文件
- 04会话连接池与双地址故障切换
- 05凭据存入操作系统凭据库
- 06本地 JSONL 审计日志
适用场景
- 01通过堡垒机检查远程服务状态
- 02在资产上执行运维命令
- 03在本地与资产间传输文件
- 04审查 AI Agent 执行记录
MCP 相关
通过 stdio 提供 MCP 服务,注册资产查询、命令执行和文件传输等工具。工具调用使用共享的连接池,并写入本地审计流。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
jms-client
面向 JumpServer v4 堡垒机的命令行客户端和 MCP 服务。 一个独立的二进制文件,即可像 Web 终端一样访问堡垒机后的资产——无需 VPN 客户端、SSH 配置或逐主机凭据。
可单独使用它来列出资产、运行命令、打开 Shell 和传输文件。运行 jms mcp 后,AI 助手(Claude Desktop、Claude Code、Codex、Cursor、pi 等)也可以通过复用且经过审计的连接完成相同操作。
$ jms exec web-01 "systemctl is-active nginx"
active
English · 简体中文
为什么开发此项目
访问堡垒机通常需要打开浏览器标签页,或者手动维护 ~/.ssh/config。这两种方式都无法与 Shell 管道、构建脚本或 AI Agent 配合使用。
jms-client 调用 Web 控制台使用的同一组 JumpServer API(Core 的 REST API 和 KoKo 的终端网关),因此:
- **凭据不会存放在配置文件中。**密码和 TOTP 密钥保存在操作系统凭据存储中。配置文件仅保存地址和用户名,因此可以安全地同步、备份或提交。
- **一次登录可供多条命令使用。**连接按服务器/资产/账户/协议进行池化并复用。
- **同一份配置可在办公室内外使用。**为服务器同时设置内部和外部地址后,客户端会自动选择可连接的地址。
- **所有操作都会在本地记录。**AI Agent 运行的每条命令都会写入 JSONL 审计流,方便查看、跟踪或交互式接入。
功能特性
| 单个静态二进制文件 | 无运行时依赖。支持 x86_64 和 arm64 架构的 Linux、macOS、Windows。 |
| 双地址故障转移 | 自动探测并选择内部/外部地址,并记住上次可用的地址,以加快冷启动速度。 |
| 连接池 | 按 server/asset/account/protocol 复用登录会话和终端。清理空闲连接,并重建已损坏的连接。 |
| 凭据存储在操作系统中 | Windows Credential Manager、macOS Keychain、Linux Secret Service。容器和 CI 环境可回退到环境变量。 |
| MCP 服务 | 通过标准输入/输出为 AI 客户端提供七种工具,共享一个池化进程。 |
| 本地审计流 | 每个进程都会生成结构化 JSONL;使用 jms tail 跟踪,使用 jms attach 监视并接入。 |
| 两种终端后端 | WebSocket(默认,与 Web 控制台使用相同链路)和 SSH,并支持自动选择。 |
要求
- JumpServer v4,且机器可以连接其 KoKo 组件。不支持 JumpServer v3 及更早版本。
- 在该 JumpServer 上拥有一个已获授权访问目标资产的账户。
- WebSocket 后端只需能够访问 HTTP(S) 地址。SFTP 和 SSH 功能还要求 KoKo 的 SSH 端口(默认
2222)在网络路径上开放——许多部署仅开放 Web 端口,因此使用这些功能前请先确认。
安装
预编译二进制文件(推荐)
从 Releases 下载适用于你平台的压缩包,并将 jms 二进制文件(Windows 上为 jms.exe)放到你的 PATH 中。
| 平台 | 文件 |
|---|---|
| Windows x86_64 | jms-client_<version>_windows_amd64.zip |
| Windows arm64 | jms-client_<version>_windows_arm64.zip |
| macOS Apple Silicon | jms-client_<version>_darwin_arm64.tar.gz |
| macOS Intel | jms-client_<version>_darwin_amd64.tar.gz |
| Linux x86_64 | jms-client_<version>_linux_amd64.tar.gz |
| Linux arm64 | jms-client_<version>_linux_arm64.tar.gz |
同一版本发布页中的 checksums.txt 可用于验证下载文件:
sha256sum -c --ignore-missing checksums.txt # Linux
shasum -a 256 -c --ignore-missing checksums.txt # macOS
Scoop(Windows)
scoop bucket add mifazhan https://github.com/MiFaZhan/scoop-bucket
scoop install jms-client
之后可使用 scoop update jms-client 升级。
Go
需要 Go 1.25 或更高版本:
go install github.com/MiFaZhan/jms-client/cmd/jms@latest
从源代码构建
git clone https://github.com/MiFaZhan/jms-client
cd jms-client
go build -o jms ./cmd/jms
仅供 MCP 客户端使用
如果你只需要 AI 集成,并且不想自行管理二进制文件,可以从 Releases 下载 jms-client.mcpb,然后用你的 MCP 客户端打开它(Claude Desktop 和其他支持 MCPB 的客户端可通过双击完成此操作)。这个单一安装包包含适用于全部六种平台和架构组合的二进制文件;打包的启动器会在启动时选择正确的文件。
快速开始
1. 保存你的服务
$ jms config add bastion
Internal URL (http(s)://..., empty to skip): https://jumpserver.corp.example.com/
External URL (http(s)://..., empty to skip):
Username: alice
Password:
Confirm password:
TOTP secret (base32, empty to enter the code each time):
Server "bastion" saved to /home/alice/.config/jms/config.toml
Server "bastion" is now the default.
地址可以留空,但至少必须填写一个。凭据会在写入任何内容之前,针对可连接的地址进行验证,因此即使密码输入错误,磁盘上的内容也不会改变。你添加的第一个服务会成为默认服务。
2. 检查连接
$ jms config test
Server: bastion (default)
Endpoint URL Reachable Probe Login
external https://jumpserver.corp.example.com/ yes 12ms ok
Credentials: keyring
config test 会探测每个已配置的地址,并尝试在每个可连接的地址上实际登录,因此网络问题会与密码错误分别报告,你也可以查看哪些地址确实可用。地址可能通过 TCP 探测,却仍无法登录——VPN 或代理可能接受连接,但其后并没有可用服务。
3. 开始使用
$ jms ls # assets you are authorized for
$ jms ls -q web # search by keyword
$ jms exec web-01 "uptime" # one command, exit code passes through
$ jms login web-01 # interactive shell (Ctrl+] to exit)
$ jms sftp web-01:/var/log/app.log . # download
$ jms sftp ./config.yml web-01:/etc/app/ # upload
连接 AI 助手(MCP)
jms mcp 会通过 stdio 运行一个 Model Context Protocol 服务。随后,任何支持 MCP 的客户端都可以通过与你的 shell 使用的同一组连接池列出资产、运行命令和传输文件。
{
"mcpServers": {
"jms": {
"command": "jms",
"args": ["mcp"]
}
}
}
你可以随时使用以下命令打印此代码片段:
jms mcp --print-config
由于 MCP 进程没有命令行标志(客户端会启动一个长期运行的进程,且无法为每次调用添加参数),因此需通过客户端条目中的环境变量来设置端点、后端和命令超时:
{
"mcpServers": {
"jms": {
"command": "jms",
"args": ["mcp"],
"env": {
"JMS_MCP_BACKEND": "ws",
"JMS_MCP_EXEC_TIMEOUT": "10m"
}
}
}
}
工具
| 工具 | 用途 | 必需参数 |
|---|---|---|
jms_ls | 列出或搜索有权访问的资产 | — |
jms_resolve_asset | 将资产解析为其地址、账户和协议 | asset |
jms_exec | 运行一条命令并返回其输出 | asset、command |
jms_sftp_upload | 将本地文件上传到资产 | src、asset、dst |
jms_sftp_download | 从资产下载文件 | asset、src、dst |
jms_sftp_relay | 在两个资产之间直接传输文件 | src_spec、dst_spec |
jms_config_list | 列出已配置的服务及其凭据来源 | — |
设置 JMS_MCP_DEBUG=1 时会注册第八个工具 jms_pool_status,用于报告连接池的状态。它用于诊断服务,不适合日常使用。
大多数工具接受可选参数 server、config_path、account、protocol 和 timeout。远程规格采用 <asset>[@<server>]:<path> 格式。
为 Agent 编写提示词时,有两点行为值得注意:
- 非零退出代码不会被报告为失败。
jms_exec会返回命令的输出;远程退出状态会记录在审计日志中,但不会显示在工具结果里。如果 Agent 必须根据成功与否采取不同操作,请让命令明确输出结果(… && echo OK || echo FAIL)。 - 命令绝不会重放。 如果命令已发送到主机后调用失败,客户端会报告错误,而不会重试,因为
rm、reboot等命令并非幂等。连接断开时会尝试通过新的登录恢复一次,但仅限于完全没有产生任何输出的命令。
命令一览
| 命令 | 功能 |
|---|---|
jms config add | list | remove | set-default | test | 管理服务条目及其凭据。 |
jms ls [server] [-q keyword] | 列出或搜索有权访问的资产。 |
jms exec <target> <command...> | 在资产上运行一条命令。 |
jms login <target> | 打开交互式 Shell。 |
jms sftp <src> <dst> | 上传或下载文件。 |
jms ssh-pipe <target> [command...] | 将标准输入输出桥接到资产(用于 rsync -e)。 |
jms tail [-f] | 实时查看本地审计流。 |
jms attach | 查看正在运行的主机,也可选择加入其会话。 |
jms log show | 查询审计日志。 |
jms mcp | 运行标准输入输出 MCP 服务。 |
目标语法为 <asset>@<server>;省略 @<server> 时使用默认服务。
完整参考: docs/command-reference.md · 简体中文
配置
配置文件位于:
| 平台 | 路径 |
|---|---|
| Windows | %AppData%\jms\config.toml |
| Linux / macOS | ~/.config/jms/config.toml(或 $XDG_CONFIG_HOME/jms/config.toml) |
可通过 --config 标志或 JMS_CONFIG 环境变量覆盖配置路径。移动配置文件也会一并移动审计目录,因为两者位于同一目录下。
version = 2
default_server = "bastion"
# Optional global proxy policy. Omitted means: connect directly.
# proxy = "socks5://127.0.0.1:1080"
[servers.bastion]
internal = "http://192.168.1.10:2280/" # internal address (optional)
external = "https://bastion.example.com/" # external address (optional)
username = "alice"
# prefer = "external" # try this address first; default is internal
# pin = "internal" # use only this address: no probing, no failover
# ssh_port = 2222 # KoKo SSH port if not the default
# proxy = "direct" # force a direct connection for this server
[servers.staging]
external = "https://jumpserver.staging.example.com/"
username = "alice"
prefer = "external"
除用户名外,所有字段均为可选,但至少需要一个地址。
如果某个服务配置了两个地址,客户端会依次探测,并登录第一个有响应的地址,同时将最近一次可用地址记住十分钟。客户端默认直接连接,并忽略 HTTP_PROXY 等代理设置;必须显式配置代理才能使用。
详情: docs/networking.md · 简体中文
凭据
| 数据 | 存储位置 |
|---|---|
| 别名、地址、用户名、偏好设置 | config.toml,明文(0600) |
| 密码、TOTP 密钥 | 操作系统凭据存储,服务名称为 jms-client |
配置文件以原子方式写入,且从不包含凭据,因此可以安全地在多台机器之间同步。请注意这一安全边界:它能防止文件泄露和将配置复制到另一台机器,但无法防范以同一用户身份运行的恶意进程。
对于无头环境(容器、CI、没有 Secret Service 的 WSL),可以使用环境变量作为回退。环境变量的优先级高于凭据存储。
| 变量 | 含义 |
|---|---|
JMS_PASSWORD_<ALIAS> | 对应服务器别名的密码。 |
JMS_OTP_<ALIAS> | 对应服务器别名的 TOTP 密钥。 |
别名会转换为大写,并将 - 替换为 _,因此 bastion-eu 会变成 JMS_PASSWORD_BASTION_EU。已导出但值为空的变量会被视为未设置,而不是空密码。如果两个来源都没有凭据,命令会失败,并提示要设置的变量名称——绝不会回退到以明文存储密码。
凭据存储已锁定时(没有桌面会话的 GNOME Keyring 通常处于这种状态),命令会在数毫秒内失败,并提示要设置的环境变量名称——请参阅故障排除。
环境变量
| 变量 | 作用 |
|---|---|
JMS_CONFIG | 配置文件的路径。 |
JMS_PASSWORD_<ALIAS>、JMS_OTP_<ALIAS> | 凭据回退(见上文)。 |
JMS_ACTOR | 审计日志中记录的名称;可用于区分同一台机器上的多个客户端。 |
JMS_AUDIT | 设置为 off 可禁用审计日志。 |
JMS_AUDIT_DIR | 更改审计目录的位置。 |
JMS_AUDIT_FULL | 设置为 1 可记录未截断的输出预览。 |
JMS_AUDIT_PREVIEW_BYTES | 输出预览的截断限制(默认为 4096)。 |
JMS_MCP_ENDPOINT | 仅限 MCP:强制使用 internal 或 external。 |
JMS_MCP_BACKEND | 仅限 MCP:强制使用 ssh、ws 或 auto。 |
JMS_MCP_EXEC_TIMEOUT | 仅限 MCP:jms_exec 的默认超时时间,例如 10m 或 600。 |
JMS_MCP_DEBUG | 仅限 MCP:设置为 1 可注册 jms_pool_status。 |
JMS_WS_DUMP | 转储原始 WebSocket 帧,用于协议调试。 |
终端后端
JumpServer 的 KoKo 组件提供两种终端通道,jms-client 均支持。
| 后端 | 通道 | 说明 |
|---|---|---|
ws(默认) | /koko/ws/terminal/ | 与 Web 控制台使用的路径相同。凡是 Web 控制台可用的地方,此通道都可用。命令默认超时时间为 30 秒。 |
ssh | KoKo SSH 端口(默认为 2222) | 每条命令都会返回原生退出状态,无需解析输出标记。要求该端口可访问,SFTP 也依赖此端口。 |
使用 --backend ssh 选择 SSH,或使用 --backend auto 尝试 SSH,并在失败时回退到 WebSocket。上次成功连接某个地址所用的后端会记在 state.json 中,因此冷启动时会直接使用该后端,而不必在被阻止的端口上等待握手超时。在 MCP 中,记住的后端还可让进程从过期连接中恢复,而无需重启。
需要 SFTP 的工具——jms sftp、jms_sftp_upload、jms_sftp_download、jms_sftp_relay——要求 KoKo 的 SSH 端口开放。如果文件传输卡住或失败,但 exec 正常工作,首先应检查该端口。
审计日志
每条命令都会记录为一行 JSON 对象:
{"ts":"2026-10-05T14:32:01.123+08:00","pid":12345,"actor":"mcp:pi","kind":"exec.end","server":"prod","asset":"web-01","backend":"ssh","endpoint":"external","command":"systemctl status nginx","exit_code":0,"duration_ms":118,"output_bytes":2140,"preview":"● nginx.service ...","pool":"hit","idle_ms":68000}
文件写入 <config dir>/audit/audit-YYYYMMDD-<pid>.jsonl,每个进程一个文件,目录和文件的权限均为 0600。使用独立的进程文件可避免 Windows 上多个进程向同一个锁定文件追加内容的问题,也便于长期运行的主机与一次性 CLI 调用共存。
事件类型:exec.start、exec.end、pool.cold、pool.hit、pool.evict、pool.reap、session.login、session.relogin、endpoint.select、error。
默认情况下,输出预览会截断至 4096 字节(可通过 JMS_AUDIT_PREVIEW_BYTES 配置;若要记录全部内容,请设置 JMS_AUDIT_FULL=1)。日志中不会插入任何凭据。
限制
- 仅支持 JumpServer v4。 v3 的身份验证和终端 API 不同。
jms sftp不支持递归复制或资产间中继。 后者请使用 MCPjms_sftp_relay工具,或通过本地计算机中继。- 不构建 32 位平台版本。 仅支持 x86_64 和 arm64。
- 审计日志存储在本地。 不会转发到中央收集器;如需汇总,请自行传送这些文件。
- 尚未实现跳板链(通过另一个资产进行代理/跳转)。
遇到问题时: docs/troubleshooting.md · 简体中文
开发
go build ./... # compile
go test ./... # unit and protocol-regression tests
go vet ./...
gofmt -l . # must print nothing
集成测试会连接到真实的 JumpServer,并通过环境变量控制是否运行;未设置该变量时,测试会跳过,因此全新克隆的项目可以顺利通过测试:
JMS_TEST_SERVER=bastion go test ./...
架构、逆向分析得到的 KoKo 协议细节、池设计和故障处理规则见 DESIGN.md(中文编写)。
通过 GitHub Actions 发布版本:
gh workflow run release --repo MiFaZhan/jms-client -f tag=v0.1.7
许可证
MIT © MiFaZhan。请参阅 LICENSE。
设计和 KoKo 协议研究基于 GCS-ZHN/jms-cli。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。