add_notes_to_clip
Insert MIDI notes into a specific clip on Ableton Live tracks. Specify track and clip indices, along with note details like pitch, start time, duration, velocity, and mute status.
Instructions
Add MIDI notes to a clip.
Parameters:
track_index: The index of the track containing the clip
clip_index: The index of the clip slot containing the clip
notes: List of note dictionaries, each with pitch, start_time, duration, velocity, and mute
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| clip_index | Yes | ||
| notes | Yes | ||
| track_index | Yes |
Implementation Reference
- MCP_Server/server.py:344-370 (handler)MCP tool handler for 'add_notes_to_clip'. Proxies the parameters to the Ableton remote script via socket connection and returns a success message with note count.@mcp.tool() def add_notes_to_clip( ctx: Context, track_index: int, clip_index: int, notes: List[Dict[str, Union[int, float, bool]]] ) -> str: """ Add MIDI notes to a clip. Parameters: - track_index: The index of the track containing the clip - clip_index: The index of the clip slot containing the clip - notes: List of note dictionaries, each with pitch, start_time, duration, velocity, and mute """ try: ableton = get_ableton_connection() result = ableton.send_command("add_notes_to_clip", { "track_index": track_index, "clip_index": clip_index, "notes": notes }) return f"Added {len(notes)} notes to clip at track {track_index}, slot {clip_index}" except Exception as e: logger.error(f"Error adding notes to clip: {str(e)}") return f"Error adding notes to clip: {str(e)}"
- Core helper function in Ableton remote script that validates inputs, converts note data, and uses Live API clip.set_notes() to add MIDI notes to the specified clip.def _add_notes_to_clip(self, track_index, clip_index, notes): """Add MIDI notes to 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 # Convert note data to Live's format live_notes = [] for note in notes: pitch = note.get("pitch", 60) start_time = note.get("start_time", 0.0) duration = note.get("duration", 0.25) velocity = note.get("velocity", 100) mute = note.get("mute", False) live_notes.append((pitch, start_time, duration, velocity, mute)) # Add the notes clip.set_notes(tuple(live_notes)) result = { "note_count": len(notes) } return result except Exception as e: self.log_message("Error adding notes to clip: " + str(e)) raise
- MCP_Server/server.py:351-358 (schema)Docstring defining the input schema/parameters for the tool: track_index (int), clip_index (int), notes (list of dicts with pitch, start_time, duration, velocity, mute). Also function signature provides type hints.""" Add MIDI notes to a clip. Parameters: - track_index: The index of the track containing the clip - clip_index: The index of the clip slot containing the clip - notes: List of note dictionaries, each with pitch, start_time, duration, velocity, and mute """
- MCP_Server/server.py:104-108 (registration)List identifying 'add_notes_to_clip' as a state-modifying command that requires processing delays in the AbletonConnection.send_command method.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"
- Dispatch logic in remote script's _process_command that extracts parameters and calls the _add_notes_to_clip helper for the 'add_notes_to_clip' command.elif command_type == "add_notes_to_clip": track_index = params.get("track_index", 0) clip_index = params.get("clip_index", 0) notes = params.get("notes", []) result = self._add_notes_to_clip(track_index, clip_index, notes) elif command_type == "set_clip_name":