Skip to main content
Glama

AbletonMCP

by chaudepark
server.py4.79 kB
# ableton_mcp_server.py from contextlib import asynccontextmanager import json import logging from typing import Any, AsyncIterator, Dict, List, Union from mcp.server.fastmcp import Context, FastMCP from .core import disconnect_global_connection, get_ableton_connection from .tools import ( add_notes_to_clip, create_clip, create_midi_track, fire_clip, get_browser_items_at_path, get_browser_tree, get_session_info, get_track_info, load_drum_kit, load_instrument_or_effect, set_clip_name, set_tempo, set_track_name, start_playback, stop_clip, stop_playback, ) # Configure logging from .utils.logging import setup_logging logger = setup_logging() @asynccontextmanager async def server_lifespan(server: FastMCP) -> AsyncIterator[dict[str, Any]]: """Manage server startup and shutdown lifecycle""" try: logger.info("AbletonMCP server starting up") try: ableton = get_ableton_connection() logger.info("Successfully connected to Ableton on startup") except Exception as e: logger.warning(f"Could not connect to Ableton on startup: {str(e)}") logger.warning("Make sure the Ableton Remote Script is running") yield {} finally: disconnect_global_connection() logger.info("AbletonMCP server shut down") # Create the MCP server with lifespan support mcp = FastMCP( "AbletonMCP", description="Ableton Live integration through the Model Context Protocol", lifespan=server_lifespan, ) # Register all tool functions with MCP decorators @mcp.tool() def get_session_info_tool(ctx: Context) -> str: """Get detailed information about the current Ableton session""" return get_session_info(ctx) @mcp.tool() def get_track_info_tool(ctx: Context, track_index: int) -> str: """Get detailed information about a specific track in Ableton.""" return get_track_info(ctx, track_index) @mcp.tool() def create_midi_track_tool(ctx: Context, index: int = -1) -> str: """Create a new MIDI track in the Ableton session.""" return create_midi_track(ctx, index) @mcp.tool() def set_track_name_tool(ctx: Context, track_index: int, name: str) -> str: """Set the name of a track.""" return set_track_name(ctx, track_index, name) @mcp.tool() def set_tempo_tool(ctx: Context, tempo: float) -> str: """Set the tempo of the Ableton session.""" return set_tempo(ctx, tempo) @mcp.tool() def create_clip_tool(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.""" return create_clip(ctx, track_index, clip_index, length) @mcp.tool() def add_notes_to_clip_tool( ctx: Context, track_index: int, clip_index: int, notes: list[dict[str, int | float | bool]], ) -> str: """Add MIDI notes to a clip.""" return add_notes_to_clip(ctx, track_index, clip_index, notes) @mcp.tool() def set_clip_name_tool(ctx: Context, track_index: int, clip_index: int, name: str) -> str: """Set the name of a clip.""" return set_clip_name(ctx, track_index, clip_index, name) @mcp.tool() def fire_clip_tool(ctx: Context, track_index: int, clip_index: int) -> str: """Start playing a clip.""" return fire_clip(ctx, track_index, clip_index) @mcp.tool() def stop_clip_tool(ctx: Context, track_index: int, clip_index: int) -> str: """Stop playing a clip.""" return stop_clip(ctx, track_index, clip_index) @mcp.tool() def start_playback_tool(ctx: Context) -> str: """Start playing the Ableton session.""" return start_playback(ctx) @mcp.tool() def stop_playback_tool(ctx: Context) -> str: """Stop playing the Ableton session.""" return stop_playback(ctx) @mcp.tool() def load_instrument_or_effect_tool(ctx: Context, track_index: int, uri: str) -> str: """Load an instrument or effect onto a track using its URI.""" return load_instrument_or_effect(ctx, track_index, uri) @mcp.tool() def get_browser_tree_tool(ctx: Context, category_type: str = "all") -> str: """Get a hierarchical tree of browser categories from Ableton.""" return get_browser_tree(ctx, category_type) @mcp.tool() def get_browser_items_at_path_tool(ctx: Context, path: str) -> str: """Get browser items at a specific path in Ableton's browser.""" return get_browser_items_at_path(ctx, path) @mcp.tool() def load_drum_kit_tool(ctx: Context, track_index: int, rack_uri: str, kit_path: str) -> str: """Load a drum rack and then load a specific drum kit into it.""" return load_drum_kit(ctx, track_index, rack_uri, kit_path) # Main execution def main() -> None: """Run the MCP server""" mcp.run() if __name__ == "__main__": main()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/chaudepark/ableton-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server