Metabase
oficialServidor 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 conget_content. - Ejecutar consultas y visualizar resultados — Haz que tu asistente ejecute consultas estructuradas mediante
execute_queryo SQL sin procesar conexecute_sql, y luego renderice los resultados como gráficos interactivos usandovisualize_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 medianteduplicate_content. - Configurar alertas y suscripciones — Pídele a tu asistente que cree alertas programadas para preguntas guardadas con
alert_writeo que configure suscripciones por correo electrónico para paneles usandosubscription_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 conbrowse_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:
- El cliente descubre los endpoints OAuth de Metabase.
- El cliente se registra con Metabase.
- El usuario es redirigido a Metabase para iniciar sesión y aprobar la conexión.
- 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:
| Alcance | Herramientas que otorga |
|---|---|
agent:content:read | browse_collection, browse_data, get_content, get_parameter_values, glossary, learn, search y el recurso de datos catalog://metabase/fields (ver Recursos) |
agent:content:write | bookmark_content, collection_write, dashboard_write, document_write, duplicate_content, measure_write, metric_write, question_write, segment_write |
agent:delivery:write | alert_write, subscription_write |
agent:query:run | execute_query, refresh_ui_credential, render_drill_through, run_saved_question, visualize_query |
agent:sql:run | execute_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.
| Herramienta | Alcance | Descripción |
|---|---|---|
alert_write | agent:delivery:write | Crear o actualizar una alerta: una notificación enviada según un horario cuando los resultados de una pregunta guardada cumplen una condición. |
bookmark_content | agent:content:write | Añ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_collection | agent:content:read | Explorar 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_data | agent:content:read | Explorar la jerarquía de datos: bases de datos → esquemas → tablas → campos. |
collection_write | agent:content:write | Crear, renombrar, mover, archivar o restaurar una colección — las carpetas que contienen preguntas, paneles, modelos y documentos. |
dashboard_write | agent:content:write | Crear o actualizar un panel y editar su diseño con operaciones ordenadas. |
document_write | agent:content:write | Crear o actualizar un documento. |
duplicate_content | agent:content:write | Copiar 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_query | agent:query:run | La 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_sql | agent:sql:run | Vía de escape: ejecutar una cadena SQL cruda contra una base de datos, devolviendo filas más un query_handle. |
get_content | agent:content:read | Obtener contenido por {type, id} — la lectura tipada para cualquier cosa encontrada mediante búsqueda o browse_collection. |
get_parameter_values | agent:content:read | Obtener los valores válidos para un filtro en un panel o pregunta guardada, para que filtres con valores reales en lugar de adivinar. |
glossary | agent:content:read | Buscar 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. |
learn | agent:content:read | Leer la documentación de tareas (skills) de este servidor para los dialectos de escritura que los esquemas no pueden describir completamente. |
measure_write | agent:content:write | Crear 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_write | agent:content:write | Crear 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_write | agent:content:write | Crear, actualizar o archivar una pregunta guardada o un modelo. |
refresh_ui_credential | agent:query:run | Refrescar la credencial con alcance utilizada por una MCP App de Metabase. |
render_drill_through | agent:query:run | Renderizar la visualización de profundización a la que el usuario acaba de navegar. |
run_saved_question | agent:query:run | Ejecutar una pregunta guardada (card) por id numérico o entity_id, devolviendo filas en línea. |
search | agent:content:read | Encontrar contenido en toda la instancia de Metabase por relevancia. |
segment_write | agent:content:write | Crear o actualizar un segmento: un filtro MBQL nombrado y reutilizable adjunto a una tabla, referenciado desde los filtros de otras consultas. |
subscription_write | agent:delivery:write | Crear o actualizar una suscripción a un panel — entrega programada de un panel completo, p. ej. |
visualize_query | agent:query:run | Visualizar 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 recurso | Alcance | Descripción |
|---|---|---|
ui://metabase/visualize-query.html | agent: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.html | agent:query:run (solo credencial de UI) | El shell al que render_drill_through apunta. |
catalog://metabase/fields | agent:content:read | Las 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étodo | Descripción |
|---|---|
initialize | Inicializar la conexión MCP. Devuelve las capacidades del servidor y un ID de sesión. |
notifications/initialized | Notificación del cliente de que la inicialización está completa. |
tools/list | Listar herramientas disponibles, sea cual sea el alcance del token. |
tools/call | Llamar a una herramienta con argumentos. |
resources/list | Listar recursos disponibles, sea cual sea el alcance del token. |
resources/read | Leer un recurso por URI; un recurso de datos necesita su alcance. Requiere una sesión. |
ping | Ping 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íadeftool; 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::unrestrictedno 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