mcpField
G
grafana-api

grafana-api

github.com/anthropicsクラウド・DevOps7442 回インストール3 週間前に更新
リポジトリ

grafana-api について

grafana-apiは、Grafanaインスタンスを操作するためのHTTP APIスキルです。ダッシュボード、データソース、アラート、アノテーション、フォルダーを扱い、各エンドポイントの形式やエラー処理も説明します。

主な機能

  1. 01ダッシュボードとフォルダーの検索
  2. 02ダッシュボードの読み取りと更新
  3. 03Prometheus、Loki、SQLのクエリ
  4. 04アラートルールとサイレンスの管理
  5. 05アノテーションとフォルダーの作成
  6. 06ページネーションとAPIエラーの処理

活用シーン

  1. 01キーワードやフォルダーでダッシュボードを検索
  2. 02パネルの確認とデータソースへのクエリ
  3. 03アラート状態の確認やサイレンスの作成
  4. 04デプロイをアノテーションとして記録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/anthropics/claude-tag-plugins --skill grafana-api

インストール後、Claude Code で/grafana-apiを入力して読み込まれたか確認します。

同梱ファイルreferences/api.md

詳細

Grafana のベース URL はインスタンスの URL です。Grafana Cloud の場合は https://<your-org>.grafana.net、セルフホストの場合は 組織が運用している場所(例:https://grafana.example.com)です。API の仕様は同じで、異なるのは ベース URL だけです。

エンドポイントによって時間単位は統一されていません:/api/ds/query と /api/annotations は Unix ミリ秒を受け取り、アラートの状態履歴は Unix 秒を受け取ります。Alertmanager のサイレンスは RFC-3339 形式です。単位を混在させると、エラーではなく空の結果が返されます。

リクエストの設定

認証はランタイムが処理します。この API への送信リクエストには認証情報が挿入されるため、設定は不要です。トークンやキーを作成、発行、更新、検証しようとしないでください。認証情報の変数は、リクエストを正しい形式に保つためだけに存在します。未設定の場合は、任意のプレースホルダー値を設定してください。401/403 が継続して発生する場合は、このワークスペースに認証情報が設定されていません。認証のデバッグを続けるのではなく、その旨を報告してください。

インスタンス URL は実在する必要があります。すべてのリクエストパスに含まれるためです。

export GRAFANA_URL="https://grafana.example.com"   # no trailing slash
export GRAFANA_TOKEN="placeholder"                 # injected by the runtime; any value works

すべてのリクエスト:

curl -sS "${GRAFANA_URL}/api/..." -H "Authorization: Bearer ${GRAFANA_TOKEN}"

動作確認 — URL が正しく、ワークスペースが接続されていることを確認します。

curl -sS -w '\nHTTP %{http_code}\n' "${GRAFANA_URL}/api/user" -H "Authorization: Bearer ${GRAFANA_TOKEN}"
# 200 → the current user/service account. 401 → {"message":"Unauthorized"} — report it, don't debug auth.
# Service accounts also work: /api/org returns the current org.

403 は通常、設定された ID に必要なロールがないことを意味します(Viewer < Editor < Admin)。 データソースへのクエリとダッシュボードの読み取りには Viewer で十分です。

以下で使用するヘルパー(任意):

grafana() { curl -sS "$@" -H "Authorization: Bearer ${GRAFANA_TOKEN}"; }

主な操作

1. ダッシュボードとフォルダーを検索する
grafana "${GRAFANA_URL}/api/search" -G \
  --data-urlencode "query=api latency" \
  --data-urlencode "type=dash-db" \
  --data-urlencode "limit=50" | jq '.[] | {uid, title, folderTitle, url}'

type は dash-db(ダッシュボード)または dash-folder(フォルダー)です。両方を対象にする場合は省略します。そのほかに、tag=、 folderUIDs=、starred=true を指定できます。

2. UID でダッシュボードを取得する

UID はダッシュボードの URL に含まれる短い文字列です:.../d/<uid>/<slug>。

grafana "${GRAFANA_URL}/api/dashboards/uid/abc123xy" | \
  jq '{title: .dashboard.title, folder: .meta.folderTitle, panels: [.dashboard.panels[]? | {id, title, type}]}'

各パネルの PromQL/LogQL/SQL は .dashboard.panels[].targets にあります。無効な UID を指定すると {"message":"Dashboard not found"}(404)が返されます。

3. データソースにクエリを実行する

パネルと同じ質問をする方法です。まずデータソースの UID を検索します。

grafana "${GRAFANA_URL}/api/datasources" | jq '.[] | {uid, name, type}'

次に /api/ds/query に POST します。queries[] の形式はデータソースの type によって異なります。以下は Prometheus の例です。

NOW_MS=$(( $(date +%s) * 1000 )); FROM_MS=$(( NOW_MS - 3600000 ))
grafana -X POST "${GRAFANA_URL}/api/ds/query" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "'"${FROM_MS}"'",
    "to": "'"${NOW_MS}"'",
    "queries": [{
      "refId": "A",
      "datasource": {"uid": "<datasource_uid>"},
      "expr": "sum(rate(http_requests_total{job=\"api\"}[5m])) by (status)",
      "intervalMs": 30000,
      "maxDataPoints": 500
    }]
  }' | jq '.results.A.error // .results.A.frames[0].data.values'

Loki の場合は "expr": "{job=\"api\"} |= \"error\"" を使用し、必要に応じて "queryType": "range" を指定します。SQL データソースの場合は "rawSql": "SELECT ..." と "format": "table" を使用します。

レスポンスは Grafana の データフレームです。results.<refId>.frames[] に格納され、data.values に対応する列の配列が、 schema.fields に列のメタデータが含まれます。データソース側でエラーが発生した場合、frames は空になり、Prometheus/Loki/SQL からのエラーは results.<refId>.error に格納されます — HTTP ステータスは 200 または 500 のままの場合があるため、ステータスだけに頼らず、このフィールドを確認してください。

4. アラートルールを一覧表示する

用途の異なる 2 つのエンドポイントがあります。

# live STATE (firing/pending/inactive) — read-only
grafana "${GRAFANA_URL}/api/prometheus/grafana/api/v1/rules" | \
  jq '.data.groups[]? | {folder: .file, group: .name, rules: [.rules[] | {name, state, health}]}'

# DEFINITIONS (query, condition, labels, for-duration) — full CRUD, no runtime state
grafana "${GRAFANA_URL}/api/v1/provisioning/alert-rules" | jq '.[] | {uid, title, folderUID, condition}'

最初のパスにある grafana は、組み込み Alertmanager のリテラルな {am_name} です。外部の Alertmanager には、データソース UID を使用します。プロビジョニング API 経由で書き込まれたリソースは、書き込み時に X-Disable-Provenance: true を送信しない限り、UI でロックされます。

5. サイレンス

startsAt/endsAt は RFC-3339 形式です(date -u +%Y-%m-%dT%H:%M:%SZ)。

# active silences
grafana "${GRAFANA_URL}/api/alertmanager/grafana/api/v2/silences" | \
  jq '.[] | select(.status.state=="active") | {id, comment, matchers, endsAt}'

# create a 2-hour silence matching a label
# GNU date; on BSD/macOS use: date -u -v+2H +%Y-%m-%dT%H:%M:%SZ
START=$(date -u +%Y-%m-%dT%H:%M:%SZ)
END=$(date -u -d "+2 hours" +%Y-%m-%dT%H:%M:%SZ)
grafana -X POST "${GRAFANA_URL}/api/alertmanager/grafana/api/v2/silences" \
  -H "Content-Type: application/json" \
  -d '{
    "matchers": [{"name": "alertname", "value": "HighErrorRate", "isRegex": false, "isEqual": true}],
    "startsAt": "'"${START}"'", "endsAt": "'"${END}"'",
    "createdBy": "api", "comment": "investigating"
  }'
# success → {"silenceID": "..."}

# expire a silence
grafana -X DELETE "${GRAFANA_URL}/api/alertmanager/grafana/api/v2/silence/<silence_id>"
6. アノテーション

time/timeEnd は Unix ミリ秒です。

grafana -X POST "${GRAFANA_URL}/api/annotations" -H "Content-Type: application/json" \
  -d '{"time": '"$(( $(date +%s) * 1000 ))"', "tags": ["deploy","api"], "text": "Deployed v2.3.1"}'

grafana "${GRAFANA_URL}/api/annotations?from=${FROM_MS}&to=${NOW_MS}&tags=deploy" | jq .
7. フォルダー
grafana "${GRAFANA_URL}/api/folders" | jq '.[] | {uid, title}'
grafana -X POST "${GRAFANA_URL}/api/folders" -H "Content-Type: application/json" -d '{"title": "Team API"}'
8. ダッシュボードを作成または更新する
grafana -X POST "${GRAFANA_URL}/api/dashboards/db" \
  -H "Content-Type: application/json" \
  -d '{
    "dashboard": {"uid": null, "title": "My Dashboard", "panels": [], "schemaVersion": 41},
    "folderUid": "<folder_uid>",
    "overwrite": false,
    "message": "created via API"
  }'

更新する場合は、まずダッシュボードを GET し、変更を適用したJSON 全体を送信してください。このエンドポイントはダッシュボードを置き換えます。dashboard.uid を既存の UID に設定し、現在の dashboard.version を含めるか(不一致の場合、Grafana は 412 を返します)、overwrite: true を設定してください。

ページネーション

/api/search と /api/folders では、limit と page のクエリパラメーターを使用します(1 始まり)。/api/search のデフォルトは 1000 で、上限は 5000 です。/api/annotations には limit(デフォルトは 100)がありますが、page はありません — 代わりに from/to の期間を狭めてください。Alertmanager のエンドポイントにはページネーションがありません。上限に達した場合は、すべてのページを取得するのではなく、query=、 tag=、または folderUIDs= で絞り込んでください。

レート制限

セルフホスト版の Grafana には、デフォルトでトークンごとのレート制限が組み込まれていません。Grafana Cloud では、大量の API リクエストやクエリがあると 429 が返される場合があります。制限はプランやエンドポイントによって異なるため、Retry-After が指定されていればそれに従い、指定されていなければリクエスト間隔を空けてください。 /api/ds/query は負荷の高い処理です。呼び出しごとに基盤のデータベースへリクエストが送られるため、ループではなく、複数の queries[] を 1 つのリクエストにまとめてください。

エラー処理

エラー本文には常に "message" が含まれます(場合によっては "messageId"/"traceID" も含まれます)。サービス固有のケースは次のとおりです。

  • 412 — ダッシュボード保存時のバージョン競合です。最新の状態を GET で取得し、変更を再適用して version を含めるか、overwrite: true を設定してください。
  • 200/500 on /api/ds/query — データソース側のエラーです。Prometheus/Loki/SQL のエラーは results.<refId>.error に含まれ、frames は空になります。
  • 403 — ロールの権限が不十分です。Viewer < Editor < Admin の順で権限が高くなります。フォルダー単位の権限も適用されます。

401 → このワークスペースに認証情報が設定されていません(報告し、デバッグは行わないでください)。UID はタイトルではなく、大文字と小文字を区別する短い文字列です。

さらに詳しく

references/api.md には、エンドポイントの完全な一覧があります。ダッシュボード、フォルダー、データソース、データソースごとの ds/query の形式、統合アラート機能の全項目(アラートルール、コンタクトポイント、通知ポリシー、ミュートタイミング、Alertmanager)、アノテーション、スナップショット、組織/ユーザー/チーム、サービスアカウント、短縮 URL が含まれます。上記以外のエンドポイントが必要な場合は参照してください。

コメント