Skip to main content
Glama

write_clip_notes

Destructive

Write MIDI notes into Ableton Live Session clips. Replace existing content or append notes, then verify the written result by reading it back.

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. ``replace``
    (the default) makes the clip match the list given; Live's own note writing appends,
    so without it a second write duplicates a melody (measured: 63 + 23 = 86 notes). Ask
    for ``append`` by name to layer onto an existing performance. An empty list with
    ``replace`` empties the clip but keeps its length, loop and envelopes; delete_clip
    takes all of them.

    A list straight from ``read_clip_notes`` can be written back: the keys in
    :data:`~live_maestro.music.notes.TOLERATED_NOTE_KEYS`, such as Live's ``note_id``,
    are dropped and reported as ``input_keys_ignored``, and every other unrecognised key
    is an error. ``pitch``, ``start_time`` and ``duration`` are never defaulted, so a
    list spelled with ``pos``/``dur`` is refused before anything is sent instead of
    becoming sixteenths stacked on beat 0.

    Times and durations do not come back bit-identical. They return with a deviation in
    both directions, about 4e-7 relative and reproducible to every digit across runs: a
    sent 0.29 reads back as 0.29000010406260407, a sent 0.18 as 0.17999994796869798 and
    a ``start_time`` of 2.29 as 2.290000104062604, while a duration of 0.5 comes back
    exactly. The cause is not established: it is neither a tick grid of 96, 192, 480
    or 960 per quarter, nor a single float32 conversion (float32 of 0.29 is
    0.28999999). At 124 BPM the error is around
    50 nanoseconds, so it matters only for comparison: never test a note time for
    equality. The diff run here 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
pathNoLOM path to a Session clip, song.tracks[N].clip_slots[M] with or without a trailing .clip, as an alternative to track and slot. A song.tracks[N].arrangement_clips[i] path is refused with code region_not_addressable.
slotNoClip slot index in track.clip_slots, counted from 0, which is the scene the clip sits in. Give track and slot, or give path instead. These are Session coordinates; an Arrangement clip has none.
notesYesThe notes to write into the clip. Each item declares its own fields, and the item schema carries their units.
trackNoSession track index in song.tracks, counted from 0. Give track and slot, or give path instead. These are Session coordinates; an Arrangement clip has none.
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.

  1. Changed10 schema fields changed
    • addedInput schema / properties / path
      Added value: +{
      +  "default": "",
      +  "description": "LOM path to a Session clip, song.tracks[N].clip_slots[M] with or without a trailing .clip, as an alternative to track and slot. A song.tracks[N].arrangement_clips[i] path is refused with code region_not_addressable.",
      +  "title": "Path",
      +  "type": "string"
      +}
    • addedInput schema / properties / slot / anyOf
      Added value: +[
      +  {
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / slot / default
      Added value: +null
    • changedInput schema / properties / slot / description
      Previous 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."New value: +"Clip slot index in track.clip_slots, counted from 0, which is the scene the clip sits in. Give track and slot, or give path instead. These are Session coordinates; an Arrangement clip has none."
    • removedInput schema / properties / slot / type
      Removed value: -"integer"
    • addedInput schema / properties / track / anyOf
      Added value: +[
      +  {
      +    "minimum": 0,
      +    "type": "integer"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedInput schema / properties / track / default
      Added value: +null
    • changedInput schema / properties / track / description
      Previous value: -"Track index in song.tracks, counted from 0."New value: +"Session track index in song.tracks, counted from 0. Give track and slot, or give path instead. These are Session coordinates; an Arrangement clip has none."
    • removedInput schema / properties / track / type
      Removed value: -"integer"
    • changedInput schema / required
      Previous value: -[
      -  "track",
      -  "slot",
      -  "notes"
      -]New value: +[
      +  "notes"
      +]
  2. 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."
  3. 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."
  4. First observedv0.1.0

TDQS

A4.9/5.0
Behavior5/5

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

The description discloses the exact behavior of replace (makes clip match the list) and append (layers), the side effect of an empty list with replace (keeps length, loop, envelopes), and the precise floating-point deviation of times (e.g., 0.29 reads back as 0.29000010406260407). It also explains how unknown keys are handled. Annotations declare destructiveHint=true and readOnlyHint=false, and the description aligns with these, adding substantial behavioral detail beyond the annotations.

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 lengthy but every section earns its place: the opening sentence states purpose, return value is described, and the note sections cover time semantics, replace/append, input validation, and numerical deviation. The structure is clear and front-loaded with the core purpose. It could be slightly tightened, but the density of useful information justifies the length.

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?

Given the tool's complexity (6 parameters including a nested notes array, an output schema, and subtle numerical behavior), the description is remarkably complete. It covers the local clip coordinate system, the append/replace semantics, the validation rules, and the exact precision caveats. An agent has everything needed to call this tool correctly without referencing external documentation.

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 critical semantic detail: times are beat-based and clip-local, replace/append behavior, the handling of tolerated keys like note_id, that pitch/start_time/duration are never defaulted, and the validation consequence of using pos/dur. This goes far beyond the schema's per-parameter descriptions and materially affects how an agent should construct the notes array.

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 description opens with 'Write MIDI notes into a Session clip' – a specific verb, resource, and action. It clearly distinguishes from siblings like read_clip_notes (reading), delete_clip (removes clip entirely), and write_automation (writes automation, not notes). The purpose is unambiguous and immediately differentiates the tool.

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 provides explicit guidance on when to use append vs replace, contrasts with delete_clip (empty list with replace keeps clip attributes, delete_clip removes everything), and notes that lists from read_clip_notes can be written back. It also warns that a list with pos/dur keys is refused. This gives clear context and alternatives, leaving nothing to inference.

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