Skip to content

Add return_track / duplicate_track / capture_midi / tap_tempo / set_track_color#94

Open
lukegimza wants to merge 1 commit into
ahujasid:mainfrom
lukegimza:add-return-track-and-utility-handlers
Open

Add return_track / duplicate_track / capture_midi / tap_tempo / set_track_color#94
lukegimza wants to merge 1 commit into
ahujasid:mainfrom
lukegimza:add-return-track-and-utility-handlers

Conversation

@lukegimza

@lukegimza lukegimza commented May 14, 2026

Copy link
Copy Markdown
Contributor

Five small additions to expose LOM methods that aren't currently surfaced. All strictly additive — no changes to existing handlers.

Added commands

Command LOM method Purpose
create_return_track Song.create_return_track() Create a return track at the end. Long-requested — see #26.
duplicate_track Song.duplicate_track(index) Duplicate a track (devices + clips).
capture_midi Song.capture_midi() Live's Capture MIDI — recovers MIDI played in the recent past on the armed track.
tap_tempo Song.tap_tempo() Register a tap-tempo tap.
set_track_color track.color_index / track.color Set a track's color by Live's palette index (0–69) or RGB integer.

Implementation

  • Each handler is wired into the existing main_thread_task dispatch (state-changing, needs scheduled execution on Live's main thread).
  • Method bodies follow the existing per-method pattern: validate input, call the LOM, return a small status dict, log on exception.
  • Server-side @mcp.tool() wrappers mirror the existing style — one short function per command that calls ableton.send_command.

Testing

Verified all five on Live 12 Suite (macOS):

  • create_return_track adds a return at the end; return_tracks_count increments correctly.
  • duplicate_track produces a copy at index+1 with devices and clips preserved.
  • capture_midi recovers MIDI from the armed track's recent buffer.
  • tap_tempo accepts a single tap (multiple taps settle to the tap interval).
  • set_track_color accepts both the Live 10+ palette index (preferred) and the legacy RGB integer.

Not included

group_tracks / ungroup_track — Live's Python LOM doesn't expose these even though Song.group_tracks exists as a Push-3 message internally. They're UI-only operations, so no wiring is possible from the Remote Script. Manual Cmd+G remains the only path for grouping.

Summary by CodeRabbit

  • New Features
    • Added MCP tools to create a return track, duplicate a track, trigger Capture MIDI, register a tap-tempo tap, and set a track’s color (palette or RGB).
  • Bug Fixes
    • Enhanced browser item discovery to include additional library locations, improving accessibility across plugins, Max for Live, user libraries, packs, and samples.

Review Change Stack

…rack_color

Five small additions to expose LOM methods that aren't currently surfaced.

- create_return_track — long-requested. Live's LOM has Song.create_return_track(); just wires it through.
- duplicate_track — Song.duplicate_track(index). Useful for layering tracks.
- capture_midi — Song.capture_midi(). Recovers MIDI played in the recent past on the armed track.
- tap_tempo — Song.tap_tempo(). Registers a tap; Live settles to the tap interval.
- set_track_color — accepts color_index (Live 10+ palette 0-69, preferred) or RGB integer (legacy fallback).

Each handler is added to the existing main_thread_task dispatch (state-changing,
needs scheduled execution on Live's main thread). Server-side @mcp.tool() wrappers
mirror the existing style — one short function per command that calls
ableton.send_command.

No changes to existing handlers. Strictly additive.
@coderabbitai

coderabbitai Bot commented May 14, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Adds Ableton operations (create return track, duplicate track, capture MIDI, tap tempo, set track color) implemented as main-thread helpers in AbletonMCP and exposes matching MCP_Server tool endpoints that send commands and return formatted responses.

Changes

Ableton command extensions

Layer / File(s) Summary
Client: main-thread allowlist, dispatcher, and helper implementations
AbletonMCP_Remote_Script/__init__.py
Expanded the main-thread-scheduled command allowlist and dispatcher to route new command types, and added helper methods that create return tracks, duplicate tracks, capture MIDI, register tap-tempo, and set track color with validation and returned values.
Server: new MCP tool endpoints
MCP_Server/server.py
Added create_return_track, duplicate_track, capture_midi, tap_tempo, and set_track_color tool functions that call the persistent Ableton connection, send corresponding commands with parameters, and return formatted success or error strings.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I tapped the tempo, set the hue so bright,
I cloned a track beneath the studio light,
A return was born, MIDI captured in a blink,
Commands hop down the wire before you can think,
Hooray — the patchwork grows, one rabbit-sized tweak at a time!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title lists all five new command types added (return_track, duplicate_track, capture_midi, tap_tempo, set_track_color), which directly aligns with the main changes summarized in the raw_summary and PR objectives.
Docstring Coverage ✅ Passed Docstring coverage is 93.75% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Fix browser item URI lookup for plugins and additional categories

🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Extend browser item URI lookup to include plugins and additional categories
• Add hasattr guards to safely access optional browser attributes
• Fix issue where URIs from get_browser_items_at_path for plugins failed to load
• Align URI lookup coverage with available browser navigation paths
Diagram
flowchart LR
  A["_find_browser_item_by_uri"] -->|"walks categories"| B["instruments, sounds, drums,<br/>audio_effects, midi_effects"]
  A -->|"NEW: walks extra categories"| C["plugins, max_for_live,<br/>user_library, packs, samples"]
  B -->|"returns"| D["BrowserItem or None"]
  C -->|"returns"| D
  D -->|"enables"| E["load_browser_item for plugins"]
Loading

Grey Divider

File Changes

1. AbletonMCP_Remote_Script/__init__.py 🐞 Bug fix +11/-2

Extend browser URI lookup to additional categories

• Extended _find_browser_item_by_uri to walk additional browser categories: plugins,
 max_for_live, user_library, packs, and samples
• Added hasattr guards to safely check for optional attributes before accessing them
• Wrapped attribute access in try-except to gracefully handle any access failures
• Added explanatory comment referencing issue #79 and #47

AbletonMCP_Remote_Script/init.py


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented May 14, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0)

Grey Divider


Remediation recommended

1. Swallowed category access errors 🐞 Bug ☼ Reliability
Description
_find_browser_item_by_uri swallows exceptions while reading extra browser root categories, so
failures become silent and valid URIs may incorrectly appear “not found” with no log evidence. This
bypasses the function’s outer error logging and is inconsistent with nearby browser attribute access
that logs exceptions.
Code

AbletonMCP_Remote_Script/init.py[R785-790]

+                for extra_attr in ('plugins', 'max_for_live', 'user_library', 'packs', 'samples'):
+                    if hasattr(browser_or_item, extra_attr):
+                        try:
+                            categories.append(getattr(browser_or_item, extra_attr))
+                        except Exception:
+                            pass
Evidence
The new inner try/except silently discards exceptions during getattr(browser_or_item, extra_attr),
which prevents the outer except in _find_browser_item_by_uri from logging the underlying
problem. Elsewhere in the same module, dynamic browser attribute reads are logged when they fail,
showing an established observability pattern that this new code breaks.

AbletonMCP_Remote_Script/init.py[761-810]
AbletonMCP_Remote_Script/init.py[925-938]
AbletonMCP_Remote_Script/init.py[996-1005]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`_find_browser_item_by_uri` adds extra root categories but wraps `getattr()` in `except Exception: pass`, hiding failures and preventing the outer handler from logging root causes.

## Issue Context
This method is used to resolve URIs for browser loading; when an attribute access throws, the search silently skips that category and later errors surface as “item not found” without diagnostics.

## Fix Focus Areas
- AbletonMCP_Remote_Script/__init__.py[782-810]
- AbletonMCP_Remote_Script/__init__.py[925-938]

## Suggested change
- Replace the inner `except Exception: pass` with at least a `self.log_message(...)` including `extra_attr` and exception details, then continue.
- Prefer catching only expected exceptions (if known) so unexpected failures still bubble to the outer logger.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Expanded main-thread browser scan 🐞 Bug ➹ Performance
Description
The URI lookup now always traverses additional top-level browser categories, increasing the
worst-case work per lookup and making main-thread load_browser_item requests more likely to exceed
the hard-coded 10s wait timeout. When the timeout triggers, the client gets a timeout error even
though the main-thread task may still be running.
Code

AbletonMCP_Remote_Script/init.py[R782-797]

+                # Also walk plugins / max_for_live / user_library / packs / samples
+                # so URIs from get_browser_items_at_path for plugins actually load.
+                # — lukegimza, 2026-05-14
+                for extra_attr in ('plugins', 'max_for_live', 'user_library', 'packs', 'samples'):
+                    if hasattr(browser_or_item, extra_attr):
+                        try:
+                            categories.append(getattr(browser_or_item, extra_attr))
+                        except Exception:
+                            pass
+
                for category in categories:
                    item = self._find_browser_item_by_uri(category, uri, max_depth, current_depth + 1)
                    if item:
                        return item
-                
+
                return None
Evidence
The diff adds five more top-level roots to the recursive traversal. load_browser_item is
dispatched onto Live’s main thread and _process_command waits for completion with a fixed
queue.get(timeout=10.0), so increased traversal cost directly increases the chance of hitting that
timeout under larger trees.

AbletonMCP_Remote_Script/init.py[761-807]
AbletonMCP_Remote_Script/init.py[782-797]
AbletonMCP_Remote_Script/init.py[228-311]
AbletonMCP_Remote_Script/init.py[726-759]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Adding more root categories increases recursive traversal work in `_find_browser_item_by_uri`. `load_browser_item` executes on the main thread and the caller only waits 10 seconds, so slower searches can lead to user-visible timeouts.

## Issue Context
The search is recursive across categories and children with no caching/visited set, and it’s invoked from the main-thread scheduled path for state-changing operations.

## Fix Focus Areas
- AbletonMCP_Remote_Script/__init__.py[228-311]
- AbletonMCP_Remote_Script/__init__.py[726-759]
- AbletonMCP_Remote_Script/__init__.py[761-807]

## Suggested change
- Add a small URI->item cache (even per-request) to avoid repeated deep scans.
- Consider a node-visit budget / early-exit guard (e.g., max nodes scanned) in addition to `max_depth`.
- If possible, narrow roots based on URI prefix/namespace instead of scanning all roots every time.
- If scan remains potentially slow, increase timeout or return progress/error that indicates scan exceeded limits (so it’s distinguishable from “not found”).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Advisory comments

3. Signed dated inline comment 🐞 Bug ⚙ Maintainability
Description
The added comment contains a personal signature/date, which will go stale and adds noise to future
diffs without improving behavior. Attribution belongs in git history; keep only the functional
rationale in the comment.
Code

AbletonMCP_Remote_Script/init.py[R782-785]

+                # Also walk plugins / max_for_live / user_library / packs / samples
+                # so URIs from get_browser_items_at_path for plugins actually load.
+                # — lukegimza, 2026-05-14
+                for extra_attr in ('plugins', 'max_for_live', 'user_library', 'packs', 'samples'):
Evidence
The new comment line includes a specific author and date, which is unrelated to runtime behavior and
will age poorly.

AbletonMCP_Remote_Script/init.py[782-785]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Inline signature/date comments become stale and create unnecessary churn in diffs.

## Issue Context
The explanatory part of the comment is useful; only the attribution/date is problematic.

## Fix Focus Areas
- AbletonMCP_Remote_Script/__init__.py[782-785]

## Suggested change
- Delete the trailing signature/date line and keep the rationale for why extra categories are walked.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AbletonMCP_Remote_Script/__init__.py`:
- Around line 787-790: The code currently swallows all exceptions when looking
up optional attributes (categories.append(getattr(browser_or_item, extra_attr)))
which hides failures; change the except block to catch Exception as e and log
the failure (including extra_attr and a representation of browser_or_item and
the exception details) before continuing so URI resolution issues are
diagnosable—use an existing logger or the logging module and prefer
logger.warning or logger.exception to record the context and stack/err text
while leaving the flow unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 42ff9b8a-6a77-46e4-929a-c7602d99e284

📥 Commits

Reviewing files that changed from the base of the PR and between e008328 and 9415157.

📒 Files selected for processing (1)
  • AbletonMCP_Remote_Script/__init__.py

Comment thread AbletonMCP_Remote_Script/__init__.py Outdated
Comment on lines +787 to +790
try:
categories.append(getattr(browser_or_item, extra_attr))
except Exception:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Don’t silently swallow optional-category lookup failures.

If an optional browser root access fails here, URI resolution quietly loses coverage with no trace. Log and continue so failures are diagnosable.

Proposed fix
                 for extra_attr in ('plugins', 'max_for_live', 'user_library', 'packs', 'samples'):
                     if hasattr(browser_or_item, extra_attr):
                         try:
                             categories.append(getattr(browser_or_item, extra_attr))
-                        except Exception:
-                            pass
+                        except Exception as e:
+                            self.log_message(
+                                "Skipping browser root '{0}': {1}".format(extra_attr, str(e))
+                            )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try:
categories.append(getattr(browser_or_item, extra_attr))
except Exception:
pass
try:
categories.append(getattr(browser_or_item, extra_attr))
except Exception as e:
self.log_message(
"Skipping browser root '{0}': {1}".format(extra_attr, str(e))
)
🧰 Tools
🪛 Ruff (0.15.12)

[error] 789-790: try-except-pass detected, consider logging the exception

(S110)


[warning] 789-789: Do not catch blind exception: Exception

(BLE001)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AbletonMCP_Remote_Script/__init__.py` around lines 787 - 790, The code
currently swallows all exceptions when looking up optional attributes
(categories.append(getattr(browser_or_item, extra_attr))) which hides failures;
change the except block to catch Exception as e and log the failure (including
extra_attr and a representation of browser_or_item and the exception details)
before continuing so URI resolution issues are diagnosable—use an existing
logger or the logging module and prefer logger.warning or logger.exception to
record the context and stack/err text while leaving the flow unchanged.

@lukegimza lukegimza force-pushed the add-return-track-and-utility-handlers branch from 9415157 to a85de1f Compare May 14, 2026 19:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
MCP_Server/server.py (1)

104-109: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add the new state-mutating commands to is_modifying_command.

The new commands (create_return_track, duplicate_track, set_track_color, and arguably capture_midi/tap_tempo) all modify Live state but are not in this allowlist, so they bypass the 100ms pre/post buffer and the extended 15s timeout that other mutators rely on. The Remote Script already routes them through the main-thread queue (see AbletonMCP_Remote_Script/__init__.py lines 229-234), so it is worth keeping the two sides in sync.

♻️ Proposed update
         is_modifying_command = command_type in [
             "create_midi_track", "create_audio_track", "set_track_name",
             "create_clip", "add_notes_to_clip", "set_clip_name",
             "set_tempo", "fire_clip", "stop_clip", "set_device_parameter",
-            "start_playback", "stop_playback", "load_instrument_or_effect"
+            "start_playback", "stop_playback", "load_instrument_or_effect",
+            "create_return_track", "duplicate_track", "set_track_color",
+            "capture_midi", "tap_tempo"
         ]
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@MCP_Server/server.py` around lines 104 - 109, The is_modifying_command
allowlist in MCP_Server/server.py currently omits several Live state-mutating
commands; update the list used to compute is_modifying_command to include
"create_return_track", "duplicate_track", "set_track_color" and also consider
adding "capture_midi" and "tap_tempo" if you want them treated the same way;
modify the array literal where is_modifying_command is assigned so these string
command names are present (the variable name is is_modifying_command and the
surrounding context checks command_type), ensuring these commands will use the
same 100ms pre/post buffer and extended 15s timeout behavior as the other
mutators.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AbletonMCP_Remote_Script/__init__.py`:
- Around line 704-730: The method _set_track_color currently only checks
color_index >= 0 but not the upper bound; add a range check such that if
color_index is provided it must be between 0 and 69 inclusive (and raise
ValueError with a clear message if out of range) before assigning
track.color_index, leaving the existing fallback to track.color intact; update
the validation around color_index/int conversion near the start of
_set_track_color and ensure the error is logged via self.log_message and
re-raised as the existing except block does.

---

Outside diff comments:
In `@MCP_Server/server.py`:
- Around line 104-109: The is_modifying_command allowlist in
MCP_Server/server.py currently omits several Live state-mutating commands;
update the list used to compute is_modifying_command to include
"create_return_track", "duplicate_track", "set_track_color" and also consider
adding "capture_midi" and "tap_tempo" if you want them treated the same way;
modify the array literal where is_modifying_command is assigned so these string
command names are present (the variable name is is_modifying_command and the
surrounding context checks command_type), ensuring these commands will use the
same 100ms pre/post buffer and extended 15s timeout behavior as the other
mutators.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3440d89-00af-4722-9a8c-b8df256bd716

📥 Commits

Reviewing files that changed from the base of the PR and between 9415157 and a85de1f.

📒 Files selected for processing (2)
  • AbletonMCP_Remote_Script/__init__.py
  • MCP_Server/server.py

Comment on lines +704 to +730
def _set_track_color(self, track_index, color_index, color):
"""Set track color.

``color_index`` is the preferred Live 10+ palette index (0-69).
``color`` (RGB integer 0xRRGGBB) is the legacy fallback.
Pass -1 for whichever you're not using.
"""
try:
if track_index < 0 or track_index >= len(self._song.tracks):
raise IndexError("Track index out of range")
track = self._song.tracks[track_index]
color_index = int(color_index)
color = int(color)
if color_index >= 0:
track.color_index = color_index
elif color >= 0:
track.color = color
else:
raise ValueError("Provide color_index (0-69) or color (RGB int).")
return {
"track_index": track_index,
"color_index": getattr(track, 'color_index', None),
"color": getattr(track, 'color', None),
}
except Exception as e:
self.log_message("Error setting track color: " + str(e))
raise

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Ableton Live Object Model track.color_index valid range palette

💡 Result:

In Ableton Live's Live Object Model (LOM), used in Max for Live and Python Remote Scripts APIs, the Track object has a 'color_index' property, which is an integer representing the index of the track's color in Ableton's predefined color palette [1][2][3]. The valid range for track.color_index is 0 to 69 (inclusive), corresponding to the 70 colors available in the palette as of Live 11 and later [4][5][6]. This is evidenced by Ableton Remote Scripts for controllers like APC64 mapping color_index 0-69 to specific RGB values [5], Python scripts assigning indices up to 69 [6][7], and user reports confirming 70 selectable colors [4][8]. Setting color_index to values outside this range may snap to the nearest palette color or be invalid, similar to how arbitrary RGB values are quantized to the palette when setting the 'color' property (an int in 0x00rrggbb format) [9][2]. Official Cycling '74 LOM docs confirm the property exists but do not specify the range explicitly [2].

Citations:


🏁 Script executed:

# Search for master track or return track color handling in the file
rg -n "master|return" AbletonMCP_Remote_Script/__init__.py | head -30

# Also search for other color-related methods
rg -n "def.*color" AbletonMCP_Remote_Script/__init__.py

Repository: ahujasid/ableton-mcp

Length of output: 1525


🏁 Script executed:

# Check if there are other methods that set colors on master or return tracks
rg -A 10 "def.*color" AbletonMCP_Remote_Script/__init__.py

# Look for any code that sets color on master_track or return_tracks
rg "master_track.*color|return_tracks.*color" AbletonMCP_Remote_Script/__init__.py

Repository: ahujasid/ableton-mcp

Length of output: 553


🏁 Script executed:

# Check what track operations are available and their scope
rg -B 2 -A 15 "def _get_track_info|def _set_track" AbletonMCP_Remote_Script/__init__.py | head -60

# Also check the overall structure of track handling
rg -n "_song\.tracks|_song\.return_tracks|_song\.master_track" AbletonMCP_Remote_Script/__init__.py | head -20

Repository: ahujasid/ableton-mcp

Length of output: 3353


Validate color_index upper bound (0-69).

The color_index parameter is checked for >= 0 but not against the upper bound of 69. Ableton Live's palette supports exactly 70 colors (indices 0–69). A simple range check prevents silent truncation or unexpected behavior when an out-of-range index is passed:

Proposed range guard
             track = self._song.tracks[track_index]
             color_index = int(color_index)
             color = int(color)
             if color_index >= 0:
+                if color_index > 69:
+                    raise ValueError("color_index must be in 0-69")
                 track.color_index = color_index
             elif color >= 0:
                 track.color = color
             else:
                 raise ValueError("Provide color_index (0-69) or color (RGB int).")

Note: This method only indexes self._song.tracks (regular tracks) and does not support return or master tracks, though they also have color_index properties. If master/return track coloring is needed, either expand the lookup or document this scope in the docstring.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@AbletonMCP_Remote_Script/__init__.py` around lines 704 - 730, The method
_set_track_color currently only checks color_index >= 0 but not the upper bound;
add a range check such that if color_index is provided it must be between 0 and
69 inclusive (and raise ValueError with a clear message if out of range) before
assigning track.color_index, leaving the existing fallback to track.color
intact; update the validation around color_index/int conversion near the start
of _set_track_color and ensure the error is logged via self.log_message and
re-raised as the existing except block does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant