Skip to main content
Glama

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
get_sessionA

Survey the running set: script handshake, song fields, tracks, clips, devices.

The call to make first. It proves the Remote Script is answering before anything
else is attempted, and it hands back the track and scene indices every other
tool here is addressed by.

Returns:
    Dictionary with script handshake info, song fields, the track list with its
    indices, group track indices, and clip and device detail where asked for.

Note:
    The round-trip handshake takes about 450 ms, so this is the expensive read. Take
    it once at the start and narrow with get_track, get_clip and get_devices
    afterwards rather than calling this again between edits. Group tracks have no arm
    state ('armed' returns null). If Live collection introspection reports zero
    tracks, index probing is used as a fallback.
get_trackA

Read one track's mixer state, flags, device chain, sends and clip slots.

One track in one round trip, where get_session covers the whole set. Use this to
read a mixer before writing it with set_mix, and get_devices when the device
chain is the only thing wanted.

Returns:
    Dictionary with the mixer fields, the arm state and whether arming applies,
    the device names and count, the send values, the clip slot count and the
    indices of the filled ones, and a per-collection flag saying whether each
    count is exact.

Note:
    ``volume`` and ``panning`` are normalised, not dB: 0.85 is 0 dB (measured),
    and the scale is not linear. ``display`` carries the dB reading where Live
    offered one.

    ``arm`` is read only after ``can_be_armed`` says the question applies,
    because reading it on a group track raises inside Live and would break the
    whole batch (measured). It comes back as ``null`` where it does not apply.

    Device names, send values and which clip slots are filled are measured by
    probing indices in one batch, because Live's collections report no length.
    Read ``counts_exact`` before treating any of those counts as complete.
get_clipA

Read one Session clip's properties: length, loop, warp, pitch, markers, flags.

Checks the slot is filled first, because a clip only exists while its slot
has one and every property read would otherwise fail one by one.

Returns:
    Dictionary with ``has_clip``, and where that is true the clip path, whether
    it is MIDI, and the property fields. An empty slot answers ``has_clip:
    false`` and says so rather than failing.

Note:
    Notes are not properties. Use ``read_clip_notes``. Automation is not a
    property either. Use ``read_automation``.

    ``warping``, ``warp_mode`` and ``pitch_coarse`` are reachable only through a
    generic path, because a per-command bridge has no command for them and a
    missing command is easily mistaken for a missing capability
    (docs/architecture.md, 'the restart tax'). Each was read, written, read back
    and restored on 2026-08-29 against Live 12.4.5, and all three rows are
    ``verified``. ``pitch_fine`` is read-verified only, with no write attempted
    on it, and the integer mapping behind ``warp_mode`` is still a hypothesis:
    confirm it against ``clip.available_warp_modes``, which is the authoritative
    per-clip list.

    Writing ``warping`` invalidates every time field this tool just returned. On a
    1.14-unit audio clip at 120 BPM, turning warping on took ``loop_end`` from 0.5704
    to 1.1408 and ``end_marker`` from 1.1408 to 2.2816, both doubled, while ``length``
    did not follow. At 60 BPM the same toggle moved neither. The mechanism is not
    established and is not claimed. What is established is that the numbers move and
    that the factor tracks the tempo. Call this again after any write to ``warping``
    rather than reusing what it said before.
get_devicesA

List a track's device chain: names, class names, on/off, parameter counts.

Reads the chain and changes nothing in it. The device indices it reports are the
ones set_parameter, delete_device and ``song.move_device`` are addressed by.

Returns:
    Dictionary with the device count and one entry per device carrying its index,
    name, class name, on/off state, parameter count and ``configure_needed`` flag.
    A track with an empty chain answers ``device_count: 0`` rather than an error.

Note:
    Read the parameter count first. A third-party plug-in reporting exactly one
    parameter has not been configured, which the ``configure_needed`` flag says
    outright. That is a limit in Live, not in this server, and only Live's GUI
    lifts it. The probe behind that flag settles one question, whether the count
    is exactly one or more than one, so where it could not settle it the count
    arrives as ``parameter_count_at_least`` instead.

    For the parameters themselves, with their ranges and display units, call
    ``describe`` with ``with_parameters=True``: this tool counts them and does
    not list them. For the mixer, sends and clip slots on the same track, call
    get_track instead of adding a second call here.
describeA

Introspect any Live object: class, properties, children, and methods.

The route to the dynamic surface: what a loaded plug-in actually exposes, which
no catalog can know in advance because it is decided at runtime and, for
third-party plug-ins, by what the user picked up in Configure mode.

Returns:
    Dictionary with the object class, its properties, its child collections, the
    methods the allowlist permits, and the parameter survey where asked for.

Note:
    Prefer this over lom_describe for a device, and prefer lom_describe for
    anything else. The difference is ``with_parameters``: lom_describe reports a
    device's parameters as a count, and a count is what a Live ``Vector`` that
    refuses ``len()`` fails to give, so a plug-in with parameters can be reported
    as having none. Measured against Live 12.4.5. When that happens this tool
    falls back to probing parameter indices, reports the names it found, and says
    which of the two answers you are looking at.

    Methods are never callable through a path. Take the name from here and invoke
    it through lom_call, which accepts only names on the Remote Script's own
    allowlist. For a device parameter, set it with set_parameter rather than
    writing the path by hand.
create_trackA

Insert a MIDI, audio, or return track and return its resolved index.

Returns:
    Dictionary with the resolved index of the new track, its kind and name, and
    the track count before and after.

Note:
    Inserting at index N shifts the track that was at N, and every track after it, up
    by one. Every track index held from before the call is then wrong, including ones
    in a plan not yet executed. Append with -1 where the position does not matter, and
    otherwise take the resolved index out of this answer rather than assuming it.

    Creating a track does not put an instrument on it. Select it and call
    load_device for that, then create_clip for something to play.
load_deviceA

Search Live's browser and load a device onto the currently selected track.

Two steps, and the first one is not optional in practice: call with confirm=False
to search and to see which track is selected, then call again with confirm=True
and the uri or item_path of the item you chose.

Returns:
    Dictionary of search candidates and the selected track on the search step, or
    the load result and the resulting device chain on the load step.

Note:
    Loading an instrument is destructive. ``Browser.load_item`` takes no track
    argument: it loads onto whatever ``song.view.selected_track`` points at.
    It cannot be aimed inside a rack from here. Measured 2026-09-07 against
    Live 12.4.5: writing ``rack.view.selected_chain`` reads back as the chain
    that was asked for, and a device loaded afterwards still lands on the
    track. The chain kept its six devices and the track went from one device
    to two. Live's browser follows the selection in its own interface, which
    no write over this channel drives. An effect is appended to the end of the
    chain, but an instrument replaces the instrument already on the track and
    discards it silently, together with every parameter configured on it and
    every clip envelope pointing at it. Check the selection and the existing
    chain with get_devices before confirming.

    Loading plug-ins in rapid succession can crash Live (measured: a batch load
    during a background plug-in rescan, with a licence dialog open, took the
    whole application down). Load one at a time, check the connection between
    loads, and save the set first.

    A successful return proves the call ran, not that the track makes a sound: a
    measured Drum Rack load reported success on a silent track. Read the chain
    back with get_devices, and for a rack check that ``chains`` is not empty.

    An instrument load renames the track while the track still carries Live's default
    name, so a track name cached from an earlier get_session is stale afterwards. An
    effect never renames. To reorder what is already loaded, call ``song.move_device``
    through lom_call rather than loading again.

    Three things about the search step are worth knowing before trusting it.

    An empty ``candidates`` with ``truncated: true`` is not proof that the item is
    absent. The walk ran out of budget before it reached the item, and a search
    narrowed with ``root`` can find on the first try what an unrooted search missed
    entirely. Narrow before concluding something is not installed.

    A ``uri`` from the search step can fail to resolve on the load step for the same
    reason, with ``stopped by node_budget``: resolving one walks the browser again,
    and a uri carries no hint about where to look. The ``item_path`` in that same
    candidate addresses the item directly and cannot run out of budget, so prefer
    it. Where the uri is what you have, pass ``root`` with it and the second walk
    is narrowed to that one category the same way the search was.

    Loading onto the main track works and is reached the same way as any other
    target, by pointing the selection at it first: write ``song.view.selected_track``
    with ``{"__path__": "song.master_track"}`` through lom_set, then load. There is no
    track index for the main track, which is why the usual index does not apply.
create_clipA

Create an empty MIDI clip of a given length in a Session slot.

The target must be a MIDI track. An audio slot takes a sample instead, which is a
different call: lom_call with path='song.tracks[N].clip_slots[M]',
method='create_audio_clip' and one absolute file path (catalog row
clip_slot.create_audio_clip).

Returns:
    Dictionary with the creation status, the clip path, and the read-back length.

Note:
    An occupied slot is refused rather than overwritten, so nothing is lost by
    aiming at the wrong slot. To replace a clip, delete_clip first.

    The clip arrives empty. Fill it with write_clip_notes, and copy it onto the
    Arrangement timeline with arrange once it holds something.
delete_clipA

Delete the clip in a Session slot, its notes and envelopes with it.

Requires confirm=True. With confirm=False it reports the clip name, length and
note count that the call would remove, and changes nothing.

Returns:
    Dictionary reporting the deletion, or the loss report when unconfirmed.

Note:
    This empties one Session slot. Slot indices do not shift, so nothing else
    moves and no other index goes stale.

    Emptying a clip is not the same as deleting it: write_clip_notes with an
    empty list and mode='replace' leaves the clip in place with its length,
    loop and envelopes intact. Prefer that where the slot should stay filled.
    A clip already copied into the Arrangement by arrange is a separate clip and
    survives this.
delete_trackA

Delete a track with everything on it. Requires confirm=True.

The widest deletion here: the devices, every Session clip and every Arrangement
clip on that track go with it. With confirm=False it reports the track name, the
devices, the filled Session slots and the Arrangement clip count the call would
remove, and changes nothing.

Returns:
    Dictionary reporting the deletion, or the loss report when unconfirmed.

Note:
    Deleting shifts every later track down one index, so any track index read
    before this call is wrong afterwards. Re-read with get_session, and where
    several tracks are going, delete from the highest index downwards so the
    earlier indices stay valid.

    For something narrower, delete_clip empties one slot and delete_device takes
    one device out of the chain, neither of which renumbers anything.
delete_deviceA

Delete one device from a track chain, its settings with it.

Requires confirm=True. With confirm=False it reports the name of the track, and
the device's name, class and parameter count, and changes nothing.

Returns:
    Dictionary reporting deletion status or pending loss report.

Note:
    The track is named in the report because a device name does not identify
    one. A device class like Utility or EQ Eight sits on several tracks in a
    normal set, so a loss report naming only the device reads the same whether
    the index points at the intended chain or at a neighbour's. Check the track
    name against the one you meant before confirming.

    Deleting shifts every later device in the chain down one index, so a second
    delete aimed at an index read before the first one lands on a different
    device. Read the chain again with get_devices between deletes.

    Two neighbouring intentions are not this tool. To reorder a chain nothing
    needs deleting: call ``song.move_device`` through lom_call. To swap the
    instrument on a track, load the replacement with load_device, which replaces
    the instrument already there in one step (measured). Deleting first only
    loses the settings earlier.

    ``kind`` reaches the return and main chains, which are addressed the same way
    get_devices addresses them. A return track carries its own index and the main
    track has none, so ``track`` is not read at all when kind is master.
write_clip_notesA

Write MIDI notes into a Session clip.

Returns:
    Dictionary containing write confirmation, validation reports, and optional diff.

Note:
    Times are in beats and clip-local, so beat 0 is the clip's own start.

    With mode='replace' (the default), the clip is updated to match the provided note
    list. Live's native note writing appends by default, so mode='replace' ensures a
    second write updates rather than duplicates a melody (measured: 63 + 23 = 86 notes).
    Ask for 'append' by name when layering notes into an existing performance. To
    empty a clip without writing new notes, use delete_clip.

    Use read_clip_notes to inspect existing notes before rewriting them. Use
    quantize_clip to adjust timing to a grid, and transpose_clip to shift pitch
    without altering rhythm.

    A list straight from ``read_clip_notes`` can be written back. Live adds
    ``note_id`` to every note it hands out, which is identity rather than content,
    so the keys in :data:`~live_maestro.music.notes.TOLERATED_NOTE_KEYS` are
    dropped instead of refused and reported as ``input_keys_ignored``. Every other
    unrecognised key is an error.

    ``pitch``, ``start_time`` and ``duration`` are never defaulted. A reader that
    substitutes ``start_time=0.0`` and ``duration=0.25`` for missing keys turns a
    list built with ``pos``/``dur`` (the humanise spelling) into a pile of
    sixteenths stacked on beat 0, and reports success while doing it. Wrong keys are
    refused before anything is sent.

    A note does not come back bit-identical to the note sent. Times and durations
    return with a small deviation in both directions: a sent 0.29 reads back as
    0.29000010406260407 and a sent 0.18 as 0.17999994796869798, about 4e-7 relative,
    and both reproduce to every digit across runs. A ``start_time`` of 2.29 comes back
    as 2.290000104062604, and a duration of 0.5 comes back exactly. The cause is not
    established: it is not a tick grid (no grid of 96, 192, 480 or 960 per quarter
    produces those numbers) and not a single float32 conversion (float32 of 0.29 is
    0.28999999). That 0.5 survives while 0.29 does not is consistent with a
    binary-representable value passing through untouched, but the mechanism is not
    claimed here. At 124 BPM the error is around 50 nanoseconds, so musically it is
    nothing. It matters only for comparison: never test a note time for equality. The
    diff run here already uses a tolerance, which is why it reports ``0 changed`` for
    values that differ in the seventh decimal.
read_clip_notesA

Read MIDI notes of a Session clip, query a specific window, or count notes.

Returns:
    Dictionary containing notes, count, window parameters, and validation report.

Note:
    Times and positions are expressed in clip-local beats. Muted notes are included
    and carry ``mute: true``. ``time_span`` is a length in beats, not an end beat:
    beats 24 to 32 is ``from_time=24, time_span=8``.

    Windowing and counting keep a small question small. A single drum clip of 384
    notes comes back as 57k characters, past the tool-result cap, so a survey across
    59 clips cannot be a full read of each. The LOM has no ``note_count`` on ``Clip``
    at all, so a count taken out here means transferring every note to measure it.
    ``count_only=True`` counts inside Live and carries back one integer.

    With ``count_only`` there is nothing to validate, so ``check`` is ignored. With a
    window, ``check`` sees the window and not the clip.

    Returned notes are sorted by time, then pitch. Live hands its notes back ordered
    by pitch, which is the one order a musical instruction never means: "the third
    note", "every other note" and "the last note" are all about when a note sounds.
    Four notes written at beats 0, 1, 2, 3 with pitches 72, 60, 67, 62 come back 60,
    62, 67, 72, so taking every other entry off the raw list picks alternating pitches
    rather than alternating beats, silently and plausibly. For Live's own order call
    ``get_notes_extended`` through ``lom_call``.
quantize_clipA

Quantize MIDI clip note positions and lengths to a specified beat grid.

Reads notes, calculates quantized positions, writes back using mode='replace',
and verifies the result.

Returns:
    Dictionary with the write result, the number of notes moved, and how far.

Note:
    Parameter interactions: ``strength`` scales note displacement towards ``grid`` from
    0.0 (raw timing preserved) to 1.0 (full snap). Use partial strength (e.g. 0.5) to
    tighten timing while preserving human groove feel. Setting ``quantize_ends=True``
    snaps note ends to the grid too, adjusting note lengths. In contrast,
    ``quantize_ends=False`` shifts note onsets only and preserves articulation.

    Quantising modifies notes in place and is not undoable. Read the notes first with
    read_clip_notes if the original unquantized timing might be needed later.

    To shift pitch instead of timing, use transpose_clip. To write custom or micro-timed
    notes off-grid, use write_clip_notes.
transpose_clipA

Transpose a MIDI clip by note pitch or an audio clip via pitch_coarse.

Relative on both paths, so calling it twice with 2 moves the clip by 4 and there
is no absolute target to aim at. A MIDI clip has every note pitch rewritten. An
audio clip is repitched as a whole instead.

Returns:
    Dictionary reporting the transposition, the notes affected, and any that hit
    the range limit.

Note:
    When to use: Shift the overall pitch of an entire clip by a constant semitone offset.
    When NOT to use: Do not use transpose_clip to edit melody contours, re-voice chords,
    or correct scale degrees. Use write_clip_notes instead. Do not use it for timing or
    groove changes, which are handled by quantize_clip.

    An audio clip is transposed by writing clip.pitch_coarse. The write is relative
    there too, because the current value is read first and the semitones added to it,
    so repeated calls do keep climbing. Live documents the bound as -48 to 48 but that
    figure is not from a probe here. The read-back in the answer is the evidence for
    any one write.

    ``out_of_range='clamp'`` and ``'drop'`` both lose information that
    transposing back will not return: clamped notes have collapsed onto one
    pitch and dropped ones are gone. Keep the default 'error' unless the clip
    has been read out with read_clip_notes first.
set_mixA

Set volume, pan, sends, mute and solo on one track in a single round trip.

Every argument is optional and only the ones given are written, so this is the
cheap way to change several mixer controls at once. Read the current state with
get_track first, since the values here are absolute and not relative.

Returns:
    Dictionary reporting each write with its before and after value, and the dB
    display where Live offered one.

Note:
    Volume and pan are normalised, so 0.85 is 0 dB (measured) rather than 85 per
    cent of anything. Read ``display`` in the answer for Live's own dB reading
    instead of converting the normalised number yourself.

    The master track has no mute and no solo. Both are refused there rather than
    silently ignored, and ``track`` is not read at all when kind is master.

    This is the mixer only. For a knob on a device in the chain use
    set_parameter, and for the tempo use set_tempo. To make a mixer control move
    over time rather than jump, write an envelope with write_automation.
set_parameterA

Set one device parameter by index or name and verify the read-back.

Returns:
    Dictionary reporting the write, the parameter index it resolved to, the
    read-back value, and the display string where the device offered one.

Note:
    Parameter values are normalised, not the unit the device displays. Read ``min``
    and ``max`` (``describe`` with ``with_parameters=True``) rather than assuming
    a range.

    The curve from 0..1 onto the displayed unit is not linear and differs per
    device. On one third-party compressor Attack is ``v^4 * 1000 ms``, so writing
    "10 ms" linearly lands at 316 ms, a factor of 30, silently. Where the device
    reports a display, aim with the display. Where it does not (all VST2), write
    normalised and calibrate by eye once.

    A parameter that shows a display also answers ``str_for_value``: lom_call with the
    parameter path, ``method='str_for_value'`` and one value returns the string that
    value would display, and moves nothing. That maps a unit onto the scale without
    deriving the taper by trial (catalog row param.str_for_value).

    A quantized parameter takes discrete steps, so a written 0.5 can legitimately read
    back as something else, and that is reported as a clamp rather than as a failure.
set_parameter_displayA

Set a device parameter by the reading it should show, not by its raw value.

Returns:
    Dictionary reporting the value written, the display it produced, the residual
    error against the target, the unit, and how many probes and round trips it
    took. On refusal, why - including the case where the device reports no units.

Note:
    This is the inverse of ``set_parameter``, and it exists because there is no
    formula to invert. The curve from the raw range onto the displayed unit
    differs per parameter and is rarely linear: on one measured third-party
    compressor Attack is ``v^4 * 1000 ms``, Ratio is ``20^v`` and Threshold about
    ``40 * log10(v)``. Writing "10" at a parameter that displays milliseconds
    lands at 316 ms there, a factor of 30, and reports success.

    So the taper is sampled rather than computed: one batch of probes asks the
    device what each raw value *would* read as, the answers are bracketed around
    the target, a second batch refines inside that bracket, and only then is a
    single value written and read back. Two round trips, and nothing in the set
    moves until the last step.

    That last point is the reason not to bisect with real writes instead. A
    probing bisection that does not restore what it touched has been measured
    leaving Delay Feedback at 100 % - self-oscillation - and Saturator Drive at
    100 % across 20 parameters (catalog row return_device.str_for_value). The
    probes here write nothing at all.

    The probes stay strictly inside the range and never ask at ``min`` or
    ``max``: an endpoint has crashed Live inside a plugin's own formatting code,
    which is native code no try/except reaches (docs/limits.md, 'Asking for a
    display string at an endpoint (Live)').

    Where the device reports no unit this refuses instead of aiming. Every VST2
    reports a bare number (0 of 36 measured), which is formally a number and
    physically meaningless, so a display-driven search there would walk the
    control to its end stop and call it a result. For those, use ``set_parameter``
    with a normalised value and calibrate by ear once.

    The result is the stored value and its display, which is not audibility: a
    parameter on a device that is switched off reads back exactly the same.
write_automationA

Write an automation envelope into a Session clip and verify the read-back.

Turns a handful of breakpoints into a written curve, then reads it back so the
result reports the stored envelope rather than the requested one.

Returns:
    Dictionary reporting the write, how many points were laid down, and the
    comparison between the stored curve and the generated one.

Note:
    Automation lives in Session clips. There is no way to write an Arrangement
    envelope directly here: write it into the Session clip and then copy the clip
    onto the timeline with arrange, which carries the envelope with it.

    A verified write proves the stored curve, never that it is audible. An
    envelope on a parameter of a device that is switched off, or on a muted
    track, reads back exactly as written and changes nothing anyone can hear.

    With ``clear_first=False`` a repeated call layers points onto the ones
    already there, so a retry after an unclear result can leave a curve that
    matches neither attempt. Read it with read_automation before writing again.
    To explicitly clear an envelope without writing new points, use clear_automation.

    Playing the clip leaves the parameter at the value this curve last reached, and
    stopping does not restore it. Capture the statics you care about before the first
    playthrough: once a curve has run, nothing reports the value it covered.
read_automationA

Sample a clip envelope into a list of values and report what it found.

Reads the curve by evaluating it at ``points`` positions, so the answer is a
sampling of the envelope rather than the breakpoints that define it.

Returns:
    Dictionary with the sampled values, the beat range they cover, the value
    range they span, and flags saying whether an envelope exists at all.

Note:
    Automation lives in Session clips, so an Arrangement clip has none to read.
    als_read is the way to see breakpoints in a saved project instead.

    Use write_automation to lay a curve down and clear_automation to remove one.
    A flat result with an envelope flag of false means nothing is automated on
    that parameter, which is not the same as an envelope holding the parameter's
    current value.
clear_automationA

Delete automation envelopes on a Session clip. Requires confirm=True.

Requires confirm=True. With confirm=False it changes nothing and reports the
envelope it would remove: its range, where the low and the high point sit, and
how densely it was sampled to find them.

That report covers one named parameter. With all_envelopes it says whether the
clip is automated at all, because has_envelopes is one flag for the whole clip.
To see which parameters those envelopes belong to, read
clip.automation_envelopes with lom_get and then each
automation_envelopes[i].parameter.name.

Returns:
    Dictionary reporting the clearance, or the envelopes that would go.

Note:
    A cleared envelope is gone, and the parameter falls back to whatever value it
    holds outside the clip rather than to the first breakpoint. Sample it with
    read_automation first if the shape might be wanted back, since nothing here
    restores it.

    The dry run samples the curve rather than reading its breakpoints, so a
    feature narrower than the reported sampling step can still sit between two
    samples. Where the exact shape matters, read it with read_automation at a
    resolution you choose, or read the breakpoints out of the saved file with
    als_read.

    To change a curve rather than remove it, write_automation with
    ``clear_first=True`` replaces it in one call and needs no clearing first.
    This tool is for leaving the parameter unautomated.
arrangeA

Copy a Session clip onto the Arrangement timeline at a beat position.

A copy, not a move: the Session clip stays in its slot and the two are separate
clips afterwards, so editing one leaves the other alone. This is how a Session
idea becomes an arrangement, and how clip automation written by write_automation
reaches the Arrangement timeline.

Returns:
    Dictionary with the placement status, the destination track, and the
    Arrangement clip count before and after.

Note:
    Call it once per placement. Repeating the same call adds another copy at the
    same beat rather than replacing the first, so a retry after an unclear result
    needs the clip count in this answer checked first.

    Use create_clip and write_clip_notes to build the source clip, and
    set_arrangement_time then play to hear where it landed.
set_locatorA

Place or remove an Arrangement cue locator. Requires confirm=True.

This toggles, and that is the whole difficulty with it. Live offers one call,
``song.set_or_delete_cue``, which adds a locator where none exists at that beat
and deletes the one that does, so the same arguments twice leave nothing behind.
Call with confirm=False first to see which of the two would happen.

Returns:
    Dictionary reporting the toggle, and the cue points and their count after it.

Note:
    A locator marks a position for a human reading the Arrangement. It does not
    move the playhead. Use set_arrangement_time to move that, and set_loop to
    mark a region rather than a point.
set_arrangement_timeA

Move the Arrangement playhead to a beat and read the position back.

Writes ``song.current_song_time``. This moves where playback would start. It
does not start it. Use play to begin, or play with ``from_beat`` to do both in
one call.

Returns:
    Dictionary with the write confirmation and the read-back song time.

Note:
    Do not sample a moving transport through lom_batch. A read that follows a
    jump inside the same batch still reports the position from before the move,
    and it reports it without an error (see lom_batch). One call per position.
playA

Start transport playback and read back the is_playing status.

Returns:
    Dictionary reporting the start call and the read-back is_playing flag.

Note:
    The read-back proves the transport is running, not that anything is audible:
    a muted track, an empty Arrangement or a track with no instrument all play
    silently. Use stop to halt, and set_arrangement_time to move the playhead
    without starting.

    Leave the transport as it was found. Nothing here stops it on its own, and a
    set left playing keeps playing for whoever is at the machine.

    A Session clip that has played leaves its track in Session view, and the
    track then ignores the Arrangement until Live's Back to Arrangement button
    is pressed. ``song.back_to_arranger`` reports that state and cannot clear
    it: measured 2026-09-07 against Live 12.4.5, writing it false reads back
    ``not_observed`` and the value stays true.
stopA

Stop transport playback, and optionally every playing Session clip.

Returns:
    Dictionary reporting the transport stop and, where asked for, the clip stop.

Note:
    With ``quantized=True`` the clips stop on the next grid point rather than at
    once, so an immediate read can still show a clip playing without anything
    having gone wrong. Use play to resume playback, or set_arrangement_time(time=0)
    to rewind the Arrangement timeline to the beginning.

    Stopping does not restore a parameter a clip envelope was driving. The envelope
    leaves the parameter at its last reached value and Live keeps no static baseline
    underneath to restore.
set_tempoA

Set the global song tempo in BPM and read back the stored value.

One tempo governs the whole set, Session and Arrangement alike. There is no
per-track tempo. The one other place a tempo can come from is a scene, below.

Returns:
    Dictionary reporting the write and the read-back tempo.

Note:
    A tempo set here does not survive every scene launch. Firing a scene whose
    ``tempo_enabled`` is on writes ``song.tempo`` again from ``scene.tempo``, so
    read ``song.tempo`` back after a launch rather than assuming this one held
    (catalog rows ``scene.tempo`` and ``scene.tempo_enabled``, both read verified
    2026-08-29 against Live 12.4.5).

    BPM is a real unit, which makes this tool the exception among the setters. A
    device parameter is normalised over whatever range the device declares: reach
    those with set_parameter and read ``min`` and ``max`` through ``describe``
    rather than assuming 0..1 (docs/limits.md). Volume, pan and sends are
    normalised the same way, and set_mix carries them.
set_loopA

Move the Arrangement loop brace, or switch looping on and off.

Every argument is optional and only the ones given are written, so the brace can
be moved without touching the switch and the reverse.

Returns:
    Dictionary reporting how many writes were made and the before and after
    values for each of enabled, loop_start and loop_length.

Note:
    The brace only loops the Arrangement transport. It has no bearing on Session
    clip looping, which is a clip property. Read that with get_clip. ``length``
    is a duration and not an end position.

    Calling with no arguments at all writes nothing and reports the current
    brace, which is the cheap way to read it.
als_readA

Read a saved Ableton project (.als) or rack (.adg) from disk.

Returns:
    Dictionary containing project metadata, track list, devices, and automation structure.

Note:
    This is Channel B, a peer of the live connection rather than a fallback. It
    answers two questions the LOM never will: what is in someone else's project, and
    where an envelope's breakpoints actually sit.

    Automation lives in two places and the LOM can read only one of them. Measured
    over the 174-project corpus (docs/limits.md section 9): 52 (30 %) have clip
    envelopes but 159 (91 %) have
    track automation, and a tool that counted clip envelopes alone reported 110 of
    those projects as unautomated. The two layers are reported separately here and
    are never added together.
als_writeA

Edit a saved .als project file on disk. Requires confirm=True.

Supported operations: 'sidechain', 'configure', 'attribute', 'restore'.
The target file must not be the one Live currently holds: Live writes its own
memory over the file when it next saves, without a conflict warning, and the
edit is gone. Live running on a different set is fine.

Returns:
    Dictionary reporting write status, changes made, and verification report.

Note:
    ``sidechain`` is here for the set Live is not holding, someone else's project
    wired on disk. Measured across the 174-project corpus (docs/limits.md section 9):
    74 of 82 in the house/trance BPM window use sidechain compression, median 6
    wirings each. For
    the set on screen use ``lom_set`` and keep the read-back.

    ``configure`` fills a plugin's parameter strip, which no LOM call can do whatever
    the strip currently holds. Two parameters written into an instance whose strip
    held nothing came back on reopen with their real values, writable through
    ``lom_set`` with ``read_back: applied``. Live allocates 128 slots per instance and
    leaves them all in the file, so nothing is inserted. Three fields of an existing
    element are filled.

    ``attribute`` sets one attribute anywhere in the file, addressed by an
    ElementTree expression. An expression matching more than one element is refused
    unless ``index`` picks one, and ``index`` counts the matches of that expression
    rather than tracks in the project: ``.//MidiTrack/Name/EffectiveName`` does not
    see the audio tracks at all.

    Where the expression comes from: ``als_read`` with ``locate='tempo'`` or
    ``locate='track_names'`` answers with the expression, the attribute and the
    index for those fields, which are the ones usually edited on a file. For
    anything else the expression is built by hand, and ``confirm=False`` resolves
    it against the file first and reports what it selects, so a wrong one is
    caught before it writes rather than after.

    Choosing between the four: ``sidechain`` and ``configure`` for the two things
    the LOM cannot do at all, ``attribute`` for anything else in the file, and
    ``restore`` to undo any of them. For
    the set open in Live, none of these: use lom_set, set_parameter or set_mix
    and keep the read-back.
lom_getA

Read one property value by LOM path, with its catalogued meaning.

The single-property read behind every getter here, for the field no getter
exposes. Where the catalog knows the path, the answer carries a ``catalog``
hint, and where it knows that a particular value is a sentinel it carries
``means`` as well: a ``scene.tempo`` of -1.0 reads back as "no tempo set for
this scene" rather than as a tempo below the legal minimum.

Returns:
    Dictionary with path, value, type, an optional display string for a device
    parameter, and the catalog hint and meaning where those exist.

Note:
    A path that is not rooted at song, app or song.view is refused here without
    Live being contacted. A path Live rejects comes back as ``ok: false`` with
    Live's own ``code``, so a missing property is an error rather than a null.

    Reach for a getter first where one exists: get_session for the whole set,
    get_track, get_clip and get_devices for one of each, read_clip_notes for
    notes, read_automation for envelopes. All of them cost one round trip for
    many fields, where this costs one per field. Use lom_batch to read several
    paths in a single trip, lom_describe when the property names are not known
    yet, and lom_set to write.
lom_setA

Write a property value by LOM path and return verification read-back.

The generic write, for the property no dedicated tool covers. Prefer
set_parameter for a device knob, set_mix for a mixer control and set_tempo for
the tempo: each validates against the catalog before writing, which this does
not. Use lom_call for a method, which is not reachable as a property, and
lom_batch to send several writes in one round trip.

Returns:
    Dictionary reporting requested, before, after, clamped, and changed status.
    For a device parameter it also carries ``display`` and ``is_quantized``.

Note:
    Live does not accept an out-of-range value silently, however often that is given
    as the reason to read back. It refuses out loud and stores nothing, so
    ``...volume.value = 1.4`` answers
    ``live_error "Invalid value. Check the parameters range with min/max"`` and leaves
    0.85 standing. A tempo of 5000 and a panning of 5 are refused the same way.

    What the read-back really catches is quantised snap.
    ``<Compressor>.parameters[10].value = 0.4`` (Model: Peak / RMS / Expand)
    stored 0 and reported ``clamped: true, read_back: "clamped", display:
    "Peak", is_quantized: true``. A caller who asks for a value between two steps
    gets a different one and is told nowhere else.

    Three more, measured separately. A write can apply asynchronously, so the
    first read is stale and comes back ``read_back: "not_observed"``, which is
    not ``clamped`` and not a failure. A method call has no read-back at all.
    And Live ignores an unknown property name silently, reporting success for a
    write that did nothing, so check ``changed`` rather than ``ok``.

    A collection (``song.tracks``, ``device.parameters``) cannot be assigned.
    Address an element and set one of its properties.

    A Live object cannot travel as a plain value. Where a property really holds
    one (``song.view.selected_track``, ``song.view.selected_scene``,
    ``song.view.detail_clip``, ``browser.hotswap_target``, ``clip.groove``, and
    on a device ``input_routing_type`` and ``input_routing_channel``) pass
    ``value={"__path__": "song.tracks[2]"}``, resolved through the same guards as
    a lom_call argument (protocol section 5.4). Handed a plain JSON value the
    first five answer ``not_settable``.
    The two routing properties, a compressor's sidechain source and its tap
    point, take their reference out of ``<device>.available_input_routing_types``
    and ``...available_input_routing_channels``, never a name string, because
    RoutingType carries ``category`` and ``display_name`` read-only and an
    ``attached_object`` pointing at the Track.
lom_callA

Invoke an allowlisted method on a Live object.

The escape hatch for the calls that have no tool of their own, such as
``song.move_device`` for reordering a device chain. What it can reach is bounded
by the Remote Script's allowlist, not by this signature.

Returns:
    Dictionary reporting the call and its return value. A refused call names the
    reason, and where a dedicated tool covers the same ground it comes back with
    ``use_instead`` naming that tool.

Note:
    A method call has no read-back, so nothing here proves the effect the way a
    write through lom_set or set_parameter does. Follow it with the matching read
    (get_devices after a move, get_session after a structural change) rather than
    treating a successful return as evidence.

    Prefer the dedicated tool wherever one exists: create_clip, delete_track,
    set_tempo, play and stop all verify what this cannot. Use lom_get and lom_set
    for properties, which are not reachable as methods, and lom_batch to send
    several calls in one round trip.
lom_batchA

Execute multiple raw LOM operations (get, set, call) in a single round trip.

One trip instead of many, which is what makes a wide read affordable at roughly
450 ms per round trip.

Returns:
    Dictionary containing ordered results for each operation.

Note:
    A batch runs inside one handler call, so nothing Live recomputes between
    operations is visible to a later operation in the same batch. A read that follows
    a transport jump in the same batch still reports the position from before the
    move. Four jumps interleaved with four reads returned four identical pre-jump
    values and no error at all. That is the failure shape to expect here. It does not
    raise. It returns a clean set of numbers that look like a measurement of a
    parameter which never changes, and the conclusion drawn from them is wrong. Sample
    a moving transport with one call per position, never inside a batch.

    ``atomic`` is a stop switch and not a transaction: nothing is undone. After a
    partial failure, read the state back rather than assuming either all or none
    of the batch landed.

    Prefer a dedicated tool for anything it covers. get_session, get_track and
    get_devices already batch their own reads, and set_mix writes a whole mixer
    in one trip, each with verification this does not perform.
lom_describeA

Reflect on any LOM object: class, properties, children, callable methods.

The raw reflection, reporting what the object itself declares. Use it to find
the property names on an object the catalog does not cover, then read them with
lom_get and write them with lom_set.

Returns:
    Dictionary reporting object class, properties, child collections with their
    counts, and the methods the Remote Script allowlist will let you call.

Note:
    For a device, prefer ``describe`` with ``with_parameters=True``. This tool
    reports a device's ``parameters`` child as a count, and a count is exactly
    what a Live ``Vector`` that refuses ``len()`` fails to give, so a plug-in
    with parameters can be reported as having none. ``describe`` falls back to
    probing indices when that happens and says which answer it is handing back.

    The methods listed here are names, not calls: invoke one through lom_call.
lom_enumsA

Look up the integer behind a named Live enum member.

Live stores an enum property as a bare integer, so a write needs the number and
a read hands back a number that means nothing on its own. This is the lookup in
both directions.

Returns:
    Dictionary of member names against their integer values, or the list of enum
    type names when ``type_name`` is empty.

Note:
    Call this before writing an enum-valued property through lom_set or
    set_parameter, rather than guessing that the members run in the order Live
    draws them. This answers what a type's members are. lom_describe answers
    what properties an object has, and neither answers the other.
find_pathA

Find the mechanism that serves an intent, and the catalog rows when rows serve it.

Returns:
    Dictionary with the chosen route, any matching rows with their paths and docs,
    and the next call to make when rows are not the answer.

Note:
    Four routes, and which one comes back matters more than the rows do.

    ``catalog_row`` means the rows carry the answer. Each hit gives the path
    template to fill in, the access verbs, the full doc, and ``scopes``: the other
    places the same property exists, since track, return, master and chain mirror one
    another and a clip row usually has an arrangement_clip twin. ``writes`` appears
    when the best row is a read-only parameter object and names the sibling that
    actually takes a value.

    ``device_parameter`` means the answer is a knob inside a device, which this
    catalog cannot enumerate: what a device exposes depends on the device. Filter
    cutoff, resonance, attack, threshold and every other parameter behind a device
    front panel arrive this way, with the procedure to reach them.

    ``blocked`` means Live's API cannot do it at all, with what to do in Live
    instead. ``intent_tool`` is reported in the ``tool`` field alongside the rows
    rather than in place of them, because a tool that verifies its own work is the
    better route to the same end but the path is still worth seeing.
    ``unresolved`` means nothing matched. ``unmatched`` lists the words that found
    nothing, which is usually where the query went wrong.

    This exists so that finding a path costs about 1.5k tokens instead of reading the
    whole catalog. It does not touch Live: it reads the catalog only, so nothing here
    proves anything about the set that is open.
analyze_audioA

Measure the audio itself: loudness, true peak, stereo phase and band balance.

Reads the LiveMaestro Analyzer Max for Live device over loopback OSC. This
is the only tool that needs that device. Without it every other tool works and
this one reports device_not_found with the steps to load it.

What comes back, and what each figure is:

- Loudness to EBU R128, from Max's loudness~: momentary (400 ms), short term
  (3 s), gated integrated since the last reset, and loudness range.
- True peak, oversampled, so peaks between two samples count. Sample peak and
  RMS beside it, and the crest factor between peak and RMS.
- Stereo correlation over the whole band and below 120 Hz, and whether the low
  end survives being summed to mono.
- Energy in seven bands on the mono sum, plus their energy weighted centre.
  That centre is a centre of mass over seven band levels, not an FFT centroid.

Where it measures matters. The device reads the signal at its own position in
the chain, so it belongs last on the track: an effect loaded after it is not
in what it reports. A master track's device chain sits before the master
fader, so a master reading matches the set's output only while that fader is
at 0.0 dB.

The two peak figures are maxima since the meter was last reset and only rise.
To measure a peak, call once with reset=true, let at least one pass of the
material through, then call again. The averaged figures need no reset.

A read-back proves the stored value and never audibility: this proves what the
signal measured as it passed the device, which is a different and stronger
claim than any parameter value, and still not a claim about the room.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
catalog_resourceReturn a map of the catalog: counts, areas, status meanings, and how to search it.
session_resourceReturn JSON string snapshot of running Live session state.
limits_resourceReturn system limits specification and documentation reference.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/romanstark/live-maestro'

If you have feedback or need assistance with the MCP directory API, please join our Discord server