Skip to content

BLE & GATT

import { Aside } from ‘@astrojs/starlight/components’;

Bluetooth Low Energy (BLE) devices use GATT (Generic Attribute Profile) to expose services and characteristics. mcbluetooth provides tools to discover, read, write, and subscribe to BLE data.

bt_ble_scan adapter="hci0" timeout=10
# Filter by name
bt_ble_scan adapter="hci0" name_filter="Fitness"
# Filter by service UUID
bt_ble_scan adapter="hci0" service_filter="0000180d-0000-1000-8000-00805f9b34fb"

BLE devices organize data hierarchically:

Device
└── Service (UUID: 0000180d-...) ← Heart Rate Service
├── Characteristic (UUID: 00002a37-...) ← Heart Rate Measurement
│ └── Descriptor ← Client Configuration
└── Characteristic (UUID: 00002a38-...) ← Body Sensor Location

After connecting:

bt_ble_services adapter="hci0" address="AA:BB:CC:DD:EE:FF"

Returns:

[
{
"uuid": "0000180f-0000-1000-8000-00805f9b34fb",
"primary": true,
"description": "Battery Service"
},
{
"uuid": "0000180d-0000-1000-8000-00805f9b34fb",
"primary": true,
"description": "Heart Rate Service"
}
]
# All characteristics
bt_ble_characteristics adapter="hci0" address="AA:BB:CC:DD:EE:FF"
# Filter by service
bt_ble_characteristics adapter="hci0" address="..." service_uuid="0000180f-0000-1000-8000-00805f9b34fb"

Returns:

[
{
"uuid": "00002a19-0000-1000-8000-00805f9b34fb",
"flags": ["read", "notify"],
"description": "Battery Level"
}
]
bt_ble_battery adapter="hci0" address="AA:BB:CC:DD:EE:FF"

Returns battery percentage (0-100).

bt_ble_read adapter="hci0" address="..." char_uuid="00002a19-0000-1000-8000-00805f9b34fb"

Returns:

{
"hex": "4b",
"decoded": 75,
"description": "Battery Level: 75%"
}
# Write hex bytes
bt_ble_write adapter="hci0" address="..." char_uuid="..." value="0102ff" value_type="hex"
# Write string
bt_ble_write adapter="hci0" address="..." char_uuid="..." value="hello" value_type="string"
# Write integer
bt_ble_write adapter="hci0" address="..." char_uuid="..." value="42" value_type="int"
# With response (default) - waits for acknowledgment
bt_ble_write ... with_response=true
# Without response (faster, less reliable)
bt_ble_write ... with_response=false

BLE notifications let devices push data when values change — essential for real-time sensor data like heart rate, temperature, or button presses.

bt_ble_notify adapter="hci0" address="..." char_uuid="00002a37-..." enable=true

Returns:

{
"status": "notifications_enabled",
"uuid": "00002a37-0000-1000-8000-00805f9b34fb",
"uuid_short": "0x2A37",
"resource_uri": "bluetooth://ble/AA:BB:CC:DD:EE:FF/00002a37-.../notifications",
"history_uri": "bluetooth://ble/AA:BB:CC:DD:EE:FF/00002a37-.../notifications/history"
}

Notification values are automatically buffered (up to 100) and accessible via MCP resources:

# Latest value and stats
ReadMcpResource uri="bluetooth://ble/AA:BB:CC:DD:EE:FF/00002a37-.../notifications"
# Buffered history
ReadMcpResource uri="bluetooth://ble/AA:BB:CC:DD:EE:FF/00002a37-.../notifications/history"

Latest notification resource:

{
"address": "AA:BB:CC:DD:EE:FF",
"characteristic_uuid": "00002a37-...",
"notifying": true,
"latest": {
"timestamp": "2026-02-09T20:05:39.091206+00:00",
"value_hex": "1648",
"value_bytes": [22, 72]
},
"buffer_count": 15,
"total_received": 47
}
bt_ble_notification_status

Returns all active notification subscriptions with buffer stats.

bt_ble_clear_notification_buffer adapter="hci0" address="..." char_uuid="..."

Clears buffered values while keeping the subscription active.

bt_ble_notify adapter="hci0" address="..." char_uuid="..." enable=false
ServiceUUIDDescription
Generic Access0x1800Device name, appearance
Generic Attribute0x1801Service change indication
Battery0x180FBattery level
Device Information0x180AManufacturer, model, etc.
Heart Rate0x180DHeart rate measurement
Health Thermometer0x1809Temperature
Blood Pressure0x1810Blood pressure
CharacteristicUUIDService
Battery Level0x2A19Battery
Heart Rate Measurement0x2A37Heart Rate
Temperature Measurement0x2A1CHealth Thermometer
Manufacturer Name0x2A29Device Information
Model Number0x2A24Device Information
# Scan for heart rate monitors
bt_ble_scan adapter="hci0" service_filter="0000180d-0000-1000-8000-00805f9b34fb"
# Connect
bt_connect adapter="hci0" address="AA:BB:CC:DD:EE:FF"
# List services
bt_ble_services adapter="hci0" address="..."
# Enable heart rate notifications
bt_ble_notify adapter="hci0" address="..." char_uuid="00002a37-0000-1000-8000-00805f9b34fb" enable=true
# Read body sensor location
bt_ble_read adapter="hci0" address="..." char_uuid="00002a38-0000-1000-8000-00805f9b34fb"
# Connect to bulb
bt_connect adapter="hci0" address="AA:BB:CC:DD:EE:FF"
# Find the control characteristic (vendor-specific)
bt_ble_characteristics adapter="hci0" address="..."
# Write command to turn on (example - actual commands vary by device)
bt_ble_write adapter="hci0" address="..." char_uuid="..." value="01" value_type="hex"
# Set color (RGB example)
bt_ble_write adapter="hci0" address="..." char_uuid="..." value="ff0000" value_type="hex"

Services aren’t discovered yet. Wait a moment after connecting:

bt_connect adapter="hci0" address="..."
# Wait 2-3 seconds
bt_ble_services adapter="hci0" address="..."

Check the characteristic flags:

  • read must be present for reading
  • write or write-without-response for writing
  • notify for notifications

BLE has limited connection capacity. Try:

  • Disconnecting other BLE devices
  • Moving closer to the adapter
  • Checking device battery level