clip_tools.py•3.96 kB
"""Clip management tools for Ableton MCP."""
from typing import Dict, List, Union
from mcp.server.fastmcp import Context
from ..core import get_ableton_connection
from ..utils.logging import get_logger
logger = get_logger("AbletonMCPServer")
def create_clip(ctx: Context, track_index: int, clip_index: int, length: float = 4.0) -> str:
"""
Create a new MIDI clip in the specified track and clip slot.
Parameters:
- track_index: The index of the track to create the clip in
- clip_index: The index of the clip slot to create the clip in
- length: The length of the clip in beats (default: 4.0)
"""
try:
ableton = get_ableton_connection()
result = ableton.send_command(
"create_clip",
{"track_index": track_index, "clip_index": clip_index, "length": length},
)
return f"Created new clip at track {track_index}, slot {clip_index} with length {length} beats"
except Exception as e:
logger.error(f"Error creating clip: {str(e)}")
return f"Error creating clip: {str(e)}"
def add_notes_to_clip(
ctx: Context,
track_index: int,
clip_index: int,
notes: list[dict[str, 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)}"
def set_clip_name(ctx: Context, track_index: int, clip_index: int, name: str) -> str:
"""
Set the name of a clip.
Parameters:
- track_index: The index of the track containing the clip
- clip_index: The index of the clip slot containing the clip
- name: The new name for the clip
"""
try:
ableton = get_ableton_connection()
result = ableton.send_command(
"set_clip_name",
{"track_index": track_index, "clip_index": clip_index, "name": name},
)
return f"Renamed clip at track {track_index}, slot {clip_index} to '{name}'"
except Exception as e:
logger.error(f"Error setting clip name: {str(e)}")
return f"Error setting clip name: {str(e)}"
def fire_clip(ctx: Context, track_index: int, clip_index: int) -> str:
"""
Start playing a clip.
Parameters:
- track_index: The index of the track containing the clip
- clip_index: The index of the clip slot containing the clip
"""
try:
ableton = get_ableton_connection()
result = ableton.send_command("fire_clip", {"track_index": track_index, "clip_index": clip_index})
return f"Started playing clip at track {track_index}, slot {clip_index}"
except Exception as e:
logger.error(f"Error firing clip: {str(e)}")
return f"Error firing clip: {str(e)}"
def stop_clip(ctx: Context, track_index: int, clip_index: int) -> str:
"""
Stop playing a clip.
Parameters:
- track_index: The index of the track containing the clip
- clip_index: The index of the clip slot containing the clip
"""
try:
ableton = get_ableton_connection()
result = ableton.send_command("stop_clip", {"track_index": track_index, "clip_index": clip_index})
return f"Stopped clip at track {track_index}, slot {clip_index}"
except Exception as e:
logger.error(f"Error stopping clip: {str(e)}")
return f"Error stopping clip: {str(e)}"