MCP server embedded in a Max for Live device — exposes Ableton Live to MCP-compatible agents
Strong tool naming (all verb-prefixed, clear intent). Descriptions are detailed and contextual (avg ~180 chars), exceeding baseline. All 13 tools have explicit input schemas with typed parameters. However, output schemas are not formally documented in the code, descriptions mention return structure (e.g., 'Returns JSON: {...}') but no JSON Schema definitions are visible. Parameter descriptions are comprehensive but some lack explicit constraints (e.g., surface_index range, direction enum values). Error handling guidance is minimal, no recovery hints or actionable error messages visible in tool definitions.
Show the named Live view and focus on it. Pass an empty string ("") to focus the main document view (Session or Arranger, whichever is currently visible). Use get_available_views to see valid names.
List the view names accepted by focus_view / show_view / hide_view / is_view_visible / scroll_view / zoom_view. Returns the constant set: "Browser", "Arranger", "Session", "Detail", "Detail/Clip", "Detail/DeviceChain". Provided so the agent doesn't have to guess names.
List the named controls (buttons, knobs, pads) exposed by a given control surface. Returns JSON array of control name strings. The set varies per controller type — e.g. Push exposes "Play_Button", "Tap_Tempo_Button", encoders, pads. These names are what grab_control / send_midi would target (those primitives are not yet exposed via MCP — read-only inspection only for now).
List the control-surface slots from Live's Tempo & MIDI Preferences. Returns JSON: [{index, type_name, is_connected}, ...]. There are typically 6-7 slots; empty slots have type_name="None" and is_connected=false. Connected slots show the script class name (e.g. "Push2", "Komplete_Kontrol_A", "Launchpad", "MaxForLive"). Use this to discover what hardware the user has set up before adapting suggestions or inspecting controls via get_control_surface_controls.
Output schemas not formally documented. Descriptions mention return structure (e.g., 'Returns JSON: {visible}') but no JSON Schema definitions visible in code. LLMs cannot reliably parse unstructured text descriptions of output.
Numeric parameters lack explicit constraints. 'direction' in scroll_view/zoom_view documented as '0=up, 1=down, 2=left, 3=right' in description but no enum constraint in schema. 'surface_index' has no min/max bounds.
No error handling guidance. Tool descriptions do not explain what happens on failure (e.g., invalid surface_index, view not found, dialog not open). No recovery hints for LLM.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | <=2025-11-25 | v2 |
Return the state of Live's modal dialogs. Returns JSON: {message, button_count, open_count}. `message` is the dialog text (empty string if no dialog is open). `button_count` is the number of buttons in the current dialog (use with press_dialog_button). `open_count` is the total number of stacked dialogs.
Return Live's current view focus and Hot-Swap Mode state. Returns JSON: {browse_mode, focused_document_view}. `browse_mode` is true when Live's Browser is in Hot-Swap Mode for some device (toggled via toggle_browse). `focused_document_view` is 'Session' or 'Arranger' depending on which is visible in the main window.
Hide the named Live view. Pass an empty string ("") for the main document view.
Return whether a Live view is currently visible. Returns JSON: {visible}. Pass an empty string ("") for the main document view.
Press a button in Live's currently-open modal dialog by index. Use get_dialog_state first to read the message + button_count. Indices are 0-based ; pressing closes the dialog and applies the corresponding action (e.g. "Save" / "Don't Save" / "Cancel").
Scroll a scrollable view (Arranger / Browser / Session / Detail/DeviceChain). direction: 0=up, 1=down, 2=left, 3=right. modifier_pressed: when view_name="Arranger" + direction in {left,right} + modifier=true, modifies the selected time region size instead of moving the playback cursor.
Show the named Live view (without changing focus). Pass an empty string ("") for the main document view.
Toggle Live's Hot-Swap Mode for the currently selected device. While active, the Browser is shown and Browser.load_item / browser_load_item replaces the device's content instead of inserting a new one. Call again to deactivate. Read browse_mode via get_view_state to check current state. Programmatic hot-swap sequence: select_device(track, device) → toggle_browse() → browser_load_item(path) → toggle_browse() to swap a preset without manual UI focus.
Zoom a zoomable view (Arrangement / Session). direction: 0=up, 1=down, 2=left, 3=right. modifier_pressed: when view_name="Arrangement" + modifier=true, restricts vertical zoom to the highlighted track. For Session view, behaves identically to scroll_view.
Parameter descriptions for view_name lack clarity on empty string behavior. Documented as 'Empty string = main document view' but not consistently explained across all view tools.
No tool composition guidance. Descriptions mention prerequisites (e.g., 'Call get_control_surfaces first') but do not explain multi-step workflows or dependencies between tools.