Skip to main content

bmahs-mcp-gateway

BMAHS(比马斯) 是一个开放的局域网硬件协议:每台设备上电即用自然语言「自我介绍」——我是谁、能做什么、安全边界在哪——让大模型智能体像接入 USB 设备一样,即插即用地发现、识别、按权限独占并安全地操作它们。

BMAHS(比马斯)设备协议 ↔ MCP 网关:把局域网内按 bmahs/1.0 协议发布的硬件设备(解析侧兼容旧版 1–1.2 字段名)动态映射为 Model Context Protocol 工具,让大模型客户端可以直接发现、占用与操作这些设备。

特性

  • 零配置发现:UDP 组播(239.255.42.42:5354 / [ff02::4242]:5354)+ Bonjour/mDNS 双通道,设备上线即被识别;也支持 BMAHS_STATIC_DEVICES 静态设备表(适配不支持组播的环境)。
  • 动态工具映射:设备的动作清单(ops)自动映射为 MCP 工具,含参数 Schema 与 any_of 预检,无需为每类设备写适配代码。
  • 协议级占用安全:控制前自动 occupy、自动携带 token、任务结束/进程退出自动 release,token 不写入 UDP/TXT/日志。
  • 标准错误信封:设备错误按 §4.7 信封(ok/action/code/error/retryable)透传给模型,error 为自然语言中文。
  • 参数死循环防护(1.3.0,默认开启):参数净化器自动矫正畸形入参(device 传成 {id: 名称} 对象、数字加引号、id/动作名近似错),同参连续失败升级提示直至停止令;报错附可逐字照抄的 retry_with 模板。
  • 设备侧 SDK:单文件 sdk/bmahs_device.py(仅标准库、拷走即用)——厂商声明「我是谁、有哪些动作」,发现/hello/信封/校验/占用全托管,声明即校验。
  • 两种接入模式:stdio(单客户端,MCP 客户端直接拉起)与 Streamable HTTP(多客户端共享一个网关进程,可选 Bearer Token 鉴权)。

安装

推荐隔离安装(uv tool 或 pipx):包与依赖装在独立环境,不污染系统/conda Python,任何终端可直接用 bmahs-mcp:

uv tool install "bmahs-mcp-gateway[http]"   # 首选;只用 stdio 模式可去掉 [http]
pipx install "bmahs-mcp-gateway[http]"     # 等效的 pipx 写法

也可直接 pip 装(装进当前 Python 环境,依赖与其它包共享、可能冲突,换环境后命令不可用):

pip install bmahs-mcp-gateway            # stdio 模式,最小依赖
pip install "bmahs-mcp-gateway[http]"    # 需要 Streamable HTTP 共享模式时

作为库集成时用 uv:uv add bmahs-mcp-gateway。要求 Python ≥ 3.10。

验证:bmahs-mcp --version 输出 bmahs-mcp 1.4.0。

快速开始

# 扫描局域网内的 BMAHS 设备
bmahs-mcp discover

# 联调:对设备执行一个动作(控制类动作自动 occupy → 执行 → release)
bmahs-mcp ctl 客厅灯 on
bmahs-mcp ctl 客厅灯 brightness --arg level=80
bmahs-mcp ctl 客厅灯 scene --arg name=cinema --ttl 600        # 指定占用租约 600 秒
bmahs-mcp ctl 客厅灯 on --no-release                          # 动作后保持占用(打印 token)
bmahs-mcp ctl 客厅灯 release --arg token=<占有时返回的 token>  # 手动释放保持的占用

# 启动 MCP 网关(stdio,供 MCP 客户端连接;默认子命令)
bmahs-mcp serve

# 以 Streamable HTTP 共享模式启动(多客户端同时连接)
bmahs-mcp http --host 0.0.0.0 --port 9530 --token 换成你的令牌

在 MCP 客户端(ZCode / Claude Desktop 等)中配置 stdio 接入:

{
  "mcpServers": {
    "bmahs": {
      "command": "bmahs-mcp",
      "args": ["serve"]
    }
  }
}

HTTP 模式的端点为 http://<host>:9530/mcp;设置了 --token 后客户端须携带 Authorization: Bearer <token>。

重启客户端后,模型可见两类工具:7 个固定工具——bmahs_devices(列设备)、bmahs_refresh(重扫描)、bmahs_describe(读自述)、bmahs_occupy / bmahs_release(占用/释放)、bmahs_call(泛化调用)、bmahs_screenshot(ui 设备抓屏);以及每台设备的动态工具——<设备id>__<动作>(如 demo-light-001__brightness),参数说明来自设备自述。典型流程:bmahs_devices 选型 → 直接调动态工具(网关自动 occupy 并携带 token,默认 120 秒租约)→ 用完 bmahs_release;token 由网关代管并遮蔽,不进模型上下文。

完整教程(也可在 GitHub 仓库 docs/ 目录阅读):

  • docs/quickstart.md —— 双轨快速开始:路线 A 十分钟跑通「三台虚拟设备 + MCP 客户端 + 一句话编排」;路线 B 写一台自己的设备。
  • docs/write-a-device.md —— 用设备侧 SDK 写一台设备:从声明到被模型调用的六步。

设备侧 SDK 与示例

设备侧 SDK sdk/bmahs_device.py:单文件、仅 Python 标准库、拷走即用(随 sdist 分发)。厂商只声明「我是谁、有哪些动作」,其余全部托管:UDP 发现(announce burst / 稳态心跳 / want 过滤应答 / goodbye)、连接即推 hello 通知、JSON-RPC 信封与 §9.1 错误码映射、参数校验(声明即校验,args 的 type/min/max/enum 自动变成 bad-arg/-32602)、last-wins / exclusive(token + 租约)占用状态机。业务失败直接 raise DeviceError("busy", "…", retryable=True)。六步教程见 docs/write-a-device.md。

示例 说明
examples/dashboard.py 一键演示:两台虚拟开关 + 全彩氛围灯 + 组播自动发现 + 网页面板(http://127.0.0.1:19530)
examples/demo_light.py 全彩灯完整参考实现(1.0/1.1/1.2 三形态、last-wins/exclusive、Bonjour、地址变化自愈)
examples/demo_switch.py 虚拟开关设备(嵌入 dashboard 使用)
examples/sdk_light.py 用 SDK 写的最小 1.2 示例灯(约 60 行声明,sdk-light-001,端口 9541)

SDK 协议栈回归测试:uv run python -m pytest tests/test_bmahs_device.py -q。

常见问题

  • 扫不到设备? 确认设备已上电且同网段、Windows 防火墙放行 UDP 5354 入站;多网卡机器用 BMAHS_MCAST_IF_V4 指定网卡;跨网段/容器用 BMAHS_STATIC_DEVICES=tcp://IP:端口 静态表兜底。
  • 报「正被 xxx 占用」(occupied)? 设备独占中:bmahs_devices 看 holder/until,等租约到期或请占用方 bmahs_release;协议无强夺机制(防止两个模型打架)。
  • HTTP 模式 401? 请求头须带 Authorization: Bearer <--token 设置的值>。
  • stdio 模式没有输出? 正常:stdout 是 MCP 协议通道,日志全走 stderr(BMAHS_LOG_LEVEL=debug 调高)。

环境变量

变量 说明
BMAHS_AGENT_ID 网关在协议中的智能体 id(默认自动生成)
BMAHS_STATIC_DEVICES 静态设备表,如 tcp://192.168.1.10:9527,逗号分隔
BMAHS_BONJOUR_BROWSE 0 关闭 mDNS 浏览通道(默认开)
BMAHS_AUTO_OCCUPY / BMAHS_AUTO_OCCUPY_TTL / BMAHS_MAX_LEASE 自动占用策略与租约上限
BMAHS_CALL_TIMEOUT / BMAHS_QUERY_INTERVAL / BMAHS_EXPIRE_SEC 调用超时、设备表刷新与过期时间
BMAHS_HTTP_HOST / BMAHS_HTTP_PORT / BMAHS_HTTP_PATH / BMAHS_HTTP_TOKEN HTTP 模式默认参数
BMAHS_LOG_LEVEL 日志级别(日志一律走 stderr,不污染 stdio 协议通道)
BMAHS_ARG_COERCE 1 开启参数净化器(防线②):device 传成对象自动解包、字符串数字转声明类型、id/动作名近似矫正;0 关闭
BMAHS_LOOP_GUARD / BMAHS_LOOP_GUARD_MAX 1 / 3 防循环守卫(防线③):同一工具同参连续失败第 2 次升级提示、第 N 次下达停止令
BMAHS_DESCRIBE_OPTIONAL 1 bmahs_describe 的 device 可选(唯一设备自动选中,多台返回选择清单)
BMAHS_DEVICE_TOOLS 0 备用:为每台设备生成零参数 <id>__describe 动态别名

协议

BMAHS 协议要点:UDP 组播一报文一 JSON(≤1400 字节)负责发现,TCP 一行 JSON + \n 负责控制,连接后先读设备 hello;网关在协议中承担「智能体」角色。完整协议文档见 docs/BMAHS1.0.md。

本地开发与构建

uv sync        # 安装依赖(含 dev 组)
uv build       # 在本目录构建 wheel + sdist(注意在包目录内执行并加 --out-dir dist)
uv publish     # 发布到 PyPI(需配置 token)
uv run pytest  # 运行测试

License

MIT

Metadata

Release files for bmahs-mcp-gateway 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bmahs-mcp-gateway 1.4.0
File Size Uploaded Provenance Actions
bmahs_mcp_gateway-1.4.0.tar.gz 112.7 kB Without provenance Details for bmahs_mcp_gateway-1.4.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bmahs-mcp-gateway 1.4.0
File Interpreter ABI Platform Actions
bmahs_mcp_gateway-1.4.0-py3-none-any.whl Python 3 none any Details for bmahs_mcp_gateway-1.4.0-py3-none-any.whl

Total release size: 181.3 kB

Release files / bmahs_mcp_gateway-1.4.0.tar.gz

Download URL bmahs_mcp_gateway-1.4.0.tar.gz
Size 112.7 kB
Tags Source
SHA-256 checksum
How to use checksums
4e25a253a17efc5e6f60dfdb2677ba943c9dfc2e1935b3eeb358542687eb7d55
BLAKE2b-256 checksum
How to use checksums
996fad9b9aa33e6aa9deebb2329e9ff05d4206882d564a146e7b8ed3be7473ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / bmahs_mcp_gateway-1.4.0-py3-none-any.whl

Download URL bmahs_mcp_gateway-1.4.0-py3-none-any.whl
Size 68.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ef484af73cf57c829e92042fff59c9f64c787815ffff4f02abb32665c5fa0c23
BLAKE2b-256 checksum
How to use checksums
a7c36b1fc9d73fbbc75b02a7f8fa0e851cb939be5b5197bffe38520aefef26a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for bmahs-mcp-gateway 1.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page