Metabase Official MCP Server について
Metabase Official MCP Serverは、AIクライアントをMetabaseインスタンスに接続する組み込みMCPサーバーです。データの探索、クエリ、可視化、コンテンツ管理のツールを提供し、ユーザー権限とOAuthスコープで利用範囲を制御します。
主な機能
- 01Metabaseコンテンツの検索と閲覧
- 02クエリ実行と結果の可視化
- 03コンテンツの作成と更新
- 04OAuth 2.0認証とスコープ別アクセス
- 05Streamable HTTPトランスポート
活用シーン
- 01AIクライアントでMetabaseデータを探索
- 02クエリを実行して可視化を確認
- 03ダッシュボードや質問を作成・更新
- 04ユーザー権限で操作範囲を制限
MCP 対応
Streamable HTTP経由で、Metabaseの検索、ナビゲーション、クエリ、可視化、コンテンツ管理ツールをMCPクライアントに公開します。OAuthスコープとMetabase権限によってアクセスを制御します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://{metabase_host}/api/mcpclaude mcp add --transport http metabase-mcp-2 https://{metabase_host}/api/mcp{"mcpServers":{"metabase-mcp-2":{"type":"http","url":"https://{metabase_host}/api/mcp"}}}Cursor で開く{"servers":{"metabase-mcp-2":{"type":"http","url":"https://{metabase_host}/api/mcp"}}}VS Code で開く{"mcpServers":{"metabase-mcp-2":{"type":"http","url":"https://{metabase_host}/api/mcp"}}}{"mcpServers":{"metabase-mcp-2":{"serverUrl":"https://{metabase_host}/api/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
Metabase MCP サーバー
Metabase には、AI クライアントが Metabase インスタンスに直接接続できる、組み込みの Model Context Protocol(MCP) サーバーが含まれています。ストリーム可能な HTTP トランスポートを使用し、Metabase の Agent API を基盤として、検索、移動、クエリ、可視化、コンテンツの作成・更新を行うツールを公開します。これらの操作はすべて、接続ユーザーの権限の範囲内で行われます。
エンドポイント
MCP サーバーは次の場所で利用できます。
https://{your-metabase.example.com}/api/metabase-mcp
従来の /api/mcp パスも既存のクライアント向けのエイリアスとして引き続き機能しますが、案内する正式な URL は /api/metabase-mcp です。
クライアントの接続
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 の場合は、Settings > MCP を開き、タイプを streamable-http に設定して、新しいサーバーを次の URL で追加します。
https://{your-metabase.example.com}/api/metabase-mcp
認証
MCP クライアントは OAuth 2.0 で認証します。Metabase は独自の組み込み OAuth サーバーを実行するため、外部プロバイダーは不要です。
初回接続時のフローは次のとおりです。
- クライアントが Metabase の OAuth エンドポイントを検出します。
- クライアントが Metabase に登録されます。
- ユーザーが Metabase にリダイレクトされ、ログインして接続を承認します。
- クライアントが、ユーザーの Metabase 権限の範囲に限定されたアクセストークンを受け取ります。
MCP が受け入れるのは OAuth アクセストークンのみです。MCP パスではセッションミドルウェアがセッション Cookie と API キーを無視するため、そのようなリクエストには、認証情報がないリクエストと同じ 401 検出チャレンジが返されます。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 にもスコープを宣言します。これは、ChatGPT がサポートするドラフト SEP-1488 です。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 です。そのようなグループが 1 つでも存在すれば MCP はオンになり、それらのグループのいずれかがツールを yes と解決すればそのツールは許可されます。判断はこれらの行だけで行われ、行は権限モードも記録します。すなわち、シンプルモード(Administrators、All Users、All tenant users)か、グループレベルモード(それ以外のすべてのグループ)であり、後者が All Users に行を持たない状態です。切り替えを行うと、新しいモードが隠すグループの行が削除され、有効化されたグループのうち行を持たないもの(グループレベルモードへの移行時は Data Analysts、そこから離れるときは All Users と All tenant users)に行がシードされます。また 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 に解決される場合(question_write)は agent:sql:run、アラートまたはサブスクリプションが延期する実行(alert_write、subscription_write)には agent:query:run です。これらの拒否は、同じ 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"(アーカイブされたコンテンツ、items モードのみ)です。 |
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} でコンテンツを取得します。search や browse_collection で見つかったものに対する型付きの読み取りです。 |
get_parameter_values | agent:content:read | ダッシュボードまたは保存された質問の 1 つのフィルターに対して有効な値を取得します。推測ではなく実際の値でフィルタリングできるようにします。 |
glossary | agent:content:read | この Metabase インスタンスが定義するビジネス用語を調べます。定義された用語名はツール自身の説明に含まれています。 |
learn | agent:content:read | スキーマでは完全に記述できない書き込み方言について、このサーバーのタスクドキュメント(スキル)を読みます。 |
measure_write | agent:content:write | メジャーを作成または更新します。メジャーとは、1 つのテーブルに紐付けられた名前付きの再利用可能な MBQL 集計であり、別のクエリの集計内で ["measure", id] として参照されます。 |
metric_write | agent:content:write | メトリックを作成または更新します。メトリックとは、コレクションに存在する保存された再利用可能な集計であり、単独でクエリしたり他のクエリから参照したりできます。 |
question_write | agent:content:write | 保存された質問またはモデルを作成、更新、またはアーカイブします。 |
refresh_ui_credential | agent:query:run | Metabase MCP App が使用するスコープ付き資格情報を更新します。 |
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 | セグメントを作成または更新します。セグメントとは、1 つのテーブルに紐付けられた名前付きの再利用可能な MBQL フィルターであり、他のクエリのフィルターから参照されます。 |
subscription_write | agent:delivery:write | ダッシュボードのサブスクリプションを作成または更新します。たとえば、ダッシュボード全体をスケジュールで配信するものです。 |
visualize_query | agent:query:run | クエリをインタラクティブなチャートまたはテーブルとして可視化し、会話内にインラインでレンダリングします。 |
execute_query は呼び出しごとに row_limit 件の行を返します(デフォルトは 100、最大は 2000)。これはページサイズであり、結果の上限ではありません。 | ||
ページが切り詰められた場合は truncated: true が返され、クエリに全体順序が指定されている場合は、次のページで cursor として渡す next_cursor も返されます。truncated: false のページが返されるまで続けます。最初の N 件だけを取得するクエリでは、ステージに limit: N(order-by とともに)を指定します。サーバーはページごとにその上限を消費するため、最後のページは完全な状態でカーソルなしで返され、ページネーションは自動的に終了します。 |
リソース
サーバーは MCP のリソースを公開しており、クライアントはツールの説明を膨らませることなく、URI から補足コンテンツを取得できます。
| リソース URI | スコープ | 説明 |
|---|---|---|
ui://metabase/visualize-query.html | agent:query:run(UI 認証情報のみ) | MCP Apps の iframe シェルで、visualize_query が対応クライアントを誘導します。 |
ui://metabase/render-drill-through.html | agent:query:run(UI 認証情報のみ) | render_drill_through が誘導するシェルです。 |
catalog://metabase/fields | agent:content:read | 各コンテンツタイプが fields 引数で受け付けるドットパスです。 |
すべてのリソースは、トークンのスコープにかかわらず一覧に表示されます。フィールドカタログなどのデータリソースを読み取れるのは、そのスコープを持つトークンのみです。それ以外の場合、読み取り時にはスコープで説明されている 403 insufficient_scope チャレンジが返されます。UI シェルはすべてのトークンで読み取れます。MCP Apps ホストはツール呼び出しとあわせてツールのシェルを読み取るため、その読み取りが拒否されると、ツール呼び出しで 403 が返された後にホストが権限を追加で要求できなくなるためです。シェルにはデータが含まれていません。シェルのスコープを持たないトークンでシェルを読み取っても、UI 認証情報は発行されません。チャートデータへのアクセスは、ツール呼び出しと refresh_ui_credential(どちらも agent:query:run)によって制限されます。iframe が何かをクエリするには、これらが必要です。不明な URI には、-32602「Resource not found」エラーが返されます。
スキルパックは、リソースではなく learn ツールを通じて提供されます。
エンティティのナビゲーションには URI スキームではなく、get_content および browse_* ツールを使用します。上記の 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
-> Scope check against requested tool
-> Synthetic request to Agent API endpoint
-> Response materialized as MCP content
-> JSON or SSE back to client
関連情報
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。