jms-mcp
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
jms-mcp
面向 JumpServer 3.10.15 的 MCP 网关:读取实例自身的 Swagger 2.0 文档,将选定 API 注册为 MCP 工具。兼容 OpenAPI 3.x 的常用 JSON 接口,提供 Streamable HTTP /mcp 和 SSE /sse。
当前版本:0.1.0。兼容结论基于 JumpServer v3.10.15 官方源码、合成接口样本和模拟上游测试;尚未在真实 JumpServer 3.10.15 实例验收,不能据此承诺全部 API 可用。上线前请执行 实例验收清单。
改进内容
原设计中的问题 | 本项目处理 |
Swagger 2 请求体未正确变成工具参数 | 原生读取 |
| 统一拼接路径,兼容完整路径与部署前缀 |
裸 Token 获取文档成功、实际调用失败 | 获取文档与业务请求共用同一认证头 |
客户端密钥与 JumpServer Token 混用 |
|
全量注册导致模型工具超限 | 默认仅资产 GET,白名单、排除列表、最多 100 个工具 |
默认关闭 TLS 验证 | 默认校验证书,支持自定义 CA |
会话 ID 绕过入站认证 | SSE 消息与 HTTP 每次请求均校验入站密钥 |
Related MCP server: mcp_proxy
快速启动
需要 Python 3.11+;推荐 Python 3.12。以下命令在仓库根目录执行。
git clone https://github.com/abchw517/jms-mcp.git
cd jms-mcp
cp .env.example .env
chmod 600 .env
# 编辑 .env:填写 jumpserver_url、api_token、api_key。
docker compose up -d --build
docker compose logs --tail=100 jms-mcp
curl --fail http://127.0.0.1:8099/readyz默认 Compose 仅映射到本机 127.0.0.1:8099。跨主机使用时,配置端口映射、allowed_hosts,并通过可信网络或 TLS 反向代理接入。
使用 docker run 启动已有镜像
推荐通过 --env-file 读取宿主机的 .env 并注入容器环境变量,无需挂载该文件,也不要把真实凭证打进镜像。镜像启动时已经调用 uv run --no-sync main.py serve,不需要追加启动命令。
先复制并编辑配置:
cp .env.example .env
chmod 600 .env至少填写以下内容。Docker --env-file 的值不要加引号;例如写成 api_token=Bearer xxx,不要写成 api_token="Bearer xxx",否则引号会成为传入值的一部分。
jumpserver_url=https://jumpserver.example.com
api_token=Bearer REPLACE_WITH_JUMPSERVER_TOKEN
api_key=REPLACE_WITH_RANDOM_MCP_KEY
server_host=0.0.0.0
server_port=8099
# 替换为MCP服务器的实际访问IP或域名;不是JumpServer地址。
allowed_hosts=192.168.1.10:*,127.0.0.1:*,localhost:*
read_only=true
include_paths=/api/v1/assets/*
max_tools=100
tls_verify=true如果使用 JumpServer 私有 Token,写成 api_token=Token xxx。请替换示例域名、IP 与两类密钥。下面沿用示例镜像标签;请确保本机存在该镜像,或可从镜像仓库拉取,后续版本请替换为实际标签。
docker run -d \
--name jms-mcp \
--restart unless-stopped \
--env-file "$PWD/.env" \
-p 8099:8099 \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=16m,mode=1777 \
--cap-drop ALL \
--security-opt no-new-privileges \
mharbor-cs.cloud.kemai.cn/public/jms-mcp:202610301650/tmp 临时挂载供 uv 初始化缓存使用。此命令将端口发布到宿主机所有地址;只需要本机访问时,改为 -p 127.0.0.1:8099:8099。MCP 客户端使用 http://服务器IP:8099/sse 或 /mcp,认证头为 Authorization: Bearer <api_key>,对应独立的 MCP 入站密钥。
检查运行状态:
docker ps --filter name=jms-mcp
docker logs --tail=100 -f jms-mcp
# 在另一个终端执行:
curl --fail http://127.0.0.1:8099/readyz初始化成功时返回 {"ready":true}。就绪接口用于确认启动初始化,不持续验证上游 Token 的有效性。
修改宿主机 .env 后必须重新创建容器,docker restart 不会重新读取 --env-file。停止并删除旧容器后,重新执行上面的 docker run 命令:
docker stop jms-mcp
docker rm jms-mcp启动失败时检查配置
如果旧镜像只输出 Invalid configuration or local file; check .env and file paths,表示旧版通用错误处理隐藏了具体异常,不能直接据此判断错误项。优先检查 api_token 是否残留引号、api_key 是否为空或含空格、jumpserver_url 是否附加了 /api/v1,以及端口和布尔配置的格式。
更新源码并重新构建镜像后,可执行离线检查;旧镜像不包含 check-config 命令:
docker run --rm --network=none \
--env-file "$PWD/.env" \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=16m,mode=1777 \
mharbor-cs.cloud.kemai.cn/public/jms-mcp:202610301650 check-config本地安装也可执行 uv run --frozen main.py check-config。该命令不请求 JumpServer,检查配置与可选 CA 文件;通过不代表网络、Token 有效性或上游权限已经验证。新版本会指出缺失字段、认证引号或格式、错误字段类型与 CA 挂载问题,不输出凭证值。
--restart unless-stopped 会在应用退出后重启容器,所以同一配置错误可能反复出现在日志里。修正 .env 后按前文重新创建容器。
本地安装
python3 -m venv .venv
. .venv/bin/activate
pip install .
jms-mcp servemain.py 统一入口
根目录 main.py 复用现有 CLI,无参数时默认执行 serve。不在脚本中重复实现认证、配置或服务逻辑,原有 jms-mcp 命令继续可用。先按前文安装依赖并配置 .env。
uv run --frozen main.py --version
# 启动服务,也可显式添加 serve:
uv run --frozen main.py
# 离线查看工具目录:
uv run --frozen main.py catalog --schema /tmp/jms-swagger-check.json已安装项目依赖的虚拟环境中,也可直接执行 python main.py。
认证配置
jumpserver_url=https://jumpserver.example.com
api_token=Bearer <JumpServer访问Token>
api_key=<独立生成的MCP入站密钥>jumpserver_url填主机根地址,不能附加/api/v1。部署在子路径时可填https://example.com/jms。JumpServer 3.10.15 登录访问令牌使用
Bearer <token>;私有 Token 使用Token <token>。Access Key ID/Secret 的 HTTP 签名认证不在本版范围内。裸
api_token默认添加Bearer;裸私有 Token 需设置auth_scheme=Token。不要重复添加认证前缀。api_key只填密钥本身。生成示例:python3 -c 'import secrets; print(secrets.token_urlsafe(32))'。Token 过期后更新配置:本地进程需重启,Docker
--env-file部署需重新创建容器;本版不保存密码,也不自动刷新令牌。配置
jms_org_id可为文档请求与业务请求统一发送X-JMS-ORG;不允许工具参数覆盖上游认证。
MCP 客户端示例(Claude Code 等支持 SSE 的客户端):
{
"mcpServers": {
"jms-mcp": {
"type": "sse",
"url": "http://127.0.0.1:8099/sse",
"headers": {"Authorization": "Bearer <MCP入站密钥>"}
}
}
}支持 Streamable HTTP 的客户端可使用 http://127.0.0.1:8099/mcp,认证头不变;具体配置语法以客户端为准。两种传输均要求客户端在后续消息请求中携带认证头。
工具范围与数量
默认配置:
read_only=true
include_paths=/api/v1/assets/*
max_tools=100过滤条件取交集:GET 限制 → 路径 glob → 精确 operationId 白名单 → operationId 排除 → 标签。include_operations 使用文档中的原始 operationId;工具名中的特殊字符会转成下划线。重名直接报错。白名单条目不支持正则或通配符。
路径过滤针对合并后的完整 API 路径。如果 Swagger 的 basePath 包含部署前缀(如 /jms/api/v1),相应设置 include_paths=/jms/api/v1/assets/*。
默认只读仅限制 HTTP 方法,不替代 JumpServer RBAC;上游应使用具备所需最小权限的专用账号。若资产接口较多而超过上限,服务启动失败并提示收窄白名单,不会静默截断。该上限只约束本服务,模型对所有 MCP 服务的总工具数量仍需统一控制。
先检查实际工具目录:
# 读取实例文档,不执行任何业务写操作
jms-mcp catalog --output catalog.json
# 离线分析已下载的 Swagger,无需真实凭证
jms-mcp catalog --schema /tmp/jms-swagger-check.json --output catalog.json输出包含工具总数、过滤数量、跳过接口及原因、每个工具的输入 schema。catalog.json 可能含资产接口信息,不要提交到公开仓库。
启用写操作需要同时配置 read_only=false 和精确白名单,例如:
read_only=false
include_operations=assets_hosts_list,assets_hosts_create这个示例 operationId 来自测试样本,实际值以实例文档为准。写操作没有服务端人工确认步骤,也不重试;先在测试组织验收,超时后先核对执行结果再决定是否重发。
工具参数按位置分组,避免路径、查询与请求体同名覆盖:
{"query": {"search": "web", "limit": 20, "offset": 0}}{"path": {"id": "<资产UUID>"}}{"body": {"name": "test-host", "address": "10.0.0.10"}}分页保持 JumpServer 原始语义,不自动拉取全部分页。
部署与运行边界
Docker 采用
ghcr.io/astral-sh/uv:0.13.4-python3.11-alpine单阶段镜像。通过 bind 挂载uv.lock与pyproject.toml,先执行uv sync --frozen --no-install-project --no-dev --no-editable,再复制项目并安装;启用 BuildKit 缓存、copy 链接模式与字节码预编译。需要启用 BuildKit 的 Docker/Buildx。显式使用镜像内的 Python 3.11,禁止 uv 下载解释器;虚拟环境位于
/app/.venv。requirements.lock保留为兼容导出,Docker 不再使用它。--frozen直接使用现有锁文件,CI 通过uv lock --check校验锁文件与项目一致。可通过--build-arg UV_IMAGE=...覆盖基础镜像,变更后需重新验证。根目录
main.py复用项目 CLI,无参数时默认启动服务;容器使用uv run --no-sync main.py serve,启动时不重新同步依赖。uv 初始化缓存需要可写临时目录,缓存位于/tmp/uv-cache;只读根文件系统部署需挂载可写/tmp,Compose 与 Kubernetes 模板已配置。镜像以 UID/GID
10001运行,支持只读根文件系统。Kubernetes 模板见 deploy/kubernetes.yaml。默认校验 TLS。内网 CA 使用
ca_bundle并挂载 CA 文件;tls_verify=false仅用于临时排障。默认关闭环境 HTTP 代理继承,需要时设置
trust_env=true。allowed_hosts是 MCP 入站 Host 白名单,非 JumpServer 地址。默认只允许 localhost。通过域名/IP 访问时设置,例如allowed_hosts=mcp.example.com:*,127.0.0.1:*,localhost:*。SDK 对携带 Origin 的请求校验
allowed_origins。需要浏览器来源时显式配置,不提供通配 CORS。/healthz检查进程,/readyz检查启动时文档和工具初始化;就绪状态不持续验证 JumpServer 连通性或 Token 有效性。SSE 会话存储在进程内;先使用单副本。重启后客户端重连。无状态
/mcp可作为后续多副本部署的基础。默认请求总超时 30 秒、并发 8、响应上限 1 MiB、Swagger 上限 16 MiB。超限返回 MCP 错误,不返回损坏的截断 JSON。
不自动重试,不跟随上游重定向,不从 Swagger 的
host/servers主机名切换请求目标,不拉取远程$ref。本版不支持文件上传、表单、Cookie 参数、递归请求 schema、复杂 query 序列化。跳过的接口可在
catalog中查看;不会发布缺少必需输入字段的工具。API 响应属于不可信外部内容;MCP 调用权限仍由客户端和 JumpServer RBAC 共同管理。
构建时 Docker Hub 前端镜像拉取超时
如果日志停在 docker-image://docker.io/docker/dockerfile:1,并提示访问 auth.docker.io/token 超时,失败发生在 Dockerfile 前端加载阶段,还未开始构建应用。本项目使用 BuildKit 自带的 Dockerfile 前端,不设置需要额外拉取镜像的 # syntax=docker/dockerfile:1。
旧副本可删除这行后重试:
sed -i '/^# syntax=docker\/dockerfile:1$/d' Dockerfile
DOCKER_BUILDKIT=1 docker build -t jms-mcp:local .保留 BuildKit,因为依赖缓存与配置文件挂载使用 RUN --mount。此修改消除 Docker Hub 前端镜像拉取需求;基础镜像、Python 依赖和 Alpine 软件源仍需按构建步骤访问。基础镜像已同步到内部仓库时,可通过 --build-arg UV_IMAGE=<内部镜像地址> 指定。
开发与验证
uv sync --frozen --extra dev
uv run --frozen ruff check .
uv run --frozen ruff format --check .
uv run --frozen pytest -q
uv build测试涵盖 Swagger 2 请求体、类型和路径、认证一致性、组织头、过滤与数量上限、错误和响应边界,以及真实 MCP SDK 对两种传输的初始化、工具发现和调用。测试上游为模拟 HTTP,不访问生产 JumpServer。
更多说明:架构 · 实例验收 · 迁移与故障排查 · 迭代计划 · 变更记录。
参考来源
设计参考 aminglinux/jms_mcp(分析基线 eeaea45b88e7ec6ece196df6309581e2f5166ad2)与 jumpserver/mcp。本项目重新实现协议适配与调用层,未复制这两个仓库的源码。来源与版本依据见 NOTICE.md。本仓库新实现采用 MIT 许可证。
This server cannot be deployed
Maintenance
Related MCP Connectors
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
Toolstile is a managed MCP gateway that connects remote MCP servers behind one endpoint, with per-agent permissions, shared accounts and activity logs. Connect at https://mcp.toolstile.com/mcp over Streamable HTTP with OAuth; sign in at https://toolstile.com, select a workspace and connect your upstream servers. Available tools, resources and prompts depend on that workspace and the agent's granted access.
Streamable HTTP MCP gateway for NV oOS fleets — one API key, namespaced tools, quotas and policy.
Host any HTTP API as MCP tools with a tamper-evident cross-agent settlement ledger.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA universal MCP server for registering internal, external, and OpenAPI-based APIs as MCP tools. It exposes them to MCP clients via Streamable HTTP and provides admin portal, RBAC/session auth, credential injection, and audit logging.-
- FlicenseNot gradedqualityBmaintenanceEnables centralized routing, discovery, namespacing, and execution of tools from multiple remote MCP servers over HTTP/SSE, aggregating them behind a unified MCP gateway with dynamic server management.-
- AlicenseNot gradedqualityAmaintenanceEnables connecting to and managing multiple backend MCP servers (Stdio, SSE, Streamable HTTP), aggregating their tools/resources, and exposing them through unified SSE, Streamable HTTP, or Stdio endpoints with routing, authentication, and optional web-based administration.112 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables aggregating and routing multiple backend MCP resource servers so clients can access their combined tools and resources through a unified SSE, Streamable HTTP, or Stdio interface, with optional authentication and web-based management.112 npmMIT