franroa avatar

working-with-grafana-mcp

Use when querying Grafana dashboards, Prometheus metrics, Loki logs, alerting, or incidents - provid

作者 franroa|オープンソース

Working with Grafana MCP

Overview

Grafana MCP provides tools for observability: dashboards, metrics (Prometheus), logs (Loki), alerting, and incident management. Always start with datasource discovery - most queries require a datasource UID.

Core Workflow

1. list_datasources → Find datasource UID
2. Use datasource-specific tools with that UID

Quick Reference

TaskTool(s)Notes
Find datasourceslist_datasourcesFilter by type: 'prometheus', 'loki'
Search dashboardssearch_dashboardsReturns UID, title, folder
Dashboard overviewget_dashboard_summaryLightweight - use first
Specific dashboard dataget_dashboard_propertyJSONPath: $.panels[*].title
Full dashboard JSONget_dashboard_by_uidHeavy - use sparingly
Query metricsquery_prometheusNeeds datasource UID
Query logsquery_loki_logsLogQL syntax
List alertslist_alert_rulesGrafana-managed by default
Current incidentslist_incidentsFilter by status

Datasource Discovery

Always first step - most operations need a datasource UID:

# Find all Prometheus datasources
grafana_list_datasources(type="prometheus")

# Find Loki datasources
grafana_list_datasources(type="loki")

Returns: id, uid, name, type, isDefault

Dashboard Access (Context-Efficient)

Prefer lightweight tools:

NeedUseAvoid
Dashboard exists?search_dashboards-
Panel count, typesget_dashboard_summaryget_dashboard_by_uid
Panel titlesget_dashboard_property with $.panels[*].titleget_dashboard_by_uid
Single panelget_dashboard_property with $.panels[0]get_dashboard_by_uid
Panel queriesget_dashboard_panel_queriesget_dashboard_by_uid
Full JSONget_dashboard_by_uid-

JSONPath examples:

  • $.title - Dashboard title
  • $.panels[*].title - All panel titles
  • $.panels[0].targets[0].expr - First panel's query
  • $.templating.list - Template variables

Prometheus Queries

# Instant query (single point)
grafana_query_prometheus(
    datasourceUid="PROM_UID",
    expr="up{job='myapp'}",
    startTime="now",
    queryType="instant"
)

# Range query (time series)
grafana_query_prometheus(
    datasourceUid="PROM_UID",
    expr="rate(http_requests_total[5m])",
    startTime="now-1h",
    endTime="now",
    stepSeconds=60,
    queryType="range"
)

Time formats: RFC3339 or relative (now, now-1h, now-30m)

Discover metrics:

# List metric names
grafana_list_prometheus_metric_names(datasourceUid="UID", regex="http.*")

# List label names
grafana_list_prometheus_label_names(datasourceUid="UID")

# List label values
grafana_list_prometheus_label_values(datasourceUid="UID", labelName="job")

Loki Log Queries

# Simple label query
grafana_query_loki_logs(
    datasourceUid="LOKI_UID",
    logql='{app="myapp"}',
    limit=50
)

# With filter
grafana_query_loki_logs(
    datasourceUid="LOKI_UID",
    logql='{app="myapp"} |= "error"',
    startRfc3339="2025-01-01T00:00:00Z",
    endRfc3339="2025-01-01T01:00:00Z"
)

LogQL patterns:

  • {label="value"} - Label selector
  • |= "text" - Line contains
  • != "text" - Line does not contain
  • |~ "regex" - Regex match
  • | json - Parse JSON
  • | logfmt - Parse logfmt

Check stream size first:

grafana_query_loki_stats(datasourceUid="UID", logql='{app="myapp"}')
# Returns: streams, chunks, entries, bytes

Alerting

List alerts:

grafana_list_alert_rules()  # Grafana-managed

# With label filter
grafana_list_alert_rules(
    label_selectors=[{"filters": [
        {"name": "severity", "type": "=", "value": "critical"}
    ]}]
)

Create alert rule:

grafana_create_alert_rule(
    title="High CPU Usage",
    ruleGroup="cpu-alerts",
    folderUID="alert-folder",
    condition="B",  # Reference to reducer
    data=[
        {
            "refId": "A",
            "datasourceUid": "PROM_UID",
            "model": {
                "expr": "avg(cpu_usage) > 80",
                "intervalMs": 1000,
                "maxDataPoints": 43200
            }
        },
        {
            "refId": "B",
            "datasourceUid": "__expr__",
            "model": {
                "type": "reduce",
                "expression": "A",
                "reducer": "last"
            }
        }
    ],
    noDataState="NoData",
    execErrState="Alerting",
    for_="5m",
    orgID=1
)

Incidents & OnCall

# List active incidents
grafana_list_incidents(status="active")

# Get incident details
grafana_get_incident(id="incident-id")

# Who's on call?
grafana_list_oncall_schedules()
grafana_get_current_oncall_users(scheduleId="schedule-id")

Dashboard Updates

Prefer patch operations for small changes:

grafana_update_dashboard(
    uid="dashboard-uid",
    operations=[
        {"op": "replace", "path": "$.title", "value": "New Title"},
        {"op": "replace", "path": "$.panels[0].title", "value": "Panel 1"}
    ],
    message="Updated titles"
)

Append to arrays:

  • $.panels/- - Append to panels array
  • $.panels[2]/- - Append to nested array

Common Mistakes

MistakeFix
Query without datasource UIDAlways list_datasources first
get_dashboard_by_uid for simple infoUse get_dashboard_summary or get_dashboard_property
Loki query without checking sizeUse query_loki_stats first for large ranges
Missing queryType in PrometheusSpecify instant or range
Alert without proper condition chainNeed query (A) → reducer (B) → condition references B

Investigation Tools

For troubleshooting, Grafana provides analysis tools:

# Find error patterns in logs
grafana_find_error_pattern_logs(
    name="App Errors Investigation",
    labels={"app": "myapp"}
)

# Find slow requests
grafana_find_slow_requests(
    name="Slow API Investigation",
    labels={"service": "api"}
)