Claude Media
Grafana OnCallをClaudeで操作しオンコール対応を自動化する

Grafana OnCallをClaudeで操作しオンコール対応を自動化する

mcp-grafanaのOnCallツール群で、今の当番確認・アラートグループの検索と応答をClaude Codeから行う手順と、stateの値やRBACで詰まる点をまとめます。

障害の一次対応で「今、誰が当番か」「このアラートグループは誰かが確認済みか」を調べるためだけにGrafanaの画面を開く手間は、Claude Codeに任せられます。mcp-grafanaのOnCallツール群は、スケジュール・シフト・当番ユーザー・アラートグループの参照から、アラートグループの確認応答・解決までを扱います。

この記事は、ツールの一覧を並べる代わりに、実際に聞くときの順序と、つまずきやすい値の違いを軸に書いています。ツールの名前・引数・権限はmcp-grafanaのREADMEとソース(tools/oncall.go)で照合した内容です。

OnCallカテゴリの8つのツールと有効化

mcp-grafanaのOnCallカテゴリは8つのツールで構成されます。参照用は7つで、list_oncall_schedules、get_oncall_shift、get_current_oncall_users、list_oncall_teams、list_oncall_users、list_alert_groups、get_alert_groupです。書き込みはupdate_alert_groupの1つだけです。ダッシュボード操作やLoki・Prometheusのクエリ実行とは独立していて、障害対応の「今の状態」に絞ったツール群です。

インストール手順とRBACスコープ設計の全体はmcp-grafanaの導入とRBAC設計にあります。OnCallは既定で有効なカテゴリに含まれるため、--disable-oncallを付けない限り追加設定なしで使えます。OnCall対応のサービスアカウントを別に用意するなら、--enabled-toolsでカテゴリを絞ります。

claude mcp add-json grafana-oncall \
  '{"command":"uvx","args":["mcp-grafana","--enabled-tools","oncall,alerting,incident"],"env":{"GRAFANA_URL":"https://myinstance.grafana.net","GRAFANA_SERVICE_ACCOUNT_TOKEN":"<サービスアカウントトークン>"}}'

claude mcp add-jsonは-s, --scope <scope>でlocal / user / projectを選べ、既定はlocalです。Claude Code v2.1.287の--helpで確認しました。トークンを含む設定をprojectスコープに置くとリポジトリに入りうるため、サービスアカウントトークンは既定のlocalのまま登録する形が無難です。

「今の当番は誰か」を聞くときの流れ

get_current_oncall_usersが受け取るのはスケジュールのID(scheduleId、必須)で、スケジュール名ではありません。そのため「〇〇スケジュールの今の当番は?」と聞くと、Claudeは先にlist_oncall_schedulesで名前をIDに引き、そのあとで当番を取りに行きます。返るのはスケジュールのIDと名前、そして当番ユーザーの詳細(ID・ユーザー名・メールアドレス・ロール)です。

流れ

当番を引くまでの呼び出し順

  1. 1

    チームを絞る(任意)

    list_oncall_teamsでチーム一覧を取り、チームIDを得ます。スケジュールが1つしかない環境なら飛ばせます。

  2. 2

    スケジュールIDを得る

    list_oncall_schedulesにチームID(teamId)を渡して絞り込みます。返る要約にはID・名前・チームID・タイムゾーン・シフトIDの一覧が入ります。

  3. 3

    当番を取得する

    get_current_oncall_usersにスケジュールIDを渡します。複数のスケジュールを聞かれたときは、Claudeがスケジュールの数だけこの呼び出しを繰り返します。

  4. 4

    シフトの中身を見る(任意)

    list_oncall_schedulesが返したシフトIDをget_oncall_shiftに渡すと、そのシフトの詳細が取れます。引き継ぎ時刻を確認したいときに使います。

list_oncall_schedules・list_oncall_teams・list_oncall_usersにはページ番号(page)の引数があります。スケジュールやユーザーが多い組織では、1回の応答に全件が入らない前提で聞くと取りこぼしを避けられます。

list_oncall_usersはuserIdかusernameで1人に絞れます。「この当番の人のメールアドレスは?」のような追い質問は、当番取得の結果にメールアドレスが含まれているため、追加のツール呼び出しなしで答えられるはずです。

アラートグループを検索する

発生中の障害を洗い出すにはlist_alert_groupsを使います。ここで一番つまずきやすいのは、状態(state)の値にfiringが存在しないことです。state引数が受け付けるのはnew・acknowledged・resolved・silencedの4つで、ツールの説明文にもそう書かれています。Prometheus系の用語に慣れていると「firingのものを出して」と書きたくなりますが、OnCall側で「まだ誰も反応していない」状態はnewです。

絞り込み引数指定の形式
状態引数state指定の形式new / acknowledged / resolved / silenced
発生時刻引数startedAt指定の形式開始_終了のISO 8601(例: 2025-01-19T00:00:00_2025-01-19T23:59:59)
ラベル引数labels指定の形式key:valueの配列(例: env:prod)
そのほか引数id routeId integrationId teamId name指定の形式該当IDまたは名前

startedAtは2つの時刻を_でつなぐ書式で、「過去1時間」のような相対表現はそのままでは渡せません。自然言語で「過去1時間」と聞いた場合、Claudeが現在時刻から開始・終了を計算して渡す形になります。UTCが前提でタイムゾーン表記は不要と説明されているため、日本時間で聞くときは9時間のずれが混ざっていないかを結果の時刻で確かめてください。

組み合わせの例は次のとおりです。

環境ラベルがprodで、まだ誰も確認していない(new)アラートグループを、
2025-01-19の1日分だけ一覧にして

この聞き方なら、Claudeは3つの引数へ展開するはずです。state: new、labels: ["env:prod"]、startedAt: 2025-01-19T00:00:00_2025-01-19T23:59:59の組み合わせです。

返るアラートグループの要約はtools/oncall_types.goのOnCallAlertGroupで定義されています。中身はID・インテグレーションID・アラート件数・状態・タイトル・permalinkと、作成・確認・解決・サイレンスの各時刻、ラベル、チームです。個別の詳細はget_alert_groupにアラートグループのIDを渡して取ります。

update_alert_groupで応答する

対応そのものはupdate_alert_groupが担当します。引数はalertGroupIdとstateの2つで、stateにはacknowledged・unacknowledged・resolved・unresolvedのいずれかを渡します。読み取り専用のツールが並ぶOnCallカテゴリの中で、書き込みはこの1つだけです。

見落としやすいのは、stateの4つの値のうちunacknowledgedとunresolvedが状態の名前ではなく操作の名前である点です。ソースのコメントにも、OnCallが実際に報告する状態はnew・acknowledged・resolved・silencedの4つだけだと書かれています。つまり、list_alert_groupsで絞り込むときの値と、update_alert_groupに渡す値は別の語彙です。

くらべる

同じ「状態」でも渡す値が違う

state

list_alert_groups(読む側)

new / acknowledged / resolved / silenced。OnCallが報告する状態そのものを指定します。

state

update_alert_group(書く側)

acknowledged / unacknowledged / resolved / unresolved。実行したい操作を指定します。silencedは渡せません。

この更新ツールは、操作が成功したあとにアラートグループを読み直し、OnCallが実際に報告する状態を結果のstateに入れて返します。ですから、確認応答のつもりが反映されていなかった場合は、返ってきたstateを見れば分かります。読み直しに失敗したときは、操作自体は成功したままstateWarningに理由が入ります。文言は原因を問わず「alert-groups:readを持っているか」を問う形です。末尾に続くエラー本文を見て、権限不足か通信の失敗かを見分けます。

もう1つ、update_alert_groupにはツールの注釈として「破壊的」(destructive)かつ「冪等でない」(idempotent: false)が付いています。MCPクライアントがこの注釈を使って確認を挟むかどうかは、クライアント側の実装次第です。Claude Codeの権限ルールで、このツールだけを都度確認にする、といった切り分けを組む余地があります。

起票まで続けるなら — Incidentツールとの組み合わせ

update_alert_groupで確認応答したあと、そのまま障害として起票して関係者を巻き込むこともできます。mcp-grafanaはGrafana Incidentのツールも別カテゴリとして持ち、「アラートグループを確認 → Incidentを作成 → 活動履歴を記録」を1つの会話でつなげられます。

Incidentのツールは6つです。参照系がlist_incidents(カスタムフィールドの値つきで一覧)、get_incident、list_incident_custom_fieldsです。書き込み系がcreate_incident、add_activity_to_incident、update_incident(ステータス・重大度・タイトル・カスタムフィールド)です。

権限の考え方がOnCallとは違います。OnCallがプラグイン固有のパーミッションで制御されるのに対し、IncidentのツールはGrafana本体の基本ロールで制御されます。READMEの記述では、参照系にViewerロール、作成・更新系にEditorロールが必要です。OnCallとIncidentの両方を同じサービスアカウントで扱うなら、プラグインのパーミッションと基本ロールを両方付与する必要があります。

任せる範囲ごとの有効化と権限

どこまでClaudeに任せるかで、必要なカテゴリと権限が変わります。

任せる範囲有効化必要な権限
当番確認有効化oncall必要な権限schedules:readとuser-settings:read
アラートグループの状況把握有効化oncall必要な権限上記 + alert-groups:read
確認応答・解決まで有効化oncall(--disable-writeなし)必要な権限上記 + alert-groups:write
障害の起票・記録まで有効化oncall, incident必要な権限上記 + Editorロール

権限名はいずれもgrafana-oncall-app.で始まります。ツールごとの対応はREADMEの表のとおり、次の形です。

ツール必要なパーミッション
list_oncall_schedules / get_oncall_shift / get_current_oncall_users必要なパーミッションgrafana-oncall-app.schedules:read
list_oncall_teams / list_oncall_users必要なパーミッションgrafana-oncall-app.user-settings:read
list_alert_groups / get_alert_group必要なパーミッションgrafana-oncall-app.alert-groups:read
update_alert_group必要なパーミッションgrafana-oncall-app.alert-groups:write(および:read)

当番の確認でschedules:readだけを付けると、途中で止まる可能性があります。チーム名からスケジュールを探す手順で、list_oncall_teamsがuser-settings:readを要求するためです。チーム名で聞く運用なら、user-settings:readも付けておくのが現実的です。

人間が最終判断する運用 — 読み取り専用で起動する

状況把握だけをClaudeに任せ、実際の確認応答は人間が行いたい場合は、起動時に--disable-writeを付けます。READMEによると、このフラグでupdate_alert_groupはツールとして登録されなくなります。ほかのカテゴリの書き込み系(create_incident・update_dashboard・create_annotationなど)も同時に外れる点に注意してください。

uvx mcp-grafana --enabled-tools "oncall" --disable-write

ソースでは、AddOnCallToolsが書き込みを許すかどうかの引数を受け取り、許さない場合はupdate_alert_groupの登録を飛ばします。参照系の7ツールは、--disable-writeの有無にかかわらず登録されます。

よくあるつまずき

スケジュール名を渡して当番が引けない: get_current_oncall_usersはスケジュールIDを要求します。名前で聞いてもClaudeが先にlist_oncall_schedulesでIDへ変換するはずですが、同名のスケジュールが複数あるとどれを指すか曖昧になります。チームIDで絞ってから引く流れにすると防げます。

書き込みを止めたつもりがカテゴリごと無効化していた: --disable-oncallはOnCallツール自体を丸ごと無効にします。参照はさせたいが確認応答だけ止めたいときは、--disable-writeを使います。両者を混同すると、当番確認まで止まります。

OnCallのAPIに届かない: OBO認証(アクセストークンとIDトークンの組)を使わない通常の構成では、mcp-grafanaはまずGrafanaの/api/plugins/grafana-irm-app/settingsを読みます。そのjsonDataから、OnCall APIのURLを取り出します。ソースにはこの段階のエラー文が2つ用意されています。「OnCall API URL is not set in settings」と「unexpected status code from settings API」です。IRMプラグインが入っていない、または設定が空のインスタンスでは、この手前で止まるはずです。権限不足と見分けるには、Grafanaでプラグインの設定が埋まっているかを先に確認してください。

まとめ

OnCallのMCPツールは、当番確認とアラートグループの状況把握を自然言語のやり取りに置き換えます。判断が要るのは、書き込みを許すサービスアカウントを分けるかどうかです。分けない場合でも、stateの語彙(読む側と書く側で別)と、スケジュールIDを経由する呼び出し順を知っておくと、結果の見間違いを減らせます。

ダッシュボードやアラートルールまで含めたRBAC設計はmcp-grafanaの導入とRBAC設計にあります。ログ調査との組み合わせはmcp-grafanaでLokiのログをLogQLなしで検索するで扱っています。

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