Judge hardware timing/serial against a contract: pass/marginal/fail (WS2812, DShot, logs)
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
Your firmware is correct on paper and wrong on the wire.
Coding agents write WS2812 drivers, ESC bitstreams, and boot logs that pass review and then fail the moment the signal hits a real chip. hwcontract closes that loop. It captures what the hardware actually did and returns a verdict you can act on:
Two things a green verdict gives you beyond the table:
No hardware in your hand? The demo below runs the whole thing on a real recorded signal, so you can see exactly what you get before wiring anything up.

That judges a real 24-LED NeoPixel capture against two contracts. Same signal, two verdicts:
Same hardware, two contracts: the generic one fails, the chip-specific one passes. A WS2812B isn't a WS2812. Measure the real signal, hold it to a spec, and match the contract to the actual chip.
100 synthesized SPI frames as raw CS/SCK/MOSI waveforms at 100MHz, reduced to
pin edges and judged against the bundled spi-frame contract. Frame 77 has
the Zephyr LPSPI DMA fault: chip-select asserts after the clock starts. Frame
42 settles MOSI 10ns before the sampling edge. Both come back with exact
timestamps, and the same broken edges are re-imported as sigrok-style B/E
jsontrace annotations:
The data is perfect in all 100 frames; a loopback test passes. The ordering is broken in two, and only a cross-signal assertion notices.
Live logic-analyzer capture (check_ws2812 / check_dshot) also needs
sigrok-cli on PATH. Judge-only tools (judge_contract, judge_serial) need
nothing extra.
One stanza per client, add it once. After install, the hwcontract command is
on your PATH.
Claude Code
Codex CLI: ~/.codex/config.toml
opencode / Cursor / Gemini / any stdio MCP client
Transport is stdio by default (local, no auth surface). For remote-only clients (e.g. ChatGPT connectors), run
hwcontract --http 8791and expose it via a tunnel withHWCONTRACT_TOKENset for bearer auth.Speaks MCP 2026-07-28, the stateless revision: per-request
_meta,server/discover, no handshake. Clients that still open withinitializeget the old shape back. Each request picks its own era, so nothing to configure.
hwcontract (PATH issues)GUI apps and some agents don't inherit your shell PATH, so a bare hwcontract
can fail with "command not found". Two robust fixes:
which hwcontract β put that full path in command.command: "python3",
args: ["-m", "hwcontract.server"]. Works from any directory once installed.Contract paths: pass an absolute contract_path, or set HWCONTRACT_ROOT
to your contracts folder. Relative paths resolve against it, defaulting to the
process's working directory, which the client controls and may not be your
project. Paths outside the root are rejected. Bundled examples install with the
package under hwcontract/examples/.
| Tool | Hardware? | What it does |
|---|---|---|
judge_contract | no | Judge given observations against a timing contract. Replay / testing. |
judge_serial | no | Judge a given log string against a serial contract's expect/forbid. |
judge_events | no | Judge decoded events against temporal assertions (when/require/within, forbid/while/before). |
check_ws2812 | yes | Capture a live WS2812 line and judge it, one call. |
check_dshot | yes | Same, for a DShot600 ESC signal. |
capture_ws2812 | yes | Just capture β observations (no judging). |
check_serial | yes | Read a serial port for N seconds and judge the log. |
Event contracts are the SVA-style layer: relationships between decoded
events, checked for every occurrence, with latency distributions and
first-failure timestamps. Feed them sigrok-cli --protocol-decoder-jsontrace
output and judge from the CLI:
The bundled spi-frame.contract.yaml catches the Zephyr LPSPI class of bug
(CS asserting after SCK starts, MOSI setup collapse) that loopback tests
cannot see.
Prefer plain pytest over MCP? pytest-hwcontract is a
plugin that turns verdicts into tests: a FAIL, MARGINAL or MISSING edge fails
the test with the verdict table in the message, JUnit included.
The repo ships a GitHub Action, so captures checked into the repo get judged on every PR:
A FAIL, MARGINAL or MISSING edge fails the step, annotates the failing line, and writes JUnit. The action self-tests on every push to this repo with one clean and one deliberately broken capture.
judge.py. The pure judge for timing and serial, plus contract validation. No hardware, no framework, cached.temporal.py. Cross-event temporal assertions: selectors, signed windows, latency distributions, first-failure timestamps.jsontrace.py. Imports sigrok-cli's Google Trace Event JSON into normalized events.sigrok_adapter.py. Turns a logic-analyzer capture into pulse-width distributions for WS2812 and DShot.serial_adapter.py. Captures a serial log, or replays a saved one.server.py. The MCP server, stdio and HTTP JSON-RPC, stdlib only.*.contract.yaml. What "correct" looks like. Human-editable, and they double as regression tests.Timing (ws2812.contract.yaml, dshot.contract.yaml): pulse widths in ns
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/hwcontract)<a href="https://allmcps.com/mcp/hwcontract"><img src="https://allmcps.com/api/badge/hwcontract?style=directory" alt="Hwcontract on AllMCPs" /></a>