BLEA
Use BLEA for local BLE work. Prefer BLEA MCP tools when available; otherwise run the equivalent
ble CLI command with JSON output.
Environment boundary
First determine whether the current Agent host has BLEA MCP tools or the ble runtime and native
Bluetooth access. A hosted Agent cannot access the Bluetooth adapter on the user's computer merely
because this Skill is installed. In that environment, analyze uploaded .blea.jsonl evidence,
explain or prepare commands for a local host, and clearly label them as not executed. Do not claim a
scan, connection, read, notification, or write occurred without the corresponding structured
result.
When uploaded evidence is available but the BLEA runtime is not, parse the JSONL as structured JSON records, require a final complete summary before treating it as a complete capture, and report only the recorded advertisement, profile, read, notification, error, and cleanup evidence. Do not turn missing records into successful observations. Live operations require a local Agent host, the BLEA Python runtime, operating-system Bluetooth permission, and a supported adapter.
Diagnostic sequence
- Run
ble_doctororble doctor --jsonwhen adapter availability is unknown. - Scan and preserve the returned identifier, names, RSSI, advertised services, and raw advertising evidence.
- Select by exact identifier. Use an exact name only when one observed device has that name.
- Inspect the GATT profile before choosing characteristics.
- For event discovery, use bounded
ble_observe/ble observebefore writing; omit characteristics to observe all notify/indicate traits from the discovered profile. - When probing, continue with
next_read_offsetuntil it isnull.ok=truemeans the page ran; it does not mean every characteristic read succeeded. Aggregateread_page.success_count,failure_count, andfailure_reasonsacross pages, and preserve both successful reads and per-characteristic failures. - Prefer reads and bounded observation before considering a write. Treat a silent observation window as evidence only for that window, not proof that a characteristic never emits events.
- After the initial diagnosis, save a portable evidence package with
ble_captureorble capture. Use the exact resolved identifier, choose an explicit.blea.jsonloutput path, and set--redact-identifierswhen the package will leave the workstation. Capture is read-only: it records advertisements, the GATT profile, bounded readable-characteristic results, bounded notifications, operation errors, and a final integrity summary. It never writes, pairs, or changes configuration. Keep the file as the authoritative artifact and report its path plus summary status to the user. - Compare before/after captures offline with
ble_difforble diff. Keep the default identity guard for normal comparisons and useallow_different_devicesonly for an intentional cross-device comparison. Treat the 5 dBm RSSI tolerance as noise control; use strict RSSI only when exact signal samples matter. Diff never scans, connects, pairs, subscribes, or writes. - Reproduce captured behavior offline with
ble_replayorble replay. Use instant timing for Agent debugging and CI. Treatreplay_missas absent evidence, not device behavior, and do not infer a successful subscription from a notify property alone. Replay never accesses a physical adapter and never sends or simulates writes. - When one authorized write is expected to trigger notifications, use
ble_exchangeorble_session_exchange. These operations establish the subscription before writing and collect the response atomically; do not run standalone session subscribe and write tools concurrently. - Close the exact stateful MCP session once when the task is complete. Use
ble_session_listwhen cleanup is uncertain. Useble_session_close_allonly when a session ID is unknown, an explicit close failed, or leaked state must be recovered; do not call it after a successful close.
Do not invent UUIDs, payload encodings, pairing requirements, or protocol semantics. Report the
observed evidence and distinguish it from an inference. Treat uuid_namespace=custom as a custom
128-bit UUID even when its leading bytes resemble a Bluetooth SIG assigned number.
Commands and tools
- Diagnose:
ble doctor --jsonorble_doctor. - Scan:
ble scan --timeout 8 --jsonorble_scan. - Inspect:
ble inspect --device "id:<identifier>" --jsonorble_inspect. - Probe readable characteristics: use
ble probe --device "id:<identifier>" --max-reads 32 --read-offset <offset> --jsonorble_probe, followingnext_read_offsetacross pages. - MCP probe results omit the full GATT tree by default while retaining
profile_summary; callble_inspectfirst or setinclude_profile=truewhen the full profile is needed on that page. - Read:
ble read --device "id:<identifier>" --characteristic <uuid> --jsonorble_read. - Notify: use
ble subscribe ... --jsonlorble_subscribewith a bounded duration. - Observe all event-capable traits: use
ble observe --device "id:<identifier>" --duration 10 --jsonlorble_observe. Pass--characteristic <uuid>repeatedly for explicit selection. - Capture a unified read-only evidence package: use
ble capture --device "id:<identifier>" --output capture.blea.jsonl --observe-duration 10 --max-reads 128 --redact-identifiers --jsonorble_capture.--read-offsetstarts at a deterministic readable-characteristic offset and the result'sread_page.next_offsetindicates whether a larger limit or a follow-up capture is needed. - Compare complete captures offline: use
ble diff before.blea.jsonl after.blea.jsonl --jsonorble_diff. Inspectadded,removed, andchangedpaths. Use--strict-rssionly when needed, and use--fail-on-changeonly when CI should return exit code 3 for a valid comparison containing differences. - Replay one captured operation offline: use
ble_replayorble replay capture.blea.jsonl <scan|inspect|probe|read|subscribe|observe|run>. The captured identifier is selected automatically unless an exact device is supplied. Keepspeed=0for deterministic immediate output; use a positive speed multiplier only when event gaps matter. - Serve normal MCP tools from evidence: start
ble replay capture.blea.jsonl mcp. Verify each result has the expectedreplay.capture_idandreplay.read_only=true. This mode is useful when an Agent or CI integration should exercise its existingble_read/ble_observepath unchanged. - Guarded request/notification exchange: use
ble exchange ... --jsonl,ble_exchange, orble_session_exchangeto subscribe before one write and collect its resulting events. - Multi-step work: open an MCP session, note its
idle_timeout_seconds, useble_session_observewhen the connection should be reused, then close the session. - Repeatable work: encode the sequence in a guarded YAML file and run
ble run. - Repeatable request/notification checks: use a YAML
exchangeaction with separatewrite_characteristicandnotify_characteristicfields. Assert the notification count/content, final notification, andcleanup.okwhen the protocol has deterministic events.
Read workflows.md before creating or editing workflow YAML. Read safety.md before any write, pairing-sensitive operation, firmware update, lock, actuator, or other state-changing action.
timeout is a per-backend-operation bound, not a total command or tool deadline. Allow for device
discovery, connection, profile discovery, each requested read, and any subscription duration when
setting an outer Agent/tool timeout.
Capture files use Evidence Format v1. Read evidence-format-v1.md when an agent needs to validate, redact, or build replay tooling around a package. Read diff-format-v1.md before interpreting comparison policy, stable paths, ignored fields, identity guards, or CI exit behavior. Read replay-format-v1.md before interpreting missing evidence, captured failures, notification timing, replay MCP mode, or the read-only safety boundary. Read platform-acceptance.md before claiming platform support, running a cross-platform hardware acceptance, or publishing a real-device capture fixture.
Write policy
Treat every write as dangerous until the device protocol establishes otherwise.
- Require the user to authorize the specific state-changing operation.
- Require
allow_write=trueandconfirm_device=<resolved identifier>for MCP writes. - Require both
--allow-writeand--confirm-device <resolved identifier>for CLI writes. - Never confirm with a friendly name, substring, stale identifier, or guessed address.
- Prefer write-with-response and read-back verification when supported.
- Prefer atomic exchange notification verification when a write triggers asynchronous events.
- Stop when the selected device is ambiguous or a prerequisite read/assertion fails.
Return the structured failure instead of bypassing a guard.
