ibm-mq-mcp
ibm-mq-mcp
把 IBM MQ 的 REST API 暴露成 LLM 可调用的 MCP 工具的服务器。
1. 项目简介
本项目仿造 IBM 官方示例 ibm-messaging/mq-mcp-server, 把 IBM MQ 的管理与消息 REST API 包装成 MCP (Model Context Protocol)工具,供支持 MCP 的 LLM 客户端(如 Claude Code)直接调用。
原版是一个约 110 行的单文件示例,只暴露 dspmq / runmqsc 两个工具,配置全部硬编码,
错误一律返回 "Something went wrong!"。本项目在保留其「REST API → MCP 工具」核心思路的
前提下做了产品化改造:
工具数从 2 个扩展到 15 个,覆盖队列管理器、MQSC、对象查询、消息收发四类;
配置支持 CLI 参数 / 环境变量 / 默认值三级优先级,不再硬编码;
区分管理 API 与消息 API 两套凭据(详见下文「两套凭据」一节),这是实测出的真实限制, 原版没有涉及;
错误按四类(HTTP 层、认证、MQSC 业务失败、其他)分别解析,返回具体原因而不是笼统的 失败提示;
提供只读模式,可在生产环境中限制 LLM 只能查询、不能修改 MQ 配置。
所有关于 MQ REST API 行为的结论(见下文「已知限制」)均来自对真实 MQ 9.4.5.1 实例的 逐条探测,不是查文档推测得出的。
2. 快速开始
前提:本机已运行一个 IBM MQ 实例(例如 IBM 官方开发镜像
icr.io/ibm-messaging/mq:9.4.5.1-r1,MQ_DEV=true),mqweb 监听在
https://127.0.0.1:9443。
# 启动 MQ 容器(如果还没有运行)——本项目不负责容器生命周期,按需自行启动,例如:
# docker run --rm -e LICENSE=accept -e MQ_QMGR_NAME=QM1 -e MQ_DEV=true \
# -e MQ_ADMIN_PASSWORD=admin -p 1414:1414 -p 9443:9443 \
# icr.io/ibm-messaging/mq:9.4.5.1-r1方式一:直接从 GitHub 运行(无需克隆)
uvx 会自动拉取源码、在临时环境里装好依赖并运行,用完即弃:
uvx --from git+https://github.com/moonfruit/ibm-mq-mcp ibm-mq-mcp带参数同理,把它们接在命令后面即可:
uvx --from git+https://github.com/moonfruit/ibm-mq-mcp ibm-mq-mcp --read-only想固定到某个版本或分支,在 URL 后加 @<ref>:
uvx --from git+https://github.com/moonfruit/ibm-mq-mcp@main ibm-mq-mcp方式二:克隆后本地运行(要改代码时用这个)
git clone https://github.com/moonfruit/ibm-mq-mcp
cd ibm-mq-mcp
uv sync
uv run ibm-mq-mcp两种方式都以 stdio 传输启动,默认连接 https://127.0.0.1:9443、管理凭据
admin/admin、忽略自签名证书校验。这组默认值正好对应 IBM 官方开发镜像,
连本机开发实例无需任何额外配置。
如果你的
uv配了国内 PyPI 镜像,可能会遇到依赖解析失败(部分镜像同步不及时, 拿不到mcp>=2.1.1)。临时指定官方源即可:UV_DEFAULT_INDEX=https://pypi.org/simple uvx --from git+... ibm-mq-mcp
3. 接入 Claude Code
在 Claude Code 的 MCP 配置中加入。直接引用 GitHub,无需克隆仓库:
{
"mcpServers": {
"ibm-mq": {
"command": "uvx",
"args": [
"--from", "git+https://github.com/moonfruit/ibm-mq-mcp",
"ibm-mq-mcp"
],
"env": {
"MQ_BASE_URL": "https://127.0.0.1:9443",
"MQ_USERNAME": "admin",
"MQ_PASSWORD": "admin",
"MQ_MESSAGING_USERNAME": "app",
"MQ_MESSAGING_PASSWORD": "admin"
}
}
}
}如果已经克隆到本地(比如你要改代码),把 command/args 换成本地路径:
"command": "uv",
"args": ["--directory", "/path/to/ibm-mq-mcp", "run", "ibm-mq-mcp"],想让接进来的服务器只能读、不能改配置也不能销毁消息,在 env 里加
"MQ_READ_ONLY": "true"——此时只注册 10 个只读工具,run_mqsc 与消息写入类工具
根本不会出现在模型的工具列表里。
也可以复制 .env.example 为 .env 并按需修改(本项目不自动加载 .env,
需要配合 direnv 之类的工具或手动 export)。
4. 配置项
配置优先级:CLI 参数 > 环境变量 > 默认值。空字符串环境变量(如 MQ_PASSWORD="")
视为未设置,会回退到默认值,避免被误当作显式的空密码。
配置 | 环境变量 | CLI 参数 | 默认值 |
mqweb 端点 |
|
|
|
管理 API 用户名 |
|
|
|
管理 API 密码 |
|
|
|
消息 API 用户名 |
|
|
|
消息 API 密码 |
|
|
|
证书校验 |
|
|
|
请求超时(秒) |
|
|
|
传输方式 |
|
|
|
监听地址 |
|
|
|
监听端口 |
|
|
|
只读模式 |
|
|
|
日志级别 |
|
|
|
--transport 支持 stdio、streamable-http、sse;stdio 下 --host/--port
不生效。日志一律写到 stderr(stdio 传输下 stdout 被 MCP 协议占用)。
5. 两套凭据——为什么消息工具默认用户名不是 admin
IBM MQ 把管理和消息拆成 MQWebAdmin 与 MQWebUser 两个互不包含的角色:
管理 API(队列管理器查询、MQSC、对象查询)要求 MQWebAdmin 角色;
消息 API(浏览/取走/发送/发布消息)要求 MQWebUser 角色。
实测对真实 MQ 9.4.5.1 实例逐条探测的结果:用 admin:admin 调用消息 API 会返回
403 MQWB0108E——IBM 开发镜像里的 admin 用户只有 MQWebAdmin 角色,没有
MQWebUser 角色。必须换用另一个用户(开发镜像里是 app:admin)才能调用消息 API。
因此本项目的默认值是两套凭据:
管理 API 默认
admin/admin;消息 API 默认
app/admin。
如果只配置了 MQ_USERNAME/MQ_PASSWORD 而不配置 MQ_MESSAGING_USERNAME/
MQ_MESSAGING_PASSWORD,消息类工具(browse_message、get_message、
put_message、publish_message)大概率会在真实环境中因权限不足而失败——这不是
本项目的 bug,是 MQ 权限模型的设计如此。
6. 工具清单
只读工具(10 个,--read-only 模式下依然可用)
工具 | 用途 |
| 列出 mqweb 服务器上的队列管理器及其运行状态 |
| 查询单个队列管理器的完整属性与运行状态 |
| 查询 IBM MQ 的安装名称、版本与平台 |
| 列出队列及其当前深度(按类型过滤:本地/别名/远程/模型) |
| 查询单个队列的全部属性,包含当前深度 |
| 列出通道及其定义 |
| 查询单个通道的定义,可选附带运行状态 |
| 列出订阅 |
| 列出主题对象 |
| 浏览队列上的第一条消息,不移除它 |
会改变状态的工具(5 个,--read-only 模式下不注册)
工具 | 用途 |
| 对指定队列管理器执行一条纯文本 MQSC 命令(可执行任意命令,包括修改/删除) |
| 以结构化形式执行 MQSC 命令,返回 JSON(同样可执行修改/删除) |
| 取走队列上的第一条消息,消息会从队列中被移除,无法撤销 |
| 向队列发送一条文本消息 |
| 向主题发布一条文本消息 |
对象查询(list_queues/get_queue/list_channels/get_channel/
list_subscriptions/list_topics)统一通过 MQSC 的 runCommandJSON 实现,
而不是走 REST 资源路径,原因见下文「已知限制」第 3 条。
7. 安全提示
默认忽略服务器证书校验(
MQ_VERIFY_SSL=false)。这是为了适配开发镜像的自签名 证书,开箱即用。生产环境应显式开启--verify-ssl(或MQ_VERIFY_SSL=true), 否则连接可能被中间人劫持。默认凭据
admin/admin属于 MQWebAdmin 角色,具备完整管理权限。把本服务器接入 LLM 意味着模型可以调用run_mqsc/run_mqsc_json执行任意 MQSC 命令,包括DELETE QLOCAL、STOP CHANNEL等破坏性操作——这不是理论风险,是这两个工具的 设计使然。生产环境建议改用只读账号,并在启动时加
--read-only(或MQ_READ_ONLY=true)。只读模式下服务器只注册上述 10 个只读工具,run_mqsc、run_mqsc_json、get_message、put_message、publish_message根本不会出现 在 LLM 可见的工具列表里,而不是注册后再依赖权限报错——即便 LLM 尝试调用也无从 下手。
8. 已知限制
以下结论均对真实 MQ 9.4.5.1 实例逐条实测得出,不是查文档推测的:
browse_message只能看到队首一条消息。MQ 的消息 REST API 没有游标分页, 实测连续 3 次 GET 请求返回的是同一条消息(messageId相同、队列深度不变)。 需要遍历整个队列的场景,请改用原生 MQ 客户端(如pymqi),本项目不支持。对象查询统一走 MQSC,而非 REST 资源路径。
/admin/qmgr/{qm}/queue、/channel、/subscription这几个 REST 资源在 MQ 9.4 的 v3 管理 API 下已被 移除(实测返回404 MQWB0116E),仅在 v1 API 保留。本项目改用runCommandJSON统一实现对象查询,覆盖面更广,对 MQ 版本差异也更不敏感—— 这一实现方式对 z/OS 队列管理器同样适用。GET 是浏览、DELETE 才是取走,这是 MQ 消息 REST API 最反直觉的一点:GET 请求消息但不会从队列移除它,只有 DELETE 才会真正取走并从队列删除。本项目用
browse_/get_两种工具命名前缀加以区分,避免 LLM 误用。MQSC 命令失败时 HTTP 状态码仍是 200,失败信息藏在响应体的
overallCompletionCode与错误详情字段(runCommandJSON用message字段、runCommand用text字段,两者不一致)里。本项目在客户端内部统一解析 为结构化错误,工具返回的文本会包含具体的 MQSC 错误原因。队列为空时 DELETE/GET 返回 204 且无响应体,这不是错误。本项目按状态码而非 响应体是否为空来判断队列是否有消息,避免把「取到一条正文为空的消息」误判为 「队列没有消息」。
9. 开发与测试
uv run ruff check .
uv run ruff format --check .
uv run pytest -v # 单元测试,默认跳过需要真实 MQ 实例的集成测试
uv run pytest -m integration -v # 集成测试,需要本机有可访问的真实 MQ 实例Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/moonfruit/ibm-mq-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server