Catalogue API for AI agents¶
SynthHub's device catalogue is open to programs, not only to people. An agent that needs the CC, NRPN or SysEx map of a synth can read it in two ways: plain JSON files on this site, or the SynthHub MCP server — hosted, nothing to install — whose engine is osc-bridge.
JSON files¶
No key, no rate limit, any origin (CORS is open). The data changes when the site is rebuilt, at each change to the catalogue.
| File | Content |
|---|---|
/api/v1/index.json |
Every driver: vendor, name, slug, source, firmware, coverage, links |
/api/v1/devices/<vendor>/<driver>.json |
The driver file itself, as osc-bridge loads it |
One entry of index.json:
{
"id": "korg/minilogue",
"vendor": "KORG",
"name": "minilogue",
"slug": "minilogue",
"kind": "hardware",
"source_tier": "pencilresearch",
"firmware": null,
"license": "CC-BY-SA-4.0",
"manufacturer_id": [],
"coverage": { "cc": 40, "sysex_params": 0, "commands": 0, "cc14": 1, "nrpn": 0, "replies": 0, "triggers": 0 },
"url": "https://synthhub.roomi-fields.com/api/v1/devices/korg/minilogue.json",
"page": "https://synthhub.roomi-fields.com/devices/korg/minilogue/"
}
source_tiersays how far to trust the driver:hardware-verifiedorsoftware-verified(tested),vendor-doc(manufacturer documentation),vendor-osc-api,electra-preset(Electra One community preset),pencilresearch(MIDI Guide community data).firmwareis the firmware version the source documents, ornullwhen the source does not say. Several drivers can exist for one device, one per source and firmware.coveragecounts what the driver maps: CC parameters (cc14of them 14-bit,nrpnof them NRPN), SysEx parameters, SysEx commands, reply patterns and named drum sounds (triggers).- The driver format is described in the device schema.
- Licence: drivers are GPL-3.0; those derived from MIDI Guide are also
CC BY-SA 4.0 (
licensefield), so keep the attribution when you reuse them.
curl -s https://synthhub.roomi-fields.com/api/v1/index.json \
| jq '.devices[] | select(.vendor == "Moog") | .name'
MCP server¶
The same catalogue as MCP tools, for Claude, Cursor and other MCP clients.
On your machine (stdio), with all eight tools including hardware
detection and sending to a running bridge: see the MCP guide.
Such a copy is linked to this server unless --offline: it mirrors the
catalogue (GET /v1/catalogue lists every driver file with its SHA-256;
POST /v1/catalogue/files with {"paths": [...]}, 100 at most, returns
their contents) and sends its reports and contributions here.
Hosted, nothing to install: add https://mcp.osc-bridge.roomi-fields.com/mcp
as a remote MCP server (a "custom connector" in Claude). It offers, at most
120 requests per minute per client: the catalogue tools list_devices (with
query, vendor, kind, limit), list_routes and get_device_docs;
report_result and get_trust (below); and the relay tools, which reach
the hardware on the user's own machine (below).
No sign-up. The server gives each client an account when it connects: a
random id, returned in the Mcp-Session-Id header and in the server's
instructions, and kept by the server. To stay the same account from one
session to the next, keep it: connect to your personal endpoint
https://mcp.osc-bridge.roomi-fields.com/u/<id>/mcp (GET /u/new hands out
a fresh one), or pass user_id in tool calls. Only ids the server issued
are accepted; the id is tied to nothing else.
What the hosted server records: the accounts it issued; for each tool
call, the time, the account, the tool and its catalogue arguments (search words, vendor,
device slug); and the reports sent with report_result. Both are kept to
improve the catalogue. It does not record your
address. Like any site, the web server in front of it keeps a short access
log (address, URL, time) for a few days for traffic statistics; the search
words are not in it.
Relay: the user's hardware, from anywhere¶
The user opens the connect page in Chrome or Edge (or runs
osc-bridge connect), which shows a pairing code, and gives the code to the
agent. With it:
| Tool | Does |
|---|---|
relay_status |
Lists the MIDI ports of the user's machine |
relay_detect |
Sends the MIDI Identity Request to every output, matches the answers (manufacturer, model, firmware) against the catalogue |
relay_send |
Sends one driver address with its arguments (/filter/cutoff, [64]), turned into the right CC, NRPN, note or SysEx by the server — or raw MIDI bytes |
relay_listen |
Collects what the hardware sends for a few seconds, decoded; with a driver, each CC or NRPN that moved is matched to its addresses |
Contributing drivers¶
Agents can add to the catalogue. submit_driver takes a whole driver file
(the device schema) for a device the catalogue lacks;
submit_fix builds a corrected copy of a driver from the mappings learned for
one firmware (below) where they differ from it. Either way the file is its
own variant, <device>.agent-contributed.fw-<firmware>.json, marked 🤖 in the
catalogue. Every half hour a merge job checks each pending contribution —
it must parse, lint and leave the library tests passing, and touch nothing
else — and merges it as a pull request; get_contribution tells where it
stands. There is no human review: trust comes from usage reports afterwards,
and contributions of a suspect account are held.
Learning what controls really send¶
Drivers can be wrong for a given device or firmware. To check one control,
the agent asks the user to move it while relay_listen runs, then records
what it saw with report_mapping: the driver address (or, for a control the
driver lacks, its panel label) and the CC, NRPN or note it sent, with the
firmware and the device's Identity Reply. When 3 accounts or more observe the
same message for a control on one firmware, more than any other, the mapping
is learned. get_trust lists a driver's learned mappings with what the
driver says and whether they differ; all of them are public at
/v1/learned.
Observations of suspect accounts are not counted.
Any program can be a relay door: it opens a WebSocket to
wss://mcp.osc-bridge.roomi-fields.com/relay (add ?user=<id> to keep its
account), receives {"type":"hello","code","user"}, then exchanges JSON text
frames — {"type":"ports","outputs":[…],"inputs":[…]} and
{"type":"midi_in","port","data":[bytes]} towards the server,
{"type":"midi_out","port","data":[bytes]} from it, and optionally
{"type":"share","enabled":bool,"private":[port names]}: enabled: false
keeps every device identity out of the records, private only those seen on
the ports named (sharing is on, no port private, until the door says
otherwise). relay_detect marks each private device with private: true.
Messages that may overwrite the device's memory — every SysEx message except
the Identity Request — never come as midi_out. They come as one request per
batch, {"type":"confirm","id","port","messages":[[bytes]],"bytes","gap_ms"}:
the door shows it to the person, sends the messages only if they accept
(waiting gap_ms between two), and answers
{"type":"confirm_reply","id","accepted":true|false}. The agent's
relay_send waits up to two minutes for that answer and reports it; without
an answer the server withdraws the request with
{"type":"confirm_cancel","id"}. A door must not send a SysEx message other
than the Identity Request that came as midi_out.
Reports and trust¶
After testing a driver on the real device, an agent calls report_result:
works, fails or partial, for the whole driver or one OSC address, with
the firmware version and the device's reply to the MIDI Identity Request
(F0 7E 7F 06 01 F7) as identity_hex. That reply proves the device was
connected and carries the firmware as the device reports it; it must come
from the driver's manufacturer.
Trust is counted per firmware, from each account's latest accepted report:
| Status | Meaning |
|---|---|
unreported |
No report yet |
unconfirmed |
Reported working, by fewer than 3 accounts on one firmware or none with an identified device |
usage-verified |
3 accounts or more agree it works on one firmware, one of them with an identified device, and none reports otherwise there |
firmware-dependent |
Works on some firmware, fails on another |
failing |
Only failures reported |
disputed |
Accounts disagree on the same firmware, or a contrary report gives no firmware |
Each report has a status: accepted (counts), pending (waits for
approval), rolled-back or rejected. A report that at least 3 other
accounts contradict on the same target and firmware, more than agree with
it, is rolled back automatically: the driver's trust returns to what it was
without it. Its account becomes suspect: its other reports, and its new ones,
are pending until an administrator approves them or clears the account.
get_trust shows how many reports of a driver are pending or rolled back.
When a disagreement involves a report without firmware, get_trust sets
needs_firmware and the server asks the next reporters to identify their
device. The identities seen for each firmware are kept, so the catalogue
learns how each device reports its versions. The trust of every reported
driver is public at
/v1/trust.
Reports waiting for approval and suspect accounts are reviewed by the server's administrator. The tools that open MIDI ports are not offered by the hosted server, since they would act on its machine, not the caller's; the relay tools reach the caller's own hardware instead.