Metabase
官方官方Metabase MCP服务器,用于通过MCP客户端搜索数据、在语义层构建查询以及可视化结果。
你可以用 Metabase MCP 做什么?
- 搜索并检索内容 — 让您的助手使用
search工具在 Metabase 中查找问题、仪表板或模型,然后通过get_content获取详细信息。 - 运行查询并可视化结果 — 让您的助手通过
execute_query执行结构化查询,或使用execute_sql执行原始 SQL,然后使用visualize_query将结果渲染为交互式图表。 - 创建并管理仪表板 — 指示您的助手使用
dashboard_write构建或更新仪表板及其布局,或通过duplicate_content将现有内容复制到集合中。 - 设置提醒和订阅 — 让您的助手使用
alert_write为保存的问题创建定时提醒,或使用subscription_write配置仪表板电子邮件订阅。 - 浏览数据层级 — 指示您的助手通过
browse_data浏览数据库、模式、表和字段,或使用browse_collection按结构浏览集合。
文档
Metabase MCP 服务器
Metabase 包含一个内置的 Model Context Protocol (MCP) 服务器,允许 AI 客户端直接连接到 Metabase 实例。它使用 Streamable HTTP 传输,并基于 Metabase 的 Agent API 公开工具,用于搜索、导航、查询、可视化以及 创建/更新内容——所有这些都限定在连接用户的权限范围内。
端点
MCP 服务器可通过以下地址访问:
https://{your-metabase.example.com}/api/metabase-mcp
旧的 /api/mcp 路径仍然作为现有客户端的别名可用,但 /api/metabase-mcp 是
应对外宣传的规范 URL。
连接客户端
将任何兼容 MCP 的客户端指向 /api/metabase-mcp 端点。例如,使用 Claude Code:
claude mcp add metabase https://{your-metabase.example.com}/api/metabase-mcp --transport streamable-http
对于 Claude Desktop,创建一个使用相同 URL 的 自定义连接器。
对于 Cursor,打开 设置 > MCP,添加一个新服务器,类型设置为 streamable-http,URL 为:
https://{your-metabase.example.com}/api/metabase-mcp
身份验证
MCP 客户端通过 OAuth 2.0 进行身份验证。Metabase 运行自己的嵌入式 OAuth 服务器——无需外部提供商。
首次连接流程:
- 客户端发现 Metabase 的 OAuth 端点。
- 客户端向 Metabase 注册自身。
- 用户被重定向到 Metabase 登录并批准连接。
- 客户端收到一个限定于用户 Metabase 权限范围之内的访问令牌。
基于浏览器的会话(cookie 认证)、API 密钥和 mb:full 令牌不持有 MCP 范围,因此它们可以连接但
无法调用任何限定范围内的工具。
范围
访问令牌被限定范围,以限制客户端可以使用的工具:
| 范围 | 授予的工具 |
|---|---|
agent:content:read | browse_collection、browse_data、get_content、get_parameter_values、glossary、learn、search 以及 catalog://metabase/fields 数据资源(参见 资源) |
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 |
一个工具只匹配表中确切的范围。诸如 * 或 agent:* 之类的通配符,以及 ::unrestricted
哨兵值,都不是 MCP 范围,因此它们不授予任何工具。
这些范围仅限制 MCP 表面。任何 REST 端点都不得将其声明为 :scope,因此颁发给
MCP 客户端的新令牌在 REST API 上不授予任何权限。
受保护资源元数据的 scopes_supported 和 401 质询的 scope 都列出了表中的每个
范围,因此新连接会请求所有这些范围。某些客户端在 403 后不会升级:从 Claude 的连接器设置手动
重新连接会注册一个新客户端,并请求这些列表中的确切内容。当它们只列出
基线范围时,该重新连接永远不会提供写入、原始 SQL 或投递功能,用户也无法授予这些权限
(ENG-11089)。授权服务器元数据也宣传所有这些范围。
基线(agent:content:read agent:query:run)在同意屏幕上被锁定:当客户端请求其中
一个时,用户无法取消勾选。agent:query:run 在基线中,因此图表永远不需要升级。Claude
Desktop 在会话未声明支持 MCP Apps 的情况下,会在升级后重试工具,因此升级后的
visualize_query 会被拒绝,其图表也永远不会嵌入。
对令牌缺少范围的工具调用或数据资源读取,将返回 HTTP 403 和
WWW-Authenticate: Bearer error="insufficient_scope" 质询,其 scope 列出令牌已持有的 v2 范围
加上所需的一个范围,以便客户端可以升级。每个工具还在 securitySchemes 中声明其范围,这是
草案 SEP-1488,由 ChatGPT 支持。它
不是 MCP 2025-03-26(此服务器报告的版本)或最终 2026-07-28 工具规范的一部分,因此其他客户端
从 403 中发现缺失的范围。在 JSON-RPC 批处理内部,拒绝是带内 -32600 错误
。UI 外壳读取永远不会被质询:参见 资源。
OAuth 受保护资源元数据可在以下地址获取:
/.well-known/oauth-protected-resource/api/metabase-mcp
在同意屏幕上,客户端请求的每个范围默认勾选,基线范围也被锁定。只有
保持勾选的范围被授予,且仅授予此授权铸造的令牌。取消勾选永远不会影响
应用已有的令牌。Metabase 不会记住未勾选的范围。后续的 403 可以在支持升级的
客户端中触发另一次升级。其他客户端可能需要手动重新授权。每个质询的 error_description 末尾
都附有说明,提示用户必须在同意屏幕上授予该权限。
多个客户端会用它们自己的文本替换 403 的 error_description,因此 initialize 结果的 instructions
也向模型解释范围失败:认证错误通常意味着缺少权限而不是登录
过期,模型应指出失败的工具或资源及其所需的权限,用户通过
重新连接并在同意屏幕上保持该权限勾选来授予权限。这些指令是一个静态字符串,对每个
调用者都相同:没有针对每个连接的权限列表。
按权限组划分的工具访问
在启用了 ai_controls 功能的 Enterprise 实例上,管理员可以在 管理 > AI > 使用控制 > MCP 工具访问 中按权限组缩小范围(只要 MCP 服务器开启,无论是否配置 LLM 提供商,都会显示)。每个组在 mcp_group_permission 中有一行,说明其成员是否可以连接,以及按工具名称,管理员的显式 "yes" 或 "no";没有条目的工具采用其作者声明的默认值,因此每个 deftool 都带有必需的 :default-access,值为 :allowed 或 :denied,之后发布的工具在每个组中都会获得该默认值,直到管理员覆盖它。条目按工具名称键控,因此重命名工具需要 :renamed-from 及其旧名称(存储在旧名称下的条目仍然适用,管理 API 以当前名称呈现它),或者作者接受每个管理员对它的选择被丢弃;metabase.mcp.v2.tool-names-test 固定实时名称,因此两者都不会意外发生。用户的有效策略是其每个启用了 MCP 的组的行的 tool_access:当存在任何此类组时,MCP 开启,当任何此类组将其解析为“是”时,工具被允许。仅由这些行决定,它们还记录权限模式:简单模式(管理员、所有用户和所有租户用户)或组级模式(其他所有组),这是“所有用户”没有行的状态。切换会删除新模式隐藏的组的行,并在进入时为其启用的没有行的组播种(进入组级模式时的数据分析师,离开时的所有用户和所有租户用户),并且 PUT 拒绝当前模式隐藏的组,因此没有请求读取缓存的模式。该策略在 tools/list 和 tools/call(v2/registry.clj)中应用于 OAuth 范围之上,并且其组不授予任何访问权限的用户在 initialize 和 resources/read(对于在 MCP 关闭之前打开的会话)被拒绝,并显示指明修复方法的错误。仅应用工具(_meta {:ui {:visibility ["app"]}},即 refresh_ui_credential)不在管理页面上:只要策略允许任何 MCP Apps 工具,它们就被允许。超级用户和内部调用者永远不会被缩小范围;OSS 允许一切。在 Enterprise 上,即使没有 ai_controls 功能,存储的行也会被强制执行(过期或无法验证的令牌会保留管理员配置的限制);该功能仅控制管理页面和 API。解析器是 permissions.clj(defenterprise,EE 实现在 metabase-enterprise.mcp.permissions 中),管理 API 是 /api/ee/ai-controls/mcp-permissions。
可用工具
从 v2 注册表生成(deftool)。此处命名的范围是注册表在工具运行之前检查的内容;
某些处理程序在知道调用内容后会检查进一步的范围——当源解析为原生 SQL 时检查 agent:sql:run(question_write),
以及警报或订阅延迟执行的 agent:query:run(alert_write、subscription_write)。这些拒绝携带相同的 403 insufficient_scope 质询。tools/list
显示每个工具,无论令牌持有何种范围,缺少该范围的令牌可能无法调用它。
| 工具 | 范围 | 描述 |
|---|---|---|
alert_write | agent:delivery:write | 创建或更新警报:当保存的问题结果满足条件时,按计划发送的通知。 |
bookmark_content | agent:content:write | 为调用用户添加或移除内容书签——即 Metabase 侧边栏显示的星标/收藏列表。 |
browse_collection | agent:content:read | 按结构浏览集合——所有分区使用统一的 id:数字 id、21 字符的 entity_id、"root"(按命名空间重新根化)或 "trash"(已归档内容,仅项目模式)。 |
browse_data | agent:content:read | 浏览数据层级:数据库 → 模式 → 表 → 字段。 |
collection_write | agent:content:write | 创建、重命名、移动、归档或恢复集合——即存放问题、仪表板、模型和文档的文件夹。 |
dashboard_write | agent:content:write | 创建或更新仪表板,并通过有序操作编辑其布局。 |
document_write | agent:content:write | 创建或更新文档。 |
duplicate_content | agent:content:write | 将问题、仪表板或文档复制到集合中——比读取原始内容再重新创建更便宜、更安全,并且保留读取投影遗漏的所有内容。 |
execute_query | agent:query:run | 从数据回答问题默认方式:验证并执行结构化(MBQL)查询,返回行以及 query_handle。 |
execute_sql | agent:sql:run | 逃生通道:对数据库执行原始 SQL 字符串,返回行以及 query_handle。 |
get_content | agent:content:read | 按 {type, id} 获取内容——用于通过搜索或 browse_collection 找到的任何内容的类型化读取。 |
get_parameter_values | agent:content:read | 获取仪表板或保存问题上某个筛选器的有效值,以便使用真实值筛选而不是猜测。 |
glossary | agent:content:read | 按此 Metabase 实例的定义查找业务术语;定义的术语名称随工具自身的描述一起提供。 |
learn | agent:content:read | 阅读此服务器的任务文档(技能),了解模式无法完全描述的写入方言。 |
measure_write | agent:content:write | 创建或更新度量:附加到单个表上的命名、可复用的 MBQL 聚合,可在另一个查询的聚合中引用为 ["measure", id]。 |
metric_write | agent:content:write | 创建或更新指标:保存在集合中的可复用聚合,可单独查询或从其他查询中引用。 |
question_write | agent:content:write | 创建、更新或归档保存的问题或模型。 |
refresh_ui_credential | agent:query:run | 刷新 Metabase MCP 应用使用的作用域凭据。 |
render_drill_through | agent:query:run | 渲染用户刚导航进入的钻取可视化。 |
run_saved_question | agent:query:run | 按数字 id 或 entity_id 运行保存的问题(卡片),内联返回行。 |
search | agent:content:read | 按相关性在 Metabase 实例中查找内容。 |
segment_write | agent:content:write | 创建或更新分段:附加到单个表上的命名、可复用的 MBQL 筛选器,可从其他查询的筛选器中引用。 |
subscription_write | agent:delivery:write | 创建或更新仪表板订阅——整个仪表板的计划投递,例如。 |
visualize_query | agent:query:run | 将查询可视化为交互式图表或表格,内联渲染在对话中。 |
execute_query 每次调用返回 row_limit 行(默认 100,最大 2000)——这是页大小,不是结果上限。
截断的页面报告 truncated: true,当查询具有全序时,还提供 next_cursor 作为
cursor 传回以获取下一页,直到某页到达时带有 truncated: false。只想获取前 N 行的查询
在其阶段中携带 limit: N(带有 order-by);服务器会在各页之间分摊该限制,因此最后一页
完整返回且没有游标,分页自动结束。
资源
服务器暴露 MCP 资源,以便 客户端可以通过 URI 获取补充内容,而无需扩大工具描述。
| 资源 URI | 范围 | 描述 |
|---|---|---|
ui://metabase/visualize-query.html | agent:query:run(仅 UI 凭据) | visualize_query 指向的 MCP 应用 iframe 外壳,供有能力的客户端使用。 |
ui://metabase/render-drill-through.html | agent:query:run(仅 UI 凭据) | render_drill_through 指向的外壳。 |
catalog://metabase/fields | agent:content:read | 每种内容类型在 fields 参数中接受的点路径。 |
无论令牌的作用域如何,每个资源都会被列出。数据资源(如字段目录)只能由持有其作用域的令牌读取;否则读取会收到 Scopes 下描述的 403 insufficient_scope 挑战。UI 外壳可由任何令牌读取,因为 MCP 应用宿主会在工具调用时同时读取工具的外壳,如果该读取被拒绝,宿主就不会在工具调用返回 403 后升级。外壳不携带数据。没有外壳作用域的令牌读取外壳时,绝不会生成 UI 凭据。图表数据由工具调用和 refresh_ui_credential(两者均为 agent:query:run)把关,iframe 需要这些才能查询任何内容。未知 URI 会返回 -32602 "Resource not found" 错误。
技能包通过 learn 工具交付,而不是作为资源。
实体导航使用 get_content 和 browse_* 工具完成,而不是 URI 方案;上述 ui://
资源仅用于让能渲染 iframe 的客户端有东西可挂载。
支持的 JSON-RPC 方法
| 方法 | 描述 |
|---|---|
initialize | 初始化 MCP 连接。返回服务器能力和会话 ID。 |
notifications/initialized | 客户端通知初始化已完成。 |
tools/list | 列出可用工具,无论令牌的作用域如何。 |
tools/call | 使用参数调用工具。 |
resources/list | 列出可用资源,无论令牌的作用域如何。 |
resources/read | 按 URI 读取资源;数据资源需要其作用域。需要会话。 |
ping | 保活 ping。 |
请求可以单独发送,也可以作为 JSON-RPC 批处理发送。服务器根据
Accept 头以 JSON 或 SSE 响应。
架构
实现位于以下文件中:
-
transport.clj- HTTP 传输层。解析 JSON-RPC 请求,验证认证和 会话头,强制执行来源检查(DNS 重绑定保护),并分派到相应的方法。 支持 JSON 和 SSE 两种响应格式。 -
v2/api.clj- 工具表面处理器。将传输层连接到 v2 工具 + 资源注册表, 并定义方法分派(tools/list、tools/call、resources/list、resources/read、ping)。 -
v2/registry.clj- v2 工具注册表。工具通过deftool自行注册;注册表 检查作用域、验证参数、分派调用并记录使用情况。 -
scope.clj- 作用域匹配逻辑。仅精确匹配:通配符、nil 作用域和::unrestricted哨兵不匹配任何内容。
请求流程
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