Metabase
공식Metabase의 공식 MCP 서버로, 데이터 검색, 시맨틱 레이어에서 쿼리 작성, MCP 클라이언트를 통한 결과 시각화를 지원합니다.
Metabase MCP(으)로 무엇을 할 수 있나요?
- Search for Metabase content — 키워드나 자연어 질의를 사용하여
search로 테이블, 메트릭, 카드, 대시보드, 컬렉션을 찾습니다. - Navigate and inspect entities —
metabase://URI와 함께read_resource를 사용하여 데이터베이스, 스키마, 테이블, 질문, 대시보드, 메트릭의 메타데이터를 읽습니다. - Build and run queries —
construct_query로 테이블이나 메트릭에 대한 질의를 구성한 후,execute_query를 통해 실행하여 결과와 컬럼 메타데이터를 얻습니다. - Run raw SQL —
execute_sql을 사용하여 데이터베이스에 대해 네이티브 SQL 질의를 실행합니다(네이티브 질의 권한과 인스턴스 설정이 활성화되어 있어야 함). - Save and update questions —
create_question과update_question을 사용하여 구성된 질의로 저장된 질문(카드)을 생성하거나 수정하며, 이동 또는 보관 처리도 가능합니다. - Create and manage dashboards —
create_dashboard로 자동 배치된 저장 질문이 포함된 새 대시보드를 구축하고,update_dashboard로 메타데이터를 업데이트하거나 보관 처리합니다.
문서
Metabase MCP Server
Metabase includes a built-in Model Context Protocol (MCP) server that lets AI clients connect directly to a Metabase instance. It uses the Streamable HTTP transport and builds on Metabase's Agent API to expose tools for searching, navigating, querying, visualizing, and creating/updating content - all scoped to the connecting user's permissions.
Endpoint
The MCP server is available at:
https://{your-metabase.example.com}/api/metabase-mcp
The legacy /api/mcp path still works as an alias for existing clients, but /api/metabase-mcp is the
canonical URL to advertise.
Connecting a client
Point any MCP-compatible client at the /api/metabase-mcp endpoint. For example, with Claude Code:
claude mcp add metabase https://{your-metabase.example.com}/api/metabase-mcp --transport streamable-http
For Claude Desktop, create a custom connector using the same URL.
For Cursor, open Settings > MCP and add a new server with the type set to streamable-http and the URL:
https://{your-metabase.example.com}/api/metabase-mcp
Authentication
MCP clients authenticate via OAuth 2.0. Metabase runs its own embedded OAuth server - no external provider is needed.
The flow for a first-time connection:
- The client discovers Metabase's OAuth endpoints.
- The client registers itself with Metabase.
- The user is redirected to Metabase to log in and approve the connection.
- The client receives an access token scoped to the user's Metabase permissions.
Browser-based sessions (cookie auth) are also supported and receive unrestricted scopes.
Scopes
Access tokens are scoped to limit what tools a client can use:
| Scope | Grants access to |
|---|---|
agent:search | search |
agent:resource:read | read_resource (always granted to any authenticated caller; per-URI perm checks happen inside the dispatcher) |
agent:query:construct | construct_query |
agent:query | query |
agent:query:execute | execute_query |
agent:sql:construct | construct_native_query |
agent:sql:execute | execute_sql |
agent:question:create | create_question |
agent:question:update | update_question (also covers "move card to collection" and archiving) |
agent:question:execute | execute_question |
agent:metric:create | create_metric |
agent:metric:update | update_metric (also covers "move metric to collection" and archiving) |
agent:dashboard:create | create_dashboard |
agent:dashboard:update | update_dashboard (also covers archiving) |
agent:collection:create | create_collection |
Wildcard patterns (e.g. agent:*) match any scope with that prefix.
OAuth protected resource metadata is available at:
/.well-known/oauth-protected-resource/api/metabase-mcp
By default our consent screen grants access to all scopes without the opportunity to customize.
Available tools
The MCP server exposes these tools, dynamically generated from the Agent API endpoint metadata:
Discovery + read
| Tool | Description |
|---|---|
search | Search for tables, metrics, cards, dashboards, and collections using keyword or natural-language queries. |
read_resource | Read one or more Metabase entities by metabase:// URI. Covers database/schema/table/collection/question/dashboard/metric/transform navigation. Up to 5 URIs per call. |
Query construction + execution
| Tool | Description |
|---|---|
construct_query | Construct a query against a table or metric. Accepts the user's original prompt when available. Returns an opaque query_handle for use with execute_query or visualize_query. |
construct_native_query | Construct a native (raw SQL) query for a database. Returns an opaque query_handle to feed create_question and save it. Does not execute the SQL; native handles are rejected by execute_query/query (use execute_sql to run raw SQL). |
query | Query a table or metric directly. Supports pagination via continuation tokens. |
execute_query | Execute a previously constructed query and return results with column metadata. |
execute_sql | Execute a raw SQL query against a database. Requires the user to have native-query permission on the target database. Can be disabled instance-wide via the mcp-execute-sql-enabled setting. |
execute_question | Run a saved question by id and return its rows + column metadata. Runs under the caller's permissions. Parameterized questions are not supported (returns an error). |
Write
| Tool | Description |
|---|---|
create_metric | Save a query as a reusable metric. Accepts a query_handle from construct_query. The query needs one aggregation and at most one date grouping. |
update_metric | Update a saved metric. Patch semantics. Setting collection_id moves it; setting archived: true archives it — a reversible soft delete, used when asked to delete a metric. A replacement query must still be a valid metric. |
create_question | Save a query as a named question (card). Accepts a query_handle from construct_query (MBQL) or construct_native_query (native SQL). Saving native requires native-query DB permission. |
update_question | Update a saved question. Patch semantics. Setting collection_id moves the card. Setting archived: true archives it — a reversible soft delete, used when asked to delete a question. Replacing the query accepts a construct_query or construct_native_query handle. |
create_dashboard | Create a new dashboard, optionally populated with saved questions (auto-positioned on the grid). |
update_dashboard | Update a dashboard's metadata (name, description, collection, archived — a reversible soft delete, used when asked to delete a dashboard). |
create_collection | Create a new collection. Optionally nested under a parent_collection_id. |
Query results are limited to 200 rows per request. When more rows are available, the response includes a
continuation_token that can be passed back to fetch the next page.
read_resource list responses cap at 25 items with truncated / total signals; drill into specific URIs to see
more, or refine via search.
Resources
The server exposes MCP resources so clients can fetch supplementary content by URI without inflating tool descriptions.
| Resource URI | Description |
|---|---|
metabase://docs/construct-query.md | Program syntax for construct_query and query: sources, operations, operator forms, worked examples, pitfalls. |
The read_resource tool (above) uses a separate URI scheme to navigate Metabase entities (metabase://question/{id},
metabase://database/{id}/tables, etc.). The two URI namespaces are independent: metabase://docs/... is for static
reference content fetched via MCP resources/read, while metabase://table/... and friends are entity URIs passed
to the read_resource tool.
Supported JSON-RPC methods
| Method | Description |
|---|---|
initialize | Initialize the MCP connection. Returns server capabilities and a session ID. |
notifications/initialized | Client notification that initialization is complete. |
tools/list | List available tools (filtered by the token's scopes). |
tools/call | Call a tool with arguments. |
resources/list | List available resources (filtered by the token's scopes). |
resources/read | Read a resource by URI. Requires an initialized session. |
ping | Keepalive ping. |
Requests can be sent individually or as a JSON-RPC batch. The server responds with JSON or SSE depending on the
Accept header.
Architecture
The implementation lives in these files:
-
api.clj- The HTTP handler. Parses JSON-RPC requests, validates authentication and session headers, enforces origin checks (DNS rebinding protection), and dispatches to the appropriate method. Supports both JSON and SSE response formats. -
tools.clj- Tool dispatch and manifest generation. Builds the tool list from Agent API endpoint metadata, checks scopes, and routes tool calls through synthetic Agent API requests. -
resources.clj- MCP resource registry and handlers. Holds documentation resources (like theconstruct_queryreference) keyed by URI, with scope-based access control onresources/listandresources/read. -
scope.clj- Scope matching logic. Supports exact matches, wildcard patterns, and the::unrestrictedsentinel for session-based auth.
Request flow
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