Skip to main content
Glama

write_clip_notes

Write MIDI notes into an Ableton Live clip, replacing or appending to existing content, with verification.

Instructions

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.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
modeNo'replace' updates the clip content to match exactly this note list. 'append' adds to what is there, which layers new notes onto existing ones.replace
slotYesClip slot index in track.clip_slots, counted from 0. A slot index is the scene the clip sits in, so slot 2 is the third scene down.
notesYesThe notes to write into the clip. Each item declares its own fields, and the item schema carries their units.
trackYesTrack index in song.tracks, counted from 0.
verifyNoTrue reads the notes back and reports the difference against what was asked for, at the cost of one extra read.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed2 schema fields changedv0.1.4
    • changedInput schema / properties / mode / description
      Previous value: -"'replace' removes the notes already in the clip and writes these instead, so the clip ends up holding exactly this list. 'append' adds to what is there, which doubles a note when the same list is sent twice."New value: +"'replace' updates the clip content to match exactly this note list. 'append' adds to what is there, which layers new notes onto existing ones."
    • changedInput schema / properties / notes / description
      Previous value: -"The notes to write. An empty list with mode='replace' clears the clip. Each item declares its own fields; the item schema carries their units."New value: +"The notes to write into the clip. Each item declares its own fields, and the item schema carries their units."
  2. Changed7 schema fields changedv0.1.1
    • addedInput schema / properties / mode / description
      Added value: +"'replace' removes the notes already in the clip and writes these instead, so the clip ends up holding exactly this list. 'append' adds to what is there, which doubles a note when the same list is sent twice."
    • addedInput schema / properties / mode / enum
      Added value: +[
      +  "replace",
      +  "append"
      +]
    • addedInput schema / properties / notes / description
      Added value: +"The notes to write. An empty list with mode='replace' clears the clip. Each item declares its own fields; the item schema carries their units."
    • changedInput schema / properties / notes / items / properties / velocity / description
      Previous value: -"1..127. Omitted or null both mean unspecified; Live default is 100."New value: +"1..127. Omitted or null both mean unspecified. Live default is 100."
    • addedInput schema / properties / slot / description
      Added value: +"Clip slot index in track.clip_slots, counted from 0. A slot index is the scene the clip sits in, so slot 2 is the third scene down."
    • addedInput schema / properties / track / description
      Added value: +"Track index in song.tracks, counted from 0."
    • addedInput schema / properties / verify / description
      Added value: +"True reads the notes back and reports the difference against what was asked for, at the cost of one extra read."
  3. First observedv0.1.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations supplying almost no behavioral signal (all false), the description carries the burden and does so thoroughly. It discloses clip-local beat timing, the replace-vs-append semantics with measured evidence, note_id tolerance and key rejection behavior, the absence of defaulting, and floating-point round-trip deviations with a clear warning never to compare for equality.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with purpose, returns, usage notes, and behavioral warnings front-loaded. It is somewhat verbose in the floating-point precision narrative, which could be trimmed without losing the core warning, but the detail is informative rather than redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutating tool with five parameters and an output schema, the description covers all essential context: units, mode semantics, note object key handling, verification behavior, and precision pitfalls. An agent has enough information to call it correctly and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds substantial input-construction guidance: note_id and tolerated keys are dropped, unrecognized keys are refused, pitch/start_time/duration are never defaulted, and the 'pos'/'dur' spelling is explicitly not accepted. This goes well beyond the schema's field-level descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource: 'Write MIDI notes into a Session clip.' It clearly differentiates from siblings like read_clip_notes and delete_clip, and the description of replace vs append modes further clarifies what the tool does.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly tells when to use alternatives: read_clip_notes for inspecting before rewriting, quantize_clip for timing, transpose_clip for pitch, and delete_clip for emptying a clip. It also gives a concrete rule for choosing mode='append' when layering notes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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