lw-ble-mcp
# lw-ble-mcp — 轻量级蓝牙调试 MCP Server
**lw-ble-mcp** 是一个面向 AI Agent 的轻量级蓝牙低功耗(BLE)调试 MCP 服务器。基于 MCP Python SDK(FastMCP)与 bleak 构建,以 `lw_ble_*` 前缀提供 21 个工具:扫描、连接、GATT 读写、描述符访问、MTU 查询、通知订阅、一键设备侦查(`lw_ble_dump`)与引擎诊断(`lw_ble_engine_status`)。
核心特性:连接永不挂死(全部原生调用在专用 I/O 事件循环上运行,带硬超时)· 下划线工具名兼容广泛 MCP 客户端 · 分层测试体系(76 个用例,含真机回环验证)。
>工具标识统一使用 `lw_ble_` 前缀与下划线风格:`lw`(lightweight,轻量级)沿用嵌入式领域惯例(如 lwIP),`ble` 明确标注协议为蓝牙低功耗。命名刻意保持独立命名空间,避免与常见 `ble_*` 工具名冲突。
**lw-ble-mcp** is a lightweight Bluetooth Low Energy (BLE) debug MCP server for AI agents. Built on the MCP Python SDK (FastMCP) and bleak, it exposes 21 tools under the `lw_ble_*` prefix: scan, connect, GATT read/write, descriptor access, MTU query, notification subscription, one-shot device recon (`lw_ble_dump`), and engine diagnostics (`lw_ble_engine_status`).
Key features: connect never hangs (all native calls run on a dedicated I/O event loop with hard timeouts) · underscore tool names for broad MCP-client compatibility · a layered test suite (76 cases, including real-hardware echo-loop verification).
## 设计要点
| 关注点 | 实现 |
|---|---|
| 连接边界保护 | 全部 bleak 调用跑在**独立线程的专用事件循环**上,外层用 `asyncio.wait_for` 包裹,卡死也能真正超时返回 |
| 客户端兼容性 | 工具名一律用下划线(`lw_ble_scan`),避免点号工具名与部分 MCP 网关冲突 |
| 错误可诊断 | 区分 `entity_not_found` / `operation_timeout` / `link_not_connected` / `internal_error` 等错误码 |
| 依赖 | 使用最新的 bleak 3.x |
## 安装
### 方式一:PyPI 安装(推荐)
```powershell
pip install lw-ble-mcp
```
### 方式二:源码安装
```powershell
pip install -r requirements.txt
```
## 在 Cursor 中配置
编辑全局 `C:\Users\Administrator\.cursor\mcp.json`(PyPI 安装后可直接用命令名):
```json
{
"mcpServers": {
"ble": {
"type": "stdio",
"command": "ble_mcp",
"args": []
}
}
}
```
源码运行时把 `command` 改为你的 Python 路径、`args` 用模块方式:
```json
{
"mcpServers": {
"ble": {
"type": "stdio",
"command": "D:/DevTools/Python/v314/python.exe",
"args": ["-m", "ble_mcp"]
}
}
}
```
配置后重启 Cursor。
## 工具列表
### 扫描
| 工具 | 说明 |
|---|---|
| `lw_ble_scan` | 启动后台扫描(支持 name_filter / service_uuid),返回 scan_id |
| `lw_ble_scan_poll` | 非阻塞获取扫描结果 |
| `lw_ble_scan_stop` | 提前停止扫描 |
| `lw_ble_scan_list` | 列出所有扫描 |
### 连接
| 工具 | 说明 |
|---|---|
| `lw_ble_connect` | 连接外设(带硬超时,不挂死),返回 connection_id |
| `lw_ble_disconnect` | 断开连接 |
| `lw_ble_connection_status` | 查询单个连接状态 |
| `lw_ble_connection_list` | 列出所有连接 |
### GATT 读写
| 工具 | 说明 |
|---|---|
| `lw_ble_discover` | 枚举服务的特征/描述符 |
| `lw_ble_read` | 读 GATT 特征(返回 base64 + hex) |
| `lw_ble_write` | 写 GATT 特征(data_b64 或 data_hex) |
| `lw_ble_read_descriptor` | 按句柄读 GATT 描述符 |
| `lw_ble_write_descriptor` | 按句柄写 GATT 描述符 |
| `lw_ble_mtu` | 查询协商 MTU |
### 通知订阅
| 工具 | 说明 |
|---|---|
| `lw_ble_subscribe` / `lw_ble_unsubscribe` | 订阅/取消订阅通知 |
| `lw_ble_poll_notifications` | 非阻塞拉取通知缓冲 |
| `lw_ble_wait_notification` | 阻塞等待下一条通知 |
| `lw_ble_subscription_list` | 列出订阅 |
### 设备侦查与引擎诊断
| 工具 | 说明 |
|---|---|
| `lw_ble_dump` | 一键侦查:服务表 + 全部可读特征值 + MTU(单个调用完成设备摸底) |
| `lw_ble_engine_status` | 引擎资源状态:连接/扫描/订阅计数、I/O 线程健康度 |
> 信号强度(RSSI)通过 `lw_ble_scan` / `lw_ble_scan_poll` 返回的每个设备记录获取。不提供独立的 RSSI 工具,因为 Windows 的 WinRT API 不支持从已建立连接中读取 RSSI。
## 测试
测试体系(常规/边界/参数/连接/稳定性/压力)详见 [tests/README.md](tests/README.md)。
```powershell
pip install -r requirements-dev.txt
pytest # mock 测试(无需硬件)
pytest -m hw # 真机测试(需 HP_RDTS_P 在线)
```
## 直接运行(冒烟测试)
```powershell
python -m ble_mcp
```
MCP stdio server 会等待 stdin 的协议消息。可用 `npx @modelcontextprotocol/inspector python -m ble_mcp` 进行图形化调试。
## 本地开发运行
```powershell
python -m ble_mcp
```
## 相关信息
| 项目 | 值 |
|:---|:---|
| 模块名 | `lw-ble-mcp` |
| 作者 | linzhiwei(zevonlin) |
| 邮箱 | zevonlin@gmail.com |
| 日期 | 2026-08-10 |
| PyPI | https://pypi.org/project/lw-ble-mcp/ |
| GitHub | https://github.com/zevonlin/lw-ble-mcp |
| 项目主页 | https://github.com/zevonlin |
| 版本 | v0.1.0 |TDQS
Scored across 21 tools
Most tools target a distinct resource+action (connect/disconnect, read/write, subscribe/unsubscribe), and the descriptions clearly separate similar-sounding pairs like scan_poll vs scan_list and poll_notifications vs wait_notification. The main soft spot is lw_ble_dump overlapping with lw_ble_discover + lw_ble_read, since dump bundles discovery and characteristic reads into one convenience call.
All tools share the lw_ble_ prefix and snake_case, with a predictable verb_noun pattern (scan_stop, read_descriptor, poll_notifications, subscription_list). A few names are noun-only or omit the verb (mtu, dump, engine_status, connection_status), which is a minor deviation from the otherwise consistent scheme.
At 21 tools this is on the heavier side, but the BLE domain legitimately spans scanning, connection management, GATT discovery, characteristic/descriptor I/O, notifications, and diagnostics, and each tool maps to a real operation. No tool looks like filler, though a couple (dump, engine_status) are arguably conveniences rather than primitives.
The surface covers the full BLE lifecycle: scan start/poll/stop/list, connect/disconnect/status/list, GATT discovery, characteristic read/write, descriptor read/write, notification subscribe/unsubscribe/poll/wait/list, MTU, plus dump and engine diagnostics. There are no obvious dead ends for typical central-role workflows.