Skip to content

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.

  • get_song — the song’s files (sources) and structural index. The model reads this before editing, because edit_file needs 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_lufs and short_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), and master (instantaneous spectral features of the live master — centroid/flatness/rolloff/spread/sharpness — in the SAME units as a reference track’s features). 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).
  • edit_file — replace exact text in a file. Unique-match by default; replace_all for 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.

  • transport — send a performance command to the open studio tab(s) and wait for the first acknowledgement. Commands include play / 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; null clears it back to the linear arrangement), and setMetronome { on }. It reports honestly: a delivered: 0 when no studio tab is open, and a timeout note if no ack arrives within ~1.5s (it may or may not have applied — check get_status).
  • list_packages — discover packages (with their owning orgs).
  • install_package — install one into the song. Same Yjs create op as create_file, so the editor sees it live and the song hot-reloads. Then the model imports its exports and uses them.

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.

A typical loop is: get_song → reason about the code → edit_fileget_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.