crosspad-mcp-server
OfficialCrossPad MCP server lets an MCP client (e.g. Claude Code) build, run, flash, instrument, and manage CrossPad firmware/hardware tools without remembering low-level commands.
Build firmware for PC simulator, ESP32-S3 IDF, or STM32G0 with incremental/clean/fullclean/reconfigure modes.
Flash ESP32-S3 over UART or OTA, and STM32G0 over SWD or DFU, with auto-detected ports and confirmation for destructive writes.
Run & interact with the PC simulator — launch/kill it, capture screenshots (as file or inline image), send pad/encoder/click/key inputs, MIDI events, read stats, and get/set settings.
Capture logs — from the PC simulator or a connected ESP device over serial, with filters, timeouts, and boot-reset options.
Discover devices — list connected USB serial devices and identify CrossPad hardware type (native ESP vs STM bridge).
Trace STM32 live variables over ST-Link/SWD — preflight checks, symbol lookup, start/stop traces, read sampled data, export CSV, write registers/RAM, and even call firmware functions.
Run tests — build and execute the Catch2 suite with filters or list-only mode.
Manage git repos — one-call status across all CrossPad repos, inspect submodule drift, update submodules, and commit staged changes.
Search code across the ecosystem — symbol definitions, interface listings, interface implementations, and platform capability flags.
Manage apps — list, install, remove, update, or sync apps from the crosspad-apps registry as submodules on IDF/PC/Arduino platforms.
Provides Git repository tools for the CrossPad ecosystem, including repo status across all repos, committing staged changes, inspecting submodule drift, and updating submodules.
Provides MIDI control for the CrossPad simulator and hardware, including sending note on/off, control change, and program change events to the simulator, and audio routing via USB MIDI SysEx.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@crosspad-mcp-serverBuild the firmware for IDF platform"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
crosspad-mcp
Talk to your CrossPad. Let Claude do the toolchain.
crosspad-mcp is an MCP server that teaches Claude Code (or any MCP client) how to develop for the CrossPad pad controller. You say "flash the new build and check that it boots"; it runs the ESP-IDF build, asks you to confirm the flash, opens the console, runs the smoke scenario and tells you what happened — with the hardware traps already built in, so you don't have to remember which serial port reboots the board when you open it.
What you can do with it
Every card is a real prompt. The tools named underneath are what runs — you never have to call them yourself.
Say this… | …and this happens |
"Build the firmware and flash it over OTA." |
|
"Show me what's on the simulator screen." |
|
"Play a drum pattern on the pads and record what comes out." |
|
"Why did it crash?" |
|
"Watch the battery charger state machine while I plug the cable in." |
|
"Install the sampler app and rebuild." |
|
"Where is |
|
"Is my board even connected?" |
|
Related MCP server: devctl-mcp
Quick start
claude mcp add crosspad -- npx -y crosspad-mcp-serverRestart Claude Code, then ask:
is my CrossPad connected, and is the toolchain set up?
That runs crosspad_doctor. Every failed check comes with a fix. The server
assumes your repos live side by side under ~/GIT/ — if they don't,
set the paths once.
Installing the bundled crosspad skill gives Claude the ecosystem map, the
per-role guides and the hardware traps up front:
/plugin marketplace add CrossPad/crosspad-mcp
/plugin install crosspad@crosspadHow it is organised
Only the core toolset is visible when the server starts, so the tool list
stays small. Claude enables the others as the conversation needs them — or you
start the server with --toolsets device,sim.
flowchart LR
core["core · always on<br/>devices · doctor · snapshot<br/>build · flash · repo status · tasks"]
sim["sim<br/>PC simulator: run, screenshot,<br/>input, MIDI, settings, tests"]
device["device<br/>the board over USB: console,<br/>CDC verbs, UI driving, USB mode"]
hil["hil<br/>scenarios, pad stimulus,<br/>audio capture + analysis, BLE"]
code["code<br/>symbols, interfaces,<br/>docs search"]
git["git<br/>submodule drift,<br/>update, commit"]
apps["apps<br/>crosspad-apps registry"]
trace["trace<br/>SWD live variables"]
core --> sim & device & code & git & apps
device --> hil
core --> traceAnything that writes to a device or your host is tiered. Flashing, DFU and
SWD writes come back as confirmation required first; --read-only removes
every writing tool from the list entirely. Long operations (builds, flashes,
scenarios) run as tasks you can check on, wait for or cancel.
Who is it for
You build and drive CrossPad firmware — mostly the simulator, sometimes the board. Start with the user guide.
You work on the firmware itself — flash, console, HIL scenarios, crash diagnosis, SWD. Read the firmware developer guide and HIL testing.
You want to extend this server — the contributor guide and the Development section.
Going deeper
Usage reference — every install path, every tool and toolset, resources and prompts, configuration, HTTP transport, the v10 migration table.
FAQ — the questions that cost people an afternoon.
License
MIT — part of the CrossPad project.
Available Tools
8 toolscrosspad_buildADestructive
[PC | ESP | STM HW] Build CrossPad for the given platform.
• platform='pc' → CMake + Ninja host simulator. PREFER THIS over cmake --build build (picks right MSVC env on Windows, parses errors/warnings, streams progress).
• platform='idf' → idf.py build for ESP32-S3 firmware. PREFER THIS over raw idf.py build (sources IDF env, auto-fullcleans when new apps detected, parses errors/warnings). Follows the board revision resolved by tools/crosspad_board.py — passes -B build_ -DSDKCONFIG=sdkconfig.; refuses if no revision is known.
• platform='stm' → CMake + Ninja + arm-none-eabi for STM32G0 firmware (CrossPad r20). Uses CMakePresets (Debug/Release); output is build//CrossPad_STM32_r20.elf.
Mode×platform compatibility:
• incremental → all (default)
• clean → all (wipes build dir, then builds)
• reconfigure → PC & STM (re-runs cmake without wiping cache)
• fullclean → IDF only (runs idf.py fullclean, then builds)
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Build mode. Compatibility: incremental & clean = all platforms; reconfigure = PC & STM; fullclean = IDF only. Pick incremental for normal iteration; clean if you suspect stale artifacts; fullclean (IDF) after adding new apps; reconfigure (PC/STM) after editing CMakeLists/presets. | incremental |
| board | No | IDF only. Board revision. Default: the connected board (hardware revision from the STM bridge), else the last choice (tools/crosspad_board.py). | |
| platform | Yes | Target platform: 'pc' = host simulator, 'idf' = ESP32-S3 firmware, 'stm' = STM32G0 firmware (CrossPad r20). | |
| build_type | No | CMake build type — PC & STM (ignored for IDF; ESP32 build type comes from sdkconfig). STM maps to the Debug/Release preset (RelWithDebInfo→Release). Only honored on mode=clean|reconfigure (incremental keeps existing cache). | Debug |
Output Schema
| Name | Required | Description |
|---|---|---|
| tail | No | |
| error | No | |
| errors | No | |
| success | Yes | |
| warnings | No | |
| board_rev | No | |
| build_dir | No | |
| output_path | No | |
| warnings_count | No | |
| duration_seconds | No | |
| auto_reconfigured | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the destructiveHint/readOnly annotations by disclosing environment sourcing (MSVC env, IDF env), auto-fullclean when new apps are detected, refusal behavior when no board revision is known, build-dir wiping for clean mode, and STM preset mapping (RelWithDebInfo→Release). The destructive actions described ('wipes build dir', 'runs idf.py fullclean') align with destructiveHint=true — no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose line, then organizes per-platform behavior in bullets and mode compatibility in a compact table. Every sentence carries distinct information — build system choice, preference rationale, output path, or mode constraint. No filler, despite covering a complex 3-platform × 4-mode matrix.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 3 platforms × 4 modes plus board-revision and build-type logic, the description covers all decision axes: which commands run, which flags are passed, when builds are refused, what gets wiped, and where output lands. Return values are covered by the existing output schema, and environment prerequisites are discoverable via siblings (crosspad_doctor, crosspad_toolsets). Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all four parameters, setting a baseline of 3. The description adds value on top: concrete flags passed for IDF (-B build_<rev> -DSDKCONFIG=sdkconfig.<rev>), board revision resolution via tools/crosspad_board.py, and the exact STM output path (build/<preset>/CrossPad_STM32_r20.elf). These enrich platform, board, and build_type semantics beyond what the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with an explicit verb+resource statement — 'Build CrossPad for the given platform' — then disambiguates three platform targets (pc/idf/stm), each with its own build system (CMake+Ninja, idf.py, arm-none-eabi). This clearly differentiates it from build-adjacent siblings like crosspad_flash and crosspad_repo_status. No ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states 'PREFER THIS over `cmake --build build`' and 'PREFER THIS over raw `idf.py build`' with concrete reasons (correct MSVC env, error parsing, progress streaming, env sourcing). The Mode×platform compatibility table tells the agent exactly which modes work on which platforms and when to pick each (incremental for normal iteration, fullclean after adding apps, reconfigure after editing CMakeLists). This is textbook when/when-not guidance with named alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_devicesARead-onlyIdempotent
[ESP HW] List connected CrossPads as seen by the crosspad-hil daemon: id (dev_xxxx, stable per USB serial), usb_mode (default|audio|bootloader|unknown), and every port role (cdc, console=STM VCP, esp_midi, stm_midi, uac2, bootloader). kind keeps the v9 meaning: 'esp-native' (rev <2.0) or 'stm-bridge' (rev 2.0, STM32 composite CDC+MIDI). selected is set when exactly one device would be chosen implicitly by every other tool.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| ts | No | |
| error | No | |
| details | No | |
| devices | No | |
| success | Yes | |
| selected | No | |
| crosspad_count | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, covering the safety profile. The description adds genuine behavioral context beyond this: the data source (crosspad-hil daemon), the stability guarantee of id (stable per USB serial), version-dependent meaning of kind, and the selection rule for 'selected.' Minor gap: no disclosure of behavior when the daemon is not running or no devices are attached.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and each clause earns its place by explaining a field or a constraint. It is dense — the port-role enumeration and version-conditional kind explanation are packed tightly — but for a tool with no schema params and a field-semantics burden, this level of detail is warranted rather than padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (0 params), complete annotations, and an output schema that presumably details the return structure, the description covers the semantic meaning an agent cannot extract from structured data: id stability, kind version semantics, and the implicit-selection rule. The remaining gap is edge-case behavior (daemon unavailable, empty device list), which is minor for a read-only enumeration tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With zero parameters and 100% schema coverage, there is nothing for the description to explain about inputs, so the baseline of 4 applies. The description instead adds value on the output side by clarifying field semantics (usb_mode value set, port role glosses, kind version mapping), which compensates for the empty input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource+source: 'List connected CrossPads as seen by the crosspad-hil daemon.' It enumerates the exact fields returned (id, usb_mode, port roles, kind, selected) with their semantics, and its function is clearly distinct from all siblings (build, flash, doctor, snapshot, etc.), which perform actions rather than enumerate hardware.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is only implied, not stated. The 'selected' field explanation hints that other tools implicitly choose a device and this tool reveals which one, which lets an agent infer when to call it (before acting on a device), but there is no explicit when-to-use/when-not-to-use statement or routing to alternatives. The differentiation from siblings is conveyed by function rather than by explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_doctorARead-onlyIdempotent
Environment doctor. Host checks: hil_python interpreter, crosspad-hil version vs the one this server needs, platform-idf root, ESP-IDF env, crosspad-pc root, per-rev build dirs and firmware age, simulator binary staleness. Daemon checks merged in: udev/dialout, port locks (holder PID + purpose), rtmidi/ALSA/sounddevice visibility. Also reports the daemon as a process: uptime, ops served, open handles and the OS resources it holds (ALSA sequencer clients, fds). Each check is {name, ok, detail, fix}; ok is false when any check fails. Run this first when a device tool errors. action=restart_daemon restarts the crosspad-hil daemon — how a newly installed crosspad-hil or a new scenario becomes visible without restarting this server.
| Name | Required | Description | Default |
|---|---|---|---|
| action | No | check: run every check; restart_daemon: stop and start the crosspad-hil daemon again — the way to pick up a newly installed crosspad-hil or a new scenario, and the repair when it has accumulated OS resources. Open console/cdc handles do not survive it | check |
| confirm_token | No | Echo the token from a confirmation_required reply to proceed |
Output Schema
| Name | Required | Description |
|---|---|---|
| ok | No | |
| hint | No | |
| tool | No | |
| error | No | |
| action | No | |
| checks | No | |
| daemon | No | |
| details | No | |
| success | Yes | |
| resultType | No | |
| confirmation | No | |
| dropped_handles | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, but the description discloses `action=restart_daemon` that stops and starts the daemon and, per the schema, drops open console/cdc handles. That is state-changing and handle-destroying behavior, directly contradicting the read-only/destructive-free annotations. Per the rubric an annotation contradiction scores 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but purposeful: it leads with the role, organizes host vs daemon checks, specifies output shape, and ends with actionable usage guidance. It could be better structured with bullets, but every sentence carries useful information with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool this complex, the description covers the check categories, the `{name, ok, detail, fix}` result shape, the all-or-nothing ok semantics, the trigger for using the tool, and the restart action's consequences. The rich output schema and 100% parameter scchema coverage fill any remaining need.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers both parameters 100%: `action` has an enum with detailed semantics and `confirm_token` is explained as echoing the token from a confirmation_required reply. The tool description reinforces `restart_daemon` but adds no parameter meaning beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies crosspad_doctor as an environment diagnostic: it enumerates host checks (hil interpreter, versions, ESP-IDF, platform-idf root, build dirs, firmware age, simulator), daemon checks (udev/dialout, port locks, audio visibility), and daemon process reporting. 'Run this first when a device tool errors' also gives it a distinct role next to build/flash/devices siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says to run this first when a device tool errors, and explains exactly when action=restart_dae `restart_daemon` is appropriate: after installing crosspad-hil or adding a scenario, or when the daemon accumulated OS resources. It lacks an explicit when-not or named alternatives, so not a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_flashADestructive
[ESP HW | STM HW] Flash firmware. Danger tier: it always runs a preflight first, always returns that preflight (refusal included), and needs a confirmation before writing anything. Preflight reports: the device's USB mode, which role the target port plays (the STM32 bridge console is refused as a flash target), the binary's own version string, whether it is older than the newest file under main/ or components/, and whether the build's board revision matches the device's — a mismatch is a blocker, because the revisions differ in pinout and the wrong image looks like dead hardware. target='esp': transport='ota' streams over USB CDC with the device running (no bootloader mode); transport='uart' runs idf.py flash and needs download mode. wait_boot=true then opens the console and returns a BootResult. target='stm': method='swd' (ST-Link) or 'dfu' (system bootloader, hold pad 1 at boot). The flash runs as a job: wait_seconds=0 (default) returns a task handle for crosspad_task; wait_seconds>0 inlines the final status. dry_run=true stops after the preflight. force=true overrides every blocker except the port-role refusal.
| Name | Required | Description | Default |
|---|---|---|---|
| port | No | ESP only. Serial port to flash. Omit to let the daemon choose. The STM32 bridge console port is refused — it carries logs, not the flash. | |
| force | No | Proceed despite preflight blockers (stale build, board-revision mismatch, missing device). The port-role and no-board refusals are never overridden. | |
| device | No | ESP only. Device id (dev_xxxx) or one of its port paths; omit when exactly one CrossPad is connected. | |
| method | No | STM only. 'swd' = ST-Link; 'dfu' = the STM32 system bootloader (hold pad 1 at boot). | |
| target | No | 'esp' = ESP32-S3 application firmware (transport uart|ota); 'stm' = STM32G0 bridge firmware via STM32_Programmer_CLI (method swd|dfu). | esp |
| dry_run | No | Run the preflight and stop: no confirmation token is minted and nothing is written. | |
| build_dir | No | ESP only. Build directory holding the binary and its sdkconfig (default: '<idf-root>/build_<rev>' of the board being flashed, from tools/crosspad_board.py; per-revision dirs are build_v1 / build_v2). | |
| transport | No | ESP only. 'ota' streams the binary over USB CDC with the device running (no bootloader mode); 'uart' runs idf.py flash and needs download mode. | |
| wait_boot | No | ESP only. After flashing, open the console and wait for the boot markers; the job result carries a BootResult {complete, missing, fatal, errors, bootloops, seconds}. Default false. | |
| build_type | No | STM only. Picks the build/<preset> dir for the default binary. Default Debug. | |
| delta_base | No | ESP OTA only. Previously flashed binary to diff against — sends a delta instead of the whole image. | |
| wait_seconds | No | 0 (default) returns the task handle immediately — poll it with crosspad_task. >0 waits that long and inlines the task status; a timeout is not an error, the job keeps running. | |
| confirm_token | No | Token from a previous confirmation_required result. Re-issue the identical call with it to proceed. | |
| firmware_path | No | Custom binary. ESP default '<build_dir>/CrossPad.bin'; STM default '<stm-root>/build/<preset>/CrossPad_STM32_r20.bin'. | |
| boot_timeout_s | No | wait_boot: how long to wait for a complete boot (default 45, the firmware's own boot budget). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ts | No | |
| hint | No | |
| task | No | |
| tool | No | |
| error | No | |
| device | No | |
| status | No | |
| target | No | |
| details | No | |
| dry_run | No | |
| success | Yes | |
| preflight | No | |
| transport | No | |
| resultType | No | |
| confirmation | No | |
| firmware_path | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond annotations: discloses the danger tier, preflight always running, confirmation requirement, refusal rules, revision mismatch blocking, and job mechanics. It explains what force does and does not override, and the difference between wait_seconds modes. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but each sentence carries essential information. It is front-loaded with the danger warning and preflight summary, then organized by target and parameter groups. No fluff; every detail is actionable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex tool with 15 parameters, the description covers all critical aspects: preflight checks, transport/method selection, job handling, confirmation token flow, force/dry_run semantics, and board revision implications. The output schema (BootResult) is not described but exists, so no need to repeat. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
While the schema already documents every parameter (100% coverage), the description adds significant semantic depth: it explains the preflight checks, the meaning of confirm_token flow, the behavior of wait_seconds=0 vs >0, default paths for firmware, and the board-revision blocking logic. This enriches the schema descriptions substantially.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Flash firmware' with clear scope for ESP and STM targets. It distinguishes itself from siblings by detailing the preflight, confirmation, and job-based execution, making its unique role obvious.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use guidance: it explains when to use each transport/method, what is refused (STM32 bridge console), how to handle confirmation, and when to use dry_run or force. It references crosspad_task for polling, giving clear routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_repo_statusARead-only
Git status across ALL detected CrossPad repos in one call: branch, HEAD, dirty files, submodule sync state. PREFER THIS over running git status per repo — handles the 5-repo monorepo layout in one shot.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | |
| repos | No | |
| success | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint=true annotation already covers the safety profile. The description adds value by disclosing the scope (ALL detected repos), the monorepo layout detail (5-repo), and what the reported fields are. It correctly presents this as an aggregation tool without overclaiming write behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, tightly packed. The key main-verb action and scope are front-loaded. Could arguably be a touch shorter but every sentence earns its place—the first establishes the action, the second gives the preference directive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists (which covers return values), zero params, and a readOnly annotation, the description covers what an agent needs: what it does, what it returns conceptually, and when to prefer it. The monorepo layout context is valuable. Minor gap is not describing submodule sync state semantics more precisely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there's no parameter description to add. The baseline for 0 params is 4, and the description appropriately focuses on behavior since schema has nothing to document at 100% coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clear specific verb+resource: reports git status across all CrossPad repos. Explicitly enumerates what's returned (branch, HEAD, dirty files, submodule sync state) and differentiates from alternatives by highlighting the 5-repo monorepo layout handling in one call.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to PREFER this tool over running `git status` per repo, providing an explicit when-to-use directive and naming the alternative it replaces. This is a clear usage guideline with a specific alternative context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_snapshotARead-onlyIdempotent
[ESP HW | PC sim] One-call state snapshot (~300 tokens): apps {running, available}, ui {focus {ref,label}, group [{ref,label}], drawer, theme, app}, kit, leds, pads, mem, ble, console counters. Refs e<i> are ENC_GROUP indices for crosspad_ui focus — any UI action invalidates them and the next snapshot re-mints them. diff_from= adds changed. target=sim maps the simulator's stats onto the same shape (ui null).
| Name | Required | Description | Default |
|---|---|---|---|
| device | No | Device id or port; omit when exactly one CrossPad is connected. Ignored for sim. | |
| target | No | Defaults to the attached board — the common case, and a snapshot with no arguments should not be a validation error. device = a connected CrossPad via the daemon; sim = the running PC simulator (ui is null there) | device |
| include | No | Sections to fill (default all). Fewer sections = fewer CDC round-trips. | |
| diff_from | No | Earlier snapshot_id; result.changed lists the top-level keys that differ. Unknown id → full snapshot. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ts | No | |
| ui | No | |
| ble | No | |
| kit | No | |
| mem | No | |
| apps | No | |
| leds | No | |
| pads | No | |
| error | No | |
| device | No | |
| changed | No | |
| console | No | |
| details | No | |
| success | Yes | |
| usb_mode | No | |
| snapshot_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish readOnly/idempotent/non-destructive, and the description adds meaningful behavior: refs are ENC_GROUP indices invalidated by UI actions, next snapshot re-mints them, diff_from appends changed, unknown diff id falls back to full snapshot, and sim mode nulls ui. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but tightly organized: snapshot contents first, then the subtle ref invalidation warning, then the two optional modifiers. Every clause earns its place and important caveats are front-loaded before parameter details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only snapshot tool with an output schema, the description is complete: it covers all parameters, edge cases (unknown diff_from, sim-specific ui null), device selection defaults, and behavioral invariants around refs. No meaningful gap remains for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers 100% of parameters, and the description enriches each one: include sections map to 'fewer CDC round-trips', target=sim maps simulator stats and nulls ui, diff_from adds changed and handles unknown ids, and device omission is valid when only one CrossPad is connected.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'One-call state snapshot' and enumerates the exact sections returned (apps, ui, kit, leds, pads, mem, ble, console), making the tool's verb and resource unmistakable. It also distinguishes the hardware and simulator modes, so it is not confused with sibling build/flash/task tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong usage context: device or sim selection, default behavior, optional include filtering, and diff_from semantics. It does not explicitly name sibling tools or state when not to use the snapshot, but the tool is clearly a read-only introspection utility and the guidance is otherwise concrete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_taskARead-onlyIdempotent
Poll, wait on, cancel or list long-running crosspad tasks (build, flash, hil_run, capture, stimulus, submodule_update). Task handles are task_; results are kept 1 h after completion. Use this when your client does not support the MCP tasks capability.
| Name | Required | Description | Default |
|---|---|---|---|
| task | No | Task handle (task_<n>). Required for status, wait and cancel; ignored by list | |
| action | Yes | status: one task; wait: block until it finishes; cancel: stop it; list: every task this session | |
| timeout_ms | No | wait only: how long to block before returning the current status (max 600000) |
Output Schema
| Name | Required | Description |
|---|---|---|
| task | No | |
| error | No | |
| tasks | No | |
| success | Yes | |
| cancelled | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and destructiveHint=false, yet the description documents a 'cancel' action that stops a running task — a state-changing operation. This is a direct contradiction between the description and annotations, so the transparency score must be very low.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action verbs and supported task types. Every sentence carries information, and there is no filler or repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the full action surface, the task handle format, result retention, and the client-capability condition, while the output schema handles return shape. It is nearly complete, though the annotation contradiction undermines overall reliability.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds the task_<n> handle pattern and the 1 h retention window, but those facts already appear in the schema defail. No meaningful extra parameter semantics are provided beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb set ('Poll, wait on, cancel or list') tied to a concrete resource ('long-running crosspad tasks') and enumerates the task types it manages. It is clearly distinct from sibling tools like crosspad_build or crosspad_flash, which create tasks rather than manage them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use the tool: when the client does not support the MCP tasks capability. It does not spell out exclusions or alternative sibling tools, but the clear context is enough for an agent to route correctly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
crosspad_toolsetsARead-onlyIdempotent
Manage which crosspad_* toolsets are visible. Only core is on at start. Toolsets: core, device, hil, sim, code, git, apps, trace. action=list shows all with enabled state; enable/disable take toolset= (core cannot be disabled); describe lists each tool with its safety tier. Enabling emits tools/list_changed — re-list tools afterwards. Tools hidden by a readonly policy never appear.
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes | What to do | |
| toolset | No | Toolset name for enable/disable/describe: core, device, hil, sim, code, git, apps, trace |
Output Schema
| Name | Required | Description |
|---|---|---|
| added | No | |
| error | No | |
| enabled | Yes | |
| removed | No | |
| success | Yes | |
| toolset | No | |
| toolsets | No | |
| policy_mode | Yes | |
| hidden_by_policy | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses useful behavior such as emitting tools/list_changed and excluding tools hidden by a readonly policy, but it directly contradicts the readOnlyHint=true annotation by describing mutating enable/disable actions and a change event. Per the rubric, a description that contraindicates annotations earns a 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded, with the purpose in the first sentence and essential operational rules packed into two sentences. Every clause adds value, with no meaningless filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers initial state, all actions, constraints, side-effect guidance, and the readonly policy, which is very complete for an agent invoking the tool. It loses a point because the readOnlyHint annotation conflict leaves the agent uncertain whether calling the tool is truly side-effect-free.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite the schema describing both parameters, the description adds meaning well beyond the enum and names: list shows enabled state, enable/disable pair with toolset, core cannot be disabled, describe returns safety tiers, and the valid toolsets are enumerated. This gives the agent actionable semantics for both parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource ('Manage which crosspad_* toolsets are visible') and then lists the exact actions and toolsets, making its purpose unambiguous. It clearly distinguishes itself from the crosspad_* sibling tools, which are build, repo, device, doctor, and task operations rather than toolset visibility management.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states when to use each action (list, enable, disable, describe), the initial state (only core on), and the constraint that core cannot be disabled. It does not explicitly name alternatives or when-non to use this tool, but no sibling tool overlaps this toolset-visibility role, so the guidance is clear enough.
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.
3 tool updates
v10.3.0- Changed
crosspad_build3 fields changed- added
Input schema / properties / boardAdded value: +{ + "description": "IDF only. Board revision. Default: the connected board (hardware revision from the STM bridge), else the last choice (tools/crosspad_board.py).", + "enum": [ + "v1", + "v2" + ], + "type": "string" +} - added
Output schema / properties / board_revAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / build_dirAdded value: +{ + "type": [ + "string", + "null" + ] +}
- Changed
crosspad_devices2 fields changed- added
Output schema / properties / devices / items / properties / fw_revAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / devices / items / properties / pcbAdded value: +{ + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] +}
- Changed
crosspad_flash2 fields changed- changed
Input schema / properties / build_dir / descriptionPrevious value: -"ESP only. Build directory holding the binary and its sdkconfig (default '<idf-root>/build'; per-revision dirs are build_v1 / build_v2)."New value: +"ESP only. Build directory holding the binary and its sdkconfig (default: '<idf-root>/build_<rev>' of the board being flashed, from tools/crosspad_board.py; per-revision dirs are build_v1 / build_v2)." - changed
Input schema / properties / force / descriptionPrevious value: -"Proceed despite preflight blockers (stale build, board-revision mismatch, missing device). The port-role refusal is never overridden."New value: +"Proceed despite preflight blockers (stale build, board-revision mismatch, missing device). The port-role and no-board refusals are never overridden."
32 tool updates
v10.2.0- Removed
crosspad_apps_install - Removed
crosspad_apps_list - Removed
crosspad_apps_remove - Removed
crosspad_apps_sync - Removed
crosspad_apps_update - Removed
crosspad_audio_route - Removed
crosspad_capabilities - Removed
crosspad_check - Removed
crosspad_commit - Changed
crosspad_devices28 fields changed- added
Output schema / properties / detailsAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / devices / items / properties / board_revAdded value: +{ + "type": [ + "string", + "null" + ] +} - removed
Output schema / properties / devices / items / properties / descriptionRemoved value: -{ - "type": "string" -} - added
Output schema / properties / devices / items / properties / idAdded value: +{ + "type": "string" +} - added
Output schema / properties / devices / items / properties / is_crosspad / constAdded value: +true - removed
Output schema / properties / devices / items / properties / kind / anyOfRemoved value: -[ - { - "enum": [ - "esp-native", - "stm-bridge" - ], - "type": "string" - }, - { - "type": "null" - } -] - added
Output schema / properties / devices / items / properties / kind / enumAdded value: +[ + "esp-native", + "stm-bridge" +] - added
Output schema / properties / devices / items / properties / kind / typeAdded value: +"string" - added
Output schema / properties / devices / items / properties / pid / anyOfAdded value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - removed
Output schema / properties / devices / items / properties / pid / maximumRemoved value: -9007199254740991 - removed
Output schema / properties / devices / items / properties / pid / minimumRemoved value: --9007199254740991 - removed
Output schema / properties / devices / items / properties / pid / typeRemoved value: -"integer" - changed
Output schema / properties / devices / items / properties / port / typePrevious value: -"string"New value: +[ + "string", + "null" +] - added
Output schema / properties / devices / items / properties / portsAdded value: +{ + "additionalProperties": {}, + "properties": { + "bootloader": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "location": { + "type": [ + "string", + "null" + ] + }, + "path": { + "type": "string" + }, + "pid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "product": { + "type": [ + "string", + "null" + ] + }, + "serial": { + "type": [ + "string", + "null" + ] + }, + "vid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "path", + "vid", + "pid", + "serial", + "product", + "location" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "cdc": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "location": { + "type": [ + "string", + "null" + ] + }, + "path": { + "type": "string" + }, + "pid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "product": { + "type": [ + "string", + "null" + ] + }, + "serial": { + "type": [ + "string", + "null" + ] + }, + "vid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "path", + "vid", + "pid", + "serial", + "product", + "location" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "console": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "location": { + "type": [ + "string", + "null" + ] + }, + "path": { + "type": "string" + }, + "pid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + "product": { + "type": [ + "string", + "null" + ] + }, + "serial": { + "type": [ + "string", + "null" + ] + }, + "vid": { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + } + }, + "required": [ + "path", + "vid", + "pid", + "serial", + "product", + "location" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "esp_midi": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "alsa_hw": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "rawmidi": { + "type": [ + "string", + "null" + ] + }, + "rtmidi_in": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "rtmidi_out": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "rtmidi_out", + "rtmidi_in", + "alsa_hw", + "rawmidi" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "stm_midi": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "alsa_hw": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "rawmidi": { + "type": [ + "string", + "null" + ] + }, + "rtmidi_in": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + }, + "rtmidi_out": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "rtmidi_out", + "rtmidi_in", + "alsa_hw", + "rawmidi" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "uac2": { + "anyOf": [ + { + "additionalProperties": {}, + "properties": { + "alsa_id": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "sounddevice_index": { + "anyOf": [ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "name", + "sounddevice_index", + "alsa_id" + ], + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "type": "object" +} - added
Output schema / properties / devices / items / properties / serialAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / devices / items / properties / usb_modeAdded value: +{ + "enum": [ + "default", + "audio", + "bootloader", + "unknown" + ], + "type": "string" +} - added
Output schema / properties / devices / items / properties / vid / anyOfAdded value: +[ + { + "maximum": 9007199254740991, + "minimum": -9007199254740991, + "type": "integer" + }, + { + "type": "null" + } +] - removed
Output schema / properties / devices / items / properties / vid / maximumRemoved value: -9007199254740991 - removed
Output schema / properties / devices / items / properties / vid / minimumRemoved value: --9007199254740991 - removed
Output schema / properties / devices / items / properties / vid / typeRemoved value: -"integer" - changed
Output schema / properties / devices / items / requiredPrevious value: -[ - "port", - "is_crosspad" -]New value: +[ + "id", + "serial", + "usb_mode", + "ports", + "kind", + "port", + "vid", + "pid", + "is_crosspad" +] - added
Output schema / properties / error / additionalPropertiesAdded value: +{} - added
Output schema / properties / error / propertiesAdded value: +{ + "code": { + "type": "string" + }, + "details": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "hint": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + } +} - added
Output schema / properties / error / requiredAdded value: +[ + "code", + "message" +] - changed
Output schema / properties / error / typePrevious value: -"string"New value: +"object" - added
Output schema / properties / selectedAdded value: +{ + "type": "string" +} - added
Output schema / properties / tsAdded value: +{ + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "success", - "devices" -]New value: +[ + "success" +]
- Added
crosspad_doctor - Changed
crosspad_flash41 fields changed- added
Input schema / properties / boot_timeout_sAdded value: +{ + "description": "wait_boot: how long to wait for a complete boot (default 45, the firmware's own boot budget).", + "maximum": 180, + "minimum": 5, + "type": "number" +} - added
Input schema / properties / build_dirAdded value: +{ + "description": "ESP only. Build directory holding the binary and its sdkconfig (default '<idf-root>/build'; per-revision dirs are build_v1 / build_v2).", + "minLength": 1, + "type": "string" +} - changed
Input schema / properties / build_type / descriptionPrevious value: -"STM only. Selects the build/<preset> dir for the default firmware binary. Defaults to Debug."New value: +"STM only. Picks the build/<preset> dir for the default binary. Default Debug." - added
Input schema / properties / confirm_tokenAdded value: +{ + "description": "Token from a previous confirmation_required result. Re-issue the identical call with it to proceed.", + "type": "string" +} - added
Input schema / properties / delta_baseAdded value: +{ + "description": "ESP OTA only. Previously flashed binary to diff against — sends a delta instead of the whole image.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / deviceAdded value: +{ + "description": "ESP only. Device id (dev_xxxx) or one of its port paths; omit when exactly one CrossPad is connected.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / dry_runAdded value: +{ + "description": "Run the preflight and stop: no confirmation token is minted and nothing is written.", + "type": "boolean" +} - changed
Input schema / properties / firmware_path / descriptionPrevious value: -"Custom firmware binary path. ESP: OTA only, defaults to <idf-root>/build/CrossPad.bin. STM: defaults to <stm-root>/build/<preset>/CrossPad_STM32_r20.bin."New value: +"Custom binary. ESP default '<build_dir>/CrossPad.bin'; STM default '<stm-root>/build/<preset>/CrossPad_STM32_r20.bin'." - added
Input schema / properties / firmware_path / minLengthAdded value: +1 - added
Input schema / properties / forceAdded value: +{ + "description": "Proceed despite preflight blockers (stale build, board-revision mismatch, missing device). The port-role refusal is never overridden.", + "type": "boolean" +} - changed
Input schema / properties / method / descriptionPrevious value: -"STM only. 'swd' = ST-Link/SWD; 'dfu' = USB DFU system bootloader."New value: +"STM only. 'swd' = ST-Link; 'dfu' = the STM32 system bootloader (hold pad 1 at boot)." - changed
Input schema / properties / port / descriptionPrevious value: -"Serial port path (e.g. /dev/ttyACM0, COM3). Auto-detected if omitted; required when multiple devices connected."New value: +"ESP only. Serial port to flash. Omit to let the daemon choose. The STM32 bridge console port is refused — it carries logs, not the flash." - added
Input schema / properties / port / minLengthAdded value: +1 - removed
Input schema / properties / port / patternRemoved value: -"^(?:\\/dev\\/(?:tty(?:ACM|USB)\\d+|cu\\.usb[A-Za-z0-9._-]+|cu\\.usbmodem[A-Za-z0-9._-]+|cu\\.usbserial[A-Za-z0-9._-]+)|COM\\d+)$" - changed
Input schema / properties / target / descriptionPrevious value: -"'esp' = ESP32-S3 (transport uart/ota); 'stm' = STM32G0 firmware via STM32_Programmer_CLI (method swd/dfu)."New value: +"'esp' = ESP32-S3 application firmware (transport uart|ota); 'stm' = STM32G0 bridge firmware via STM32_Programmer_CLI (method swd|dfu)." - changed
Input schema / properties / transport / descriptionPrevious value: -"ESP only. 'uart' = bootloader-mode flash via idf.py; 'ota' = USB-CDC OTA flash via ota_flash.py."New value: +"ESP only. 'ota' streams the binary over USB CDC with the device running (no bootloader mode); 'uart' runs idf.py flash and needs download mode." - added
Input schema / properties / wait_bootAdded value: +{ + "description": "ESP only. After flashing, open the console and wait for the boot markers; the job result carries a BootResult {complete, missing, fatal, errors, bootloops, seconds}. Default false.", + "type": "boolean" +} - added
Input schema / properties / wait_secondsAdded value: +{ + "description": "0 (default) returns the task handle immediately — poll it with crosspad_task. >0 waits that long and inlines the task status; a timeout is not an error, the job keeps running.", + "maximum": 900, + "minimum": 0, + "type": "number" +} - added
Output schema / properties / confirmationAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / detailsAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / deviceAdded value: +{ + "type": "string" +} - added
Output schema / properties / dry_runAdded value: +{ + "type": "boolean" +} - removed
Output schema / properties / duration_secondsRemoved value: -{ - "type": "number" -} - added
Output schema / properties / error / additionalPropertiesAdded value: +{} - added
Output schema / properties / error / propertiesAdded value: +{ + "code": { + "type": "string" + }, + "details": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "hint": { + "type": [ + "string", + "null" + ] + }, + "message": { + "type": "string" + } +} - added
Output schema / properties / error / requiredAdded value: +[ + "code", + "message" +] - changed
Output schema / properties / error / typePrevious value: -"string"New value: +"object" - added
Output schema / properties / hintAdded value: +{ + "type": "string" +} - removed
Output schema / properties / methodRemoved value: -{ - "enum": [ - "uart", - "ota", - "swd", - "dfu" - ], - "type": "string" -} - removed
Output schema / properties / output_tailRemoved value: -{ - "items": { - "type": "string" - }, - "type": "array" -} - removed
Output schema / properties / portRemoved value: -{ - "type": "string" -} - added
Output schema / properties / preflightAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - removed
Output schema / properties / programmerRemoved value: -{ - "type": "string" -} - added
Output schema / properties / resultTypeAdded value: +{ + "type": "string" +} - added
Output schema / properties / statusAdded value: +{ + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" +} - added
Output schema / properties / targetAdded value: +{ + "enum": [ + "esp", + "stm" + ], + "type": "string" +} - added
Output schema / properties / taskAdded value: +{ + "type": "string" +} - added
Output schema / properties / toolAdded value: +{ + "type": "string" +} - added
Output schema / properties / transportAdded value: +{ + "type": "string" +} - added
Output schema / properties / tsAdded value: +{ + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "success", - "method", - "duration_seconds", - "output_tail" -]New value: +[ + "success" +]
- Removed
crosspad_input - Removed
crosspad_interface_implementations - Removed
crosspad_kill - Removed
crosspad_list_apps_source - Removed
crosspad_list_interfaces - Removed
crosspad_log - Removed
crosspad_midi - Removed
crosspad_repo_diff - Removed
crosspad_run - Removed
crosspad_screenshot - Removed
crosspad_search_symbols - Removed
crosspad_settings_get - Removed
crosspad_settings_set - Added
crosspad_snapshot - Removed
crosspad_stats - Removed
crosspad_submodule_update - Added
crosspad_task - Removed
crosspad_test_run - Added
crosspad_toolsets - Removed
crosspad_trace
1 tool update
v9.3.0- Added
crosspad_audio_route
29 tool updates
v9.2.0- First observed
crosspad_apps_install - First observed
crosspad_apps_list - First observed
crosspad_apps_remove - First observed
crosspad_apps_sync - First observed
crosspad_apps_update - First observed
crosspad_build - First observed
crosspad_capabilities - First observed
crosspad_check - First observed
crosspad_commit - First observed
crosspad_devices - First observed
crosspad_flash - First observed
crosspad_input - First observed
crosspad_interface_implementations - First observed
crosspad_kill - First observed
crosspad_list_apps_source - First observed
crosspad_list_interfaces - First observed
crosspad_log - First observed
crosspad_midi - First observed
crosspad_repo_diff - First observed
crosspad_repo_status - First observed
crosspad_run - First observed
crosspad_screenshot - First observed
crosspad_search_symbols - First observed
crosspad_settings_get - First observed
crosspad_settings_set - First observed
crosspad_stats - First observed
crosspad_submodule_update - First observed
crosspad_test_run - First observed
crosspad_trace
TDQS
Scored across 8 tools
Each tool targets a distinct concern: repo status, build, device enumeration, environment health, runtime snapshot, flashing, toolset visibility, and task lifecycle. No two tools have overlapping responsibilities, and the descriptions reinforce clear boundaries with explicit platform and scope tags.
All names share the consistent `crosspad_` prefix and snake_case format, so the set is easy to scan and predict. However, the pattern is slightly mixed: `crosspad_build` and `crosspad_flash` are verb-like, while `crosspad_devices`, `crosspad_snapshot`, and `crosspad_toolsets` are noun-like resources.
Eight tools is a well-scoped count for a multi-platform development server, with each tool covering a major workflow area and no redundancy. The count sits comfortably in the ideal range, especially given the built-in toolset management for expanding or hiding tools.
Core workflows—repo status, build, device discovery, environment checks, snapshot, flash, and async task management—are covered without dead ends. Minor gaps like direct device reset, app interaction, or trace collection are plausibly deferred to non-core toolsets, so the surface is slightly incomplete but not broken.
Maintenance
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Claude Code / MCP skills for the dev pipeline: discover, spec, design, build, ship, operate.
- i3deployOAuthcom.i3deploy
Deploy & release tracking with native MCP — ask Claude what's in production and cut the release.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server that spawns autonomous Claude Code agents in GitHub repos, enabling task delegation with persistent state, multi-step workflows, and job monitoring.4779 npm2Apache 2.0
- FlicenseNot gradedqualityDmaintenanceAn MCP server that lets Claude manage long-running development processes across frameworks like Flutter, Next.js, Spring Boot, and Vite, with lifecycle control, log streaming, and hot reload support.1-
- AlicenseAqualityBmaintenanceCode intelligence MCP server for Claude Code providing multi-project code graph, semantic search, session history, knowledge base, and web search.153MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that enables Claude Code to communicate with other Claude Code agents over HTTP, allowing users to ask questions about remote codebases or delegate coding tasks.MIT