Skip to main content
Glama

a claude code session uses harald to find a sony wh-1000xm5's control channel over bluetooth classic, is refused until a human arms the headphones, then turns noise cancelling on and reads the battery

fig. 1 · claude + harald find a sony wh-1000xm5's control channel over bluetooth classic, wait for you to arm it, then turn noise cancelling on. real hardware, sped up.

一 how it works

harald is an mcp server, a cli and a playbook for coding agents. it gives your agent hands and ears for bluetooth le and classic, so it can work out the protocol of a gadget you own. then you control that gadget from your own code instead of the vendor's app.

listen

decode

speak

harald reads what the vendor app says to the gadget, from your phone's bluetooth log.

your agent works out the language, keys and checksums included, by diffing payloads, testing keys and searching the vendor's android app.

you get the protocol written up and a standalone driver script with its own small cli. no vendor app.

Related MCP server: btdiag

二 install

you need uv. then:

uv tool install harald

that puts harald on your path for the commands below. if your shell can't find it, run uv tool update-shell. to try harald without installing it, run uvx harald --help: uvx fetches harald and runs it once. tested on mac.

the first time harald scans, macos asks whether your terminal app may use bluetooth. allow it. if you missed the prompt, turn it on in system settings › privacy & security › bluetooth.

two optional tools, for the steps that need them:

  • brew install jadx lets harald read a vendor's android app.

  • brew install libimobiledevice records your iphone's bluetooth log from the terminal.

harald also works without an agent:

harald scan                          list bluetooth le devices nearby
harald connect <address>             list a device's services and characteristics
harald read <address> <char>         read a characteristic once
harald write <address> <char> <hex>  write bytes, once you have armed the device
harald capture open <file>           show a phone capture as a timeline
harald apk <file>                    search a vendor android app for uuids and keys
harald devices                       list the device library
harald drive <slug> <command>        run a library device's driver

harald --help lists the rest, and bluetooth classic has the commands for classic gadgets.

三 devices

device

what harald found

status

sony wh-1000xm5 headphones

noise cancelling, ambient and battery over bluetooth classic

decoded

your device

open a pull request with its device.toml, protocol.md and driver.py

wanted

each decoded device lives in devices/ with its protocol written up and a standalone driver. harald devices lists them, and harald drive <slug> <command> runs one, for example harald drive <slug> on.

四 agent setup

add the mcp server to your agent, then install the playbook: the step-by-step method your agent follows to crack a gadget.

claude code, in your project folder:

claude mcp add harald -- uvx harald mcp
harald playbook install claude-code --dest .claude/skills/harald

use --dest ~/.claude/skills/harald to have the skill in every project.

codex

add this to ~/.codex/config.toml, or run codex mcp add harald -- uvx harald mcp:

[mcp_servers.harald]
command = "uvx"
args = ["harald", "mcp"]

then, in your project folder:

harald playbook install codex

this writes AGENTS.md. if your project already has one, harald leaves it alone; use --dest ~/.codex to install it for every project instead.

cursor

add this to .cursor/mcp.json in your project, or to ~/.cursor/mcp.json for every project:

{
  "mcpServers": {
    "harald": {
      "command": "uvx",
      "args": ["harald", "mcp"]
    }
  }
}

cursor has no playbook; it uses harald's tools directly.

then ask your agent to work out your gadget with harald. it will ask you for two things only you can do.

record your phone talking to the gadget. a computer cannot overhear phone-to-gadget traffic without extra hardware, so the log comes from your own iphone. a bluetooth classic gadget's log comes from an android phone instead; see bluetooth classic.

  1. on the iphone, install apple's bluetooth logging profile: "bluetooth for ios/ipados" on apple's profiles and logs page. it is free.

  2. connect the iphone to your mac by cable. open packetlogger, from apple's additional tools for xcode, and choose file › new ios trace. or, from the terminal: idevicebtlogger capture.pklg, which records until you press ctrl-c.

  3. in the vendor app, do one thing at a time, a few seconds apart, in the order your agent asks for.

  4. stop the trace, save the .pklg file and give your agent its path. to look at it yourself: harald capture open capture.pklg.

if packetlogger records nothing, remove the logging profile and install it again.

get the vendor's android app. if the commands look encrypted, your agent asks for the apk of the vendor app you already use. you don't need an android phone, and harald never downloads apps: download it yourself from apkmirror, which verifies each app's signature, or with apkeep (apkeep -a <package name> .). the package name is the id= part of the app's play store address.

五 bluetooth classic

some gadgets, often headphones and speakers, are controlled over bluetooth classic instead of bluetooth le: the vendor app talks to an rfcomm channel, a plain byte stream. harald reaches those too, on a mac only for now; bluetooth le works as before.

pair the gadget in system settings > bluetooth first and keep it connected there. harald doesn't search for or pair classic gadgets, and harald scan only sees bluetooth le. classic addresses look like aa:bb:cc:11:22:33.

harald classic devices                         list the gadgets paired with this mac
harald classic services <address>              list a gadget's rfcomm services
harald classic send <address> <service> <hex>  send messages, once you have armed it
harald classic listen <address> <service>      show what a channel says, sending nothing
harald capture open <file> --channel n         show one rfcomm channel of a capture

<service> is a service uuid or channel number from harald classic services; add --refresh there when the list looks out of date. harald classic send takes one or more messages and sends them in order, listening for replies after each one (--listen s, 2 seconds by default). if the grant runs out or the link fails partway, it prints what it sent and received, says why on stderr and exits 1. harald classic listen sends nothing and listens for --seconds s (5 by default). either listens for at most 30 seconds at a time.

like harald write, harald classic send needs harald arm <address> first, and every message spends one write from the grant, a query too. harald never opens the channels of protected profiles such as hands-free or file transfer; see safety. your agent gets the same four as mcp tools: classic_devices, classic_services, classic_send and classic_listen. none of them arms.

classic captures come from android. an iphone capture of a classic gadget shows only apple's iap2 wrapper, which harald can't unwrap yet, so record the vendor app from an android phone's bluetooth log:

  1. turn on developer options (tap the build number seven times in the phone's about screen), then turn on the bluetooth hci snoop log in them, choosing enabled rather than filtered if it asks.

  2. with the vendor app closed, turn the phone's bluetooth off and on, so the log is running before the app opens its channel.

  3. in the vendor app, do one thing at a time, a few seconds apart, as your agent asks.

  4. with usb debugging on, run adb bugreport. its zip holds btsnoop_hci.log; give your agent that file's path, or look at it yourself with harald capture open btsnoop_hci.log.

harald apk flags the rfcomm sockets and uuids in a vendor's android app as well as its bluetooth le calls.

六 safety

harald is for gadgets you own: interoperability and research. don't use it on anyone else's devices.

  • writes need you. harald refuses every write until you run, in your own terminal:

    harald arm <address> --writes n --minutes m

    that grants a budget of n writes for m minutes (50 and 30 if you leave the flags out), and each write spends one. it shows the grant and waits for you to type arm, and it refuses to run without a terminal. harald status shows what is armed and harald disarm <address> revokes it. there is no mcp tool that arms.

  • the gate has limits. harald arm stops casual or accidental arming by an agent, but it is not a sandbox. grants live in a file, ~/.harald/arm.json, and any agent that can run arbitrary commands or write files on your machine could get around the gate. what keeps a cooperative agent out is the playbook's rule: it never runs harald arm, harald write, harald drive, harald classic send or a driver from its own shell; you do. it sends classic messages only through its classic_send tool.

  • firmware updates are blocked. writes to firmware-update (dfu) services stay refused even when a device is armed, so a stray write cannot start a firmware update. only --allow-dfu on harald arm lifts that, and working out a protocol never needs it. harald also blocks the classic firmware-update channels it knows, so far airoha's tooling channel, the same way unless you arm with --allow-dfu. but many classic gadgets take firmware over their normal control channel, where harald can't tell an update from any other message, so your agent must never send a message whose purpose it doesn't know.

  • classic channels are fenced. harald never opens a channel whose service record lists hands-free, headset, dial-up networking, obex object push and file transfer, phonebook, messages, sim access or apple iap2. the serial port profile is allowed, since many gadgets' control channels use it. harald also refuses channels missing from the device's service list. with harald classic send, every message spends one write, a query too.

  • library drivers need no arming. harald drive runs a devices/ entry's standalone driver, which you start yourself, so it sits outside the gate. read a driver before you run it, as you would any script.

  • only app-wide keys are shared. a devices/ entry may carry a key only if it is the same on every unit and ships inside the vendor app. per-unit keys and pairing keys never go in the library; they stay in your own harald-work/ folder.

七 contributing a device

cracked a gadget? your agent's work is in harald-work/<slug>/. turn it into devices/<slug>/ with a device.toml, protocol.md and driver.py, then open a pull request. the contributing guide has the details, including the keys rule.

mit license. harald is named after king harald "bluetooth" of denmark, after whom bluetooth is named; ᚼᛅᚱᛅᛚᛏᚱ is his name as it is carved on the jelling stone.

Available Tools

18 tools
analyze_apkA

statically analyze a vendor android app (.apk, .xapk or .apks) already on disk.

detects the framework. for a native app it runs jadx and lists the uuids (gatt and rfcomm) in gatt_uuids and file:line candidates (uuids, aes keys, base64 blobs, command builders, rfcomm socket calls) to open under jadx_dir, the app's own package first and third-party libraries skipped. each list keeps at most 50 per kind; totals has the full counts, and when anything was cut a warning names the file under jadx_dir that lists them all. flutter and react-native apps keep their ble code compiled, so the warnings point to capture analysis instead. harald never downloads apps.

NameRequiredDescriptionDefault
pathYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses that jadx is invoked, that the app's own package is prioritized, that third-party libraries are skipped, that lists are capped at 50 per kind with totals and a warning file listing everything, and that nothing is downloaded. Those are exactly the operational traits an agent needs that a one-param schema cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first two lines and each subsequent sentence adds distinct information (output lists, caps, framework caveats, no-download guarantee). The dense lowercase run-on listing of candidate kinds costs some readability, but little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description needn't define return values, yet it still explains the shape of gatt_uuids, candidates, totals and warnings. For a heavyweight static-analysis run, the only notable omission is any hint of runtime cost or failure modes when jadx cannot process a file.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does partially: it defines the accepted file types (.apk, .xapk, .apks), that the file must exist locally, and that output lands under jadx_dir. It never explicitly says the lone `path` parameter is that file's location, but the mapping is easy to infer.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('statically analyze a vendor android app (.apk, .xapk or .apks) already on disk') and then enumerates the concrete outputs: framework detection, gatt_uuids, and file:line candidates. This clearly separates it from runtime siblings like scan, connect, or open_capture.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'already on disk' plus 'harald never downloads apps' sets a clear precondition, and the note that Flutter/React-Native apps keep BLE code compiled 'so the warnings point to capture analysis instead' redirects the agent to a sibling approach. It stops short of naming an explicit alternative tool for other cases, but the context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

classic_devicesA

list the bluetooth classic devices paired with this mac.

connected says whether each is linked to the mac now. use an address from here with classic_services, classic_send and classic_listen.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully defines the 'connected' field ('whether each is linked to the mac now'), but says nothing about whether Bluetooth must be powered, permission/pairing prerequisites, or whether the call is a cached lookup versus an active scan — meaningful for a device-enumeration tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the purpose, then the one output field that matters, then the follow-up routing. Nothing is padded and no sentence could be dropped without loss.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be enumerated, and the description adds the one field-level meaning worth knowing plus next-step tools. The remaining gap is the unresolved relationship to list_devices and scan, which an agent picking between the three would want.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There is no argument semantics to explain and the description correctly spends no words on inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'list the bluetooth classic devices paired with this mac,' which scopes it precisely to paired Classic devices. It does not, however, name sibling list_devices or explain how it differs from a scan, so the agent must infer the Classic-vs-BLE/paired-vs-discovered split.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second half explicitly routes the agent: 'use an address from here with classic_services, classic_send and classic_listen,' which is clear downstream guidance naming three concrete alternatives. It lacks a negative case (e.g., use scan/list_devices for unpaired or BLE devices), so the only gap is an exclusion clause.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

classic_listenA

open a classic device's rfcomm channel, send nothing, and collect seconds (at most 30) of what it says.

needs no arm, but standard profiles are still refused. service is an rfcomm service uuid or channel number from classic_services. returns one entry per chunk: seconds since the channel opened and the value as hex.

NameRequiredDescriptionDefault
addressYes
secondsYes
serviceYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the load well: it discloses the passive/no-send behavior, a hard 30-second cap, that standard profiles are refused, and the chunked return shape. It omits pairing/auth requirements and failure behavior, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the cap, and every sentence adds information. The line-broken formatting is slightly awkward but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and the description still summarizes the return shape, and the key operational limits are covered. The reference to "arm" assumes knowledge of a sibling tool's concept, which is a minor unexplained dependency.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does for two of three params: `service` is an rfcomm service UUID or channel number from classic_services, and `seconds` is capped at 30. `address` is only implied as a classic device address, not spelled out as a MAC.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb+resource: open an rfcomm channel, send nothing, collect output for `seconds`. The phrase "send nothing" implicitly distinguishes it from the sibling classic_send, but no sibling is named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides preconditions ("needs no arm, but standard profiles are still refused") and points to classic_services as the source of the service value, but never states when to choose this over classic_send or other read paths explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

classic_sendA

send hex messages to a classic device's rfcomm channel and collect its answers.

refused unless the human armed this device by running harald arm <address> in their own terminal. each message spends one armed write, a query included, because classic has no read. all messages go over one connection, in order, with listen seconds (at most 30) of listening after each, so handshakes and acks can be sent as messages. service is an rfcomm service uuid or channel number from classic_services; standard profiles and channels missing from classic_services are refused, and firmware-update channels stay blocked. received holds each chunk with the message number it followed (0 = before the first), seconds since the channel opened and the value as hex. stopped explains a budget that ran out partway, or a link that failed after the first message; it is empty when every message was sent.

NameRequiredDescriptionDefault
listenNo
addressYes
serviceYes
messages_hexYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations exist, and the description carries the full burden well: it discloses the arming prerequisite and its human-in-the-loop nature, that every message (including a query) consumes one armed write because classic has no read, that all messages share one ordered connection with `listen` seconds (max 30) after each, and what `received` and `stopped` mean.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in sentence one and no sentence is filler; constraints, budget semantics, and return shape follow in logical order. The hard-wrapped, run-on sentence construction (e.g. the single sentence covering connection ordering plus listen window plus use of handshakes) makes it denser to parse than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values did not need explaining, yet the description still clarifies `received` chunk fields and when `stopped` is populated. Combined with the budget, ordering, and service-allowlist rules, nothing an agent needs to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, yet every parameter gains meaning: `service` is constrained to rfcomm UUIDs or channels from classic_services with firmware-update channels refused, `listen` is bounded at 30 seconds, `messages_hex` are hex messages sent in order on one connection, and `address` is tied to the armed device. This fully compensates for the undocumented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('send hex messages to a classic device's rfcomm channel and collect its answers'), which separates it from classic_listen (listen-only) and classic_services (enumeration) without needing their schemas. The final clause about collecting answers makes the request/response nature explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete gating conditions: the device must be armed by the human via `harald arm <address>` in their terminal, and the service must be an rfcomm UUID/channel drawn from classic_services, with firmware-update channels permanently blocked. It does not explicitly name when to prefer classic_listen instead, so alternative routing is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

classic_servicesA

list a paired classic device's service records from the mac's sdp cache.

each record has a name, service-class uuids and an rfcomm channel (null when rfcomm cannot reach it). protected channels are standard profiles such as hands-free and headset, which harald never opens; firmware_update channels stay blocked for writes. refresh=true asks the device again instead of trusting the cache.

NameRequiredDescriptionDefault
addressYes
refreshNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does meaningful work: it discloses the data source (local SDP cache vs. live query), that rfcomm channels can be null when unreachable, and that protected/firmware_update channels are blocked by the host tool. It does not mention permissions, whether the device must be connected, or failure behavior, leaving some behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences that are front-loaded with the core action and data source, followed by record shape and channel caveats. The protected/firmware channel explanation is slightly tangential for a read-only listing tool, but it is relevant and earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not required, yet the description still sketches record contents (name, service-class UUIDs, rfcomm channel). For a two-parameter read tool, everything needed to call it — data source, refresh behavior, caveats — is present except address format.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It fully explains 'refresh' (re-query the device instead of trusting the cache), but 'address' is only implicitly defined via 'a paired classic device's' — no format or source (e.g., from classic_devices) is given. Half the parameters are well-covered, half are left to inference.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('list a paired classic device's service records from the mac's sdp cache'), which is clearly distinct from the sibling classic_devices (devices, not services). It stops short of naming any sibling or explicitly contrasting use cases, so it is clear but not maximally differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The only explicit usage rule is the refresh flag ('refresh=true asks the device again instead of trusting the cache'), which is a solid conditional hint. There is no guidance on when to choose this over classic_devices, connect, or classic_send, and no prerequisites (pairing, connection state) are stated, so usage is implied rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

connectC

connect to a device and list its gatt services and their characteristics.

use the characteristic uuids listed here with read_char, write_char and subscribe.

NameRequiredDescriptionDefault
addressYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it discloses almost nothing: it does not say whether the connection persists after listing, whether it replaces/disconnects a previously connected device, whether pairing or OS permissions are required, or how failures are surfaced. Only the enumeration side effect is mentioned, which the output schema already covers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with no filler, and the primary action is front-loaded. It is efficiently worded, though the second sentence leans on the reader knowing the named sibling tools.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return structure need not be explained, but for a connection-establishing tool with zero annotations the description omits address format, connection lifecycle, and error/prerequisite behavior. Given the complexity of BLE connection semantics, the definition is not complete enough to call safely.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single required parameter 'address', so the description must compensate and does not. It never states the address format (BLE MAC vs. platform UUID) or where a valid value comes from (e.g., scan or list_devices), which is exactly the ambiguity that causes bad calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource ('connect to a device') plus a secondary effect ('list its gatt services and their characteristics'), so the agent knows this both connects and enumerates. It names the downstream siblings read_char/write_char/subscribe, which anchors it in the workflow, but does not distinguish it from scan or list_devices, the obvious tools for obtaining an address in the first place.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The second sentence conveys what to do with the result ('use the characteristic uuids listed here with read_char, write_char and subscribe'), which implies this is the entry point for GATT operations. However, there is no explicit when-to-use statement versus scan/list_devices, and no stated precondition such as needing an address already discovered by a scan.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

diffB

compare hex payloads byte by byte.

returns how many payloads have each length, the byte at every position that is the same in all of them (over the shortest), the positions that vary, and whether the set looks like block-cipher output.

NameRequiredDescriptionDefault
payloads_hexYes

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully describes the analytical outputs and the block-cipher heuristic, but it does not explicitly state that the tool is read-only/side-effect-free or explain error handling for malformed hex inputs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence, and the return details are compact. The second sentence is long but adds useful analytical context rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is relatively simple with one parameter and an output schema, and the description explains the analysis and outputs. However, it omits input constraints, minimum payload requirements, and malformed-input behavior, leaving gaps for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description should compensate. It only implies that the inputs are hex payloads and that lengths may vary ('over the shortest'), but it does not describe the array shape, minimum payload count, required format per item, or validation expectations.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: 'compare hex payloads byte by byte.' It does not explicitly differentiate from any sibling tool, but none of the listed siblings appears to be a direct alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the phrase 'compare hex payloads byte by byte,' but the description does not state when to use this tool versus alternatives, nor when not to use it. It provides no exclusions or routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

guess_checksB

name the checksums and length fields one hex payload is consistent with.

checks sum8 and xor8 in the last byte, and the byte before a trailing end marker, over the bytes after a leading start marker; crc16-ccitt in the last two; and a length byte at position 0 or 1.

NameRequiredDescriptionDefault
payload_hexYes

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and it does disclose meaningful behavioral detail: which checksums are computed (sum8, xor8, crc16-ccitt), at which byte positions, and the start/end marker assumptions. However, it omits whether markers are fixed or inferred, error behavior for malformed hex, and that the operation is a read-only analysis.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The one-line purpose is front-loaded before the detailed checksum spec, and every sentence carries technical content. The phrasing is dense but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is rightly omitted, and the algorithm is well covered. The remaining gap is the parameter format and the assumptions about leading/trailing markers, which an agent needs to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate for the single payload_hex parameter, and it only implies the format via the phrase 'one hex payload'. It does not specify prefix, case, whitespace tolerance, or byte-length constraints, leaving format details to be guessed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: it names which checksums and length fields a hex payload is consistent with. The purpose is clear and distinguishable from siblings like diff and try_keys, though the description never explicitly contrasts itself with them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance is given and no alternatives are named, despite sibling tools (diff, try_keys) that plausibly overlap in the 'analyze a payload' space. The agent must infer that this is for reverse-engineering checksum schemes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_devicesB

list the gadgets in harald's device library, with status and summary.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden; it does disclose that results include 'status and summary', which is useful behavioral context. However, it says nothing about whether the listing reflects cached/paired entries only, whether it triggers hardware activity, or permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no wasted clauses. Slight deduction for the informal 'gadgets' and the vague 'summary', which cost clarity rather than length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no parameters and an output schema present, the description needn't explain return values, and it correctly stays short. What is missing is the relationship to sibling enumeration tools and whether the device library is BLE-only, which matters given the presence of classic_devices.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to disambiguate; baseline 4 applies. The description correctly implies a no-argument enumeration rather than suggesting any filtering inputs.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The verb 'list' and resource 'device library' are stated, but 'gadgets' is odd jargon that leaves the resource type ambiguous, and nothing distinguishes this from siblings like classic_devices or scan. An agent can guess it enumerates devices, but cannot tell from the description which device domain it covers.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use guidance and no alternatives named, despite obvious sibling overlap (classic_devices, scan, load_device). The agent must infer call ordering – e.g. whether a scan must precede listing – entirely on its own.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

load_deviceC

the device library entry for one slug, including any app-wide key and cipher.

NameRequiredDescriptionDefault
slugYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.6/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It usefully discloses that the response contains an app-wide key and cipher (sensitive material), but says nothing about whether the call is read-only, what permissions are required to retrieve secrets, or any side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One short sentence fragment with no padding, and the key information (single slug, returns key and cipher) is front-loaded. It is efficient but under-specified rather than genuinely concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter tool with an output schema, the description covers the essential idea: it fetches one device entry by slug and includes key/cipher fields. The main missing piece is how to obtain a valid slug and whether secret retrieval needs authorization, which is a moderate gap rather than a fatal one.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for the single parameter, and the description only says "one slug" without explaining the format, case sensitivity, or where a slug comes from (e.g., list_devices output). It adds a hint about the parameter's role but does not compensate for the undocumented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The phrase "the device library entry for one slug" identifies the resource and scopes it to a single item, which implicitly contrasts with list_devices/classic_devices. However, it is a noun fragment describing the return value rather than stating the action, so the agent must infer the verb from the tool name.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to call this versus list_devices, classic_devices, or connect. There is no mention of prerequisites (e.g., obtaining a slug first) or exclusions, leaving selection entirely to inference from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

open_captureA

show the att and rfcomm timeline of a phone capture (.pklg or btsnoop log).

one line per event with time, acl connection, direction, op and value hex. att events show their handle and uuid; rfcomm events (rfcomm data, rfcomm_open and rfcomm_close) show their server channel, e.g. ch=9. any warnings come first and a showing a–b of n events footer comes last. a capture can hold several connections, each with its own handles. page with limit and offset. handle (an integer, e.g. 18 for h=0x0012) keeps only att events on that handle, channel (e.g. 9) only rfcomm events on that channel, conn (e.g. 64 for c=0x0040) only events on that connection, and offset then counts those filtered events. for a bluetooth classic gadget, capture its android app in a btsnoop log: an iphone app reaches classic gadgets only through apple iap2, which harald shows as rfcomm data but can't unwrap yet. relative paths resolve against the server's working directory.

NameRequiredDescriptionDefault
connNo
pathYes
limitNo
handleNo
offsetNo
channelNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the output shape (warnings first, one line per event with time/acl/direction/op/value hex, a 'showing a–b of n events' footer), that a capture can hold several connections each with its own handles, and the known iAP2 limitation. It doesn't state read-only status explicitly or what happens on a missing/invalid file.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Information-dense and front-loaded: the core behavior and output format come first, filter semantics next, caveats last. Slightly long with the iAP2 digression, but nearly every sentence contributes operational detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given six parameters at 0% schema coverage and an existing output schema, the description covers filtering, paging, formatting, and path resolution well enough to call the tool correctly. Minor gaps remain around read-only semantics and error behavior for unreadable captures.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate — and it does: handle takes an integer like 18 for h=0x0012, channel takes e.g. 9, conn takes e.g. 64 for c=0x0040, and it explains that offset counts filtered events after handle/channel/conn are applied. Pagination via limit and offset is also stated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'show the att and rfcomm timeline of a phone capture (.pklg or btsnoop log)'. This distinguishes it clearly from siblings like diff, scan, and read_char, and clarifies that despite the name 'open_capture' it renders a timeline rather than just loading a file.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Offers real situational guidance — use a btsnoop log from an Android app for classic gadgets because iAP2 traffic on iPhone can't be unwrapped — and notes that relative paths resolve against the server's working directory. However, it never says when to pick this over sibling tools such as diff or scan for the same capture, so usage is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_charB

read a characteristic once; returns its value as hex.

NameRequiredDescriptionDefault
addressYes
char_uuidYes

Output Schema

NameRequiredDescription
resultYes

TDQS

B3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden: it does disclose that this is a single non-streaming read and that the value comes back hex-encoded, which is genuine behavioral context. It says nothing about connection prerequisites, error modes (characteristic not found, permission denied, timeout), or whether reads can fail silently.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One compact clause pair with zero filler, front-loading the action and then the result. Nothing is wasted and nothing is buried.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema covers the return value, but for a hardware tool with no annotations and 0% parameter documentation the description omits critical call context: prior connection requirement and failure behavior. An agent knows what it does but not the conditions under which it will succeed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so both 'address' and 'char_uuid' are undocumented, and the description does not compensate at all. Only the word 'characteristic' loosely hints that char_uuid is a characteristic UUID; nothing explains the address format (MAC vs handle) or which device it identifies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (read a characteristic) plus a scope qualifier (once) and the return encoding (hex), which implicitly distinguishes it from the streaming sibling subscribe and from write_char. It does not name any sibling explicitly, so differentiation is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use guidance, no mention that the device must already be connected (connect/load_device are siblings), and no named alternative. The word 'once' hints at the contrast with subscribe, but the agent must infer prerequisites on its own.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_notesC

the working notes for a device, or an empty string when there are none.

notes live in harald-work//notes.md, relative to the server's working directory.

NameRequiredDescriptionDefault
slugYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full disclosure burden. It does disclose one genuinely useful behavior — an empty string is returned when no notes exist — but says nothing about read-only semantics, permissions, or what happens for an unknown/invalid slug (error vs empty string).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Short and free of padding, but it is front-loaded with the return value (a sentence fragment with no subject or verb) instead of the action. The path convention detail is useful; the structure is awkward for an agent scanning for purpose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the leading sentence about the return value largely duplicates structured data while the actual gaps — read-only nature, slug provenance, missing-file/error behavior — go unfilled. For a tool with zero annotation coverage and an undocumented required parameter, this leaves an agent with real unanswered questions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the single 'slug' parameter has no description at all. The description partially compensates by showing the path template harald-work/<slug>/notes.md, revealing that slug is a directory identifier, but it never says what a slug looks like or where to obtain one (e.g., list_devices).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose3/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is a noun phrase ('the working notes for a device') rather than a verb+resource statement, so the action is only inferable from the name read_notes. It does add useful specificity about where notes live, but it never explicitly says 'reads/returns the note file for the given device slug' nor distinguishes itself from the sibling save_note.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to call this versus alternatives; the obvious counterpart save_note is never mentioned. The agent must infer read-vs-write from the tool names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_noteA

append a timestamped note to harald-work//notes.md.

the path is relative to the server's working directory. slugs use lowercase letters, digits and hyphens, e.g. demo-lamp.

NameRequiredDescriptionDefault
slugYes
textYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It usefully discloses that content is appended (not overwritten), that a timestamp is added automatically, that the path is relative to the server's working directory, and the slug character rules. It does not say whether missing directories/files are created, whether slugs are validated or rejected, or what happens on write failure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences with zero filler, front-loaded with the action and destination. The path-relative caveat and slug constraint each earn their place as format details the schema lacks.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and the description covers the essential unknowns for a two-parameter write: destination path, append semantics, timestamping, and slug format. Directory-creation and error behavior are the only meaningful omissions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate, and it does for slug: lowercase letters, digits, hyphens, with a concrete example ('demo-lamp'). The text parameter is only implicitly characterized as the note body (timestamp added separately).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb and resource: 'append a timestamped note to harald-work/<slug>/notes.md' tells an agent exactly what happens and to what file. It does not name the sibling it complements (read_notes), but the write/read pairing is unambiguous from the verb and target path.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use or when-not guidance and never references read_notes or any alternative. An agent must infer that this is the write counterpart of read_notes purely from the tool name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

scanA

scan for bluetooth le devices for timeout seconds, strongest signal first.

manufacturer_data maps each company id (as 0x-hex) to its payload hex.

NameRequiredDescriptionDefault
timeoutNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; it does disclose that the call blocks for `timeout` seconds and that results are ordered strongest signal first, which is genuine behavioral value. However, it omits permission requirements, what happens if the adapter is off or the scan fails, and whether concurrent scans are allowed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and its timing, followed by a return-format note. No filler, no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-optional-parameter tool with an output schema, the core contract is covered: what it does, how long it runs, how results are ordered, and how `manufacturer_data` is keyed. The missing piece is operational context (permissions, failure modes), which matters for a radio scan but is not severe.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% — the `timeout` property has no description at all — so the description must compensate, and it does by establishing that `timeout` is expressed in seconds and bounds the scan duration. The schema's default of 5 is left unmentioned but is visible in the schema itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: a Bluetooth LE device scan, with the duration scoped by `timeout`. The word 'scan' plus 'bluetooth le' implicitly separates it from the cached-list siblings (`list_devices`, `classic_devices`), though it never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage — a scan that runs for `timeout` seconds — but gives no explicit when/when-not guidance, no mention of when to prefer `list_devices` or `classic_devices` over an active scan, and no note about prerequisites like an enabled adapter.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

subscribeA

collect notifications from a characteristic for seconds.

returns one entry per notification: seconds since the start and the value as hex.

NameRequiredDescriptionDefault
addressYes
secondsYes
char_uuidYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It usefully discloses that the call is duration-bound and that it emits one entry per notification, but omits prerequisites (device must be connected/handles resolved), whether the subscription is torn down at the end, and any timeout or empty-result behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and duration, then the return shape. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The return shape is described and an output schema also exists, but for a stateful BLE operation with zero annotation coverage the definition leaves out connection prerequisites and teardown behavior that an agent needs to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate; it explains `seconds` semantically as the collection window but says nothing about `address` or `char_uuid`. Two of three parameters remain defined only by their titles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: collect notifications from a characteristic for a bounded duration. This clearly contrasts with one-shot reads like read_char, though it does not name the sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the contrast between 'collect ... for seconds' and the existence of read_char, but no explicit when/when-not guidance is given. Nothing says a prior connect or characteristic discovery is required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

try_keysA

decrypt hex payloads with each candidate aes key, in ecb and in cbc with a zero iv, best-scoring first. samples holds the first plaintexts as hex.

the score only tells keys apart across several distinct payloads: with one payload, or identical copies, every key scores 1.0. keys that are not 16, 24 or 32 bytes and payloads that are not a multiple of 16 bytes are skipped.

NameRequiredDescriptionDefault
keys_hexYes
payloads_hexYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses both cipher modes tried, the zero-IV assumption, output ordering, where plaintext samples appear, how scoring behaves, and that malformed key lengths (not 16/24/32) or payloads (not a multiple of 16) are silently skipped. Missing only runtime/cost expectations for large key × payload cross products.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and mode coverage, then caveats, then validation rules. Three tight blocks with no filler. The scoring paragraph could be one clause shorter but every sentence carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a pure-compute crypto tool with an output schema covering return values, the description supplies the mode set, ordering, caveats, and skip rules — everything needed to call it correctly and interpret the score. Only performance expectations are absent, which is minor.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: keys_hex implicitly requires 16/24/32-byte values and payloads_hex requires hex blocks that are multiples of 16 bytes. The 'samples holds the first plaintexts as hex' line clarifies the output shape even though an output schema exists. It doesn't state that both parameters are arrays or their ordering/cardinality relationship.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: decrypt hex payloads with each candidate AES key, in ECB and CBC with a zero IV, returning best-scoring first. An agent knows exactly what the tool computes. It doesn't explicitly contrast with siblings (guess_checks is the nearest), but no sibling actually overlaps this operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: use it when you hold candidate keys and captured payloads. The note that scores only discriminate across several distinct payloads (and that one payload makes every key score 1.0) is effectively a when-not-to-use warning. No alternative tool is named for any case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

write_charA

write hex bytes to a characteristic; returns the writes left.

refused unless the human armed this device by running harald arm <address> in their own terminal. each write spends one from that budget, and firmware-update services stay blocked. by default it writes without response when the characteristic allows that, and with response otherwise. response=true waits for the device to acknowledge the write; false does not.

NameRequiredDescriptionDefault
addressYes
data_hexYes
responseNo
char_uuidYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description takes on the full disclosure burden and does well: it reveals the arming precondition, that each call consumes one write from a budget, that firmware-update services are blocked, and how the write type is chosen by default. It does not say what happens when the budget is exhausted or the write is refused (error vs. partial result), which is the main remaining gap for a mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and return value, then precondition, then budget and default behavior. Dense and free of filler, though the fragmented line-broken style and the slightly opaque 'firmware-update services stay blocked' phrase cost it a point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the return needn't be described further; the description sensibly spends its words on authorization gating and write-mode defaults instead. The remaining shortfall is caller-facing: no error/refusal behavior and no input format guidance for the three required-but-undocumented parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate and only partly does: it explains `response` fully (null = auto, true = wait for ack, false = fire and forget). For `address`, `char_uuid`, and `data_hex` it only implies roles — no format guidance on MAC vs handle, full vs short UUID, or accepted hex string syntax and byte order.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('write hex bytes to a characteristic') plus the return value ('returns the writes left'), which cleanly distinguishes it from read_char and subscribe among the siblings. An agent knows immediately this is a mutating BLE write, not a read or a subscription.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a hard precondition ('refused unless the human armed this device by running `harald arm <address>`') and an explicit usage rule for the response parameter (true when you need an acknowledgement, false when you don't). It also scopes out firmware-update services. It stops short of naming sibling alternatives, but the context is otherwise unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 18 tool updatesv0.1.0
    • First observedanalyze_apk
    • First observedclassic_devices
    • First observedclassic_listen
    • First observedclassic_send
    • First observedclassic_services
    • First observedconnect
    • First observeddiff
    • First observedguess_checks
    • First observedlist_devices
    • First observedload_device
    • First observedopen_capture
    • First observedread_char
    • First observedread_notes
    • First observedsave_note
    • First observedscan
    • First observedsubscribe
    • First observedtry_keys
    • First observedwrite_char

TDQS

B3.4/5.0

Scored across 18 tools

Disambiguation4/5

Most tools are cleanly separated by transport (BLE vs classic) and action (scan, connect, read_char, write_char, subscribe, classic_send, classic_listen). There is mild overlap among the three listing/discovery tools (scan, list_devices, classic_devices) and between open_capture and analyze_apk, but descriptions make the boundaries clear.

Naming Consistency4/5

All names use snake_case consistently, with a sensible classic_* namespace for the classic transport tools. However, the convention is a mix of verb_noun (read_char, save_note), noun_action (classic_send, classic_devices), and bare verbs (scan, connect, subscribe, diff), so it is not a single predictable pattern.

Tool Count4/5

18 tools is on the heavier side but each maps to a distinct capability (transport ops, capture analysis, crypto analysis, APK analysis, notes/library). The breadth is justified by the varied reverse-engineering workflow rather than being padding.

Completeness4/5

Covers the full BLE and classic lifecycle (scan, connect, read/write/subscribe/send/listen) plus strong analysis tooling (captures, diff, checksums, key trial, APK static analysis) and a notes/device library. Minor gaps like no explicit BLE disconnect/unsubscribe or device-library registration keep it from a 5.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers