OpenBaud
# OpenBaud
[](https://github.com/Leonezz/openbaud/actions/workflows/ci.yml)
[](https://github.com/Leonezz/openbaud/releases/latest)
[](LICENSE)
**Turn serial hardware into reusable, auditable tools for coding agents.**
OpenBaud gives Codex structured access to local serial devices. Inside an agent
task, it makes hardware actions visible and auditable, returns structured
results instead of byte dumps, and turns verified exploration into durable
tools. It combines an MCP server with device profiles, typed commands,
workflows, lossless captures, byte-exact replay, and a hardware-exploration
skill.

[Watch the 46-second PV](docs/assets/openbaud-pv.mp4) ·
[Try without hardware](examples/pv-demo/README.md) ·
[Install for Codex](#install-the-codex-plugin)
## Why OpenBaud
A serial terminal can send bytes. An ad-hoc script can make one device work.
OpenBaud keeps the evidence that makes the result repeatable:
- **Explore safely:** identify ports by USB metadata, frame responses, audit
writes, and require explicit acknowledgement for dangerous commands.
- **Sediment knowledge:** turn verified behavior into typed, reviewable YAML
commands and fixed workflows with provenance.
- **Parse real protocols:** validate checksums and decode scalars, bit fields,
split lists, and record arrays into structured results — including data a
device pushes on its own, checked frame by frame.
- **Refuse what would be wrong:** a command declares the device state it
depends on (`requires`), and is refused before a byte is sent when the
session has not established that state — instead of returning a valid frame
that means something else.
- **Replay without hardware:** record every RX/TX byte in `.obcap`, then rerun
the same command and parser against the capture.
```text
serial device → lossless capture → checksum → typed parse → command → replay
```
## Real ESP32 demo
The product video uses a physical ESP32-S3 development board running a new
binary protocol, **OBP/1**. OpenBaud recorded eight hardware exchanges and
decoded every 196-byte response into 36 polar points with CRC-16 verification.
The USB transport, board timestamps, frames, captures, and parsing are real.
The radar scene is generated by the test firmware, and that fact is declared on
the wire as `simulated_scene: 1`.
Run the exact parser against the included real-device capture:
```sh
cargo run --locked -p openbaud -- run openbaud-pv-board/obp1_radar_scan \
--workspace examples/pv-demo \
--port replay:captures/obp1-radar-seq42.obcap \
--set seq=42
```
Expected result: `outcome: normal`, `seq: 42`, `point_count: 36`, and 36
decoded `{angle_deg, distance_mm, intensity}` records. The
[example workspace](examples/pv-demo/) includes the command, protocol layout,
and lossless capture.
## Install the Codex plugin
Register this Git repository as the `openbaud-marketplace` marketplace and
install its plugin:
```sh
codex plugin marketplace add Leonezz/openbaud --ref stable
codex plugin add openbaud@openbaud-marketplace
```
Start a new Codex task, connect a serial device, then ask:
```text
Use OpenBaud to identify this serial device. Start read-only, preserve a
capture, and turn verified behavior into reusable commands.
```
The stable marketplace plugin bundles all five native MCP runtimes and selects
the matching one locally at startup. Users need Node.js 18 or newer for the
portable launcher, but do not need Rust, Cargo, Homebrew, an install hook, or a
runtime download. The supported hosts are macOS ARM64/Intel, Linux x64/ARM64,
and Windows x64. macOS binaries are ad-hoc signed for preview distribution but
are not yet Apple-notarized.
The `stable` branch advances only after every native package and the aggregated
plugin pass their smoke tests. To refresh it immediately, run:
```sh
codex plugin marketplace upgrade openbaud-marketplace
```
Start a new task after an update. For an immutable installation, download the
versioned universal or host-specific marketplace archive from GitHub Releases
and register its extracted local path.
See [plugins/openbaud/README.md](plugins/openbaud/README.md) for platform
archives, upgrade instructions, packaging details, and smoke tests.
## Knowledge format
An OpenBaud workspace keeps device knowledge next to the project:
```text
devices/<device>/profile.yaml
devices/<device>/commands/*.yaml
devices/<device>/workflows/*.yaml
devices/<device>/notes.md
captures/*.obcap
.openbaud/audit.jsonl
reports/ # derived analysis for people, citing the captures it came from
scripts/ # one-off analysis helpers; device behavior belongs in commands
```
The `schema` MCP tool and `openbaud schema` CLI command are the authority for
the current profile, command, and workflow formats.
## Build and verify
```sh
cargo test --workspace
python3 scripts/validate-package.py
python3 -m unittest scripts/test_package_plugin.py
node --test scripts/test-plugin-launcher.mjs
plugins/openbaud/scripts/build-runtime
plugins/openbaud/scripts/smoke-test
```
GitHub Actions runs Clippy, package validation, native builds, tests, archive
verification, and real MCP smoke tests on macOS ARM64/Intel, Linux x64/ARM64,
and Windows x64. Stable `vMAJOR.MINOR.PATCH` tags publish all five platform
archives, one universal marketplace archive, and SHA-256 files. The release
workflow then advances the `stable` marketplace branch to that verified
universal bundle.
The Remotion source and real capture used to produce the public video live in
[media/pv](media/pv/). Regenerate its data with `pnpm extract`, preview with
`pnpm studio`, and render with `pnpm render`.
## Safety
Serial writes can reconfigure or actuate physical hardware. OpenBaud marks raw
writes and device commands as potentially destructive MCP operations, keeps an
append-only audit, and requires explicit acknowledgement for commands declared
with `risk: danger`. Commands that declare `requires` are refused until the
session has established that device state; overriding with
`assume_preconditions` is recorded in the result and the audit. Start unknown
devices read-only and preserve a recovery path before changing state.
## License
MIT
TDQS
Scored across 18 tools
Descriptions go out of their way to delineate boundaries (send=raw fire-and-forget, request=send+await, run_command=named typed command; read=cursor read, stream_poll=independent per-consumer subscription; ask_port 'not for discovery, that's list_ports'). This is unusually explicit, though three byte-sending tools and two frame-reading tools still require careful reading to pick correctly.
Most names are a clean verb_noun or noun_noun pattern (list_ports, run_command, run_workflow, capture_start, session_timeline, diagnose_frame, show_result, stream_poll), and the capture_*/session_* prefixes group cleanly. A handful of bare verbs (open, close, read, send, request) deviate slightly, but the overall scheme stays predictable.
18 tools is slightly heavy but justified by the breadth of a serial-toolkit domain: discovery, session lifecycle, three send modes, capture, re-framing, diagnostics, stats, streaming, plus schema and viewer helpers. Each tool maps to a distinct capability rather than being redundant.
The surface covers the full lifecycle: discovery (list_ports), open/close, multiple send/execute modes (send, request, run_command, run_workflow), lossless capture (capture_start/stop) with offline analysis (capture_frames, session_timeline, diagnose_frame), live stats and streaming, plus schema and result rendering. No obvious dead ends for the stated purpose.