spix_playbook_language_list
Retrieve the list of languages supported by Spix playbooks for voice calls, email, and contact management, enabling selection of appropriate language settings.
Instructions
List supported languages
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- src/spix_mcp/registry.py:207-215 (schema)CommandSchema definition for the 'playbook.language.list' command. This is the source-of-truth schema that defines the tool path, HTTP method (GET), API endpoint (/playbooks/languages), CLI usage, and that it is exposed as an MCP tool with 'safe' profile. It has no parameters (path params or query params), just returns the list of supported languages.
CommandSchema( path="playbook.language.list", cli_usage="spix playbook language list", http_method="GET", api_endpoint="/playbooks/languages", mcp_expose="tool", mcp_profile="safe", description="List supported languages", ), - src/spix_mcp/server.py:85-101 (registration)MCP tool registration: the schema at path 'playbook.language.list' (from COMMAND_REGISTRY) is converted to the MCP tool name 'spix_playbook_language_list' via the pattern f'spix_{{schema.path.replace(".", "_")}}'. The tool is registered with its description and inputSchema (built from build_json_schema).
tool_schemas = get_mcp_tools(profile=tool_profile, disabled=disabled_tools) tool_defs: list[Tool] = [] for schema in tool_schemas: # Convert path to tool name: playbook.create -> spix_playbook_create tool_name = f"spix_{schema.path.replace('.', '_')}" tool_defs.append( Tool( name=tool_name, description=schema.description or f"Spix {schema.path}", inputSchema=build_json_schema(schema), ) ) @server.list_tools() async def list_tools() -> list[Tool]: return tool_defs - src/spix_mcp/tools.py:94-203 (handler)The generic tool handler (create_tool_handler) that handles all tool calls including 'spix_playbook_language_list'. It resolves the tool name using get_schema_by_tool_name (which converts 'spix_playbook_language_list' -> 'playbook.language.list'), validates scope/access, builds the endpoint URL (/playbooks/languages), and dispatches a GET request to the backend API. Since playbook.language.list has no params, remaining_args will be empty.
async def create_tool_handler( session: McpSessionContext, tool_name: str, arguments: dict, ) -> list: """Execute an MCP tool call by dispatching to the backend API. This function: 1. Resolves the tool name to a command schema 2. Validates session scope (playbook access, channel access) 3. Builds the API request 4. Dispatches to the backend 5. Returns the response as MCP TextContent Args: session: The MCP session context for scope validation. tool_name: The MCP tool name (e.g., "spix_playbook_create"). arguments: The tool arguments from the MCP client. Returns: List containing a single TextContent with the JSON response. """ # Import here to avoid circular imports and handle missing mcp package try: from mcp.types import TextContent except ImportError: # Fallback for when mcp is not installed class TextContent: # type: ignore[no-redef] def __init__(self, type: str, text: str) -> None: self.type = type self.text = text # Resolve tool name to schema schema = get_schema_by_tool_name(tool_name) if not schema: return [ TextContent( type="text", text=orjson.dumps( {"ok": False, "error": {"code": "unknown_tool", "message": f"Unknown tool: {tool_name}"}} ).decode(), ) ] # Validate tool access (not disabled) try: session.validate_tool_access(schema.path) except Exception as e: from spix_mcp.session import McpScopeError if isinstance(e, McpScopeError): return [TextContent(type="text", text=orjson.dumps({"ok": False, "error": e.to_dict()}).decode())] raise # Validate channel access if applicable channel = infer_channel_from_tool(schema.path) if channel: try: session.validate_channel_access(channel) except Exception as e: from spix_mcp.session import McpScopeError if isinstance(e, McpScopeError): return [TextContent(type="text", text=orjson.dumps({"ok": False, "error": e.to_dict()}).decode())] raise # Handle playbook_id: validate and apply default playbook_id = arguments.get("playbook_id") try: effective_playbook = session.validate_playbook_access(playbook_id) if effective_playbook and not playbook_id: # Apply default playbook arguments["playbook_id"] = effective_playbook except Exception as e: from spix_mcp.session import McpScopeError if isinstance(e, McpScopeError): return [TextContent(type="text", text=orjson.dumps({"ok": False, "error": e.to_dict()}).decode())] raise # Build endpoint URL with path parameters endpoint, remaining_args = build_endpoint_url(schema, arguments) # Dispatch to backend API client = session.client method = schema.http_method.lower() if method == "get": response = await asyncio.to_thread(client.get, endpoint, params=remaining_args if remaining_args else None) elif method == "post": response = await asyncio.to_thread(client.post, endpoint, json=remaining_args if remaining_args else None) elif method == "patch": response = await asyncio.to_thread(client.patch, endpoint, json=remaining_args if remaining_args else None) elif method == "delete": response = await asyncio.to_thread(client.delete, endpoint, params=remaining_args if remaining_args else None) else: response = await asyncio.to_thread(client.get, endpoint) # Build response envelope envelope: dict = {"ok": response.ok, "meta": response.meta} if response.ok: envelope["data"] = response.data if response.pagination: envelope["pagination"] = response.pagination if response.warnings: envelope["warnings"] = response.warnings else: envelope["error"] = response.error return [TextContent(type="text", text=orjson.dumps(envelope).decode())]