Skip to main content
Glama

darwin_search

Search nix-darwin configuration options for macOS system setup by name and description to find specific settings.

Instructions

Search nix-darwin (macOS) configuration options.

Searches through available nix-darwin options by name and description.

Args: query: The search query string to match against option names and descriptions limit: Maximum number of results to return (default: 20, max: 100)

Returns: Plain text list of matching options with name, type, and description

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYes
limitNo

Implementation Reference

  • The core handler function for the 'darwin_search' MCP tool. Registered via @mcp.tool() decorator. Parses nix-darwin HTML documentation to search for matching configuration options and returns formatted plain text results.
    async def darwin_search(query: str, limit: int = 20) -> str:
        """Search nix-darwin (macOS) configuration options.
    
        Searches through available nix-darwin options by name and description.
    
        Args:
            query: The search query string to match against option names and descriptions
            limit: Maximum number of results to return (default: 20, max: 100)
    
        Returns:
            Plain text list of matching options with name, type, and description
        """
        if not 1 <= limit <= 100:
            return error("Limit must be 1-100")
    
        try:
            options = parse_html_options(DARWIN_URL, query, "", limit)
    
            if not options:
                return f"No nix-darwin options found matching '{query}'"
    
            results = []
            results.append(f"Found {len(options)} nix-darwin options matching '{query}':\n")
    
            for opt in options:
                results.append(f"• {opt['name']}")
                if opt["type"]:
                    results.append(f"  Type: {opt['type']}")
                if opt["description"]:
                    results.append(f"  {opt['description']}")
                results.append("")
    
            return "\n".join(results).strip()
    
        except Exception as e:
            return error(str(e))
  • Key helper function called by darwin_search to fetch and parse HTML from the nix-darwin manual, extracting option names, types, and descriptions matching the query.
    def parse_html_options(url: str, query: str = "", prefix: str = "", limit: int = 100) -> list[dict[str, str]]:
        """Parse options from HTML documentation."""
        try:
            resp = requests.get(url, timeout=30)  # Increase timeout for large docs
            resp.raise_for_status()
            # Use resp.content to let BeautifulSoup handle encoding detection
            # This prevents encoding errors like "unknown encoding: windows-1252"
            soup = BeautifulSoup(resp.content, "html.parser")
            options = []
    
            # Get all dt elements
            dts = soup.find_all("dt")
    
            for dt in dts:
                # Get option name
                name = ""
                if "home-manager" in url:
                    # Home Manager uses anchor IDs like "opt-programs.git.enable"
                    anchor = dt.find("a", id=True)
                    if anchor:
                        anchor_id = anchor.get("id", "")
                        # Remove "opt-" prefix and convert underscores
                        if anchor_id.startswith("opt-"):
                            name = anchor_id[4:]  # Remove "opt-" prefix
                            # Convert _name_ placeholders back to <name>
                            name = name.replace("_name_", "<name>")
                    else:
                        # Fallback to text content
                        name_elem = dt.find(string=True, recursive=False)
                        if name_elem:
                            name = name_elem.strip()
                        else:
                            name = dt.get_text(strip=True)
                else:
                    # Darwin and fallback - use text content
                    name = dt.get_text(strip=True)
    
                # Skip if it doesn't look like an option (must contain a dot)
                # But allow single-word options in some cases
                if "." not in name and len(name.split()) > 1:
                    continue
    
                # Filter by query or prefix
                if query and query.lower() not in name.lower():
                    continue
                if prefix and not (name.startswith(prefix + ".") or name == prefix):
                    continue
    
                # Find the corresponding dd element
                dd = dt.find_next_sibling("dd")
                if dd:
                    # Extract description (first p tag or direct text)
                    desc_elem = dd.find("p")
                    if desc_elem:
                        description = desc_elem.get_text(strip=True)
                    else:
                        # Get first text node, handle None case
                        text = dd.get_text(strip=True)
                        description = text.split("\n")[0] if text else ""
    
                    # Extract type info - look for various patterns
                    type_info = ""
                    # Pattern 1: <span class="term">Type: ...</span>
                    type_elem = dd.find("span", class_="term")
                    if type_elem and "Type:" in type_elem.get_text():
                        type_info = type_elem.get_text(strip=True).replace("Type:", "").strip()
                    # Pattern 2: Look for "Type:" in text
                    elif "Type:" in dd.get_text():
                        text = dd.get_text()
                        type_start = text.find("Type:") + 5
                        type_end = text.find("\n", type_start)
                        if type_end == -1:
                            type_end = len(text)
                        type_info = text[type_start:type_end].strip()
    
                    options.append(
                        {
                            "name": name,
                            "description": description[:200] if len(description) > 200 else description,
                            "type": type_info,
                        }
                    )
    
                    if len(options) >= limit:
                        break
    
            return options
        except Exception as exc:
            raise DocumentParseError(f"Failed to fetch docs: {str(exc)}") from exc
  • URL constant for the nix-darwin documentation used by darwin_search and related tools.
    DARWIN_URL = "https://nix-darwin.github.io/nix-darwin/manual/index.html"

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/utensils/mcp-nixos'

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