Skip to content

Add clip editing, mixer controls, scene launch, undo, and audio track support#84

Open
LofiFren wants to merge 3 commits intoahujasid:mainfrom
LofiFren:feature/extended-clip-and-mixer-controls
Open

Add clip editing, mixer controls, scene launch, undo, and audio track support#84
LofiFren wants to merge 3 commits intoahujasid:mainfrom
LofiFren:feature/extended-clip-and-mixer-controls

Conversation

@LofiFren
Copy link
Copy Markdown

@LofiFren LofiFren commented Mar 27, 2026

Summary

  • Clip editing: get_clip_notes, remove_notes_from_clip, delete_clip, duplicate_clip_to - enables reading notes back, clearing/editing clips, and duplicating for variations
  • Mixer controls: set_track_volume, set_track_pan, set_track_send - allows mixing directly via MCP
  • Session management: fire_scene (launch entire scene rows), create_audio_track (was referenced but unimplemented), undo

These 11 new tools address workflow gaps discovered while using this already awesome MCP for composition sessions. The biggest pain points were:

  1. No way to read or edit notes in existing clips (had to create new clips instead of fixing)
  2. No way to delete clips (slots accumulate)
  3. No mixer control (could read volume/pan but not set them)
  4. No scene launching (couldn't fire both tracks simultaneously)

All new handlers follow the existing patterns: Remote Script methods with main-thread scheduling, MCP server tool endpoints with proper error handling, and command routing in both _process_command and is_modifying_command.

Test plan

  • Verify get_clip_notes returns correct note data from an existing clip
  • Verify remove_notes_from_clip clears all notes (default params) and targeted ranges
  • Verify delete_clip removes a clip and leaves the slot empty
  • Verify duplicate_clip_to copies clip to an empty target slot
  • Verify set_track_volume and set_track_pan update mixer values
  • Verify set_track_send routes to return tracks
  • Verify fire_scene launches all clips in a scene row
  • Verify create_audio_track creates a track (was previously a dead code path)
  • Verify undo reverses the last action

Summary by CodeRabbit

  • New Features
    • Retrieve clip notes with note count, length, and note details.
    • Remove notes from a clip, delete clips, and duplicate clips between slots.
    • Adjust track volume, pan, and send levels.
    • Launch scenes and report scene names.
    • Create new audio tracks and return their names/indices.
    • Undo the last action.

… support

New MCP tools and Remote Script handlers:

Clip editing:
- get_clip_notes: Read all MIDI notes back from a clip
- remove_notes_from_clip: Remove notes by range (or all notes)
- delete_clip: Delete a clip from a slot entirely
- duplicate_clip_to: Copy a clip to another slot on the same track

Mixer controls:
- set_track_volume: Set track volume (0.0-1.0)
- set_track_pan: Set track panning (-1.0 to 1.0)
- set_track_send: Set send amounts to return tracks

Session management:
- fire_scene: Launch an entire scene row across all tracks
- create_audio_track: Create audio tracks (was referenced but unimplemented)
- undo: Undo the last action in Ableton

These additions address workflow gaps discovered while using this
already awesome MCP, where inability to edit notes, clear clips,
or control mixing forced unnecessary workarounds.
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Add clip editing, mixer controls, and session management tools

✨ Enhancement

Grey Divider

Walkthroughs

Description
• Add 10 new MCP tools for clip editing, mixer control, and session management
• Implement get_clip_notes, remove_notes_from_clip, delete_clip, duplicate_clip_to for clip
  manipulation
• Implement set_track_volume, set_track_pan, set_track_send for mixer control
• Implement fire_scene, create_audio_track, undo for session management
• Update command routing to schedule all new operations on main thread
Diagram
flowchart LR
  MCP["MCP Server Tools"]
  Remote["Remote Script Handlers"]
  Ableton["Ableton Live API"]
  
  MCP -->|get_clip_notes| Remote
  MCP -->|remove_notes_from_clip| Remote
  MCP -->|delete_clip| Remote
  MCP -->|duplicate_clip_to| Remote
  MCP -->|set_track_volume| Remote
  MCP -->|set_track_pan| Remote
  MCP -->|set_track_send| Remote
  MCP -->|fire_scene| Remote
  MCP -->|create_audio_track| Remote
  MCP -->|undo| Remote
  
  Remote -->|clip operations| Ableton
  Remote -->|mixer operations| Ableton
  Remote -->|session operations| Ableton
Loading

Grey Divider

File Changes

1. AbletonMCP_Remote_Script/__init__.py ✨ Enhancement +290/-3

Add Remote Script handlers for clip and mixer operations

• Add 10 new handler methods for clip editing, mixer control, and session management
• Update command routing in _process_command to include all new command types
• Add new commands to main-thread scheduling list for thread-safe execution
• Implement _get_clip_notes, _remove_notes_from_clip, _delete_clip, _duplicate_clip_to for
 clip operations
• Implement _set_track_volume, _set_track_pan, _set_track_send for mixer operations
• Implement _fire_scene, _create_audio_track, _undo for session management

AbletonMCP_Remote_Script/init.py


2. MCP_Server/server.py ✨ Enhancement +213/-1

Add MCP server endpoints for new Ableton operations

• Add 10 new MCP tool endpoints with comprehensive docstrings
• Update is_modifying_command list to include all new command types
• Implement get_clip_notes, remove_notes_from_clip, delete_clip, duplicate_clip_to tools
• Implement set_track_volume, set_track_pan, set_track_send tools
• Implement fire_scene, create_audio_track, undo tools
• All tools include proper error handling and logging

MCP_Server/server.py


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review bot commented Mar 27, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 📐 Spec deviations (0)

Grey Divider


Action required

1. Main-thread timeout race🐞 Bug ⛯ Reliability
Description
Remote Script main-thread scheduling waits only 10 seconds for completion; if it times out, the
response returns an error but the scheduled task may still execute later. Since this PR routes new
destructive commands (remove_notes_from_clip/delete_clip/undo/etc.) through this path, clients can
see a timeout and retry while the original action still applies, causing inconsistent results.
Code

AbletonMCP_Remote_Script/init.py[R229-235]

+            elif command_type in ["create_midi_track", "set_track_name",
+                                 "create_clip", "add_notes_to_clip", "set_clip_name",
                               "set_tempo", "fire_clip", "stop_clip",
-                                 "start_playback", "stop_playback", "load_browser_item"]:
+                                 "start_playback", "stop_playback", "load_browser_item",
+                                 "get_clip_notes", "remove_notes_from_clip", "delete_clip",
+                                 "duplicate_clip_to", "set_track_volume", "set_track_pan",
+                                 "set_track_send", "fire_scene", "create_audio_track", "undo"]:
Evidence
This PR adds the new commands to the list executed via schedule_message(0, main_thread_task). That
path uses a fixed response_queue.get(timeout=10.0); on timeout it returns an error, but there is
no cancellation of the already-scheduled main-thread task, so the action can still happen after the
client receives a timeout.

AbletonMCP_Remote_Script/init.py[229-237]
AbletonMCP_Remote_Script/init.py[338-356]

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

## Issue description
Main-thread scheduled commands time out after 10 seconds on the Remote Script side, but the scheduled callback can still run later. With new destructive commands now routed through this mechanism, callers can receive a timeout error and retry while the original operation still executes, leading to duplicate actions or confusing state.
### Issue Context
- New commands are added to the main-thread scheduled command list.
- The scheduler path uses `response_queue.get(timeout=10.0)` and returns an error on timeout.
- There is no mechanism to prevent the already-scheduled `main_thread_task` from executing after the timeout.
### Fix Focus Areas
- AbletonMCP_Remote_Script/__init__.py[229-237]
- AbletonMCP_Remote_Script/__init__.py[338-356]
### Suggested fix
1. Increase the Remote Script wait timeout for main-thread tasks to a value that safely exceeds worst-case operations (and keep it consistent with the client socket timeout).
2. Consider per-command timeouts (e.g., `get_clip_notes` and browser loads may need longer than simple mixer ops).
3. If you keep a timeout, change semantics to avoid lying about execution (e.g., return `{"status":"pending"}` with a request id and provide a follow-up polling tool), or ensure commands become idempotent / safe to retry.

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



Remediation recommended

2. Unbounded notes response 🐞 Bug ➹ Performance
Description
_get_clip_notes always returns every note in the clip and serializes them into a single JSON
response, which can become extremely large for dense/long clips and risk timeouts or memory/CPU
spikes. This is amplified by the server’s receive loop repeatedly attempting to json-parse the
growing buffer to detect message completeness.
Code

AbletonMCP_Remote_Script/init.py[R685-721]

+    def _get_clip_notes(self, track_index, clip_index):
+        """Get all notes from a clip"""
+        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]
+
+            if clip_index < 0 or clip_index >= len(track.clip_slots):
+                raise IndexError("Clip index out of range")
+
+            clip_slot = track.clip_slots[clip_index]
+
+            if not clip_slot.has_clip:
+                raise Exception("No clip in slot")
+
+            clip = clip_slot.clip
+
+            # Get all notes from the clip
+            # get_notes(from_time, from_pitch, time_span, pitch_span)
+            notes_tuple = clip.get_notes(0.0, 0, clip.length, 128)
+
+            notes = []
+            for note in notes_tuple:
+                notes.append({
+                    "pitch": note[0],
+                    "start_time": note[1],
+                    "duration": note[2],
+                    "velocity": note[3],
+                    "mute": note[4]
+                })
+
+            result = {
+                "note_count": len(notes),
+                "clip_length": clip.length,
+                "notes": notes
+            }
Evidence
The new Remote Script handler fetches all notes across the entire clip length and constructs a full
in-memory list for the response. On the server side, the socket receive code repeatedly calls
json.loads() on the concatenated buffer to check whether a complete JSON object has arrived, which
becomes increasingly expensive as response size grows.

AbletonMCP_Remote_Script/init.py[685-722]
MCP_Server/server.py[46-70]

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

## Issue description
`get_clip_notes` currently fetches **all** MIDI notes from a clip and returns them in one JSON payload. Large clips can generate multi-megabyte responses, stressing memory/CPU and increasing timeout risk. This is exacerbated by the server socket receiver trying `json.loads()` repeatedly on the growing buffer to detect message completion.
### Issue Context
- Remote Script builds an unbounded `notes` list from `clip.get_notes(0.0, 0, clip.length, 128)`.
- Server-side `receive_full_response` attempts `json.loads()` on each receive loop iteration.
### Fix Focus Areas
- AbletonMCP_Remote_Script/__init__.py[685-722]
- MCP_Server/server.py[46-70]
### Suggested fix
1. Extend the command/API to accept range parameters (e.g., `from_time`, `time_span`, `from_pitch`, `pitch_span`) and/or a `max_notes` limit.
2. Return a `truncated: true` flag (and optionally `next_from_time` / continuation token) when limits are hit.
3. (Optional but recommended) Improve socket framing so the server doesn’t repeatedly parse JSON to detect completeness (e.g., prefix messages with length, or append a delimiter and parse once).

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


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 2026

📝 Walkthrough

Walkthrough

Adds 10 Ableton command handlers to the remote script (including clip note retrieval and various clip/track/session mutators), updates main-thread scheduling and timeout cancellation behavior, and exposes 10 corresponding MCP server endpoints that call the remote script and return JSON or confirmation strings.

Changes

Cohort / File(s) Summary
Remote Script Command Handlers
AbletonMCP_Remote_Script/__init__.py
Added 10 internal handlers (_get_clip_notes, _remove_notes_from_clip, _delete_clip, _duplicate_clip_to, _set_track_volume, _set_track_pan, _set_track_send, _fire_scene, _create_audio_track, _undo). Routed get_clip_notes as direct/read-only (no main-thread scheduling); scheduled other mutating commands on the main thread. Implemented queue timeout cancellation via a shared cancelled flag and updated timeout messaging.
Server MCP Tool Endpoints
MCP_Server/server.py
Added 10 MCP tool functions (get_clip_notes, remove_notes_from_clip, delete_clip, duplicate_clip_to, set_track_volume, set_track_pan, set_track_send, fire_scene, create_audio_track, undo) that call ableton.send_command(...) with try/except and return JSON-formatted results or confirmation strings. Extended classification of state-modifying commands in send_command() for pre/post delays and longer socket timeouts.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Server as MCP Server
    participant Remote as Remote Script
    participant Ableton as Ableton Session

    Client->>Server: HTTP RPC / tool call (command, params)
    Server->>Remote: ableton.send_command(command, params)

    alt read-only (get_clip_notes)
        Remote->>Ableton: direct read (get notes)
    else mutating command
        Remote->>Remote: enqueue for main-thread execution
        Remote->>Remote: wait for worker / handle queue timeout (set cancelled)
        Remote->>Ableton: execute handler on main thread (remove/delete/duplicate/set/fire/create/undo)
    end

    Ableton-->>Remote: return result
    Remote-->>Server: forward formatted result
    Server->>Client: respond (JSON or confirmation)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 I hop through clips with tiny paws,
I count the notes and tidy laws,
I copy, pan, and mute, then cheer,
I build a track and make things clear,
A rabbit's nibble — session saved with applause!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and accurately summarizes the main changes: adding 11 new MCP tools for clip editing, mixer controls, scene launching, undo, and audio track creation.
Docstring Coverage ✅ Passed Docstring coverage is 96.30% which is sufficient. The required threshold is 80.00%.

✏️ 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.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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 the current code and only fix it if needed.

Inline comments:
In `@MCP_Server/server.py`:
- Around line 108-111: The list of state-modifying commands in server.py
incorrectly includes "get_clip_notes", causing unnecessary delay and longer
timeout; remove "get_clip_notes" from the is_modifying_command list (the array
that currently contains "start_playback", "stop_playback", ..., "undo") so it is
treated as a read-only command, and run/adjust any related tests or callers that
assume it was modifying state to ensure no other logic depends on its presence
in that list.
🪄 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: 555970b1-154d-425d-bd68-201a20f5cd18

📥 Commits

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

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

…ect execution

Thanks for the thoughtful feedback on the timeout race condition!

1. Move get_clip_notes to direct execution block (alongside get_session_info
   and get_track_info) since it is a read-only operation that does not need
   main-thread scheduling.

2. Add cancellation flag to main-thread scheduled tasks. When the 10s wait
   times out, the flag prevents the queued callback from executing late.
   This avoids the scenario where a destructive command (delete_clip,
   remove_notes, undo) runs after the client already received a timeout
   error and potentially retried.

3. Remove get_clip_notes from is_modifying_command in server.py so reads
   do not incur the artificial delay meant for state-modifying operations.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

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-111: ⚠️ Potential issue | 🟠 Major

Classify load_browser_item as the modifying wire command here.

The tool at Lines 423-426 sends load_browser_item, but this list still marks load_instrument_or_effect instead. That means browser loads still take the read-only path here and miss the extra delay/timeout budget intended for main-thread mutations.

🔧 Suggested fix
         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_browser_item",
             "remove_notes_from_clip", "delete_clip",
             "duplicate_clip_to", "set_track_volume", "set_track_pan",
             "set_track_send", "fire_scene", "undo"
         ]
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@MCP_Server/server.py` around lines 104 - 111, The list computing
is_modifying_command is missing "load_browser_item", causing browser loads to be
treated as read-only; update the array in the is_modifying_command expression
(the list that currently includes "load_instrument_or_effect") to also include
"load_browser_item" so that commands sent by send/load_browser_item take the
modifying path and get the extra delay/timeout budget.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@AbletonMCP_Remote_Script/__init__.py`:
- Around line 243-252: The current cancellation flag (cancelled = [False]) and
the pre-start check inside main_thread_task incorrectly report a timed-out
command as "cancelled" even if it started; change to a three-state tracker
(e.g., state = ["pending"/"running"/"finished"]) alongside cancelled, set state
to "running" immediately at the start of main_thread_task and to "finished" at
the end, and update the timeout/handler logic that currently flips cancelled to
only mark and log a cancellation when state == "pending" (leave commands that
reached "running" or "finished" reported differently or not marked cancelled).
Ensure you update any logging that used cancelled[0] to consult the new state
variable and reference the existing symbols main_thread_task and cancelled to
locate where to modify the timeout handling and pre-start checks.

---

Outside diff comments:
In `@MCP_Server/server.py`:
- Around line 104-111: The list computing is_modifying_command is missing
"load_browser_item", causing browser loads to be treated as read-only; update
the array in the is_modifying_command expression (the list that currently
includes "load_instrument_or_effect") to also include "load_browser_item" so
that commands sent by send/load_browser_item take the modifying path and get the
extra delay/timeout budget.
🪄 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: 622be003-1f68-44df-803f-b01aa4bddc9d

📥 Commits

Reviewing files that changed from the base of the PR and between bbb9805 and 54b7618.

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

Comment on lines +243 to +252
# Cancellation flag: if the wait times out, prevent late execution
# of destructive operations that haven't started yet
cancelled = [False]

# Define a function to execute on the main thread
def main_thread_task():
try:
if cancelled[0]:
self.log_message("Skipping cancelled command: " + command_type)
return
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 | 🟠 Major

Don’t report a timed-out command as cancelled unless it never started.

Line 250 only checks cancelled[0] before the handler begins. If the main-thread task starts just before Line 360 times out, the Ableton mutation will still run, but the client gets told it was cancelled and may safely retry a destructive command. Track pending/running/finished state and only use the cancellation wording when the task was still pending at timeout.

Also applies to: 360-364

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@AbletonMCP_Remote_Script/__init__.py` around lines 243 - 252, The current
cancellation flag (cancelled = [False]) and the pre-start check inside
main_thread_task incorrectly report a timed-out command as "cancelled" even if
it started; change to a three-state tracker (e.g., state =
["pending"/"running"/"finished"]) alongside cancelled, set state to "running"
immediately at the start of main_thread_task and to "finished" at the end, and
update the timeout/handler logic that currently flips cancelled to only mark and
log a cancellation when state == "pending" (leave commands that reached
"running" or "finished" reported differently or not marked cancelled). Ensure
you update any logging that used cancelled[0] to consult the new state variable
and reference the existing symbols main_thread_task and cancelled to locate
where to modify the timeout handling and pre-start checks.

Copy link
Copy Markdown
Author

@LofiFren LofiFren left a comment

Choose a reason for hiding this comment

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

Thanks for the great feedback! Pushed a fix

The MCP server tool sends 'load_browser_item' as the wire command but
the is_modifying_command list had 'load_instrument_or_effect' instead,
causing browser loads to miss the extra delay and timeout budget meant
for state-modifying operations. This was a pre-existing issue, not
introduced by this PR.
@LofiFren
Copy link
Copy Markdown
Author

Thanks for the thorough review! Fixed the load_browser_item / is_modifying_command mismatch - good catch, that was a pre-existing bug.

Regarding the suggestion to replace the boolean cancelled flag with a three-state tracker (pending/running/finished):

We're intentionally keeping the simple boolean. Here's the reasoning:

  • The flag's only job is to prevent a not-yet-started task from executing after the timeout fires. If cancelled[0] is True when the main-thread callback runs, it skips execution. That's the complete contract.
  • If the task has already started or finished, the flag is never checked again - it's irrelevant. The result is already in the queue (or will be shortly), and the timeout handler has already returned an error to the client.
  • The theoretical race window (task starts executing at the exact nanosecond the timeout fires) is negligible under CPython's GIL, and even if it occurred, the outcome is the same as normal completion - the result goes into the queue, nobody reads it, no harm done.
  • A three-state system adds complexity (more mutable state, more branches, more logging) for no change in observable behavior.

Simple code that does the job > clever code that handles theoretical scenarios.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
MCP_Server/server.py (1)

522-524: Consider using explicit conversion flags (file-wide).

Static analysis flags str(e) in f-strings across all new functions. The idiomatic form is f"{e!s}". However, this pattern is consistent with all existing tool endpoints in this file, so changing only the new code would introduce inconsistency.

If you want to address this, it should be done file-wide as a separate cleanup.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@MCP_Server/server.py` around lines 522 - 524, The f-strings in the exception
handler use str(e) which static analysis flags; update the file to consistently
use the explicit conversion flag f"{e!s}" instead of f"{str(e)}" (e.g., the
logger.error and return statements that currently contain "Error getting clip
notes: {str(e)}"), but do this as a file-wide cleanup so the pattern stays
consistent across all endpoints in MCP_Server/server.py rather than changing
only this new handler.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@MCP_Server/server.py`:
- Around line 522-524: The f-strings in the exception handler use str(e) which
static analysis flags; update the file to consistently use the explicit
conversion flag f"{e!s}" instead of f"{str(e)}" (e.g., the logger.error and
return statements that currently contain "Error getting clip notes: {str(e)}"),
but do this as a file-wide cleanup so the pattern stays consistent across all
endpoints in MCP_Server/server.py rather than changing only this new handler.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d4be22f6-2702-414c-abeb-0d8c448cdd64

📥 Commits

Reviewing files that changed from the base of the PR and between 54b7618 and 76591df.

📒 Files selected for processing (1)
  • MCP_Server/server.py

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