Current release: 3.2.0
codex-live-bridge is a Max for Live OSC/UDP bridge for Ableton Live. It lets
codex and local scripts inspect a Live set through LiveAPI. A local capability
token also allows controlled changes when you choose to configure one.
The repo ships the editable Max patch and the JavaScript files that run the
bridge. A Python OSC client/CLI sends local commands on UDP 9000 and receives
ACKs or observer events on UDP 9001.
Started during the OpenAI 2026 Hackathon in San Francisco, built in tandem with GPT-5.3-Codex.
This project is independent and is not affiliated with or endorsed by OpenAI, Ableton, or Cycling '74. All trademarks belong to their respective owners.
This repository contains LiveUdpBridge, the standalone external bridge. A Live Extension and shared inspection core are separate components and are not included here.
| Surface | Responsibility |
|---|---|
| LiveUdpBridge (included) | External control, observers, LiveAPI, MIDI, writes, and insertion |
| Live Extension (separate) | Clip actions, large clip reads, and reports inside Live |
| Shared inspection core (separate) | Validate, analyze, report, and compare |
- For LiveUdpBridge, release or Beta Ableton Live with Max for Live support: Ableton Live and Max for Live
- A local terminal, or an optional codex surface: Codex app, Codex CLI, or Codex IDE extension
- Python 3.10+
- Node.js for device updates, Python security tests, and JavaScript syntax checks
The separate Live Extension requires Live 12 Suite Beta 12.4.5 or later. For details, see Extensions and join the Live Beta.
- Clone and run the tests:
git clone https://github.com/sunflower-of-parchman/codex-live-bridge.git
cd codex-live-bridge
python3 -m unittest discover -s bridge -p "test_*.py"
python3 -m unittest discover -s tests -p "test_*.py"
node --check bridge/m4l/live_udp_bridge.js
node --check bridge/m4l/osc_loopback_receiver.js
node --check scripts/ableton-device.js- Download and extract the packaged Max for Live device:
The 3.2.0 release includes the device and both JavaScript runtime files:
LiveUdpBridge.amxd
live_udp_bridge.js
osc_loopback_receiver.js
You can also build the device from bridge/m4l/LiveUdpBridge.maxpat in a
Live-hosted Max MIDI Effect. Follow INSTALL.md for the source-build steps.
-
Keep both JavaScript runtime files next to the device, then load it onto a MIDI track. Max resolves the LiveAPI router through
[js live_udp_bridge.js]. Node for Max runs the loopback-only command receiver. -
Verify the bridge with a read-only status command:
python3 bridge/ableton_udp_bridge.py --ack --status --no-tempo --no-signatureExpected ACK shape:
ack: /ack pong
ack: /ack status <total_tracks> <midi_tracks> <audio_tracks> <return_tracks> live_set <id>
Read-only commands do not require a token. With --ack, the client exits with
an error if its reply listener cannot open, a complete matching response does
not arrive, or the bridge reports an error. It does not send the command when
the listener cannot open.
- Optional: configure a local token for writes and observers:
export CODEX_LIVE_BRIDGE_TOKEN="$(
python3 -c 'import secrets; print(secrets.token_urlsafe(32))'
)"
printf '%s\n' "$CODEX_LIVE_BRIDGE_TOKEN"Copy the printed token into the Max set_auth_token CHANGE_ME_BEFORE_USE
message, replacing CHANGE_ME_BEFORE_USE. Save and reload the local device.
The exported environment variable gives the Python client the same token.
Keep real tokens out of the tracked .maxpat source.
The editable .maxpat file is the canonical tracked source. Packaged .amxd
devices are release artifacts saved from a Live-hosted Max MIDI Effect.
Stage an updated copy from an existing installed device:
node scripts/ableton-device.jsThis command only stages the device and both JavaScript files in a private
temporary directory. It does not change the installed files. Its JSON output
includes stageDir, installed, verifiedLive, backupDir,
tokenConfigured, and hashes.
To update the installation and verify the running Ableton bridge:
node scripts/ableton-device.js --install --verify-liveInstallation requires --install. It preserves the existing device metadata
and write token. A persistent backup restores the previous files if the
token-free Live status check fails. Staged devices and backups can contain a
configured token. Keep them private and do not commit or upload them. See
INSTALL.md for default locations and command options.
bridge/m4l/LiveUdpBridge.maxpat: editable Max for Live patch sourcebridge/m4l/live_udp_bridge.js: LiveAPI command router loaded by the patchbridge/m4l/osc_loopback_receiver.js: dependency-free Node-for-Max receiver bound explicitly to127.0.0.1:9000bridge/ableton_udp_bridge.py: Python OSC client/CLI with ACK and listen modesbridge/full_surface_smoke_test.py: opt-in mutating smoke test for disposable setsscripts/ableton-device.js: local device staging and opt-in installationbridge/commands.md: command cheat sheetINSTALL.md: source export and device loading instructionsPROTOCOL.md: canonical OSC/UDP protocol contract
The bridge exposes four command families:
- Core Live set control:
/ping, tempo, time signature, track create/delete, track rename, session clip write/append/inspect, MIDI CC, sustain CC64, and/status. - Generic LiveAPI RPC:
/api/ping,/api/get,/api/set,/api/call,/api/children, and/api/describe. - Observer lifecycle:
/api_observe,/api_unobserve,/api_observers, and/api_clear_observers, with asynchronous/ack api_eventpayloads. - Named LiveAPI wrappers:
/api/session_context,/api/theory_status,/api/tuning_status,/api/device_list,/api/device_parameters,/api/mixer_status,/api/parameter_set,/api/insert_device,/api/insert_chain, and/api/drum_chain_in_note.
Safety classes are documented in PROTOCOL.md:
- Read: inspect Live state without mutation.
- Bounded write: set a specific validated value.
- Additive mutation: create tracks, clips, devices, chains, or notes.
- Destructive mutation: delete, clear, overwrite, or reset state.
The generic RPC layer can reach broad LiveAPI behavior. Automation defaults and examples should favor read commands, bounded writes, explicit request IDs, and clear user approval for mutations.
Read-only commands are tokenless. Writes, generic calls, observer lifecycle
changes, track and clip mutations, insertion, and MIDI output require the
local capability token through --auth-token or
CODEX_LIVE_BRIDGE_TOKEN.
codex-live-bridge is the public, standalone external automation surface.
It does not require Ableton's Extensions SDK. The Live Extension and shared
inspection core are separate and are not included in this repository.
The broader product architecture assigns responsibilities this way:
- Bridge: external and headless automation, persistent observers, generic LiveAPI RPC, raw MIDI output, and release-Live compatibility.
- Extension: native context actions, large contextual clip reads, modal user interface, and future user-invoked undoable transforms.
- Shared core: canonical schema validation, note normalization, clip inspection, report formatting, and parity comparison across adapters.
The bridge continues to provide the full external automation surface described in this repository. The Extension provides a native Beta workflow for contextual, user-invoked tools, while the bridge supports local scripts, agents, persistent listeners, and Live versions that do not host Extensions.
The protocol 3.1 session clip endpoint supplies the external adapter with correlated raw facts. Every request has a required request ID, every successful fragment echoes it, and every encoded response packet is capped at 4096 bytes. Product-specific interpretation can happen in a separate shared-core consumer without adding an Extensions SDK dependency to the bridge.
- Default host:
127.0.0.1 - Command channel: UDP
9000, active while the Max for Live device is loaded - ACK/event channel: UDP
9001, active only while a client is listening - Structured payloads travel as JSON strings.
- LiveAPI paths use Ableton's zero-based indexes, for example
live_set tracks 0. - Ableton UI labels are one-based, so UI Track 1 maps to
track_index=0. - LiveAPI object IDs are dynamic and should be read per session.
For exact command signatures, ACK shapes, note schema, wrapper behavior, and
Live 12.3 insertion limits, read PROTOCOL.md. For quick examples, read
bridge/commands.md.
flowchart LR
U["Local script, agent, or Codex"] --> P["Python or Node client"]
P --> C["OSC commands :9000"]
C --> B["LiveUdpBridge Max patch"]
B --> L["LiveAPI"]
L --> A["Ableton Live set"]
A --> R["OSC ACKs and events :9001"]
R --> P
P --> S["Optional shared inspection core"]
Read the current set status:
python3 bridge/ableton_udp_bridge.py --ack --status --no-tempo --no-signatureRead Live set tempo through the generic RPC surface:
python3 bridge/ableton_udp_bridge.py --ack --no-tempo --no-signature \
--api-get live_set tempo req-tempoList tracks:
python3 bridge/ableton_udp_bridge.py --ack --no-tempo --no-signature \
--api-children live_set tracks req-tracksInspect a session MIDI clip with required request correlation and packet-bounded fragments:
python3 bridge/ableton_udp_bridge.py --ack --no-tempo --no-signature \
--api-session-clip-inspect 0 0 req-clipThe endpoint preserves note IDs and release velocity when LiveAPI returns
them. During separate Extensions SDK 1.0.0 qualification, the native SDK
omitted those two fields. Cross-surface consumers must therefore treat note-ID
matching as unavailable and release velocity as an explicit SDK-side gap.
Register and listen for tempo changes after configuring the local token:
python3 bridge/ableton_udp_bridge.py --ack --listen --listen-timeout 30 \
--listen-max-events 20 --no-tempo --no-signature \
--api-observe live_set tempo \
'{"observer_id":"obs-tempo","emit_initial":true}' req-observeRemove the observer when you are done:
python3 bridge/ableton_udp_bridge.py --ack --no-tempo --no-signature \
--api-unobserve obs-tempo req-unobserveRun the full-surface smoke test in a disposable set:
python3 bridge/full_surface_smoke_test.py --i-understand-this-mutates-live-setThe smoke test creates a MIDI track, writes a MIDI clip, and changes tempo and meter. Use it only when those changes are acceptable.
If you modify bridge/m4l/LiveUdpBridge.maxpat or either JavaScript runtime
file:
- Keep both JS files next to the patch, or update the Max runtime objects.
- Reload the device in Ableton Live.
- Save packaged
.amxdartifacts from a Live-hosted Max MIDI Effect only during an explicit release pass.
Local validation:
python3 -m unittest discover -s bridge -p "test_*.py"
python3 -m unittest discover -s tests -p "test_*.py"
node --check bridge/m4l/live_udp_bridge.js
node --check bridge/m4l/osc_loopback_receiver.js
node --check scripts/ableton-device.js
python3 -m json.tool bridge/m4l/LiveUdpBridge.maxpat >/dev/null
bash .github/scripts/audit_public_hygiene.shLive-runtime validation is separate from static validation. Before a release,
package LiveUdpBridge.amxd from a Live-hosted Max MIDI Effect and load that
device in Ableton Live. Confirm the command receiver is listening on UDP
9000; UDP 9001 opens only while a client is listening. Then check read
wrappers, observer cleanup, bounded parameter writes, and Live 12.3 native
insertion wrappers in a disposable set.
This repo ships no trained model weights, training pipeline, fine-tuning pipeline, audio corpus, or generative music model. The bridge itself is not a generative music system.
The project does not train on, ingest, copy, or emulate artist catalogs, genres, songs, recordings, or user material. User intent stays user-authored: the bridge only sends explicit local OSC/LiveAPI commands into Ableton Live. When a user improves a Live set, that improvement comes from direct editing, direct commands, or external tools that call the bridge; this repo does not learn a user profile or improve itself from behavior over time.
The OSC bridge uses a local capability token for writes and persistent control.
Read-only inspection remains tokenless. The shipped command receiver binds
explicitly to 127.0.0.1:9000, and the Python client rejects non-loopback
targets. UDP does not encrypt the token or Live data. The reply client binds
127.0.0.1:9001 only while it is listening. Treat generic /api/set and
/api/call commands as powerful local LiveAPI access. Only one ACK-listening
client can bind the default 9001 port at a time.
PROTOCOL.md: public protocol and safety classesINSTALL.md: source export and device loading instructionsbridge/commands.md: command examplesCONTRIBUTING.md: contribution process and validationSUPPORT.md: support scope and issue checklistSECURITY.md: vulnerability reporting and local runtime boundaryCHANGELOG.md: release history
MIT. See LICENSE.