Skip to main content
Glama

get_browser_tree

Retrieve a hierarchical tree of browser categories from Ableton Live to organize and navigate instruments, sounds, effects, and drum kits for music production workflows.

Instructions

Get a hierarchical tree of browser categories from Ableton.

Parameters:

  • category_type: Type of categories to get ('all', 'instruments', 'sounds', 'drums', 'audio_effects', 'midi_effects')

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
category_typeNoall

Implementation Reference

  • MCP tool handler for get_browser_tree. Proxies the command to Ableton remote script via socket, receives raw tree data, and formats it into a readable hierarchical string with indentation and paths.
    @mcp.tool() def get_browser_tree(ctx: Context, category_type: str = "all") -> str: """ Get a hierarchical tree of browser categories from Ableton. Parameters: - category_type: Type of categories to get ('all', 'instruments', 'sounds', 'drums', 'audio_effects', 'midi_effects') """ try: ableton = get_ableton_connection() result = ableton.send_command("get_browser_tree", { "category_type": category_type }) # Check if we got any categories if "available_categories" in result and len(result.get("categories", [])) == 0: available_cats = result.get("available_categories", []) return (f"No categories found for '{category_type}'. " f"Available browser categories: {', '.join(available_cats)}") # Format the tree in a more readable way total_folders = result.get("total_folders", 0) formatted_output = f"Browser tree for '{category_type}' (showing {total_folders} folders):\n\n" def format_tree(item, indent=0): output = "" if item: prefix = " " * indent name = item.get("name", "Unknown") path = item.get("path", "") has_more = item.get("has_more", False) # Add this item output += f"{prefix}• {name}" if path: output += f" (path: {path})" if has_more: output += " [...]" output += "\n" # Add children for child in item.get("children", []): output += format_tree(child, indent + 1) return output # Format each category for category in result.get("categories", []): formatted_output += format_tree(category) formatted_output += "\n" return formatted_output except Exception as e: error_msg = str(e) if "Browser is not available" in error_msg: logger.error(f"Browser is not available in Ableton: {error_msg}") return f"Error: The Ableton browser is not available. Make sure Ableton Live is fully loaded and try again." elif "Could not access Live application" in error_msg: logger.error(f"Could not access Live application: {error_msg}") return f"Error: Could not access the Ableton Live application. Make sure Ableton Live is running and the Remote Script is loaded." else: logger.error(f"Error getting browser tree: {error_msg}") return f"Error getting browser tree: {error_msg}"
  • Helper implementation in Ableton remote script that interacts with Live's browser API to build the raw category tree dictionary for specified category_type, handling various browser roots like instruments, sounds, etc.
    def get_browser_tree(self, category_type="all"): """ Get a simplified tree of browser categories. Args: category_type: Type of categories to get ('all', 'instruments', 'sounds', etc.) Returns: Dictionary with the browser tree structure """ try: # Access the application's browser instance instead of creating a new one app = self.application() if not app: raise RuntimeError("Could not access Live application") # Check if browser is available if not hasattr(app, 'browser') or app.browser is None: raise RuntimeError("Browser is not available in the Live application") # Log available browser attributes to help diagnose issues browser_attrs = [attr for attr in dir(app.browser) if not attr.startswith('_')] self.log_message("Available browser attributes: {0}".format(browser_attrs)) result = { "type": category_type, "categories": [], "available_categories": browser_attrs } # Helper function to process a browser item and its children def process_item(item, depth=0): if not item: return None result = { "name": item.name if hasattr(item, 'name') else "Unknown", "is_folder": hasattr(item, 'children') and bool(item.children), "is_device": hasattr(item, 'is_device') and item.is_device, "is_loadable": hasattr(item, 'is_loadable') and item.is_loadable, "uri": item.uri if hasattr(item, 'uri') else None, "children": [] } return result # Process based on category type and available attributes if (category_type == "all" or category_type == "instruments") and hasattr(app.browser, 'instruments'): try: instruments = process_item(app.browser.instruments) if instruments: instruments["name"] = "Instruments" # Ensure consistent naming result["categories"].append(instruments) except Exception as e: self.log_message("Error processing instruments: {0}".format(str(e))) if (category_type == "all" or category_type == "sounds") and hasattr(app.browser, 'sounds'): try: sounds = process_item(app.browser.sounds) if sounds: sounds["name"] = "Sounds" # Ensure consistent naming result["categories"].append(sounds) except Exception as e: self.log_message("Error processing sounds: {0}".format(str(e))) if (category_type == "all" or category_type == "drums") and hasattr(app.browser, 'drums'): try: drums = process_item(app.browser.drums) if drums: drums["name"] = "Drums" # Ensure consistent naming result["categories"].append(drums) except Exception as e: self.log_message("Error processing drums: {0}".format(str(e))) if (category_type == "all" or category_type == "audio_effects") and hasattr(app.browser, 'audio_effects'): try: audio_effects = process_item(app.browser.audio_effects) if audio_effects: audio_effects["name"] = "Audio Effects" # Ensure consistent naming result["categories"].append(audio_effects) except Exception as e: self.log_message("Error processing audio_effects: {0}".format(str(e))) if (category_type == "all" or category_type == "midi_effects") and hasattr(app.browser, 'midi_effects'): try: midi_effects = process_item(app.browser.midi_effects) if midi_effects: midi_effects["name"] = "MIDI Effects" result["categories"].append(midi_effects) except Exception as e: self.log_message("Error processing midi_effects: {0}".format(str(e))) # Try to process other potentially available categories for attr in browser_attrs: if attr not in ['instruments', 'sounds', 'drums', 'audio_effects', 'midi_effects'] and \ (category_type == "all" or category_type == attr): try: item = getattr(app.browser, attr) if hasattr(item, 'children') or hasattr(item, 'name'): category = process_item(item) if category: category["name"] = attr.capitalize() result["categories"].append(category) except Exception as e: self.log_message("Error processing {0}: {1}".format(attr, str(e))) self.log_message("Browser tree generated for {0} with {1} root categories".format( category_type, len(result['categories']))) return result except Exception as e: self.log_message("Error getting browser tree: {0}".format(str(e))) self.log_message(traceback.format_exc()) raise

Latest Blog Posts

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/ahujasid/ableton-mcp'

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