Claude Media
mcp-grafanaでダッシュボードを読む — summaryとJSONPathの使い分け

mcp-grafanaでダッシュボードを読む — summaryとJSONPathの使い分け

mcp-grafanaのダッシュボード系ツールを、全JSONを返すget_dashboard_by_uidとsummary・JSONPath・patchで比べ、コンテキストを溢れさせない読み方と書き換え方を示します。

mcp-grafanaには、ダッシュボードを読むツールが複数あります。全JSONを返すget_dashboard_by_uid、概要だけを返すget_dashboard_summary、JSONPathで一部だけ抜くget_dashboard_propertyです。どれを呼ぶかで、会話に流れ込むトークン量は大きく変わります。公式READMEは、大きなダッシュボードの全JSONがコンテキストウィンドウを大きく消費すると警告しています。

結論は単純です。最初はget_dashboard_summary、中身が要るところだけget_dashboard_property、変更はupdate_dashboardのpatchモード。全JSONの取得は、本当に全体が要るときだけに回します。導入とRBACの設計はmcp-grafanaの導入とRBAC設計にあるので、ここではツールの選び方に絞ります。

3つの読み取りツールは何が違うのか

READMEのDashboards節には、ダッシュボード系ツールが次のように並んでいます。コンテキストへの影響が大きい順に見ると、使い分けの軸がはっきりします。

ツール返すものコンテキスト消費
get_dashboard_by_uid返すものパネル・変数・設定を含む完全なJSONコンテキスト消費大きい(公式が警告)
get_dashboard_summary返すものタイトル・パネル数・パネル種別・変数・メタデータコンテキスト消費小さい
get_dashboard_property返すものJSONPathで指定した部分だけコンテキスト消費指定した範囲だけ
get_dashboard_panel_queries返すもの全パネルのタイトル・クエリ文字列・データソース情報コンテキスト消費中間

READMEは「Context Window Management」という小節で、この順の使い方を明示しています。概要の把握と変更の計画にはget_dashboard_summary、必要な部分だけならget_dashboard_property、完全なJSONが本当に必要なときを除いてget_dashboard_by_uidを避ける、という3点です。この小節は、リポジトリのissue #101で議論された対策として書かれています。

summaryが返す項目

ソースコード上のDashboardSummary型を見ると、返る項目が具体的に分かります。UID、タイトル、説明、タグ、パネル数、パネルごとの要約、変数の要約、時間範囲、リフレッシュ間隔、メタデータです。

パネルの要約に入るのは、ID・タイトル・種別・説明・クエリ数までです。クエリの中身(PromQLやLogQLの式)は入りません。変数も名前・種別・ラベルだけで、選択肢の一覧までは含みません。「どんなパネルがいくつあるか」は分かっても、「このパネルが何を計算しているか」はsummaryからは分からない設計です。

propertyはJSONPathで切り出す

get_dashboard_propertyは、UIDとJSONPath式を受け取ります。ツール説明には、クラシック形式(v1)の例として次の式が挙がっています。

知りたいことJSONPath
タイトルJSONPath$.title
全パネルのタイトルJSONPath$.panels[*].title
最初のパネル全体JSONPath$.panels[0]
変数の定義JSONPath$.templating.list
保存済みの注釈クエリJSONPath$.annotations.list
タグJSONPath$.tags
全パネルのクエリ式JSONPath$.panels[*].targets[*].expr

呼び出しの引数は、例えば次のような形になります(ツール定義のパラメータ名に沿った例です)。

{
  "uid": "<dashboard-uid>",
  "jsonPath": "$.panels[*].targets[*].expr"
}

この式なら、数百行のレイアウト情報やスタイル設定は流れ込まず、クエリ式の配列だけが返ります。

実際の読み進め方は3段階になる

目的別に並べると、次の流れが基本形です。

  1. search_dashboardsでUIDを特定する
  2. get_dashboard_summaryで構造を把握する(パネル数、種別、変数)
  3. 気になるパネルだけget_dashboard_propertyで掘る

たとえば「レイテンシ系のパネルのクエリを確認したい」なら、summaryでパネルのタイトル一覧から該当のインデックスを探します。その後、$.panels[3].targetsのように1パネル分だけ取得します。全パネルのクエリが要るなら、get_dashboard_panel_queriesが使えます。こちらはパネルIDで1枚に絞ることもできます。

全JSONを取りに行ってよい場面

完全なJSONが必要なのは、ダッシュボードを別環境へ丸ごと複製する場合や、スキーマ全体を見て移行を計画する場合です。get_dashboard_by_uidにはオプションのversion引数があり、保存済みのスナップショットを読めます。版の差分を見るならlist_dashboard_versionsで版番号・作者・時刻・保存メッセージのメタデータだけを先に取り、必要な版だけversion付きで読むほうが無駄がありません。

変更はpatchで小さく書く

書き込み側にも同じ構造があります。READMEはupdate_dashboardについて、完全なダッシュボードJSONを渡す方式は大量のコンテキストを使うと警告し、patch方式は全JSON不要で、的を絞った変更のコンテキスト消費を大きく減らせると説明しています。

ソースコードでは、update_dashboardが2つのモードを持っています。

  • dashboardに完全なJSONを渡す(新規作成や全面置換)
  • uidとoperationsを渡す(既存ダッシュボードへの部分変更)

operationsの各要素は、op(replace・add・removeのいずれか)、path、valueで構成されます。例えばパネルのクエリ式を1つ差し替える呼び出しは、次のような形です。

{
  "uid": "<dashboard-uid>",
  "operations": [
    {
      "op": "replace",
      "path": "$.panels[0].targets[0].expr",
      "value": "sum(rate(http_requests_total[5m]))"
    }
  ],
  "message": "リクエストレートの式を更新"
}

messageはバージョン履歴に残る保存メッセージです。変更の理由を書いておくと、あとからlist_dashboard_versionsで追えます。

patchの制約を知っておく

ツール説明には、patchのパスに関する制約が明記されています。

  • パスに使える添字は数値のみ
  • [?(@.id==2)]のようなフィルタ式と、[*]のようなワイルドカードは使えない
  • 配列への追加は/-の書き方($.templating.list/-、$.panels/-など)
  • 同じ配列に対する複数のremoveは、添字のずれを避けるため自動で並べ替えられる

ここがreadとwriteの非対称な点です。get_dashboard_propertyは$.panels[*].titleのようなワイルドカードを受け付けますが、patchでは使えません。読むときはワイルドカードで全体を見渡し、書くときは数値の添字を確定させて1つずつ指定します。また、uidだけを渡してoperationsを省くと、ツールはエラーを返します。

ツールごとの権限と、読み取り専用運用との関係

READMEのRBAC表では、読み取り系のダッシュボードツールは同じ権限で動きます。get_dashboard_by_uid・get_dashboard_property・get_dashboard_summary・get_dashboard_panel_queriesはいずれもdashboards:readが要り、スコープはdashboards:uid:abc123のようにUID単位で絞れます。トークンを節約するための使い分けは、権限を増やさずにできるということです。

一方のupdate_dashboardは、dashboards:create・dashboards:write・folders:readなどが必要です。ツールにはdestructiveのヒントが付いていて、読み取り系とは性格が違います。変更までClaudeに任せない環境では、--disable-writeで書き込み系ツールをまとめて外せます。その場合はsummaryとpropertyだけが残り、トークン効率の議論と安全面の議論が同じ方向を向きます。

パネルのクエリを実際に動かしたいとき

get_dashboard_panel_queriesが返すのは、パネルのタイトル、クエリ文字列、データソースのUIDと種別です。panelIdで1枚に絞り、variablesで変数を置き換えて渡せます。式を読むだけならここまでで足ります。

式を実行して結果まで見たい場合はrun_panel_queryです。ただしRun panel queryのツールは既定で無効で、有効にするには--enabled-toolsにrunpanelqueryを加えます。実行にはdatasources:queryも要ります。ダッシュボードの構造確認までで済む作業なら、有効にしないままのほうが露出するツールの数を抑えられます。

具体例: 重いパネルの式を直す流れ

「ダッシュボードの遅いパネルを軽くしたい」という依頼を例に、ツールの呼び出しを並べます。

  1. search_dashboardsでUIDを特定する
  2. get_dashboard_summaryで、パネルのタイトル・種別・クエリ数を見て対象を絞る
  3. get_dashboard_panel_queriesにpanelIdを渡し、該当パネルの式とデータソースを確認する
  4. 式を書き換える案をClaudeが作り、update_dashboardのpatchで$.panels[n].targets[0].exprだけを差し替える
  5. list_dashboard_versionsで保存履歴を確かめる

この流れで全JSONを読む場面は一度もありません。パネル数が多いダッシュボードほど、手順2と3で済ませる効果が出ます。手順4のnは、手順2で得たパネル一覧の並びから数値で確定させます。ワイルドカードが使えないので、推測で添字を書かずに、直前に$.panels[n].titleをpropertyで引いて対象を確認してから書くと、別のパネルを上書きする事故を避けられます。

落とし穴と設定での歯止め

v2スキーマではパスが変わる

新しいGrafanaにはv2形式のダッシュボードがあり、get_dashboard_by_uidの応答にはisV2とapiVersionが含まれます。v2では、パネルがpanels[]ではなくelementsにキー付きで入り、配置はlayoutが持ちます。変数はvariablesです。

ツール説明によれば、v2のpropertyパスは$.elements、$.variables、$.annotationsなどで、patchのパス例は$.elements.<name>.spec.titleや$.variables/-です。v1用の$.panels[0]を前提にした手順は、v2のダッシュボードには当てはまりません。既存のダッシュボードは、保存されているスキーマのまま扱う方針がツール説明に書かれています。最初のsummaryで構造を確かめてから、パスを決めるのが安全です。

propertyで通信量が減るわけではない

ソースを読むと、get_dashboard_propertyは内部でダッシュボード全体を取得してから、JSONPathで抜き出しています。Grafana APIとMCPサーバー間のやり取りは全JSON分のまま、Claudeに返る分だけが小さくなります。節約されるのはコンテキストとトークンであり、Grafana側の負荷ではない点は、巨大なダッシュボードを何度も読む運用で意識しておく価値があります。

運用側で歯止めをかける

Claudeに任せていると、気づかないうちにget_dashboard_by_uidが呼ばれることがあります。Claude Codeの権限設定で、このツールを拒否できます。MCPツールの名前はmcp__<サーバー名>__<ツール名>の形で、deny規則に書けば、そのツールはClaudeのコンテキストから取り除かれます。サーバー名をgrafanaとして登録している場合、.claude/settings.jsonは例えば次のようになります。

{
  "permissions": {
    "deny": [
      "mcp__grafana__get_dashboard_by_uid"
    ]
  }
}

この設定を入れると、全JSONの取得が必要な作業もできなくなります。複製や移行の作業をするときだけ、この行を外す運用になります。常用せずに、CLAUDE.mdの指示で「最初にsummary、次にproperty」と書く方法でも、呼び出しの順序はかなり誘導できます。

## Grafanaダッシュボードの扱い
- 最初に get_dashboard_summary で構造を確認する
- 中身は get_dashboard_property のJSONPathで必要な部分だけ取る
- 変更は update_dashboard の uid + operations で行い、全JSONは渡さない

ツール定義そのものが重い場合は、カテゴリ単位で外す方法もあります。--disable-<category>で使わないカテゴリを止める手順は導入とRBAC設計の記事で扱っています。ツール定義がコンテキストを圧迫する仕組みはMCPのツール定義とコンテキスト圧迫に詳しくあります。

消費量は実測して確かめる

ダッシュボードの大きさは、パネル数・データソース・設定の細かさで数倍も変わります。どのツールがどれだけ使ったかは、Claude Codeのコンテキスト表示で確認できます。手順はClaude Codeのコンテキストウィンドウを可視化する方法にまとめています。summaryで済む作業と、全JSONが要る作業を実測で切り分けておくと、CLAUDE.mdの指示もチームの運用ルールも決めやすくなります。

まとめ

mcp-grafanaのダッシュボード操作は、読む側も書く側も「全体を渡す」か「部分だけ渡す」かの選択になっています。

  • 構造の把握はsummary。クエリ式は入らない
  • 中身の取得はJSONPathのproperty。v1とv2でパスが違う
  • 変更はuidとoperationsのpatch。ワイルドカードとフィルタは使えない
  • 全JSONの取得は、複製や移行など全体が要る場面に限る

大きなダッシュボードを何枚も扱うほど、この差は効いてきます。

この記事を共有:XはてブLinkedIn