# Tool Reference

Every Producer Pal tool and its parameters. For what Producer Pal can do in
plain terms, start with [Features](/features).

The AI picks these tools and fills in the parameters itself — you don't call
them by hand. Read this when you want to know exactly what a tool accepts, or
when you're driving Producer Pal from the [REST API](/guide/rest-api) or the
[Agent Skill](/guide/skills).

## Core Tools

### 🔧 Connect (`ppal-connect`) {#ppal-connect}

- Summarizes the state of the current Live Set
- Returns a [skill set](/features#skills) and [context](/guide/context) that
  teach the AI how to use Producer Pal effectively. Standard skills cover the
  full feature set. [Small model mode](/features#small-model-mode) provides
  simplified skills and schemas for less capable models.
- Call it first when a model is driving Producer Pal — that's how the AI learns
  the notation and conventions. A plain REST script can skip it.

<p class="vp-doc-muted">(no parameters)</p>

### 🔧 Context (`ppal-context`) {#ppal-context}

- Read and write the three [context layers](/guide/context): project context
  (notes about this Live Set), global context (preferences that apply to every
  project), and memory (facts AI records about you as you work)

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `action` | `"read"`&nbsp;\|<br>`"write"`&nbsp;\|<br>`"delete"`&nbsp;🐘 | read (default): project/global → the document; memory → the entry named `name`, or the whole index if no `name`. write: replace the document, or create/update the memory entry `name`. delete: remove the memory entry `name`. |
| `scope` | `"project"`&nbsp;\|<br>`"global"`&nbsp;\|<br>`"memory"`&nbsp;🐘 | project (default): facts about THIS Live Set (genre, song structure), always in its context. global: who the user is across ALL projects (style, preferences, high-level goals), always in context. memory: durable facts and rules that matter only in CERTAIN situations, loaded on demand by name. |
| `content` | string | Text to write — project/global: the whole document; memory: the entry body (one fact). Max 10000 chars. |
| `name` 🐘 | string | Memory entry name (read/write/delete on scope:memory). Reuse a name to update, not duplicate. |
| `description` 🐘 | string | Memory entry's one-line recall hook for the index — what's inside and when it's relevant. Required on a memory write. |
| `force` | boolean | Only when a write was skipped for dropping the whole document: true replaces it anyway. |

_🐘 = large model only (hidden in small model mode)_

</details>

## Session Tools

### 🔧 Playback (`ppal-playback`) {#ppal-playback}

- Start/stop playback in Session or Arrangement view
- Play specific scenes or clips
- Set loop points and playback position
- Jump to arrangement locators by ID or name
- Set loop start/end using locators
- Playback always follows the Arrangement (no per-track override)
- Stop all clips or specific clips

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `action` | `"play-arrangement"`&nbsp;\|<br>`"update-arrangement"`&nbsp;\|<br>`"play-scene"`&nbsp;\|<br>`"play-session-clips"`&nbsp;\|<br>`"stop-session-clips"`&nbsp;\|<br>`"stop-all-session-clips"`&nbsp;\|<br>`"stop"`<br><span class="vp-doc-muted">(required)</span> | play-arrangement: from startTime<br>update-arrangement: modify loop<br>play-scene: all clips in scene<br>play-session-clips: by id(s) or slot(s)<br>stop-session-clips: by id(s) or slot(s)<br>stop-all-session-clips: all<br>stop: session and arrangement |
| `startTime` | string | bar\|beat position in arrangement (song meter) |
| `startLocator` 🐘 | string | locator ID or name for start position (e.g., locator-0 or Verse) |
| `loop` | boolean | arrangement loop? |
| `loopStart` | string | bar\|beat position (song meter) |
| `loopStartLocator` 🐘 | string | locator ID or name for loop start |
| `loopEnd` | string | bar\|beat position (song meter) |
| `loopEndLocator` 🐘 | string | locator ID or name for loop end |
| `ids` | string | comma-separated ID(s) for clip operations |
| `slots` | string | session clip slot(s), trackIndex/sceneIndex format, comma-separated (e.g., '0/1' or '0/1,2/3') |
| `sceneIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based scene index for play-scene |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Library (`ppal-library`) {#ppal-library}

::: warning Requires Live 12.4+

The library tools require Ableton Live 12.4 or later. On older versions they
return an error explaining the requirement. Use the version of Max bundled with
Live, or make sure your standalone Max is up to date. See
[Troubleshooting](/support/troubleshooting) for details.

:::

- Search Live's browser library by name, tags, content kind, device kind, or
  source category (User Library, Pack, Built-in, Cloud, Plugin, or your sample
  folder)
- Also includes the user-configured sample folder when set, with results merged
  and de-duplicated against Live's library
- Sort by `use_count` (Live's persistent usage counter — surfaces what you
  actually use most), `mod_date`, or `name`
- Enumerate available tags with `action: "listTags"` so the AI can discover the
  tag vocabulary on your machine, or browse Live's category taxonomy (Sounds,
  Drums, Genres, …) with `action: "listCategories"`
- Run many filtered searches in one call with `action: "searchBatch"` — results
  grouped per query, so the AI can assemble a whole drum kit in one round trip
- List the VST/VST3/AU plug-ins Live knows about with `action: "listPlugins"`
  (filter by query, vendor, format, device kind, or subcategory)
- Rank samples by audio similarity to a seed sample with `action: "findSimilar"`
  — Live's own similarity index, not Producer Pal listening — or group library
  samples with identical audio (re-shipped duplicates) with
  `action: "findDuplicates"` — both can be narrowed with the search filters

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `action` | `"search"`&nbsp;\|<br>`"listTags"`&nbsp;\|<br>`"listCategories"`&nbsp;🐘&nbsp;\|<br>`"searchBatch"`&nbsp;🐘&nbsp;\|<br>`"listPlugins"`&nbsp;🐘&nbsp;\|<br>`"findSimilar"`&nbsp;🐘&nbsp;\|<br>`"findDuplicates"`&nbsp;🐘 | search: filter library items (default) \| listTags: enumerate available tags \| listCategories: browse Live's category taxonomy (Sounds, Drums, Genres, …); pass category to drill into its tags \| searchBatch: run many filtered searches in one call (e.g. build a drum kit), results grouped per query \| listPlugins: list installed VST/VST3/AU plugins Live knows about (filter with query, vendor, format, deviceKind, subcategory) \| findSimilar: rank samples by audio similarity to a seed sample (similarTo); combine with the search filters to constrain candidates \| findDuplicates: group library samples with identical audio (re-shipped duplicates), scoped by the search filters |
| `queries` 🐘 | array | searchBatch only: array of query objects, each with the same filters as a single search (query, tags, kind, type, deviceKind, source, inFolder, sort, limit, verifyPaths) plus an optional label; results are returned in order, grouped per query (capped at 20) |
| `query` | string | name substring (search: supports * as a multi-character wildcard; listPlugins: plain case-insensitive substring) |
| `tags` | string | comma-separated tag names; results must match ALL listed tags (search only) |
| `kind` | `"audio"`&nbsp;\|<br>`"midi"`&nbsp;\|<br>`"live-clip"`&nbsp;🐘&nbsp;\|<br>`"preset"`&nbsp;\|<br>`"device-group"`&nbsp;\|<br>`"m4l-device"`&nbsp;🐘&nbsp;\|<br>`"live-set"`&nbsp;🐘&nbsp;\|<br>`"plugin"`&nbsp;🐘&nbsp;\|<br>`"image"`&nbsp;🐘&nbsp;\|<br>`"video"`&nbsp;🐘&nbsp;\|<br>`"folder"`&nbsp;🐘 | content kind filter (search only; default: audio — the only kind loadable into clips/Simpler today, others are discovery-only). audio=.wav/.aif/.mp3/etc. samples \| midi=.mid files PLUS MIDI Live clips (.alc), so it covers all MIDI content \| live-clip=all .alc Ableton clips (MIDI+audio; each result reports subtype) \| preset=instrument/effect presets \| device-group=.adg device chains (racks) \| m4l-device=.amxd Max for Live devices \| live-set=.als project files \| plugin=VST/AU specs and presets \| image/video=media assets \| folder=directory entries (a DB row type, distinct from source:sampleFolder) |
| `type` | `"loop"`&nbsp;\|<br>`"oneshot"`&nbsp;\|<br>`"impulse-response"` | playback type filter (search only): loop=loops \| oneshot=one-shots (e.g. a kick) \| impulse-response=convolution IRs. Also reported per result as `type`. |
| `category` 🐘 | string | listCategories only: a top-level category name (from listCategories with no category) to drill into; returns its tag names, each usable as a tags filter |
| `similarTo` 🐘 | string | findSimilar only: absolute path of a seed sample (e.g. a path from a prior search) to rank other samples by audio similarity. Combine with the search filters to constrain candidates — e.g. similarTo a kick + tags=Kick for 'more kicks like this one'. Each result carries a `similarity` score (-1 to 1, ~1 = very similar). |
| `deviceKind` 🐘 | `"instrument"`&nbsp;\|<br>`"audiofx"`&nbsp;\|<br>`"midifx"` | device classification filter (search + listPlugins; for listPlugins only instrument/audiofx apply) |
| `vendor` 🐘 | string | vendor/manufacturer substring, case-insensitive (listPlugins only) |
| `format` 🐘 | `"VST"`&nbsp;\|<br>`"VST3"`&nbsp;\|<br>`"AU"` | plugin binary format filter (listPlugins only) |
| `subcategory` 🐘 | string | subcategory substring filter, case-insensitive (listPlugins only; matches any of a plugin's genre/role tags, e.g. reverb, delay, synth). Also reported per result as `subcategories`. |
| `source` | `"sampleFolder"`&nbsp;\|<br>`"user"`&nbsp;\|<br>`"pack"`&nbsp;\|<br>`"builtin"`&nbsp;\|<br>`"cloud"`&nbsp;\|<br>`"plugin"` | where the file lives (search only). sampleFolder=user-configured sample folder on disk (bypasses Live's DB) \| user=your User Library \| pack=installed Packs (factory + 3rd-party) \| builtin=Ableton's Core Library \| cloud=Cloud-stored items \| plugin=installed VST/AU/etc. plugins |
| `inFolder` | string | absolute folder path; returns only immediate children of that folder (search only). Composes with other filters. Case-insensitive (ASCII). Unresolvable paths return no results with a `reason` explaining the path wasn't found. |
| `sort` 🐘 | `"use_count"`&nbsp;\|<br>`"mod_date"`&nbsp;\|<br>`"name"` | sort order (search only); defaults to use_count desc |
| `verifyPaths` 🐘 | boolean | search only: stat each result's path and add pathExists (true/false) so you can skip files moved/deleted since Live last indexed. Off by default (one filesystem check per result). |
| `limit` | number | max results; defaults to 50 (search) or 200 (listTags) |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Select (`ppal-select`) {#ppal-select}

- Read current selection and view state (when no arguments)
  - Returns only non-null fields: selected track, scene, clip, device
  - Rich object shapes with IDs, types, and context (slot, path, etc.)
- Update selection and return only relevant fields
  - Select any object by ID (auto-detects track/scene/clip/device)
  - Select tracks by index/category, scenes by index
  - Select clips by slot position (e.g., `0/3`)
  - Select devices by path (e.g., `t0/d1`)
  - Switch between Session and Arrangement views
  - Auto-switches to session view for scene/clipSlot selection
  - Detail views auto-managed: clip detail opens on clip selection, device
    detail on device selection

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | string | select by ID (auto-detects track/scene/clip/device) |
| `trackIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based track index |
| `trackType` | `"return"`&nbsp;\|<br>`"master"` | omit for audio/midi tracks, or: return, master |
| `sceneIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based scene index |
| `slot` | string | session clip slot: trackIndex/sceneIndex (e.g., '0/3') |
| `devicePath` | string | select device by path (e.g. t0/d1) |
| `openPluginWindow` 🐘 | boolean | open (true) or close (false) a plug-in's (VST/AU) floating editor window; targets the device given by id or devicePath |
| `view` | `"session"`&nbsp;\|<br>`"arrangement"` | main view |

_🐘 = large model only (hidden in small model mode)_

</details>

## Action Tools

### 🔧 Delete (`ppal-delete`) {#ppal-delete}

- Remove tracks, return tracks, scenes, clips, devices, or drum pads
- Bulk delete multiple objects

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `ids` | string | comma-separated ID(s) to delete (must be same type) |
| `path` | string | comma-separated device/drum-pad paths to delete (e.g., 't0/d1', 't1/d0/pC1/d0', 't1/d0/pC1') |
| `type` | `"track"`&nbsp;\|<br>`"scene"`&nbsp;\|<br>`"clip"`&nbsp;\|<br>`"device"`&nbsp;\|<br>`"drum-pad"`<br><span class="vp-doc-muted">(required)</span> | type of objects to delete |

</details>

### 🔧 Duplicate (`ppal-duplicate`) {#ppal-duplicate}

- Copy tracks, scenes, clips, or devices
- Create multiple copies at once
- Copy clips anywhere in the Session, Arrangement, or from Session to
  Arrangement
  - Position in the Arrangement by bar|beat or locator
  - Auto-tile clips to fill longer arrangement durations
- Apply [transforms](/features#transforms) to each duplicated clip (e.g.
  transpose copies, vary velocities) without a separate update step
- Stack MIDI variations on [take lanes](/features#take-lanes) with
  `takeLane: "new"` + transforms — audition alternates at the same arrangement
  position
- Copy devices to any track, return track, or rack chain
- Route duplicated tracks to source instrument for MIDI layering

Note: Return tracks and devices on return tracks cannot be duplicated (Live API
limitation).

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | string <nobr><span class="vp-doc-muted">(required)</span></nobr> | object to duplicate |
| `type` | `"track"`&nbsp;\|<br>`"scene"`&nbsp;\|<br>`"clip"`&nbsp;\|<br>`"device"`<br><span class="vp-doc-muted">(required)</span> | type of object to duplicate |
| `name` | string | name (comma-separated when duplicating multiple) |
| `color` | string | #RRGGBB (comma-separated when duplicating multiple, cycles) |
| `count` 🐘 | integer <nobr><span class="vp-doc-muted">(≥ 1)</span></nobr> | number of copies (tracks/scenes only, ignored for clips/devices) |
| `withoutClips` 🐘 | boolean | exclude clips? |
| `withoutDevices` 🐘 | boolean | exclude devices? |
| `arrangementStart` | string | arrangement bar\|beat position(s) for clips/scenes, comma-separated for multiple (e.g., '1\|1' or '1\|1,2\|1,3\|1'). Song meter |
| `locator` 🐘 | string | arrangement locator ID(s) or name(s), comma-separated for multiple (e.g., 'locator-0' or 'Verse' or 'locator-0,Chorus') |
| `arrangementLength` | string | duration: Nbar (e.g., '4bar'), n&lt;fraction&gt; note value (e.g., 'n/4'), or Nbar+n&lt;fraction&gt; (e.g., '1bar+n/4'). Auto-fills with loops; song meter |
| `toSlot` | string | session destination clip slot(s), trackIndex/sceneIndex format, comma-separated for multiple (e.g., '0/1' or '0/1,2/3') |
| `toPath` | string | device destination path(s), comma-separated for multiple (e.g., 't1/d0' or 't1/d0,t2/d0') |
| `routeToSource` 🐘 | boolean | route new track to source's instrument? (for MIDI layering/polyrhythms) |
| `transforms` 🐘 | string | transform expressions (broadcast across copies; clips only); newline-separated for multiple. Use clip.index / clipseq() for per-copy variation |
| `takeLane` 🐘 | string | arrangement take lane (MIDI clips only): omit/0 = main lane, 1+ = that lane (auto-created), "new" = append a fresh lane for a variation |
| `takeLaneName` 🐘 | string | name for a take lane newly created by this call |

_🐘 = large model only (hidden in small model mode)_

</details>

## Live Set Tools

### 🔧 Read Live Set (`ppal-read-live-set`) {#ppal-read-live-set}

- Get complete Live project overview
- View all tracks and scenes at once, with a clip count per track (clip contents
  come from [Read Track](#ppal-read-track), [Read Scene](#ppal-read-scene), and
  [Read Clip](#ppal-read-clip))
- See tempo, time signature, and scale settings
- View arrangement locators with times and names
- Check what's playing and track states

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `include` | <span class="vp-doc-muted">array of:</span><br>`"tracks"`&nbsp;\|<br>`"scenes"`&nbsp;\|<br>`"routings"`&nbsp;\|<br>`"mixer"`&nbsp;\|<br>`"color"`&nbsp;\|<br>`"locators"`&nbsp;🐘&nbsp;\|<br>`"*"`&nbsp;🐘 | tracks, scenes = lists. routings, mixer, color = detail (use with tracks/scenes). locators = arrangement markers. "*" = all |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Update Live Set (`ppal-update-live-set`) {#ppal-update-live-set}

- Change tempo, time signature, scale
- Create, rename, or delete arrangement locators

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `tempo` | number <nobr><span class="vp-doc-muted">(20–999)</span></nobr> | BPM |
| `timeSignature` | string | N/D (4/4) |
| `scale` | string | "Root ScaleName" ("C Major", "F# Minor", "Bb Dorian"). Empty string disables scale |
| `locatorOperation` 🐘 | `"create"`&nbsp;\|<br>`"delete"`&nbsp;\|<br>`"rename"` | Locator operation |
| `locatorId` 🐘 | string | Locator ID for delete/rename (e.g. locator-0). Positional — shifts if locators are added/removed, so prefer locatorTime or locatorName |
| `locatorTime` 🐘 | string | Bar\|beat position, song meter (required for create, alt ID for delete/rename) |
| `locatorName` 🐘 | string | Name for create/rename, or name-match filter for delete |

_🐘 = large model only (hidden in small model mode)_

</details>

## Track Tools

### 🔧 Create Track (`ppal-create-track`) {#ppal-create-track}

- Add MIDI, audio, or return tracks
- Position tracks exactly where you want
- Set initial mute/solo/arm states

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `trackIndex` | integer | 0-based index, -1 or omit to append |
| `count` 🐘 | integer <nobr><span class="vp-doc-muted">(≥ 1)</span></nobr> | number to create |
| `name` | string | name for all, or comma-separated for each |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than count) |
| `type` | `"midi"`&nbsp;\|<br>`"audio"`&nbsp;\|<br>`"return"` | type |
| `mute` 🐘 | boolean | muted? |
| `solo` 🐘 | boolean | soloed? |
| `arm` 🐘 | boolean | record armed? |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Read Track (`ppal-read-track`) {#ppal-read-track}

- Get detailed track information
- View all clips in Session and Arrangement
- List [take lanes](/features#take-lanes) and their clips (with the
  `arrangement-clips` include)
- See devices, routing options, and drum pad mappings
- Check track states (muted, soloed, armed)
- View mixer properties: gain, pan, panning mode, and send levels

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `trackId` | string | provide this or trackType/trackIndex |
| `trackType` | `"return"`&nbsp;\|<br>`"master"` | return or master (omit for audio/midi tracks, which have independent trackIndexes) |
| `trackIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based index |
| `include` | <span class="vp-doc-muted">array of:</span><br>`"session-clips"`&nbsp;\|<br>`"arrangement-clips"`&nbsp;\|<br>`"notes"`&nbsp;\|<br>`"timing"`&nbsp;\|<br>`"sample"`&nbsp;\|<br>`"devices"`&nbsp;\|<br>`"drum-map"`&nbsp;\|<br>`"routings"`&nbsp;\|<br>`"available-routings"`&nbsp;🐘&nbsp;\|<br>`"mixer"`&nbsp;\|<br>`"color"`&nbsp;\|<br>`"*"`&nbsp;🐘 | session-clips, arrangement-clips = clip lists (arrangement-clips also lists take lanes). notes, timing, sample = clip detail (use with clips). devices, routings, available-routings, mixer = track data. drum-map = the kit's actual pad pitches and names; read it before writing drums. color = track + clip color. "*" = all |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Update Track (`ppal-update-track`) {#ppal-update-track}

- Change track gain (volume), panning, and send levels
- Change mute, solo, arm, I/O routings, and monitoring state
- Change track name and color
- Update multiple tracks at once

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `ids` | string <nobr><span class="vp-doc-muted">(required)</span></nobr> | comma-separated track ID(s) to update |
| `name` | string | name for all, or comma-separated for each (extras keep existing name), ideally unique |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than ids) |
| `gainDb` | number <nobr><span class="vp-doc-muted">(-70–6)</span></nobr> | track gain in dB |
| `pan` | number <nobr><span class="vp-doc-muted">(-1–1)</span></nobr> | pan: -1 (left) to 1 (right) |
| `panningMode` 🐘 | `"stereo"`&nbsp;\|<br>`"split"` | panning mode: stereo or split |
| `leftPan` 🐘 | number <nobr><span class="vp-doc-muted">(-1–1)</span></nobr> | left channel pan in split mode (-1 to 1) |
| `rightPan` 🐘 | number <nobr><span class="vp-doc-muted">(-1–1)</span></nobr> | right channel pan in split mode (-1 to 1) |
| `mute` | boolean | muted? |
| `solo` | boolean | soloed? |
| `arm` | boolean | record armed? |
| `inputRoutingTypeId` 🐘 | string | from availableInputRoutingTypes, set before channel |
| `inputRoutingChannelId` 🐘 | string | from availableInputRoutingChannels |
| `outputRoutingTypeId` 🐘 | string | from availableOutputRoutingTypes, set before channel |
| `outputRoutingChannelId` 🐘 | string | from availableOutputRoutingChannels |
| `monitoringState` 🐘 | `"in"`&nbsp;\|<br>`"auto"`&nbsp;\|<br>`"off"` | input monitoring |
| `sendGainDb` 🐘 | number <nobr><span class="vp-doc-muted">(-70–0)</span></nobr> | send gain in dB, requires sendReturn |
| `sendReturn` 🐘 | string | return track: exact name (e.g., "A-Reverb") or letter (e.g., "A") |

_🐘 = large model only (hidden in small model mode)_

</details>

## Scene Tools

### 🔧 Create Scene (`ppal-create-scene`) {#ppal-create-scene}

- Add new scenes at any position
- Set scene name, color, tempo, and time signature
- Scenes can follow song tempo or have their own
- Ability to capture currently playing clips into a new scene

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `sceneIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based index for new scene(s), shifts existing scenes. Required when capture=false, optional when capture=true |
| `count` 🐘 | integer <nobr><span class="vp-doc-muted">(≥ 1)</span></nobr> | number to create |
| `capture` 🐘 | boolean | copy playing session clips instead of creating empty? |
| `name` | string | name for all, or comma-separated for each |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than count) |
| `tempo` 🐘 | number | BPM (-1 disables when capturing) |
| `timeSignature` 🐘 | string | N/D (4/4) or "disabled" when capturing |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Read Scene (`ppal-read-scene`) {#ppal-read-scene}

- View scene details and all its clips
- Check which clips are playing/triggered
- See scene tempo and time signature

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `sceneId` | string | provide this or sceneIndex |
| `sceneIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based index |
| `include` | <span class="vp-doc-muted">array of:</span><br>`"clips"`&nbsp;\|<br>`"notes"`&nbsp;\|<br>`"sample"`&nbsp;\|<br>`"timing"`&nbsp;\|<br>`"warp"`&nbsp;🐘&nbsp;\|<br>`"color"`&nbsp;\|<br>`"*"`&nbsp;🐘 | clips = clip list. notes, sample, timing, warp = clip detail (use with clips). color = scene + clip color. "*" = all |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Update Scene (`ppal-update-scene`) {#ppal-update-scene}

- Change scene name, color, tempo, and time signature
- Update multiple scenes at once

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `ids` | string <nobr><span class="vp-doc-muted">(required)</span></nobr> | comma-separated scene ID(s) to update |
| `name` | string | name for all, or comma-separated for each (extras keep existing name) |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than ids) |
| `tempo` | number | BPM (-1 disables) |
| `timeSignature` | string | N/D (4/4) or "disabled" |

</details>

## Clip Tools

::: info Parameters shown use the default notation

The `notes` parameter on Create Clip and Update Clip is rewritten to match the
active [notation](/features/midi-notation). The tables below show it in
`bar|beat`, the default — see [MIDI Notation](/features/midi-notation#bar-beat)
for how it reads under [MIDI JSON](/features/midi-notation#midi-json) and
[Stark](/features/midi-notation#stark).

:::

### 🔧 Create Clip (`ppal-create-clip`) {#ppal-create-clip}

- Generate MIDI clips with notes, velocities, and timing using
  [custom notation](/features#custom-music-notation)
- Place clips in Session slots or Arrangement timeline
- Place arrangement clips on [take lanes](/features#take-lanes) with `takeLane`
- Support for probability, velocity ranges, and complex rhythms
- Apply [transforms](/features#transforms) to shape notes with math expressions
- Create audio clips from a sample file with `sampleFile`, and choose whether
  Live warps it with `warping` (see [Audio Clips](#audio-clips))
- Auto-create scenes as needed

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `slot` | string | session clip slot(s): trackIndex/sceneIndex, both 0-based (scene 1 = index 0), comma-separated (e.g., '0/0' or '0/0,0/2,0/5') |
| `trackIndex` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | 0-based track index (arrangement clips) |
| `arrangementStart` | string | arrangement clip bar\|beat position(s), comma-separated for multiple (e.g., '1\|1' or '1\|1,2\|1,3\|3'). Song meter |
| `name` | string | name for all, or comma-separated for each (indexed: session positions first, then arrangement) |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than positions) |
| `timeSignature` | string | N/D (4/4), default: global time signature |
| `start` | string | bar\|beat position where loop/clip region begins (clip meter) |
| `length` | string | duration: Nbar (e.g., '4bar'), n&lt;fraction&gt; note value (e.g., 'n/4'), or Nbar+n&lt;fraction&gt; (e.g., '1bar+n/4'). Clip meter. MIDI only, default: next full bar after latest note. Audio clip length comes from the sample |
| `looping` | boolean | enable looping for the clip |
| `firstStart` 🐘 | string | bar\|beat playback start (looping clips, when different from start; clip meter) |
| `notes` | string | MIDI in bar\|beat notation: v0-127 n&lt;dur&gt; [p0-1] note(s) bar\|beat(s) - MIDI clips only |
| `transforms` 🐘 | string | transform expressions (parameter: expression per line) |
| `sampleFile` | string | absolute path to audio file - audio clips only |
| `warping` | boolean | audio clips only. Omit and Live decides per its Loop/Warp Short Samples setting, often time-stretching the file to the tempo. false = play the file as rendered. The settled state comes back as `warping` |
| `gainDb` | number <nobr><span class="vp-doc-muted">(-70–24)</span></nobr> | audio clip gain in decibels (ignored for MIDI) |
| `pitchShift` | number <nobr><span class="vp-doc-muted">(-48–48)</span></nobr> | audio clip pitch shift in semitones, supports decimals (ignored for MIDI) |
| `warpMode` | `"beats"`&nbsp;\|<br>`"tones"`&nbsp;\|<br>`"texture"`&nbsp;\|<br>`"repitch"`&nbsp;\|<br>`"complex"`&nbsp;\|<br>`"pro"` | audio clip warp mode (ignored for MIDI) |
| `auto` 🐘 | `"play-scene"`&nbsp;\|<br>`"play-clip"` | auto-play the new session clip(s) — worth setting whenever the user will want to hear what you made. play-scene launches the whole scene so the new clip stays in sync with the others (it restarts them; say so first). play-clip fires the clip alone |
| `takeLane` 🐘 | string | arrangement take lane: omit/0 = main lane, 1+ = that lane (auto-created), "new" = append a fresh lane (for variations) |
| `takeLaneName` 🐘 | string | name for a take lane newly created by this call |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Read Clip (`ppal-read-clip`) {#ppal-read-clip}

- Get detailed info about any clip in Session or Arrangement
- Read MIDI notes in [custom notation](/features#custom-music-notation) (C3,
  D#4, etc.)
- Get audio clip gain, pitch, warp settings, and sample info

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `clipId` | string | provide this or slot |
| `slot` | string | session clip slot: trackIndex/sceneIndex (e.g., '0/3'). provide this or clipId |
| `include` | <span class="vp-doc-muted">array of:</span><br>`"sample"`&nbsp;\|<br>`"notes"`&nbsp;\|<br>`"color"`&nbsp;\|<br>`"timing"`&nbsp;\|<br>`"warp"`&nbsp;🐘&nbsp;\|<br>`"*"`&nbsp;🐘 | notes = MIDI data. timing = loop/start/end markers. sample = audio file info (sampleFile, gainDb, pitchShift). warp = warp settings (sampleLength, sampleRate, warping, warpMode). color. "*" = all |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Update Clip (`ppal-update-clip`) {#ppal-update-clip}

- Change clip name, color, and loop settings
- Add/remove MIDI notes using [custom notation](/features#custom-music-notation)
- Apply [transforms](/features#transforms) to modify existing notes and audio
  properties (use `clip.index`/`clipseq()` for per-clip variation when updating
  multiple)
- Change audio clip gain, pitch shift, and warp settings (see
  [Audio Clips](#audio-clips))
- Move clips and change their length in the Arrangement
- Split arrangement clips at specified positions
- Update multiple clips at once

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `ids` | string <nobr><span class="vp-doc-muted">(required)</span></nobr> | comma-separated clip ID(s) to update |
| `name` | string | name for all, or comma-separated for each (extras keep existing name) |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than ids) |
| `timeSignature` | string | N/D (4/4) |
| `start` | string | bar\|beat position where loop/clip region begins (clip meter) |
| `length` | string | duration: Nbar (e.g., '4bar'), n&lt;fraction&gt; note value (e.g., 'n/4' = quarter), or Nbar+n&lt;fraction&gt; (e.g., '1bar+n/4'); clip meter |
| `looping` | boolean | enable looping for the clip |
| `duplicateLoop` | boolean | double the clip length and copy existing notes (and automation envelopes) into the new half (Live's Duplicate Loop). MIDI clips only. Composes with edits in a defined order: start/length/firstStart set the loop region first (select a portion to double; any content past that region is pushed later, not deleted), preTransforms edit the source, then the double; notes/transforms then apply across the full doubled clip |
| `firstStart` 🐘 | string | bar\|beat playback start (looping clips, when different from start; clip meter) |
| `arrangementStart` | string | bar\|beat position (song meter) to move arrangement clip (arrangement clips only) |
| `arrangementLength` | string | duration: Nbar (e.g., '4bar'), n&lt;fraction&gt; note value (e.g., 'n/4'), or Nbar+n&lt;fraction&gt; (e.g., '1bar+n/4'). Arrangement clips only; song meter |
| `toSlot` | string | trackIndex/sceneIndex to move session clip (e.g., '2/3') |
| `split` 🐘 | string | comma-separated bar\|beat split positions, measured from the clip's start (1\|1 = clip start, NOT song time) (e.g., '2\|1, 3\|1') - max 32 points, arrangement clips only; song meter |
| `gainDb` | number <nobr><span class="vp-doc-muted">(-70–24)</span></nobr> | audio clip gain in decibels (ignored for MIDI) |
| `pitchShift` | number <nobr><span class="vp-doc-muted">(-48–48)</span></nobr> | audio clip pitch shift in semitones, supports decimals (ignored for MIDI) |
| `warpMode` | `"beats"`&nbsp;\|<br>`"tones"`&nbsp;\|<br>`"texture"`&nbsp;\|<br>`"repitch"`&nbsp;\|<br>`"complex"`&nbsp;\|<br>`"pro"` | audio clip warp mode (ignored for MIDI) |
| `warping` | boolean | audio clip warping on/off (ignored for MIDI). false resets the region to the whole file and turns looping off; looping:true forces warping back on |
| `notes` | string | MIDI notes in bar\|beat notation: v0-127 n&lt;dur&gt; [p0-1] note(s) bar\|beat(s) - MIDI clips only. MERGES into existing notes (overwrites at same pitch+start - restate a note to edit it in place). To delete/move existing notes or replace a region use preTransforms; don't rewrite the whole clip |
| `transforms` 🐘 | string | transform expressions applied AFTER merging notes (broadcast across ids); newline-separated for multiple. Use clip.index / clipseq() for per-clip variation |
| `preTransforms` | string | transform expressions applied to EXISTING notes BEFORE merging any new notes (broadcast across ids); clear or edit notes already in the clip. v0 deletes (zero velocity): clear a whole bar ('3\|*: v0', \|* wildcard avoids spilling onto the next downbeat), a span ('1\|1-2\|1: v0'), or all ('v0'); also remap a drum lane ('C1: C4'). Works with or without notes |
| `quantize` | number <nobr><span class="vp-doc-muted">(0–1)</span></nobr> | MIDI quantize strength 0-1 (1 = full snap); snaps note starts to quantizeGrid (default 1/16). MIDI clips only |
| `quantizeGrid` | `"1/4"`&nbsp;\|<br>`"1/8"`&nbsp;\|<br>`"1/8T"`&nbsp;\|<br>`"1/8+1/8T"`&nbsp;\|<br>`"1/16"`&nbsp;\|<br>`"1/16T"`&nbsp;\|<br>`"1/16+1/16T"`&nbsp;\|<br>`"1/32"`&nbsp;\|<br>`"n/4"`&nbsp;\|<br>`"n/8"`&nbsp;\|<br>`"n/12"`&nbsp;\|<br>`"n/16"`&nbsp;\|<br>`"n/24"`&nbsp;\|<br>`"n/32"` | grid that note starts snap to: 1/16 (default), 1/8, 1/4, 1/8T, 1/16T, 1/32; n/N note values also accepted (n/12=1/8T, n/24=1/16T); mixed grids 1/8+1/8T and 1/16+1/16T are enum-only |
| `quantizePitch` 🐘 | string | limit quantization to specific pitch (e.g., C3, D#4) |

_🐘 = large model only (hidden in small model mode)_

</details>

### Audio Clips {#audio-clips}

A new audio clip's region comes from its sample, so `start`, `length`,
`firstStart`, and `looping` are MIDI-only on Create Clip and are ignored (with a
warning) alongside a `sampleFile`. `timeSignature` and the audio properties —
`gainDb`, `pitchShift`, `warpMode`, `warping` — do apply. On Update Clip,
`start` and `length` reshape an existing audio clip's region normally.

**Warping.** When you create an audio clip, Live decides for itself whether to
warp the sample, following your **Loop/Warp Short Samples** preference — which
no API can read, so the same call can land differently on two machines. Pass
`warping: false` to play the file exactly as recorded or rendered. Omit it and
Live still decides, but the result reports which way it went.

`warping: false` means the same thing on Create Clip and Update Clip: reset the
region to the whole file and turn looping off, which is what Live does
underneath. Two consequences on Update Clip:

- It erases a `start`/`length` sent in the same call. Reshape the region in a
  follow-up call.
- `looping: true` forces warping back on, so it vetoes a `warping: false` sent
  alongside it, and warns that it did.

**Unwarped clips are measured against the sample.** Live switches a clip's
markers from beats to seconds when warping is off, and reports an unwarped
session clip's `length` as though it were still warped. Producer Pal measures
the region from the markers instead, so a 1.2-second one-shot reads as the beats
it really occupies at your tempo rather than as 1.2 beats — which is also what
keeps [Duplicate](#ppal-duplicate) from tiling copies over audio that's still
sounding.

## Device Tools

### 🔧 Create Device (`ppal-create-device`) {#ppal-create-device}

- Add native Live devices (instruments, MIDI effects, audio effects)
- Place devices on any track type: MIDI, audio, return, or master
- Position devices at a specific index in the device chain
- Create devices inside rack chains or drum pads using path notation
- List the native Live devices
- Load a sample into a Simpler instrument via
  `params: [{name: "sample", value: "<path>"}]`, and set its level with
  `{name: "gainDb", value: <dB>}` (new in Live 12.4)

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `deviceName` | string | device name, omit to list available devices |
| `path` | string | insertion path(s), required with deviceName, comma-separated for multiple (e.g., 't0' or 't0,t1,t0/d0/c0') |
| `name` | string | name for all, or comma-separated for each |
| `params` | array | applied after creation — array of {name, value}. name = param name or read-device id; value in display units (enum string, note name, number). For a Drum Rack, prefix the name with a pad path to address a pad's device, e.g. {name:'pC1/d0/sample', value:'&lt;abs file path&gt;'} loads a sample into pad C1 (auto-creates the pad's Simpler) — build a full kit in one call |

</details>

### 🔧 Read Device (`ppal-read-device`) {#ppal-read-device}

- Get detailed info about any device, including inside rack chains and drum pad
  chains
- List device parameter names and values (the state of knobs, dials, etc)

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `deviceId` | string | Device ID to read |
| `path` | string | path (e.g., 't1/d0', 't1/d0/c0', 't1/d0/pC1', 't1/d0/rc0') |
| `include` | <span class="vp-doc-muted">array of:</span><br>`"actions"`&nbsp;\|<br>`"chains"`&nbsp;\|<br>`"drum-map"`&nbsp;\|<br>`"drum-pads"`&nbsp;🐘&nbsp;\|<br>`"params"`&nbsp;\|<br>`"param-values"`&nbsp;\|<br>`"return-chains"`&nbsp;🐘&nbsp;\|<br>`"sample"`&nbsp;\|<br>`"options"`&nbsp;\|<br>`"*"`&nbsp;🐘 | chains, return-chains, drum-pads = rack contents (use maxDepth). params, param-values = parameters. drum-map = pad names keyed by note (drum name in stark, MIDI number in midi-json). sample = Simpler sample file path (flat top-level field; gainDb and other sample params are in params). actions = device-specific actions for update-device (name, signature, description). options = valid pseudo-param values (paramOptions) + dynamic catalogs for specialized devices (IR files, sidechain sources, wavetables) + Wavetable mod routes. "*" = all |
| `maxDepth` | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | Device tree depth for chains/drum-pads. 0=chains only with deviceCount, 1=direct devices, 2+=deeper |
| `paramSearch` | string | Filter parameters by case-insensitive substring match on name |

_🐘 = large model only (hidden in small model mode)_

</details>

### 🔧 Update Device (`ppal-update-device`) {#ppal-update-device}

- Change device name
- Change device parameter values (control knobs, dials, etc)
- Update multiple devices at once
- Move devices anywhere else in the Live Set, including into racks / wrapping in
  a new rack
- Create, load, delete, revert, and randomize rack macro variations
- A/B Compare with supported devices
- Control chain and drum pad mute and solo state
- Change the choke group and output MIDI note of drum chains
- Load a sample into a Simpler instrument (see
  [Create Device](#ppal-create-device) above)

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `ids` | string | comma-separated ID(s) to update (device, chain, or drum pad) |
| `path` | string | comma-separated path(s) (e.g., 't1/d0', 't1/d0/c0', 't1/d0/pC1') |
| `toPath` | string | move to path (e.g., 't2', 't0/d0/c1', 't0/d0/pD1') |
| `name` | string | name for all, or comma-separated for each (extras keep existing name, not drum pads) |
| `params` | array | array of {name, value}. name = param name or read-device id; value in display units (enum string, note name, number). For a Drum Rack target, prefix the name with a pad path, e.g. {name:'pC1/d0/sample', value:'&lt;abs file path&gt;'} sets pad C1's sample (auto-creates the pad's Simpler) |
| `actions` 🐘 | array | Device-specific action(s), function-call syntax: bare name or name(args). E.g. "reverse", "warpAs(4)", "setModulation('Osc 1 Pos','Env 2',0.5)" |
| `macroVariation` 🐘 | `"create"`&nbsp;\|<br>`"load"`&nbsp;\|<br>`"delete"`&nbsp;\|<br>`"revert"`&nbsp;\|<br>`"randomize"` | Rack only: create/load/delete/revert variation, or randomize macros. load/delete require macroVariationIndex. create always appends. |
| `macroVariationIndex` 🐘 | integer <nobr><span class="vp-doc-muted">(≥ 0)</span></nobr> | Rack only: variation index for load/delete operations (0-based) |
| `macroCount` 🐘 | integer <nobr><span class="vp-doc-muted">(0–16)</span></nobr> | Rack only: set visible macro count (0-16) |
| `abCompare` 🐘 | `"a"`&nbsp;\|<br>`"b"`&nbsp;\|<br>`"save"` | AB Compare: switch to 'a' or 'b' preset, or 'save' current to other slot |
| `mute` | boolean | mute state (chains/drum pads only) |
| `solo` | boolean | solo state (chains/drum pads only) |
| `color` | string | #RRGGBB for all, or comma-separated for each (cycles if fewer than ids; chains only) |
| `chokeGroup` 🐘 | integer <nobr><span class="vp-doc-muted">(0–16)</span></nobr> | choke group 0-16, 0=none (drum chains only) |
| `mappedPitch` 🐘 | string | output MIDI note e.g. 'C3' (drum chains only) |
| `wrapInRack` 🐘 | boolean | Wrap device(s) in a new rack (auto-detects type from device) |

_🐘 = large model only (hidden in small model mode)_

</details>

## Advanced Tools

### 🔧 Live API (`ppal-live-api`) {#ppal-live-api}

Direct access to the
[Ableton Live Object Model](https://docs.cycling74.com/apiref/lom/) for
scripting and debugging.

**Off by default.** Producer Pal's specialized tools are tuned for reliable
results across most models; the raw Live API is low-level and can give weaker
results out of the box, so it's hidden rather than competing with them. It's a
powerful escape hatch for scripting and advanced workflows, especially with
capable coding agents. Enable it on the **Setup** tab of the Producer Pal Max
for Live device, or programmatically via `POST /config` (the `npx producer-pal`
MCP server also accepts a `--live-api` flag). See the REST API's
[Live API section](/guide/rest-api#live-api) for the full operation reference
and examples.

<details>
<summary>Parameters</summary>

| Parameter | Type | Description |
|-----------|------|-------------|
| `path` | string | Optional LiveAPI path (e.g., 'live_set tracks 0') |
| `operations` | array <nobr><span class="vp-doc-muted">(required)</span></nobr> | Array of operations to execute (max 50) |

</details>
