neuron-explorer
Qwen3.5‑4B 전용 조향형 뉴런 탐색기, 모든 MLP 뉴런을 밀어 결과를 보관·탐색
오픈소스 OSC↔MIDI/SysEx 브리지와 MCP 서버, 963종 신시사이저·드럼머신·DAW 지원
Open-source OSC ↔ MIDI/SysEx bridge and MCP server for 963 synthesizers, drum machines and DAWs. Drive hardware by parameter name from Claude, SuperCollider, Sonic Pi, TouchDesigner or a web page.
개발 도구Rust · PythonGitHub @roomi-fields온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기OSC ↔ MIDI/SysEx bridge for 849 hardware synths and music software (Ableton, Bitwig, Reaper, Sonic Pi). A MIDI MCP and OSC MCP for Claude.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Declarative OSC bridge for music hardware and software — and an MCP server to drive it from an LLM.
Hardware synthesizers over MIDI / SysEx, plus DAWs and live-coding environments over OSC (Ableton, Bitwig, Reaper, Sonic Pi, SuperCollider, Pure Data, TouchDesigner, VCV Rack). Every device gets a clean, named OSC surface described by one JSON file, its driver; the catalogue of drivers lives on SynthHub, which hands them out one at a time. Drive it from a live-coding client, a DAW, a script, the CLI — or from Claude via the built-in MCP server (a MIDI MCP and OSC MCP).
Hosted MCP server, nothing to install — the SynthHub server, run by the maintainer of osc-bridge, with the catalogue, trust from real use and the relay to your own hardware:
https://mcp.synthhub.roomi-fields.com/mcpclaude mcp add --transport http synthhub https://mcp.synthhub.roomi-fields.com/mcp{"mcpServers": {"synthhub": {"url": "https://mcp.synthhub.roomi-fields.com/mcp"}}}On your machine — the MCP server over stdio, with hardware detection and OSC to a running bridge (each driver fetched from SynthHub when needed and kept in a cache; you choose what it shares):
npx -y @roomi-fields/osc-bridge mcp
As a standalone bridge / CLI:
npm install -g @roomi-fields/osc-bridge # downloads the prebuilt binary
# or grab a binary directly from the Releases page
osc-bridge run --device arturia/minilab3 --out-port 4 # a driver id, or a JSON file of yours
MCP client config and the tools → docs/MCP.md. Full
quick-start with MIDI port discovery → § Install & quick start.
Modern synths — hardware and software alike — expose themselves over MIDI, SysEx, and OSC with proprietary, scattered protocols. Using them from live-coding environments, a DAW, a script, or an LLM is painful:
osc-bridge gives every supported synth a clean, named OSC surface:
~mb = NetAddr("127.0.0.1", 7777);
~mb.sendMsg("/minilab3/knob/3/cc_number", 64); // reconfigure knob 3
~mb.sendMsg("/minilab3/pad/0/color", 127, 0, 0); // pad 1 red
~mb.sendMsg("/minilab3/display/text", "Hello", "World");
Each synth is described by one JSON file. No Rust recompile required to add a device.
The catalogue lives on SynthHub, not in this repository: browse and search it at synthhub.roomi-fields.com. osc-bridge asks the SynthHub server for one driver at a time, when it needs it:
osc-bridge run --device korg/minilogue (a driver id) or --device minilogue
(a slug: the device's best variant) fetches that driver and keeps it in the
cache (~/.cache/osc-bridge/drivers/, or $XDG_CACHE_HOME, %LOCALAPPDATA%),
then downloads it again only when the server's copy changed;osc-bridge detect and the MCP tool detect_hardware ask the server which
makers' identity requests to send, then send it the names of the MIDI
ports found here and what the devices answered, and it names the matching
drivers and firmware; list_devices searches the catalogue there;osc-bridge privacy --offline on, OSC_BRIDGE_OFFLINE=1), only
the drivers already cached are used and nothing is sent.These requests carry no account. A JSON file on your machine is used as it is
(--device my-synth.json, osc-bridge mcp --devices-dir my-drivers/).
osc-bridge run picks it up.osc-bridge mcp exposes the SynthHub 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._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.--osc-client flag.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.The catalogue — synths, drum machines, controllers, DAWs and live-coding environments, with each driver's source and how far users confirmed it — is on SynthHub:
/api/v1/devices/<vendor>/<driver>.json), or the hosted MCP server at https://mcp.synthhub.roomi-fields.com/mcp — see API for agents.Each driver declares its source in _sources[]: ✅ hardware-verified, ✅ software-verified, 📘 vendor-doc, 📡 vendor-osc-api / 📡 third-party-osc, 🎛️ electra-preset, 📦 pencilresearch.
New here? The 30-minute tutorial builds a working driver end to end. Otherwise — three common cases, pick yours:
Your synth isn't listed → write its driver and send it to SynthHub.
docs/DEVICE_JSON_SCHEMA.md; the driver of a similar device (/api/v1/devices/<id>.json on SynthHub, or the copy in your cache) is a good template.osc-bridge lint my-synth.json, then osc-bridge run --device my-synth.json on the device.submit_driver tool (it is checked, then added to the catalogue); or open an issue here with the file.A driver is wrong, or you tested it on the hardware → tell SynthHub: report_result and report_mapping (MCP) record what works on which firmware, and submit_fix turns learned mappings into a corrected driver.
Full contributor guide (schema extensions, bug reports, Lua escape hatch) → CONTRIBUTING.md. For devices whose protocol can't be expressed declaratively, see docs/scripting.md — use sparingly; osc-bridge lint warns on every use.
Most synths have a fixed set of controls — MiniLab 3's knobs always mean the same thing. The Electra One MK2 is different: its 216 controls are defined by a preset that you upload to the device, and the meaning of every CC changes when the preset changes. A static JSON spec can't describe that; the bridge treats it as a first-class case.
This integration is what validates the whole Lua scripting subsystem in anger.
The MK2 driver exercises every feature of the scripting.rs layer on real
hardware (firmware 4.1.4, verified 2026-04-14):
ob.json_decode / ob.json_encode) — parses a full
Electra preset (up to 100 KB of nested pages/devices/groups/controls/overlays)
in a single Lua block, under the 500 ms preset_ingest profile.ob.state) — the driver stores the active
preset name so /electra1/preset/current can report it on demand.ob.register_cc_route /
ob.clear_routes / ob.set_current_page) — every preset upload rebuilds
the bridge's routing table from scratch, zero restart.ob.emit_sysex) — the upload script emits
the wrapped SysEx preset data block directly from Lua.ob.emit_osc) — powers the introspection
endpoints: /routes/list, /preset/current, /page/current.ctx.bindings) — when the device
reports a page switch over SysEx, a reply script updates the bridge's active
page so CC routing tracks the hardware UI automatically.electra-one.md, next to its JSON) are
loaded at startup and served over /bridge/docs, so LLM-driven integrators
read the device-specific quirks (hex-color requirement, inputs[{potId}]
mandatory, envelope-segment cycling gesture, MIDI port selection, etc.)
without any code-side knowledge.Every item above has a unit test, an end-to-end test against the real .json
driver, and a hardware-verified green light. If you're building a driver for
another reconfigurable controller (Faderfox custom, programmable MIDI Fighter),
the Electra driver is the template — copy its custom_commands block, adapt
the JSON→routes parsing to your device's preset format, done.
Kanopi / your client osc-bridge Electra One MK2
───────────────────── ──────────────── ────────────────────
/electra1/preset/upload ───► parse preset JSON (preset_ingest
"<preset JSON>" profile: 500 ms / 4 MiB Lua)
┌─ ob.clear_routes()
├─ ob.register_cc_route × N
│ (one per cc7 control,
│ per-page, with channel)
└─ ob.emit_sysex(…) ──────────► F0 00 21 45 01 01 <json> F7
(reconfigures device)
◄────────── F0 00 21 45 7E 01 … ACK
(user turns knob on page 2) ◄────────── B4 4A 53 (CC#74 ch5 = 83)
route lookup: page=2, ch=4, cc=74
→ /electra1/page2/cutoff 0.65 ───► /electra1/page2/cutoff 0.65
(user switches page on device) ◄────────── F0 00 21 45 7E 06 03 F7
reply.script fires:
ob.set_current_page(3)
───► /electra1/page/switched 3
Every piece of device-specific knowledge is exposed over OSC — clients never hardcode slugification rules, page indexing, or SysEx opcodes:
| Send | Receive |
|---|---|
/bridge/status | One /bridge/status/device <slug> <status> per connected device |
/bridge/docs | /bridge/docs/device <slug> <markdown> — full integration guide (the device's companion .md, loaded automatically) |
/electra1/routes/list | N× /electra1/routes/entry <addr> <ch> <cc> <page> <min> <max> then /electra1/routes/done |
/electra1/preset/current | /electra1/preset/current <name> |
/electra1/page/current | /electra1/page/current <n> |
An LLM-driven integrator needs exactly four steps to go from cold start to
routing knob turns: /bridge/status → /bridge/docs → /electra1/preset/upload
→ /electra1/routes/list. Everything else is in the markdown guide embedded
in the bridge itself.
The machinery (DynamicRoutes, ob.register_cc_route, ob.emit_sysex,
custom_commands, companion .md auto-loading) is device-agnostic. Adding
a reconfigurable Faderfox, a custom MIDI Fighter Twister layout, or any
programmable controller is the same recipe: a preset-parsing Lua block inside
the device JSON that calls ob.register_cc_route per control. No core changes.
Grab the latest osc-bridge.exe (Windows), osc-bridge (Linux/macOS) from
the Releases page.
git clone https://github.com/roomi-fields/osc-bridge
cd osc-bridge
cargo build --release
./target/release/osc-bridge list
# 1. Find your synth, its driver and its MIDI ports
osc-bridge detect
# 2. Start the bridge
osc-bridge run --device arturia/minilab3 \
--out-port 4 --in-port 0 \
--bind 127.0.0.1:7777 --osc-client 127.0.0.1:8888
# 3. From another terminal, send OSC
osc-bridge osc-send /minilab3/display/text "Hello" "World"
osc-bridge osc-send /minilab3/pad/0/color 127 0 0
osc-bridge osc-send /minilab3/knob/3/cc_number 100
Incoming MIDI events (knob turns, pads played, pitch-bend, SysEx GET replies)
are forwarded to --osc-client as OSC:
/minilab3/cc/18 95 0 ← knob moved
/minilab3/note/on 60 127 0
/minilab3/param/value 0 7 0 0 1 ← reply from a /param/get
Browsers can't speak UDP. Pass --ws-bind to expose the same OSC surface
over WebSocket:
osc-bridge run --device arturia/minilab3 \
--out-port 4 --in-port 0 --ws-bind 127.0.0.1:7890
Binary WS frames carry raw OSC packets — the exact bytes the UDP transport
uses, so a minimal dependency-free OSC encoder/decoder in JS covers both
directions. Every connected WS client behaves like an extra --osc-client:
it receives all outbound events (decoded MIDI-in, SysEx replies,
/bridge/status) and its frames go through the same dispatch as UDP.
Under orchestrate, set ws_bind = "127.0.0.1:7890" in the [osc]
section of bridge.toml. Disabled by default; keep it on 127.0.0.1
unless you really want LAN clients.
Only pages served from this machine (localhost, 127.0.0.1) and
non-browser clients may connect: any other website open in your browser is
refused (HTTP 403), so it cannot reach your synths. Allow a specific site
with --ws-allow-origin https://example.org (repeatable; null for
file:// pages; * for any), or ws_allow_origins = [...] in
bridge.toml.
--oscquery-bind 127.0.0.1:7891 (or oscquery_bind in the [osc] section
of bridge.toml) answers OSCQuery requests: http://127.0.0.1:7891/ lists
every OSC address the bridge answers, with its types and ranges, so OSCQuery
clients build their controls by themselves. osc-bridge export --device <driver> --format oscquery|midnam writes the same namespace, or the driver's
MIDI names as a MIDNAM file for DAWs. See docs/EXPORT.md.
Since the March 2026 cumulative update (KB5079473), Windows 11 ships
Microsoft's new USBMidi2-ACX driver which enforces stricter USB descriptor
checks. Devices that pass the old checks but fail the new ones appear in
Device Manager with Status: Unknown, or bind to a driver that exposes
them only through the new MIDI Services API — invisible to midir (and
therefore to osc-bridge) which queries the legacy MME interface.
Confirmed affected: Polyend Synth / Play / Tracker / Mess / Step (VID 16D0). Likely affected: any older USB-MIDI device whose descriptor doesn't meet the new spec.
Workaround — force the legacy usbaudio driver:
osc-bridge list should now show the device.Track Microsoft's progress on KB5079473 if you want a permanent fix — Pete Brown (Microsoft) acknowledged the packet-size issue publicly but classified it as non-blocking. Polyend's firmware-side fix is not announced at the time of writing.
osc-bridge detect
Lists MIDI ports, asks each device who it is (the standard MIDI Identity
Request, then the makers' own requests the drivers name — harmless), has the
SynthHub server match the answers against the drivers' identity blocks
(offline: the drivers cached here), with the firmware read from them, and
prints a ready-to-run osc-bridge run line. --no-probe matches by port
name only.
osc-bridge backup --in-port minilab --out backups/minilab3.syx # then start the dump on the device
osc-bridge restore --out-port minilab backups/minilab3.syx # overwrites the device's memory
Ports take an index or a name fragment. backup --request "F0 … F7" --out-port …
sends a dump request first; restore --gap-ms paces older devices.
Drivers with a drum map expose each voice: /drm1_mkiv/drum/kick 110 fires
the Vermona DRM1 MKIV kick at velocity 110 (note 36, channel 10). When a
device documents several trigger modes, the address carries the mode, e.g.
/tr_8s/drum/default_note_map/bass_drum. See
DEVICE_JSON_SCHEMA.md.
osc-bridge inspect arturia/minilab3
osc-bridge osc-listen --bind 127.0.0.1:8888
osc-bridge osc-send /minilab3/raw/syx "F0 00 20 6B 7F 42 02 00 16 04 7F 00 00 F7"
A device file declares three things:
Example snippet (the arturia/minilab3 driver):
{
"commands": [
{
"osc": "/pad/{pad}/color",
"args": [
{"name":"pad","type":"u7","range":[0,7]},
{"name":"r","type":"u7"},
{"name":"g","type":"u7"},
{"name":"b","type":"u7"},
{"name":"mode","type":"enum",
"values":{"user":0,"arturia":1,"daw":2},"default":"user"}
],
"pre": [{"bind":"pad_id","expr":"pad + 4"}],
"frame": [2, "{mode}", 22, "{pad_id}", "{r}", "{g}", "{b}"]
}
],
"params": {
"get_frame": [32, "{pr}", "{p}", "{c}", "{r}"],
"set_frame": [33, "{pr}", "{p}", "{c}", "{r}", "{val}"],
"value_type": "u7",
"entries": [
{"osc":"/global/backlight", "pr":7, "p":0, "c":0, "r":0, "range":[0,1]}
]
}
}
osc-bridge isn't only for hardware synthesizers. Since version 0.10 it also
treats DAWs and live-coding environments as first-class devices, behind
the same /<env> OSC surface as a Prophet or a Matriarch. A driver JSON
declares device.transport.kind = "osc" and the bridge forwards OSC to the
target's UDP port instead of going through a MIDI cable.
Two flavors:
Declarative drivers — when the host software has a fixed, documented OSC
surface (Ableton via AbletonOSC,
Bitwig via DrivenByMoss, Reaper's
native OSC). The driver enumerates commands[] with typed args, plus
replies[] for incoming events.
Passthrough drivers — when the host software has no fixed OSC surface and
each user defines their own paths in their project (Sonic Pi, SuperCollider,
Pure Data, TouchDesigner, VCV Rack). The driver just declares
transport.passthrough_prefix and the bridge forwards anything under
/<env>/... verbatim. Replies travel the other way with the prefix added back.
Currently supported:
| Target | Mode | Status |
|---|---|---|
| Ableton Live 12.2.7 + AbletonOSC | declarative | ✅ software-verified |
| Bitwig Studio + DrivenByMoss | declarative | 📡 third-party-osc |
| Reaper 7 (Default.ReaperOSC) | declarative | 📡 vendor-osc-api |
| Sonic Pi 4.5 | passthrough | 📡 vendor-osc-api |
| SuperCollider sclang 3.13 | passthrough | 📡 vendor-osc-api |
| Pure Data 0.55-x | passthrough | 📡 vendor-osc-api |
| TouchDesigner 2023 | passthrough | 📡 vendor-osc-api |
| VCV Rack 2 + vcv-osc plugin | passthrough | 📡 third-party-osc |
Each driver comes with its .md notes on SynthHub that document the
required setup on the host side (Remote Script installation, ports, conventions).
Combined with osc-bridge orchestrate, you can drive a hardware MiniLab 3,
an Ableton Live, and a Sonic Pi loop from a single process. With the
new [[routes]] section in bridge.toml, a knob turn on the MiniLab can
drive an Ableton track volume or a Sonic Pi cue, without writing any client
code:
[osc]
bind = "127.0.0.1:7777"
clients = ["127.0.0.1:8888"]
# ws_bind = "127.0.0.1:7890" # optional — browser clients over WebSocket
[[devices]]
spec = "arturia/minilab3" # a driver id or slug, or a JSON file
midi_out_port = 4
midi_in_port = 0
[[devices]]
spec = "ableton/live.third-party-osc.fw-12.2" # AbletonOSC: no MIDI port needed
[[routes]]
from = "/minilab3/cc/74"
to = "/ableton/track/0/volume"
map.from = [0, 127]
map.to = [0, 1]
osc-bridge ships a Model Context Protocol server — a MIDI MCP and OSC MCP. Point any MCP client at it and the model can browse the SynthHub catalogue, read a device's OSC surface, and send OSC to synths and DAWs.
Hosted — add https://mcp.synthhub.roomi-fields.com/mcp as a remote MCP server (see
Install). Nothing to install; your synth joins through the relay
page, synthhub.roomi-fields.com/connect.
On your machine:
{
"mcpServers": {
"osc-bridge": {
"command": "npx",
"args": ["-y", "@roomi-fields/osc-bridge", "mcp"]
}
}
}
Nine local tools — list_devices, get_device_docs, list_routes, export_device,
send, get_status, detect_hardware, backup_presets, restore_presets — plus
the server's: reports, trust, contributions and shared presets (find, load, take from the synth,
share). Then in conversation:
"What can the MatrixBrute do? Sweep its filter cutoff." — the model calls
list_routes("matrixbrute"), then send. No glue code.
Full setup — Claude Desktop / Cursor config, the workflow, driving software
targets → docs/MCP.md.
Started as a MatrixBrute OSC driver (patch format reverse-engineered from the GPL-3 sysex-controls and the community MBPV tool). Grew into a generic declarative bridge once the Arturia protocol family became clear.
AGPL-3.0-or-later. Running a modified version as a network service obliges
you to offer its source to the users of that service. The sysex-controls
reverse engineering that seeded our MiniLab 3 parameter table is GPL-3.0,
which GPL-3.0 section 13 allows to combine with AGPL-3.0 code.
The driver catalogue is SynthHub's, each driver with the credit and licence of
its sources in _sources[]. The few drivers kept here for the tests
(tests/fixtures/devices/) keep theirs: those of type pencilresearch are
adapted from MIDI Guide by Pencil Research and
contributors, licensed CC BY-SA 4.0
(source: pencilresearch/midi); each
records the licence, the attribution and the exact upstream CSV and commit;
the change made is the conversion of CSV rows to the osc-bridge JSON schema.
/bridge/docs/electra1/routes/listtransform / 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.