A Model Context Protocol server for Metabase integration, providing comprehensive functionality for dashboard management, question/card management, database operations, user and permission management, collections, and analytics
Complex object parameters (dataset_query, visualization_settings, details, native_parameters, connection_details) are typed as generic 'object' with minimal description of expected structure. LLMs cannot construct valid payloads without examples or nested schema.
Document output schemas for ALL tools. For list_* tools: specify that responses contain arrays with fields like {id, name, description, created_at}. For create_* tools: specify returned object structure. For execute_card: specify column names, data types, row count. Use structured return types, not generic JSON text.
Convert object-typed parameters to explicit nested schemas. For 'dataset_query', provide a minified example schema showing the MBQL or native query structure Metabase expects. For 'details' in create_database_connection, document {host, port, dbname, user, password, ssl} structure.
Implement pagination on list operations: add limit (default 20, max 100) and offset parameters. Return {items: [...], total: N, has_more: bool}. Document in tool descriptions.
Add recovery guidance to error responses. Wrap API errors in McpError with actionable messages. Example: if card_id not found, suggest 'Card not found. Call list_cards() to find available cards, or search_content(query="<name>") to search by name.'
Support natural identifiers (name, email, display names) alongside IDs. Add optional 'card_name' param to execute_card so users can call with 'Sales Dashboard' instead of card_id=42. Implement name-to-ID resolution inside the tool handler.
Missing enums for constrained string parameters. 'display' param in create_card/update_card accepts strings like 'table', 'line', 'bar' but is not declared as an enum, LLMs may hallucinate invalid values. Same for database 'engine' (postgres, mysql, h2) and content 'models' (card, dashboard, etc.).
Destructive operations (delete_card, delete_dashboard with hard_delete=true) lack confirmation/dry-run pattern. No explicit guidance that these are irreversible. LLMs may accidentally delete resources.
Error handling is minimal. Tools throw McpError but responses lack recovery guidance. Example: 'Card not found' should suggest 'Try list_cards() to see available cards' (per pattern:recovery-guide).
No pagination support on list operations. list_cards, list_databases, list_dashboards, list_users, list_collections return raw array without limit/offset params or total count. Large result sets waste context tokens.
No natural-identifier support. Tools require numeric IDs (card_id, database_id, dashboard_id) but descriptions do not explain how to obtain them. Users say 'Show me the sales dashboard', not 'Get dashboard 42'. No lookup-by-name variants offered.
Add dry-run/confirmation for destructive operations. Before delete_card executes a hard_delete, return a confirmation prompt showing what will be deleted (card name, visualization count). Let the agent confirm before proceeding.
Document boolean parameter implications clearly. For hard_delete: 'If false (default), card moves to trash and can be recovered. If true, card is permanently deleted.' For auto_run_queries: 'If true, Metabase auto-runs queries on database changes; false requires manual refresh.'
Add validation error examples to descriptions. For 'display' param, state: 'Must be one of: table, line, bar. Invalid value example: display="pie" → error "Invalid display: pie. Valid types: table, line, bar..."'
Batch variants for tools called in loops. Add add_cards_to_dashboard (accepts array of {card_id, row, col, sizeX, sizeY}) so agents compose one batch call instead of N sequential add_card_to_dashboard calls, reducing latency and token waste.