Tools
The barline MCP server exposes a small set of tools. Crucially, the song is code — so the LLM edits files, not a bespoke AST API. Hallucinated semantic operations are impossible because there’s nothing to hallucinate: it’s the same TypeScript you’d type. Every file edit is an atomic Yjs transaction inside the song’s Durable Object — the identical edit path as a keystroke — so undo, presence, and sync stay uniform.
Reading
Section titled “Reading”get_song— the song’s files (sources) and structural index. The model reads this before editing, becauseedit_fileneeds exact, currently-present text.get_status— the live state:compile(ok / error — check after every edit!),transport(stopped / playing / paused),playhead,structure, and audio features including per-track post-fader levels (features.tracks),integrated_lufsandshort_term_lufs(ITU-R BS.1770-4 loudness in LUFS, or null when silent),true_peak(the inter-sample peak in dBTP — keep under ~ −1), andmaster(instantaneous spectral features of the live master — centroid/flatness/rolloff/spread/sharpness — in the SAME units as a reference track’sfeatures). So the model can judge the mix and chase a target (e.g. techno ~ −8 LUFS at −1 dBTP, brighter to match the reference centroid).
Editing files
Section titled “Editing files”edit_file— replace exact text in a file. Unique-match by default;replace_allfor every occurrence, with an occurrence count reported on conflict. Preferred for small changes (it preserves collaborative history best).write_file— replace a whole file (or create one). Use for new files or full rewrites.create_file— add a new file to the song.delete_file— remove a file.
After any edit the model should call get_status to confirm compile is ok.
Driving the transport
Section titled “Driving the transport”transport— send a performance command to the open studio tab(s) and wait for the first acknowledgement. Commands includeplay/pause/stop,seek { bar },setFlag { name, value },setLoop { section },launchScene { section }(Session view: loop a section as a live scene, quantized to the next bar;nullclears it back to the linear arrangement), andsetMetronome { on }. It reports honestly: adelivered: 0when no studio tab is open, and a timeout note if no ack arrives within ~1.5s (it may or may not have applied — checkget_status).
The registry
Section titled “The registry”list_packages— discover packages (with their owning orgs).install_package— install one into the song. Same Yjs create op ascreate_file, so the editor sees it live and the song hot-reloads. Then the model imports its exports and uses them.
Resources
Section titled “Resources”Two read-only resources mirror the read tools: song://{org}/{slug}/status (the
telemetry: compile state, transport, playhead, structure, features) and
song://{org}/{slug}/{+path} (a file’s source, e.g. song://barline/demo/main.ts).
A song id is the <org>/<slug> pair. Use them when a client prefers resource
reads to tool calls.
The shape of an AI edit
Section titled “The shape of an AI edit”A typical loop is: get_song → reason about the code → edit_file →
get_status (compile ok?) → transport { play } → read features → iterate.
The browser observes the Yjs doc, recompiles, and hot-reloads, so the change is
audible at the next bar boundary — see
the listening loop.