{
  "markdown": "# osc-bridge\n\n[![Release](https://img.shields.io/github/v/release/roomi-fields/osc-bridge?sort=semver&display_name=tag)](https://github.com/roomi-fields/osc-bridge/releases)\n[![CI](https://github.com/roomi-fields/osc-bridge/actions/workflows/ci.yml/badge.svg)](https://github.com/roomi-fields/osc-bridge/actions/workflows/ci.yml)\n[![License: GPL-3.0-or-later](https://img.shields.io/badge/license-GPL--3.0--or--later-blue.svg)](LICENSE)\n\n**Declarative OSC bridge for music hardware *and* software — and an MCP server to drive it from an LLM.**\n\n849 hardware synthesizers over MIDI / SysEx, plus DAWs and live-coding\nenvironments over OSC (Ableton, Bitwig, Reaper, Sonic Pi, SuperCollider, Pure\nData, TouchDesigner, VCV Rack). Every device gets a clean, named OSC surface\ndescribed by one JSON file. Drive it from a live-coding client, a DAW, a\nscript, the CLI — or from Claude via the built-in **MCP server** (a **MIDI MCP**\n*and* **OSC MCP**).\n\n![osc-bridge — clients (OSC clients, the CLI, an LLM via MCP) feed one osc-bridge core that fans out to hardware synthesizers over MIDI/SysEx and music software (Ableton, Bitwig, Reaper, Sonic Pi) over OSC](docs/demo/osc-bridge-demo.png)\n\n## Install\n\nAs an **MCP server** — drive synths and DAWs from Claude, nothing to install:\n\n```bash\nnpx -y @roomi-fields/osc-bridge mcp\n```\n\nAs a **standalone bridge / CLI**:\n\n```bash\nnpm install -g @roomi-fields/osc-bridge      # downloads the prebuilt binary\n# or grab a binary directly from the Releases page\nosc-bridge run --device devices/arturia/minilab3.json --out-port 4\n```\n\nMCP client config and the five tools → [`docs/MCP.md`](docs/MCP.md). Full\nquick-start with MIDI port discovery → [§ Install & quick start](#install--quick-start).\n\n## Why a bridge?\n\nModern synths — hardware and software alike — expose themselves over MIDI,\nSysEx, and OSC with proprietary, scattered protocols. Using them from\nlive-coding environments, a DAW, a script, or an LLM is painful:\n\n- CC / NRPN addresses are cryptic\n- SysEx byte formats are hand-rolled per device\n- Bidirectional state (what the device CURRENTLY knows) is hard to track\n\n**`osc-bridge`** gives every supported synth a clean, named OSC surface:\n\n```supercollider\n~mb = NetAddr(\"127.0.0.1\", 7777);\n~mb.sendMsg(\"/minilab3/knob/3/cc_number\", 64);     // reconfigure knob 3\n~mb.sendMsg(\"/minilab3/pad/0/color\", 127, 0, 0);    // pad 1 red\n~mb.sendMsg(\"/minilab3/display/text\", \"Hello\", \"World\");\n```\n\nEach synth is described by one JSON file. No Rust recompile required to add a device.\n\n## What makes it different\n\n- **One JSON = one driver.** Adding a synth is ~30 lines of declarative JSON — CC numbers, SysEx frame templates, optional parameter tables. No Rust, no bindings, no build step. Ship a PR, `osc-bridge run` picks it up.\n- **849 devices out of the box.** Every Prophet, every Oberheim, every Yamaha DX-family, MatrixBrute, Hydrasynth, Virus TI, Digitone, Matrix-1000… most of the catalogue is usable today. Fully searchable at [roomi-fields.github.io/osc-bridge](https://roomi-fields.github.io/osc-bridge/).\n- **Hardware *and* software.** The same named OSC surface drives a hardware synth over MIDI/SysEx *or* a DAW / live-coding environment over OSC — Ableton, Bitwig, Reaper, Sonic Pi, SuperCollider, Pure Data, TouchDesigner, VCV Rack. See [§ Software targets](#software-targets--daws-and-live-coding-environments).\n- **An MCP server built in.** `osc-bridge mcp` exposes the whole catalogue to Claude (or any MCP client) — a MIDI MCP *and* OSC MCP. Discover devices, read a device's OSC surface, send OSC to synths and DAWs. See [`docs/MCP.md`](docs/MCP.md).\n- **Honest provenance.** Each device declares its source in `_sources[]`: `✅ hardware-verified`, `✅ software-verified`, `📘 vendor-doc`, `📡 vendor-osc-api` / `📡 third-party-osc`, `🎛️ electra-preset`, `📦 pencilresearch`. You always know whether a mapping was tested on the device or lifted from a spec sheet.\n- **Bidirectional out of the box.** Incoming MIDI (knob turns, SysEx replies, NRPN) is decoded and re-emitted as OSC. Multi-client fan-out is a `--osc-client` flag.\n- **N-to-N orchestration.** One process can drive several synths at once (`osc-bridge orchestrate --config bridge.toml`), each reachable under its own OSC prefix — so two MatrixBrutes live side-by-side as `/matrixbrute-1` and `/matrixbrute-2`.\n- **First-class reconfigurable controllers (Electra One MK2).** Upload a generated preset as one OSC call; the bridge parses the JSON, reconfigures the device over SysEx, and *dynamically* rewires its own CC↔OSC routing so each knob on the new layout is reachable by name. Self-describing over OSC: `/bridge/docs` returns the integration guide, `/electra1/routes/list` returns the authoritative address table, so clients (or LLM-driven integrators) never hardcode slugification or protocol details. See [§ Reconfigurable controllers](#reconfigurable-controllers-electra-one-mk2--the-scripts-stress-test) below.\n- **Escape hatch when JSON isn't enough.** For devices with checksums, quirky scaling, or stateful protocols, an optional per-parameter `transform` / per-command `script` runs Lua 5.4 sandboxed (1 MiB / 10 ms caps, no `os`/`io`/loaders). Used sparingly — `osc-bridge lint` warns on every script use — but it lets the declarative core stay small without giving up on edge cases. See [`docs/scripting.md`](docs/scripting.md).\n- **Runtime you can trust.** Rate-limiting per device, backpressure-aware, zero-alloc hot path, no GC. Single static binary on Windows / Linux / macOS.\n\n## Supported devices\n\n**849 devices across 187 vendors** — Moog · Arturia · Novation · Korg · Sequential · Dave Smith Instruments · Roland · Yamaha · Elektron · Waldorf · Behringer · Dreadbox · Erica Synths · Polyend · Modal · Expressive E · Bastl · Chase Bliss · Make Noise · Electra One · Tasty Chips · Oberheim · Access · ASM · Black Corporation · Hologram · Strymon · Empress · Meris · Eventide · Ensoniq · Rhodes · Haken · Tubbutec · **Ableton · Bitwig · Cockos (Reaper) · Sonic Pi · SuperCollider · Pure Data · TouchDesigner · VCV Rack** · and ~85 more.\n\n| Status | Count | Highlight |\n|---|---|---|\n| ✅ **Hardware-verified** (tested on the physical device — scope varies per driver, see `_sources` in each JSON) | **4** | Arturia MiniLab 3 · Electra One MK2 · Ableton Push 3 · Arturia MatrixBrute (firmware-RE partial) |\n| ✅ **Software-verified** (tested end-to-end against a running instance of the host software) | **1** | Ableton Live 12.2.7 (via AbletonOSC) |\n| 📘 **Vendor-doc derived** (from manufacturer programmer's references — bytes match the spec) | **193** | Novation Launch Control XL 3 · Polyend Synth · … |\n| 📡 **OSC-API (software targets)** — DAWs and live coding environments, declarative or passthrough | **7** | Bitwig Studio · Reaper · Sonic Pi · SuperCollider · Pure Data · TouchDesigner · VCV Rack |\n| 🎛️ **Electra-preset derived** (from the [Electra One community preset library](https://app.electra.one/) — covers SysEx + CC/NRPN, author's editorial choices) | **398** | Prophet 5/10 · Prophet 6 · OB-6 · OB-X8 · Matriarch · Hydrasynth · Virus TI · Digitone · … |\n| 📦 **Pencilresearch derived** (from [pencilresearch/midi](https://github.com/pencilresearch/midi) — CC/NRPN only) | **244** | Moog · Sequential · DSI · Roland · Yamaha · Waldorf · Behringer · Dreadbox · … |\n| 🚧 **WIP / 📝 stub** | **2** | GR Mega (placeholder) |\n\n**Searching for your device?**\n- 🔎 Interactive browser → **<https://roomi-fields.github.io/osc-bridge/>** (live search by vendor / model / author / source).\n- 📄 Full catalogue as Markdown → [`docs/SUPPORTED_DEVICES.md`](docs/SUPPORTED_DEVICES.md) (auto-generated, organised by vendor).\n\nYour synth isn't there, or a doc-derived entry (`📘` / `📡` / `🎛️` / `📦`) needs promoting to `✅` after you test it on hardware? See the next section.\n\n### Share your own device\n\nNew here? The [30-minute tutorial](docs/TUTORIAL_FIRST_DEVICE.md) builds a\nworking driver end to end. Otherwise — three common cases, pick yours:\n\n**Your synth isn't listed** → open a PR adding `devices/<vendor>/<slug>.json`.\n  1. Find a source: vendor programmer's reference, MIDI implementation PDF, or a canonical CSV. No source cited = PR stays open until one is provided.\n  2. If it's in [pencilresearch/midi](https://github.com/pencilresearch/midi), run `python3 scripts/import_pencilresearch.py <path-to-csv>` — generates the JSON for you.\n  3. Otherwise copy a similar existing device from `devices/` as a template and follow [`docs/DEVICE_JSON_SCHEMA.md`](docs/DEVICE_JSON_SCHEMA.md).\n  4. Run `cargo run --release -- lint <file>` and `cargo test --release`.\n  5. Run `python3 scripts/regen_supported_devices.py` to refresh the catalogue.\n  6. Open the PR — GitHub shows the `new_device.md` template.\n\n**Your synth is listed but not yet `✅`, and you have the hardware** → PR promoting it to `✅`. Test every route, attach the log, flip the marker. `promote_to_verified.md` template.\n\n**Your synth is listed but a CC is wrong / needs SysEx added** → PR updating the JSON. `update_device.md` template. Especially welcome on pencilresearch-imported devices where SysEx needs to be layered in.\n\nFull contributor guide (schema extensions, bug reports, Lua escape hatch) → [`CONTRIBUTING.md`](CONTRIBUTING.md). For devices whose protocol can't be expressed declaratively, see [`docs/scripting.md`](docs/scripting.md) — use sparingly; `osc-bridge lint` warns on every use.\n\n## Reconfigurable controllers (Electra One MK2) — the scripts stress-test\n\nMost synths have a fixed set of controls — MiniLab 3's knobs always mean the same\nthing. The [Electra One MK2](https://electra.one/) is different: its 216 controls\nare defined by a preset that you upload to the device, and the meaning of every\nCC changes when the preset changes. A static JSON spec can't describe that; the\nbridge treats it as a first-class case.\n\n**This integration is what validates the whole Lua scripting subsystem in anger.**\nThe MK2 driver exercises every feature of the `scripting.rs` layer on real\nhardware (firmware 4.1.4, verified 2026-04-14):\n\n- **Native JSON codec** (`ob.json_decode` / `ob.json_encode`) — parses a full\n  Electra preset (up to 100 KB of nested pages/devices/groups/controls/overlays)\n  in a single Lua block, under the 500 ms `preset_ingest` profile.\n- **Persistent per-device state** (`ob.state`) — the driver stores the active\n  preset name so `/electra1/preset/current` can report it on demand.\n- **Dynamic CC↔OSC route registration** (`ob.register_cc_route` /\n  `ob.clear_routes` / `ob.set_current_page`) — every preset upload rebuilds\n  the bridge's routing table from scratch, zero restart.\n- **Multi-block SysEx emission** (`ob.emit_sysex`) — the upload script emits\n  the wrapped SysEx preset data block directly from Lua.\n- **Outbound OSC emission** (`ob.emit_osc`) — powers the introspection\n  endpoints: `/routes/list`, `/preset/current`, `/page/current`.\n- **Reply scripts with matched bindings** (`ctx.bindings`) — when the device\n  reports a page switch over SysEx, a reply script updates the bridge's active\n  page so CC routing tracks the hardware UI automatically.\n- **Companion markdown auto-load** — `devices/electra-one/electra-one.md` is\n  loaded at startup and served over `/bridge/docs`, so LLM-driven integrators\n  read the device-specific quirks (hex-color requirement, `inputs[{potId}]`\n  mandatory, envelope-segment cycling gesture, MIDI port selection, etc.)\n  without any code-side knowledge.\n\nEvery item above has a unit test, an end-to-end test against the real `.json`\ndriver, and a hardware-verified green light. If you're building a driver for\nanother reconfigurable controller (Faderfox custom, programmable MIDI Fighter),\nthe Electra driver is the template — copy its `custom_commands` block, adapt\nthe JSON→routes parsing to your device's preset format, done.\n\n### What the bridge does\n\n```\n Kanopi / your client                   osc-bridge                     Electra One MK2\n─────────────────────                 ────────────────               ────────────────────\n\n /electra1/preset/upload  ───► parse preset JSON (preset_ingest\n   \"<preset JSON>\"                profile: 500 ms / 4 MiB Lua)\n                                ┌─ ob.clear_routes()\n                                ├─ ob.register_cc_route × N\n                                │    (one per cc7 control,\n                                │     per-page, with channel)\n                                └─ ob.emit_sysex(…)  ──────────► F0 00 21 45 01 01 <json> F7\n                                                                          (reconfigures device)\n                                                   ◄────────── F0 00 21 45 7E 01 …  ACK\n\n (user turns knob on page 2)                     ◄────────── B4 4A 53  (CC#74 ch5 = 83)\n                             route lookup: page=2, ch=4, cc=74\n                             → /electra1/page2/cutoff 0.65 ───► /electra1/page2/cutoff 0.65\n\n (user switches page on device)                  ◄────────── F0 00 21 45 7E 06 03 F7\n                             reply.script fires:\n                             ob.set_current_page(3)\n                                                               ───► /electra1/page/switched 3\n```\n\n### Discovery from zero\n\nEvery piece of device-specific knowledge is exposed over OSC — clients never\nhardcode slugification rules, page indexing, or SysEx opcodes:\n\n| Send | Receive |\n|---|---|\n| `/bridge/status` | One `/bridge/status/device <slug> <status>` per connected device |\n| `/bridge/docs` | `/bridge/docs/device <slug> <markdown>` — full integration guide (the device's companion `.md`, loaded automatically) |\n| `/electra1/routes/list` | N× `/electra1/routes/entry <addr> <ch> <cc> <page> <min> <max>` then `/electra1/routes/done` |\n| `/electra1/preset/current` | `/electra1/preset/current <name>` |\n| `/electra1/page/current` | `/electra1/page/current <n>` |\n\nAn LLM-driven integrator needs exactly four steps to go from cold start to\nrouting knob turns: `/bridge/status` → `/bridge/docs` → `/electra1/preset/upload`\n→ `/electra1/routes/list`. Everything else is in the markdown guide embedded\nin the bridge itself.\n\n### Generalising to other reconfigurable controllers\n\nThe machinery (`DynamicRoutes`, `ob.register_cc_route`, `ob.emit_sysex`,\n`custom_commands`, companion `.md` auto-loading) is device-agnostic. Adding\na reconfigurable Faderfox, a custom MIDI Fighter Twister layout, or any\nprogrammable controller is the same recipe: a preset-parsing Lua block inside\nthe device JSON that calls `ob.register_cc_route` per control. No core changes.\n\n## Install & quick start\n\n### Prebuilt binaries\nGrab the latest `osc-bridge.exe` (Windows), `osc-bridge` (Linux/macOS) from\nthe [Releases page](https://github.com/roomi-fields/osc-bridge/releases).\n\n### From source\n```\ngit clone https://github.com/roomi-fields/osc-bridge\ncd osc-bridge\ncargo build --release\n./target/release/osc-bridge list\n```\n\n### Minimal MiniLab 3 workflow\n\n```bash\n# 1. Find your MIDI port indices\nosc-bridge list\n\n# 2. Start the bridge\nosc-bridge run --device devices/arturia/minilab3.json \\\n  --out-port 4 --in-port 0 \\\n  --bind 127.0.0.1:7777 --osc-client 127.0.0.1:8888\n\n# 3. From another terminal, send OSC\nosc-bridge osc-send /minilab3/display/text \"Hello\" \"World\"\nosc-bridge osc-send /minilab3/pad/0/color 127 0 0\nosc-bridge osc-send /minilab3/knob/3/cc_number 100\n```\n\nIncoming MIDI events (knob turns, pads played, pitch-bend, SysEx GET replies)\nare forwarded to `--osc-client` as OSC:\n\n```\n/minilab3/cc/18 95 0        ← knob moved\n/minilab3/note/on 60 127 0\n/minilab3/param/value 0 7 0 0 1   ← reply from a /param/get\n```\n\n### Browser clients (OSC over WebSocket)\n\nBrowsers can't speak UDP. Pass `--ws-bind` to expose the same OSC surface\nover WebSocket:\n\n```bash\nosc-bridge run --device devices/arturia/minilab3.json \\\n  --out-port 4 --in-port 0 --ws-bind 127.0.0.1:7890\n```\n\nBinary WS frames carry raw OSC packets — the exact bytes the UDP transport\nuses, so a minimal dependency-free OSC encoder/decoder in JS covers both\ndirections. Every connected WS client behaves like an extra `--osc-client`:\nit receives all outbound events (decoded MIDI-in, SysEx replies,\n`/bridge/status`) and its frames go through the same dispatch as UDP.\nUnder `orchestrate`, set `ws_bind = \"127.0.0.1:7890\"` in the `[osc]`\nsection of `bridge.toml`. Disabled by default; keep it on `127.0.0.1`\nunless you really want LAN clients.\n\n### Device not showing up? (Windows 11 24H2+)\n\nSince the March 2026 cumulative update (KB5079473), Windows 11 ships\nMicrosoft's new `USBMidi2-ACX` driver which enforces stricter USB descriptor\nchecks. Devices that pass the old checks but fail the new ones appear in\nDevice Manager with **Status: Unknown**, or bind to a driver that exposes\nthem only through the new MIDI Services API — **invisible to `midir` (and\ntherefore to osc-bridge)** which queries the legacy MME interface.\n\nConfirmed affected: **Polyend Synth / Play / Tracker / Mess / Step**\n(VID 16D0). Likely affected: any older USB-MIDI device whose descriptor\ndoesn't meet the new spec.\n\nWorkaround — force the legacy `usbaudio` driver:\n\n1. Device Manager → **Sound, video and game controllers** → right-click the\n   device → **Update Driver**.\n2. **Browse my computer for drivers** → **Let me pick from a list of\n   available drivers on my computer**.\n3. Select **USB Audio Device** (FR: \"Périphérique audio USB\"). If not\n   visible, uncheck \"Show compatible hardware\" and look under the Standard\n   USB section.\n4. Install, then unplug/replug the USB cable to force MME to re-enumerate.\n5. `osc-bridge list` should now show the device.\n\nTrack Microsoft's progress on KB5079473 if you want a permanent fix —\nPete Brown (Microsoft) acknowledged the packet-size issue publicly but\nclassified it as non-blocking. Polyend's firmware-side fix is not\nannounced at the time of writing.\n\n## Ergonomics\n\n### Explore a device spec without connecting anything\n```\nosc-bridge inspect devices/arturia/minilab3.json\n```\n\n### Live-debug the OSC traffic\n```\nosc-bridge osc-listen --bind 127.0.0.1:8888\n```\n\n### Send raw SysEx (power user)\n```\nosc-bridge osc-send /minilab3/raw/syx \"F0 00 20 6B 7F 42 02 00 16 04 7F 00 00 F7\"\n```\n\n## How device JSONs work\n\nA device file declares three things:\n\n1. **Framing** — the SysEx header/footer bytes.\n2. **Commands** — high-level OSC routes (pad colors, display text, preset recall) that build frames by substituting OSC args into placeholder templates.\n3. **Params** — a flat table of parameter addresses for bulk GET/SET via a shared opcode.\n\nExample snippet (`devices/arturia/minilab3.json`):\n\n```jsonc\n{\n  \"commands\": [\n    {\n      \"osc\": \"/pad/{pad}/color\",\n      \"args\": [\n        {\"name\":\"pad\",\"type\":\"u7\",\"range\":[0,7]},\n        {\"name\":\"r\",\"type\":\"u7\"},\n        {\"name\":\"g\",\"type\":\"u7\"},\n        {\"name\":\"b\",\"type\":\"u7\"},\n        {\"name\":\"mode\",\"type\":\"enum\",\n         \"values\":{\"user\":0,\"arturia\":1,\"daw\":2},\"default\":\"user\"}\n      ],\n      \"pre\": [{\"bind\":\"pad_id\",\"expr\":\"pad + 4\"}],\n      \"frame\": [2, \"{mode}\", 22, \"{pad_id}\", \"{r}\", \"{g}\", \"{b}\"]\n    }\n  ],\n  \"params\": {\n    \"get_frame\": [32, \"{pr}\", \"{p}\", \"{c}\", \"{r}\"],\n    \"set_frame\": [33, \"{pr}\", \"{p}\", \"{c}\", \"{r}\", \"{val}\"],\n    \"value_type\": \"u7\",\n    \"entries\": [\n      {\"osc\":\"/global/backlight\", \"pr\":7, \"p\":0, \"c\":0, \"r\":0, \"range\":[0,1]}\n    ]\n  }\n}\n```\n\n## Software targets — DAWs and live coding environments\n\nosc-bridge isn't only for hardware synthesizers. Since version 0.10 it also\ntreats DAWs and live-coding environments as **first-class devices**, behind\nthe same `/<env>` OSC surface as a Prophet or a Matriarch. A driver JSON\ndeclares `device.transport.kind = \"osc\"` and the bridge forwards OSC to the\ntarget's UDP port instead of going through a MIDI cable.\n\nTwo flavors:\n\n**Declarative drivers** — when the host software has a fixed, documented OSC\nsurface (Ableton via [AbletonOSC](https://github.com/ideoforms/AbletonOSC),\nBitwig via [DrivenByMoss](https://github.com/git-moss/DrivenByMoss), Reaper's\nnative OSC). The driver enumerates `commands[]` with typed args, plus\n`replies[]` for incoming events.\n\n**Passthrough drivers** — when the host software has no fixed OSC surface and\neach user defines their own paths in their project (Sonic Pi, SuperCollider,\nPure Data, TouchDesigner, VCV Rack). The driver just declares\n`transport.passthrough_prefix` and the bridge forwards anything under\n`/<env>/...` verbatim. Replies travel the other way with the prefix added back.\n\nCurrently supported:\n\n| Target | Mode | Status |\n|---|---|---|\n| Ableton Live 12.2.7 + AbletonOSC | declarative | ✅ software-verified |\n| Bitwig Studio + DrivenByMoss | declarative | 📡 third-party-osc |\n| Reaper 7 (Default.ReaperOSC) | declarative | 📡 vendor-osc-api |\n| Sonic Pi 4.5 | passthrough | 📡 vendor-osc-api |\n| SuperCollider sclang 3.13 | passthrough | 📡 vendor-osc-api |\n| Pure Data 0.55-x | passthrough | 📡 vendor-osc-api |\n| TouchDesigner 2023 | passthrough | 📡 vendor-osc-api |\n| VCV Rack 2 + [vcv-osc](https://github.com/roomi-fields/vcv-osc) plugin | passthrough | 📡 third-party-osc |\n\nEach comes with a `.md` companion under `devices/<vendor>/` that documents the\nrequired setup on the host side (Remote Script installation, ports, conventions).\n\nCombined with `osc-bridge orchestrate`, you can drive a hardware MiniLab 3,\nan Ableton Live, and a Sonic Pi loop **from a single process**. With the\nnew `[[routes]]` section in `bridge.toml`, a knob turn on the MiniLab can\ndrive an Ableton track volume or a Sonic Pi cue, without writing any client\ncode:\n\n```toml\n[osc]\nbind = \"127.0.0.1:7777\"\nclients = [\"127.0.0.1:8888\"]\n# ws_bind = \"127.0.0.1:7890\"   # optional — browser clients over WebSocket\n\n[[devices]]\nspec = \"devices/arturia/minilab3.json\"\nmidi_out_port = 4\nmidi_in_port = 0\n\n[[routes]]\nfrom = \"/minilab3/cc/74\"\nto = \"/ableton/track/0/volume\"\nmap.from = [0, 127]\nmap.to = [0, 1]\n```\n\n## Use from Claude via MCP\n\nosc-bridge ships a [Model Context Protocol](https://modelcontextprotocol.io)\nserver — a **MIDI MCP** *and* **OSC MCP**. Point any MCP client at it and the\nmodel can browse the 849-device catalogue, read a device's OSC surface, and\nsend OSC to synths and DAWs.\n\n```jsonc\n{\n  \"mcpServers\": {\n    \"osc-bridge\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@roomi-fields/osc-bridge\", \"mcp\"]\n    }\n  }\n}\n```\n\nFive tools — `list_devices`, `get_device_docs`, `list_routes`, `send`,\n`get_status`. Then in conversation: *\"What can the MatrixBrute do? Sweep its\nfilter cutoff.\"* — the model calls `list_routes(\"matrixbrute\")`, then `send`.\nNo glue code.\n\nFull setup — Claude Desktop / Cursor config, the workflow, driving software\ntargets → **[`docs/MCP.md`](docs/MCP.md)**.\n\n## Project genesis\n\nStarted as a MatrixBrute OSC driver (patch format reverse-engineered from the\nGPL-3 [sysex-controls](https://github.com/soyersoyer/sysex-controls) and the\ncommunity MBPV tool). Grew into a generic declarative bridge once the Arturia\nprotocol family became clear.\n\n## License\n\nGPL-3.0-or-later. Inherits GPL obligations from the `sysex-controls` reverse\nengineering that seeded our MiniLab 3 parameter table.\n",
  "bytes": 23136,
  "sha": "85d2b2900078cab3467ac1e3a386fc5e31872904cbcfdea646952171a9c0e0df",
  "repo_slug": "roomi-fields/osc-bridge",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_roomi_fields_osc_bridge_c6c9d1bc/readme"
}