Ble MCP Server
Bluetooth Low Energy (BLE) MCP server for Claude Code and other MCP-compatible agents.
Install / Use
/learn @es617/Ble MCP ServerQuality Score
Category
Development & EngineeringSupported Platforms
README
BLE MCP Server
<!-- mcp-name: io.github.es617/ble-mcp-server -->
A stateful Bluetooth Low Energy (BLE) Model Context Protocol (MCP) server for developer tooling and AI agents. Works out of the box with Claude Code, VS Code with Copilot, and any MCP-compatible runtime. Communicates over stdio (no HTTP, no open ports) and uses bleak for cross-platform BLE on macOS, Windows, and Linux.
Example: Let Claude Code scan for nearby BLE devices, connect to one, read characteristics, and stream notifications from real hardware.
Demo
7-minute video walkthrough — scanning a real BLE device, discovering services, reading values, and promoting flows into plugins.
Why this exists
You have a BLE device. You want an AI agent to talk to it — scan, connect, read sensors, send commands, stream data. This server makes that possible.
It gives any MCP-compatible agent a full set of BLE tools: scanning, connecting, reading, writing, subscribing to notifications — plus protocol specs and device plugins, so the agent can reason about higher-level device behavior instead of just raw UUIDs and bytes.
The agent calls these tools, gets structured JSON back, and reasons about what to do next — no human in the loop for each BLE operation.
What agents can do with it:
- Develop and debug — connect to your device, explore its services, read characteristics, test commands, and diagnose issues conversationally. "Why is this sensor returning zeros?" becomes a question you can ask.
- Iterate on new hardware — building a BLE device? Attach a protocol spec so the agent understands your commands and data formats as you evolve them.
- Automate testing — write device-specific plugins that expose high-level actions (e.g., device.start_stream, device.run_self_test), then let the agent run test sequences: enable a sensor, collect samples, validate values, report results.
- Explore — point the agent at a device you’ve never seen. It discovers services, probes characteristics, and builds up protocol documentation from scratch.
- Build BLE automation — agents controlling real hardware for real tasks: reading environmental sensors on a schedule, managing a fleet of BLE beacons, triggering actuators based on conditions.
Who is this for?
- Embedded engineers — faster iteration on BLE protocols, conversational debugging, automated test sequences
- Hobbyists and makers — explore BLE devices without writing boilerplate; let the agent help reverse-engineer simple protocols
- QA and test engineers — build repeatable BLE test suites with plugin tools, run them from CI or agent sessions
- Support and field engineers — diagnose BLE device issues interactively without specialized tooling
- Researchers — automate data collection from BLE sensors, explore device capabilities systematically
Quickstart (Claude Code)
pip install ble-mcp-server
# Register the MCP server with Claude Code (read-only by default)
claude mcp add ble -- ble_mcp
Then in Claude Code, try:
"Scan for nearby BLE devices and connect to the one whose name starts with Arduino."
The server is read-only by default. Writes and plugins can control real hardware and execute code, and are opt-in via environment variables. See Safety for details.
<p align="center"><img src="https://raw.githubusercontent.com/es617/ble-mcp-server/main/docs/assets/scan.gif" alt="Scanning for BLE devices" width="600"></p>What the agent can do
Once connected, the agent has full BLE capabilities:
- Scan for nearby devices, with optional name or service UUID filters
- Connect to a device and discover its services and characteristics
- Read and write characteristic values (writes require
BLE_MCP_ALLOW_WRITES) - Subscribe to notifications and collect streaming data — single events, polling, or batch draining
- Attach protocol specs to understand device-specific commands and data formats
- Use plugins for high-level device operations (e.g.,
sensortag.read_temp) instead of raw reads/writes - Create specs and plugins for new devices, building up reusable knowledge across sessions
The agent handles multi-step flows automatically. For example, "read the temperature from my SensorTag" might involve scanning, connecting, discovering services, attaching a spec, enabling the sensor, and reading the value — without you specifying each step.
At a high level:
Raw BLE → Protocol Spec → Plugin
You can start with raw BLE tools, then move up the stack as your device protocol becomes understood and repeatable. See Concepts for how the pieces fit together.
Install (development)
# Editable install from repo root
pip install -e .
# Or with uv
uv pip install -e .
MCP is a protocol — this server works with any MCP-compatible client. Below are setup instructions for the most common ones.
Add to Claude Code
# Minimal (read-only)
claude mcp add ble -- ble_mcp
# Or run as a module
claude mcp add ble -- python -m ble_mcp_server
# Enable writes
claude mcp add ble -e BLE_MCP_ALLOW_WRITES=true -- ble_mcp
# Enable writes with an allowlist of characteristic UUIDs
claude mcp add ble \
-e BLE_MCP_ALLOW_WRITES=true \
-e BLE_MCP_WRITE_ALLOWLIST="2a00,12345678-1234-1234-1234-123456789abc" \
-- ble_mcp
# Enable all plugins
claude mcp add ble -e BLE_MCP_PLUGINS=all -- ble_mcp
# Enable specific plugins only
claude mcp add ble -e BLE_MCP_PLUGINS=sensortag,hello -- ble_mcp
# Debug logging
claude mcp add ble -e BLE_MCP_LOG_LEVEL=DEBUG -- ble_mcp
Add to VS Code / Copilot
Add to your project's .vscode/mcp.json (or create it):
{
"servers": {
"ble": {
"type": "stdio",
"command": "ble_mcp",
"args": [],
"env": {
"BLE_MCP_ALLOW_WRITES": "true",
"BLE_MCP_PLUGINS": "all"
}
}
}
}
Adjust env to match your needs — remove BLE_MCP_ALLOW_WRITES for read-only mode, or set BLE_MCP_PLUGINS to specific plugin names.
Add to Cursor
Add to your project's .cursor/mcp.json (or create it). Cursor does not support dots in tool names, so BLE_MCP_TOOL_SEPARATOR must be set to _:
{
"mcpServers": {
"ble": {
"command": "ble_mcp",
"args": [],
"env": {
"BLE_MCP_ALLOW_WRITES": "true",
"BLE_MCP_PLUGINS": "all",
"BLE_MCP_TOOL_SEPARATOR": "_"
}
}
}
}
Environment variables
| Variable | Default | Description |
|---|---|---|
| BLE_MCP_ALLOW_WRITES | disabled | Set to true, 1, or yes to enable ble.write. |
| BLE_MCP_WRITE_ALLOWLIST | empty | Comma-separated UUID allowlist for writable characteristics (checked only when writes are enabled). |
| BLE_MCP_PLUGINS | disabled | Plugin policy: all to allow all, or name1,name2 to allow specific plugins. Unset = disabled. |
| BLE_MCP_LOG_LEVEL | WARNING | Python log level (DEBUG, INFO, WARNING, ERROR). Logs go to stderr. |
| BLE_MCP_TRACE | enabled | JSONL tracing of every tool call. Set to 0, false, or no to disable. |
| BLE_MCP_TRACE_PAYLOADS | disabled | Include value_b64/value_hex in traced args (stripped by default). |
| BLE_MCP_TRACE_MAX_BYTES | 16384 | Max payload chars before truncation (only applies when TRACE_PAYLOADS is on). |
| BLE_MCP_TOOL_SEPARATOR | . | Character used to separate tool name segments. Set to _ for MCP clients that reject dots in tool names (e.g. Cursor). |
Tools
See Concepts for how everything fits together, and the Tools Reference for detailed input/output schemas.
| Category | Tools |
|---|---|
| BLE Core | ble.scan_start, ble.scan_get_results, ble.scan_stop, ble.connect, ble.disconnect, ble.connection_status, ble.discover, ble.mtu, ble.read, ble.write, ble.read_descriptor, ble.write_descriptor, ble.subscribe, ble.unsubscribe, ble.wait_notification, ble.poll_notifications, ble.drain_notifications |
| Introspection | ble.connections.list, ble.subscriptions.list, ble.scans.list |
| Protocol Specs | ble.spec.template, ble.spec.register, ble.spec.list, ble.spec.attach, ble.spec.get, ble.spec.read, ble.spec.search |
| Tracing | ble.trace.status, ble.trace.tail |
| Plugins | ble.plugin.template, ble.plugin.list, ble.plugin.reload, ble.plugin.load |
Protocol Specs
Specs are markdown files that describe a BLE device's protocol — services, characteristics, commands, and data formats. They live in .ble_mcp/specs/ and teach the agent what a device can do beyond raw UUIDs and bytes.
Without a spec, the agent can still discover services and read characteristics. With a spec, it knows what the values mean and what commands to send.
You can create specs by telling the agent about your device — paste a datasheet, describe the protocol, or just let it explore and document what it finds. The agent generates the spec file, registers it, and references it in future sessions. You can also write specs by hand.
<p align="center"><img src="https://raw.githubusercontent.com/es617/ble-mcp-server/main/docs/assets/specs_flow.gif" alt="Working with protocol specs" width="600"></p>See Concepts for details on spec format and how the agent uses them.
Plugins
Plugins add device-specific shortcut tools to
