Metabase

oficial

Servidor MCP oficial de Metabase para buscar datos, construir consultas en la capa semántica y visualizar resultados a través de clientes MCP.

¿Qué puedes hacer con Metabase MCP?

  • Buscar y recuperar contenido — Pídele a tu asistente que encuentre preguntas, paneles o modelos en Metabase usando la herramienta search, y luego obtén los detalles con get_content.
  • Ejecutar consultas y visualizar resultados — Haz que tu asistente ejecute consultas estructuradas mediante execute_query o SQL sin procesar con execute_sql, y luego renderice los resultados como gráficos interactivos usando visualize_query.
  • Crear y gestionar paneles — Indícale a tu asistente que cree o actualice paneles y sus diseños con dashboard_write, o que duplique contenido existente en colecciones mediante duplicate_content.
  • Configurar alertas y suscripciones — Pídele a tu asistente que cree alertas programadas para preguntas guardadas con alert_write o que configure suscripciones por correo electrónico para paneles usando subscription_write.
  • Explorar la jerarquía de datos — Dirige a tu asistente para que navegue por bases de datos, esquemas, tablas y campos a través de browse_data, o que recorra colecciones de forma estructural con browse_collection.

Documentación

Servidor MCP de Metabase

Metabase incluye un servidor integrado de Model Context Protocol (MCP) que permite a los clientes de IA conectarse directamente a una instancia de Metabase. Utiliza el https://modelcontextprotocol.io/specification/2025-03-26/basic/transports#streamable-http y se basa en la Agent API de Metabase para exponer herramientas de búsqueda, navegación, consultas, visualización y creación/actualización de contenido, todo limitado a los permisos del usuario que se conecta.

Endpoint

El servidor MCP está disponible en:

https://{your-metabase.example.com}/api/metabase-mcp

La ruta heredada /api/mcp sigue funcionando como alias para clientes existentes, pero /api/metabase-mcp es la URL canónica que se debe anunciar.

Conexión de un cliente

Apunta cualquier cliente compatible con MCP al endpoint /api/metabase-mcp. Por ejemplo, con Claude Code:

claude mcp add metabase https://{your-metabase.example.com}/api/metabase-mcp --transport streamable-http

Para Claude Desktop, crea un conector personalizado usando la misma URL.

Para Cursor, abre Settings > MCP y añade un nuevo servidor con el tipo configurado como streamable-http y la URL:

https://{your-metabase.example.com}/api/metabase-mcp

Autenticación

Los clientes MCP se autentican mediante OAuth 2.0. Metabase ejecuta su propio servidor OAuth integrado; no se necesita ningún proveedor externo.

El flujo para una primera conexión:

  1. El cliente descubre los endpoints OAuth de Metabase.
  2. El cliente se registra con Metabase.
  3. El usuario es redirigido a Metabase para iniciar sesión y aprobar la conexión.
  4. El cliente recibe un token de acceso limitado a los permisos del usuario en Metabase.

Las sesiones basadas en navegador (autenticación por cookies), las claves API y los tokens mb:full no tienen alcance MCP, por lo que pueden conectarse pero no pueden llamar a ninguna herramienta con alcance.

Alcances

Los tokens de acceso tienen alcances que limitan qué herramientas puede usar un cliente:

AlcanceHerramientas que otorga
agent:content:readbrowse_collection, browse_data, get_content, get_parameter_values, glossary, learn, search y el recurso de datos catalog://metabase/fields (ver Recursos)
agent:content:writebookmark_content, collection_write, dashboard_write, document_write, duplicate_content, measure_write, metric_write, question_write, segment_write
agent:delivery:writealert_write, subscription_write
agent:query:runexecute_query, refresh_ui_credential, render_drill_through, run_saved_question, visualize_query
agent:sql:runexecute_sql

Una herramienta coincide solo con el alcance exacto de la tabla. Un comodín como * o agent:*, y el centinela ::unrestricted, no son alcances MCP, por lo que no otorgan ninguna herramienta.

Estos alcances limitan únicamente la superficie MCP. Ningún endpoint REST puede declarar uno de ellos como su :scope, por lo que un token nuevo emitido a un cliente MCP no otorga nada en la API REST.

El scopes_supported de los metadatos del recurso protegido y el scope del desafío 401 enumeran todos los alcances de la tabla, por lo que una conexión nueva solicita todos ellos. Algunos clientes no escalan después de un 403: una reconexión manual desde la configuración del conector de Claude registra un cliente nuevo y solicita exactamente lo que estos listan. Cuando solo listaban el alcance base, esa reconexión nunca ofrecía escritura, SQL sin procesar ni entrega, y el usuario no tenía forma de otorgarlos (ENG-11089). Los metadatos del servidor de autorización también los anuncian todos.

El alcance base (agent:content:read agent:query:run) está bloqueado en la pantalla de consentimiento: cuando un cliente solicita uno de estos, el usuario no puede desmarcarlo. agent:query:run está en el alcance base para que los gráficos nunca necesiten un escalado. Claude Desktop reintenta una herramienta después de un escalado en una sesión que no declara soporte para MCP Apps, por lo que un visualize_query escalado es rechazado y su gráfico nunca se incrusta.

Una llamada a una herramienta o una lectura de recurso de datos para la que el token no tiene alcance se rechaza con HTTP 403 y un desafío WWW-Authenticate: Bearer error="insufficient_scope" cuyo scope lista los alcances v2 que el token ya posee más el requerido, para que un cliente pueda escalar. Cada herramienta también declara su alcance en securitySchemes, que es el borrador SEP-1488, compatible con ChatGPT. No forma parte de MCP 2025-03-26 (la versión que este servidor reporta) ni de la especificación final de herramientas 2026-07-28, por lo que otros clientes descubren el alcance faltante desde el 403. Dentro de un lote JSON-RPC, el rechazo es un error -32600 en banda. Las lecturas del shell de la interfaz nunca se desafían: ver Recursos.

Los metadatos de recursos protegidos OAuth están disponibles en:

/.well-known/oauth-protected-resource/api/metabase-mcp

En la pantalla de consentimiento, cada alcance solicitado por el cliente comienza marcado, y los alcances base también están bloqueados. Solo se otorgan los alcances que quedan marcados, y solo para el token que esta autorización emite. Desmarcar nunca afecta a un token que la aplicación ya tiene. Un alcance desmarcado no es recordado por Metabase. Un 403 posterior puede desencadenar otro escalado en clientes que lo soporten. Otros clientes pueden requerir una reautorización manual. El error_description de cada desafío termina con una nota de que el usuario debe otorgar el permiso en la pantalla de consentimiento.

Varios clientes reemplazan el error_description del 403 con su propio texto, por lo que el instructions del resultado initialize también explica los fallos de alcance al modelo: un error de autenticación generalmente significa un permiso faltante en lugar de una sesión caducada; el modelo debe nombrar la herramienta o recurso fallido y el permiso que requiere, y el usuario lo otorga reconectándose y dejando el permiso marcado en la pantalla de consentimiento. Las instrucciones son una cadena estática, la misma para cada llamador: no hay una lista de permisos por conexión.

Acceso a herramientas por grupo

En instancias Enterprise con la función ai_controls, un administrador puede restringir la superficie por grupo de permisos en Admin > AI > Usage controls > MCP tools access (se muestra siempre que el servidor MCP esté activo, con o sin proveedor de LLM). Cada grupo tiene una fila en mcp_group_permission que indica si sus miembros pueden conectarse y, por nombre de herramienta, la decisión explícita del administrador de "yes" o "no"; una herramienta sin entrada toma el valor predeterminado declarado por su autor, por lo que cada deftool lleva un :default-access obligatorio de :allowed o :denied, y una herramienta lanzada posteriormente obtiene exactamente ese valor predeterminado en cada grupo hasta que un administrador lo anule. Las entradas se identifican por nombre de herramienta, por lo que renombrar una herramienta requiere :renamed-from con sus nombres anteriores (una entrada almacenada bajo un nombre anterior sigue aplicándose y la API de administración la presenta bajo el nombre actual), o el autor acepta que se descarte la elección de cada administrador; metabase.mcp.v2.tool-names-test fija los nombres en vivo para que nada de esto ocurra por accidente. La política efectiva de un usuario es la tool_access de cada grupo suyo cuya fila habilita MCP: MCP está activo cuando existe cualquier grupo de este tipo, y una herramienta está permitida cuando cualquiera de esos grupos la resuelve como sí. Solo las filas deciden esto, y también registran el modo de permisos: modo simple (Administrators, All Users y All tenant users) o modo por grupos (cualquier otro grupo), que es el estado en el que All Users no tiene fila. Un interruptor elimina las filas de los grupos que el nuevo modo oculta y siembra los grupos que habilita al entrar y que no tienen fila (Data Analysts al entrar en modo por grupos, All Users y All tenant users al salir de él), y PUT rechaza un grupo que el modo actual oculta, por lo que ninguna solicitud lee un modo en caché. La política se aplica además de los alcances OAuth en tools/list y tools/call (v2/registry.clj), y un usuario cuyos grupos no otorgan acceso es rechazado en initialize y en resources/read (para sesiones abiertas antes de que MCP se desactivara) con un error que indica la solución. Las herramientas solo de aplicación (_meta {:ui {:visibility ["app"]}}, es decir, refresh_ui_credential) no están en la página de administración: se permiten mientras la política permita cualquier herramienta de MCP Apps. Los superusuarios y los llamadores internos nunca se restringen; OSS lo permite todo. En Enterprise, las filas almacenadas se aplican incluso sin la función ai_controls (un token caducado o no verificable mantiene las restricciones configuradas por un administrador); la función solo controla la página y la API de administración. El resolvedor es permissions.clj (defenterprise, implementación EE en metabase-enterprise.mcp.permissions) y la API de administración es /api/ee/ai-controls/mcp-permissions.

Herramientas disponibles

Generadas desde el registro v2 (deftool). El alcance indicado aquí es el que el registro verifica antes de que la herramienta se ejecute; algunos manejadores verifican un alcance adicional una vez que saben qué hace la llamada: agent:sql:run cuando una fuente se resuelve a SQL nativo (question_write), y agent:query:run para la ejecución que una alerta o suscripción difiere (alert_write, subscription_write). Esos rechazos llevan el mismo desafío 403 insufficient_scope. tools/list muestra cada herramienta sea cual sea el token que se posea, y un token sin el alcance no puede llamarla.

HerramientaAlcanceDescripción
alert_writeagent:delivery:writeCrear o actualizar una alerta: una notificación enviada según un horario cuando los resultados de una pregunta guardada cumplen una condición.
bookmark_contentagent:content:writeAñadir o eliminar un marcador en contenido para el usuario que llama — la misma lista de favoritos/estrellas que muestra la barra lateral de Metabase.
browse_collectionagent:content:readExplorar colecciones estructuralmente — un id uniforme sobre cada partición: un id numérico, un entity_id de 21 caracteres, "root" (re-enraizado por espacio de nombres), o "trash" (contenido archivado, solo modo de elementos).
browse_dataagent:content:readExplorar la jerarquía de datos: bases de datos → esquemas → tablas → campos.
collection_writeagent:content:writeCrear, renombrar, mover, archivar o restaurar una colección — las carpetas que contienen preguntas, paneles, modelos y documentos.
dashboard_writeagent:content:writeCrear o actualizar un panel y editar su diseño con operaciones ordenadas.
document_writeagent:content:writeCrear o actualizar un documento.
duplicate_contentagent:content:writeCopiar una pregunta, panel o documento en una colección — más barato y seguro que leer el original y recrearlo, y preserva todo lo que las proyecciones de lectura omiten.
execute_queryagent:query:runLa forma predeterminada de responder una pregunta a partir de datos: validar y ejecutar una consulta estructurada (MBQL), devolviendo filas más un query_handle.
execute_sqlagent:sql:runVía de escape: ejecutar una cadena SQL cruda contra una base de datos, devolviendo filas más un query_handle.
get_contentagent:content:readObtener contenido por {type, id} — la lectura tipada para cualquier cosa encontrada mediante búsqueda o browse_collection.
get_parameter_valuesagent:content:readObtener los valores válidos para un filtro en un panel o pregunta guardada, para que filtres con valores reales en lugar de adivinar.
glossaryagent:content:readBuscar un término de negocio tal como esta instancia de Metabase lo define; los nombres de términos definidos viajan en la propia descripción de la herramienta.
learnagent:content:readLeer la documentación de tareas (skills) de este servidor para los dialectos de escritura que los esquemas no pueden describir completamente.
measure_writeagent:content:writeCrear o actualizar una medida: una agregación MBQL nombrada y reutilizable adjunta a una tabla, referenciada dentro de la agregación de otra consulta como ["measure", id].
metric_writeagent:content:writeCrear o actualizar una métrica: una agregación guardada y reutilizable que vive en una colección y puede consultarse por sí sola o referenciarse desde otras consultas.
question_writeagent:content:writeCrear, actualizar o archivar una pregunta guardada o un modelo.
refresh_ui_credentialagent:query:runRefrescar la credencial con alcance utilizada por una MCP App de Metabase.
render_drill_throughagent:query:runRenderizar la visualización de profundización a la que el usuario acaba de navegar.
run_saved_questionagent:query:runEjecutar una pregunta guardada (card) por id numérico o entity_id, devolviendo filas en línea.
searchagent:content:readEncontrar contenido en toda la instancia de Metabase por relevancia.
segment_writeagent:content:writeCrear o actualizar un segmento: un filtro MBQL nombrado y reutilizable adjunto a una tabla, referenciado desde los filtros de otras consultas.
subscription_writeagent:delivery:writeCrear o actualizar una suscripción a un panel — entrega programada de un panel completo, p. ej.
visualize_queryagent:query:runVisualizar una consulta como un gráfico o tabla interactiva, renderizado en línea en la conversación.

execute_query devuelve row_limit filas por llamada (predeterminado 100, máximo 2000) — un tamaño de página, no un límite en el resultado. Una página truncada informa truncated: true y, cuando la consulta tiene un orden total, un next_cursor para pasar de vuelta como cursor para la siguiente página, hasta que una página llegue con truncated: false. Una consulta que solo quiere sus primeras N filas lleva limit: N en su etapa (con un order-by); el servidor gasta ese límite a lo largo de las páginas, así que la última página vuelve completa sin cursor y la paginación termina por sí sola.

Recursos

El servidor expone recursos de MCP para que los clientes puedan obtener contenido complementario por URI sin inflar las descripciones de las herramientas.

URI del recursoAlcanceDescripción
ui://metabase/visualize-query.htmlagent:query:run (solo credencial de UI)El shell iframe de MCP Apps al que visualize_query apunta para un cliente capaz.
ui://metabase/render-drill-through.htmlagent:query:run (solo credencial de UI)El shell al que render_drill_through apunta.
catalog://metabase/fieldsagent:content:readLas rutas de puntos que cada tipo de contenido acepta en argumentos de fields.

Cada recurso está listado sea cual sea el alcance del token. Un recurso de datos, como el catálogo de campos, solo es leído por un token que tenga su alcance; de lo contrario, la lectura obtiene el desafío 403 insufficient_scope descrito en Alcances. Un shell de UI es leído por cualquier token, porque un host de MCP Apps lee el shell de una herramienta junto con la llamada a la herramienta, y si esa lectura fuera rechazada, el host no daría el siguiente paso después del 403 de la llamada a la herramienta. Los shells no llevan datos. Un shell leído por un token sin el alcance del shell nunca acuña una credencial de UI. Los datos del gráfico están protegidos por la llamada a la herramienta y por refresh_ui_credential (ambos agent:query:run), que el iframe necesita antes de poder consultar cualquier cosa. Una URI desconocida es un error -32602 "Recurso no encontrado".

Los paquetes de habilidades se entregan a través de la herramienta learn en lugar de como recursos.

La navegación de entidades se realiza con las herramientas get_content y browse_* en lugar de un esquema de URI; los recursos ui:// anteriores existen solo para que un cliente que pueda renderizar un iframe tenga algo que montar.

Métodos JSON-RPC admitidos

MétodoDescripción
initializeInicializar la conexión MCP. Devuelve las capacidades del servidor y un ID de sesión.
notifications/initializedNotificación del cliente de que la inicialización está completa.
tools/listListar herramientas disponibles, sea cual sea el alcance del token.
tools/callLlamar a una herramienta con argumentos.
resources/listListar recursos disponibles, sea cual sea el alcance del token.
resources/readLeer un recurso por URI; un recurso de datos necesita su alcance. Requiere una sesión.
pingPing de mantenimiento.

Las solicitudes pueden enviarse individualmente o como un lote JSON-RPC. El servidor responde con JSON o SSE dependiendo del encabezado Accept.

Arquitectura

La implementación vive en estos archivos:

  • transport.clj - El transporte HTTP. Analiza solicitudes JSON-RPC, valida autenticación y encabezados de sesión, aplica verificaciones de origen (protección contra rebinding de DNS) y despacha al método apropiado. Admite formatos de respuesta JSON y SSE.

  • v2/api.clj - El manejador de superficie de herramientas. Conecta el transporte a los registros de herramientas y recursos v2 y define el despacho de métodos (tools/list, tools/call, resources/list, resources/read, ping).

  • v2/registry.clj - El registro de herramientas v2. Las herramientas se auto-registran vía deftool; el registro verifica alcances, valida argumentos, despacha llamadas y registra uso.

  • scope.clj - Lógica de coincidencia de alcances. Solo coincidencias exactas: comodines, alcances nulos y el centinela ::unrestricted no coinciden con nada.

Flujo de solicitudes

MCP client
  -> POST /api/metabase-mcp (JSON-RPC)
  -> Origin + session validation
  -> Auth: OAuth bearer token or browser session
  -> Scope check against requested tool
  -> Synthetic request to Agent API endpoint
  -> Response materialized as MCP content
  -> JSON or SSE back to client

Lectura adicional