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_doctor or ble doctor --json when 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 observe before writing; omit characteristics
to observe all notify/indicate traits from the discovered profile.
- When probing, continue with
next_read_offset until it is null. ok=true means the page ran;
it does not mean every characteristic read succeeded. Aggregate read_page.success_count,
failure_count, and failure_reasons across 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_capture or
ble capture. Use the exact resolved identifier, choose an explicit .blea.jsonl output path,
and set --redact-identifiers when 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_diff or ble diff. Keep the default identity
guard for normal comparisons and use allow_different_devices only 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_replay or ble replay. Use instant timing for
Agent debugging and CI. Treat replay_miss as 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_exchange or
ble_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_list when
cleanup is uncertain. Use ble_session_close_all only 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 --json or ble_doctor.
- Scan:
ble scan --timeout 8 --json or ble_scan.
- Inspect:
ble inspect --device "id:<identifier>" --json or ble_inspect.
- Probe readable characteristics: use
ble probe --device "id:<identifier>" --max-reads 32 --read-offset <offset> --json or ble_probe, following next_read_offset across pages.
- MCP probe results omit the full GATT tree by default while retaining
profile_summary; call
ble_inspect first or set include_profile=true when the full profile is needed on that page.
- Read:
ble read --device "id:<identifier>" --characteristic <uuid> --json or ble_read.
- Notify: use
ble subscribe ... --jsonl or ble_subscribe with a bounded duration.
- Observe all event-capable traits: use
ble observe --device "id:<identifier>" --duration 10 --jsonl or ble_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 --json or ble_capture. --read-offset starts at a
deterministic readable-characteristic offset and the result's read_page.next_offset indicates
whether a larger limit or a follow-up capture is needed.
- Compare complete captures offline: use
ble diff before.blea.jsonl after.blea.jsonl --json or ble_diff. Inspect added, removed,
and changed paths. Use --strict-rssi only when needed, and use --fail-on-change only when CI
should return exit code 3 for a valid comparison containing differences.
- Replay one captured operation offline: use
ble_replay or
ble replay capture.blea.jsonl <scan|inspect|probe|read|subscribe|observe|run>. The captured
identifier is selected automatically unless an exact device is supplied. Keep speed=0 for
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 expected replay.capture_id and replay.read_only=true. This mode is useful when
an Agent or CI integration should exercise its existing ble_read/ble_observe path unchanged.
- Guarded request/notification exchange: use
ble exchange ... --jsonl, ble_exchange, or
ble_session_exchange to subscribe before one write and collect its resulting events.
- Multi-step work: open an MCP session, note its
idle_timeout_seconds, use
ble_session_observe when 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
exchange action with separate
write_characteristic and notify_characteristic fields. Assert the notification count/content,
final notification, and cleanup.ok when 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=true and confirm_device=<resolved identifier> for MCP writes.
- Require both
--allow-write and --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.
1---2name: ble3description: Use BLEA to diagnose and automate local Bluetooth Low Energy devices. Trigger for BLE adapter or permission problems, nearby-device scans, deterministic device selection, GATT discovery and reads, bounded notification observation, read-only JSONL evidence capture, offline semantic comparison or replay of BLE captures, adapter-free CI tests, guarded request/notification exchanges, guarded writes, repeatable BLE YAML workflows, and raw-byte evidence collection through the `ble` CLI or BLEA MCP tools.4---56# BLEA78Use BLEA for local BLE work. Prefer BLEA MCP tools when available; otherwise run the equivalent9`ble` CLI command with JSON output.1011## Environment boundary1213First determine whether the current Agent host has BLEA MCP tools or the `ble` runtime and native14Bluetooth access. A hosted Agent cannot access the Bluetooth adapter on the user's computer merely15because this Skill is installed. In that environment, analyze uploaded `.blea.jsonl` evidence,16explain or prepare commands for a local host, and clearly label them as not executed. Do not claim a17scan, connection, read, notification, or write occurred without the corresponding structured18result.1920When uploaded evidence is available but the BLEA runtime is not, parse the JSONL as structured JSON21records, require a final complete summary before treating it as a complete capture, and report only22the recorded advertisement, profile, read, notification, error, and cleanup evidence. Do not turn23missing records into successful observations. Live operations require a local Agent host, the BLEA24Python runtime, operating-system Bluetooth permission, and a supported adapter.2526## Diagnostic sequence27281. Run `ble_doctor` or `ble doctor --json` when adapter availability is unknown.292. Scan and preserve the returned identifier, names, RSSI, advertised services, and raw advertising30 evidence.313. Select by exact identifier. Use an exact name only when one observed device has that name.324. Inspect the GATT profile before choosing characteristics.335. For event discovery, use bounded `ble_observe`/`ble observe` before writing; omit characteristics34 to observe all notify/indicate traits from the discovered profile.356. When probing, continue with `next_read_offset` until it is `null`. `ok=true` means the page ran;36 it does not mean every characteristic read succeeded. Aggregate `read_page.success_count`,37 `failure_count`, and `failure_reasons` across pages, and preserve both successful reads and38 per-characteristic failures.397. Prefer reads and bounded observation before considering a write. Treat a silent observation40 window as evidence only for that window, not proof that a characteristic never emits events.418. After the initial diagnosis, save a portable evidence package with `ble_capture` or42 `ble capture`. Use the exact resolved identifier, choose an explicit `.blea.jsonl` output path,43 and set `--redact-identifiers` when the package will leave the workstation. Capture is read-only:44 it records advertisements, the GATT profile, bounded readable-characteristic results, bounded45 notifications, operation errors, and a final integrity summary. It never writes, pairs, or46 changes configuration. Keep the file as the authoritative artifact and report its path plus47 summary status to the user.489. Compare before/after captures offline with `ble_diff` or `ble diff`. Keep the default identity49 guard for normal comparisons and use `allow_different_devices` only for an intentional50 cross-device comparison. Treat the 5 dBm RSSI tolerance as noise control; use strict RSSI only51 when exact signal samples matter. Diff never scans, connects, pairs, subscribes, or writes.5210. Reproduce captured behavior offline with `ble_replay` or `ble replay`. Use instant timing for53 Agent debugging and CI. Treat `replay_miss` as absent evidence, not device behavior, and do not54 infer a successful subscription from a notify property alone. Replay never accesses a physical55 adapter and never sends or simulates writes.5611. When one authorized write is expected to trigger notifications, use `ble_exchange` or57 `ble_session_exchange`. These operations establish the subscription before writing and collect58 the response atomically; do not run standalone session subscribe and write tools concurrently.5912. Close the exact stateful MCP session once when the task is complete. Use `ble_session_list` when60 cleanup is uncertain. Use `ble_session_close_all` only when a session ID is unknown, an explicit61 close failed, or leaked state must be recovered; do not call it after a successful close.6263Do not invent UUIDs, payload encodings, pairing requirements, or protocol semantics. Report the64observed evidence and distinguish it from an inference. Treat `uuid_namespace=custom` as a custom65128-bit UUID even when its leading bytes resemble a Bluetooth SIG assigned number.6667## Commands and tools6869- Diagnose: `ble doctor --json` or `ble_doctor`.70- Scan: `ble scan --timeout 8 --json` or `ble_scan`.71- Inspect: `ble inspect --device "id:<identifier>" --json` or `ble_inspect`.72- Probe readable characteristics: use `ble probe --device "id:<identifier>" --max-reads 3273 --read-offset <offset> --json` or `ble_probe`, following `next_read_offset` across pages.74- MCP probe results omit the full GATT tree by default while retaining `profile_summary`; call75 `ble_inspect` first or set `include_profile=true` when the full profile is needed on that page.76- Read: `ble read --device "id:<identifier>" --characteristic <uuid> --json` or `ble_read`.77- Notify: use `ble subscribe ... --jsonl` or `ble_subscribe` with a bounded duration.78- Observe all event-capable traits: use `ble observe --device "id:<identifier>" --duration 1079 --jsonl` or `ble_observe`. Pass `--characteristic <uuid>` repeatedly for explicit selection.80- Capture a unified read-only evidence package: use81 `ble capture --device "id:<identifier>" --output capture.blea.jsonl --observe-duration 1082 --max-reads 128 --redact-identifiers --json` or `ble_capture`. `--read-offset` starts at a83 deterministic readable-characteristic offset and the result's `read_page.next_offset` indicates84 whether a larger limit or a follow-up capture is needed.85- Compare complete captures offline: use86 `ble diff before.blea.jsonl after.blea.jsonl --json` or `ble_diff`. Inspect `added`, `removed`,87 and `changed` paths. Use `--strict-rssi` only when needed, and use `--fail-on-change` only when CI88 should return exit code 3 for a valid comparison containing differences.89- Replay one captured operation offline: use `ble_replay` or90 `ble replay capture.blea.jsonl <scan|inspect|probe|read|subscribe|observe|run>`. The captured91 identifier is selected automatically unless an exact device is supplied. Keep `speed=0` for92 deterministic immediate output; use a positive speed multiplier only when event gaps matter.93- Serve normal MCP tools from evidence: start `ble replay capture.blea.jsonl mcp`. Verify each94 result has the expected `replay.capture_id` and `replay.read_only=true`. This mode is useful when95 an Agent or CI integration should exercise its existing `ble_read`/`ble_observe` path unchanged.96- Guarded request/notification exchange: use `ble exchange ... --jsonl`, `ble_exchange`, or97 `ble_session_exchange` to subscribe before one write and collect its resulting events.98- Multi-step work: open an MCP session, note its `idle_timeout_seconds`, use99 `ble_session_observe` when the connection should be reused, then close the session.100- Repeatable work: encode the sequence in a guarded YAML file and run `ble run`.101- Repeatable request/notification checks: use a YAML `exchange` action with separate102 `write_characteristic` and `notify_characteristic` fields. Assert the notification count/content,103 final notification, and `cleanup.ok` when the protocol has deterministic events.104105Read [workflows.md](references/workflows.md) before creating or editing workflow YAML. Read106[safety.md](references/safety.md) before any write, pairing-sensitive operation, firmware update,107lock, actuator, or other state-changing action.108109`timeout` is a per-backend-operation bound, not a total command or tool deadline. Allow for device110discovery, connection, profile discovery, each requested read, and any subscription duration when111setting an outer Agent/tool timeout.112113Capture files use Evidence Format v1. Read114[evidence-format-v1.md](https://github.com/Nitmi/blea/blob/v0.6.1/docs/evidence-format-v1.md)115when an agent needs to validate, redact, or build replay tooling around a package. Read116[diff-format-v1.md](https://github.com/Nitmi/blea/blob/v0.6.1/docs/diff-format-v1.md) before117interpreting comparison policy, stable paths, ignored fields, identity guards, or CI exit behavior.118Read [replay-format-v1.md](https://github.com/Nitmi/blea/blob/v0.6.1/docs/replay-format-v1.md)119before interpreting missing evidence, captured failures, notification timing, replay MCP mode, or120the read-only safety boundary. Read121[platform-acceptance.md](https://github.com/Nitmi/blea/blob/v0.6.1/docs/platform-acceptance.md)122before claiming platform support, running a cross-platform hardware acceptance, or publishing a123real-device capture fixture.124125## Write policy126127Treat every write as dangerous until the device protocol establishes otherwise.128129- Require the user to authorize the specific state-changing operation.130- Require `allow_write=true` and `confirm_device=<resolved identifier>` for MCP writes.131- Require both `--allow-write` and `--confirm-device <resolved identifier>` for CLI writes.132- Never confirm with a friendly name, substring, stale identifier, or guessed address.133- Prefer write-with-response and read-back verification when supported.134- Prefer atomic exchange notification verification when a write triggers asynchronous events.135- Stop when the selected device is ambiguous or a prerequisite read/assertion fails.136137Return the structured failure instead of bypassing a guard.