list_teamsLABSCO SUMMARY
Grafana publishes the RBAC action and scope for every single tool, which makes least privilege actually achievable.
That table is the reason to run this with a purpose-built service account rather than an Editor token: you can grant datasources:query on two specific datasource UIDs and know exactly which tools still work. The optional categories go the same way — administration and the heavier datasource integrations are off until named, so a connection starts narrow and widens on purpose. Worth knowing before your first call: fetching a large dashboard by UID returns the whole JSON, and the summary and property tools exist precisely because that can swallow a context window.
What it is
Grafana's own server for a Grafana instance, open source or Cloud. It reaches dashboards, datasources and the query languages behind them, plus alerting, incidents, Sift investigations, OnCall and administration.
What you get
- Dashboards found, read whole or in parts, summarized without the full JSON, and created or updated — search_dashboards, get_dashboard_by_uid, get_dashboard_summary, get_dashboard_property, get_dashboard_panel_queries, update_dashboard
- Datasources listed and resolved by UID or name, with example queries per type — list_datasources, get_datasource, get_query_examples
- Prometheus queried directly, including histograms, with metric names, metadata and label discovery — query_prometheus, query_prometheus_histogram, list_prometheus_metric_names, list_prometheus_metric_metadata, list_prometheus_label_names, list_prometheus_label_values
- Loki logs, patterns, stats and labels — query_loki_logs, query_loki_patterns, query_loki_stats, list_loki_label_names, list_loki_label_values
- Optional datasource categories that stay off until you enable them: ClickHouse, CloudWatch, InfluxDB, Snowflake, Elasticsearch and Quickwit, each with its own query and table tools
- Profiling through Pyroscope — query_pyroscope, list_pyroscope_profile_types, list_pyroscope_label_names, list_pyroscope_label_values
- Alerting and on-call: alert rules, routing and silences managed, alert groups and schedules read, and who is on call right now — alerting_manage_rules, alerting_manage_routing, alerting_manage_silences, list_alert_groups, get_current_oncall_users, list_oncall_schedules
- Incident response: incidents created, updated and annotated, and Sift investigations run to find error patterns and slow requests — create_incident, update_incident, add_activity_to_incident, list_incidents, find_error_pattern_logs, find_slow_requests, get_sift_analysis
- The surrounding furniture — folders, annotations, snapshots, deeplinks, provisioning checks, rendered panel images, and Grafana Assistant — create_folder, get_annotations, create_annotation, create_snapshot, generate_deeplink, get_panel_image, list_provisioning_repositories, ask_assistant
- Administration behind its own switch: teams, users, roles, assignments and resource permissions — list_teams, list_users_by_org, list_all_roles, get_role_details, get_resource_permissions
Requirements
Grafana 9.0 or later, and a service account token in GRAFANA_SERVICE_ACCOUNT_TOKEN with GRAFANA_URL pointing at the instance — your own host, or the Grafana Cloud URL. Run it with uvx as mcp-grafana, or from the binary, Docker image or Helm chart. Permissions are per tool: each one needs its own RBAC action and a matching scope, such as datasources:query on datasources:uid:prometheus-prod. Whole categories — Admin, Assistant, ClickHouse, CloudWatch, Snowflake, Elasticsearch, Quickwit, Examples and run_panel_query among them — stay off until you name them in --enabled-tools.
Setup effort
One command plus a key — uvx mcp-grafana, then supply credentials
USE CASES
Investigating an alert that just fired
Read the alert group, query the metric behind it over the relevant window, then look at the logs from the same period.
Understanding a dashboard you did not build
Take the summary rather than the full JSON, then pull the panel queries for the panels that matter.
Finding which metric or label actually exists
List metric names and label values from the datasource before writing a query against guessed names.
Running an incident from where you already are
Open the incident, add what you learn as activity, and update it as the picture changes.
Working out who to wake up
Check who is on call now and which schedule they are covering before escalating.
Putting a picture of the problem into a write-up
Render the panel as an image and generate a deeplink to the same view for whoever reads it next.
97 tools
Listed in project docs. Your client may show a different list.
list_users_by_orglist_all_rolesget_role_detailsget_role_assignmentslist_user_roleslist_team_rolesget_resource_permissionsget_resource_descriptionsearch_dashboardsget_dashboard_by_uidupdate_dashboardget_dashboard_panel_queriesrun_panel_queryget_dashboard_propertyget_dashboard_summarylist_datasourcesget_datasourceget_query_examplesquery_prometheuslist_prometheus_metric_metadatalist_prometheus_metric_nameslist_prometheus_label_nameslist_prometheus_label_valuesquery_prometheus_histogramlist_incidentscreate_incidentadd_activity_to_incidentupdate_incidentget_incidentquery_loki_logslist_loki_label_nameslist_loki_label_valuesquery_loki_statsquery_loki_patternsanalyze_loki_labelssuggest_loki_alloy_label_configquery_influxdblist_clickhouse_tablesdescribe_clickhouse_tablequery_clickhouselist_cloudwatch_namespaceslist_cloudwatch_metricslist_cloudwatch_dimensionsquery_cloudwatchlist_athena_catalogslist_athena_databaseslist_athena_tablesdescribe_athena_tablequery_athenaquery_elasticsearchquery_quickwitlist_snowflake_tablesdescribe_snowflake_tablequery_snowflakealerting_manage_rulesalerting_manage_routingalerting_manage_silenceslist_oncall_schedulesget_oncall_shiftget_current_oncall_userslist_oncall_teamslist_oncall_userslist_alert_groupsget_alert_groupupdate_alert_groupget_sift_investigationget_sift_analysislist_sift_investigationsfind_error_pattern_logsfind_slow_requestslist_pyroscope_label_nameslist_pyroscope_label_valueslist_pyroscope_profile_typesquery_pyroscopeget_assertionsagento11y_manage_conversationsagento11y_manage_generationsagento11y_manage_agentsagento11y_manage_evaluatorsagento11y_manage_eval_rulesagento11y_manage_eval_collectionsagento11y_manage_experimentsagento11y_manage_test_suitesask_assistantgenerate_deeplinkget_annotationscreate_annotationupdate_annotationget_annotation_tagslist_snapshotsget_snapshotcreate_snapshotdelete_snapshotget_panel_imagelist_provisioning_repositoriesvalidate_provisioning_fileBEFORE YOU INSTALL
What to know first
Tools you get
97 tools named in the project's documentation.
Requires
- uvx on PATH
- GRAFANA_SERVICE_ACCOUNT_TOKEN in your environment
Optional
- GRAFANA_USERNAME in your environment
- GRAFANA_PASSWORD in your environment
INSTALLATION
Connect your client
Server setup
uvx
uvx mcp-grafanaHosted endpoint
https://mcp.grafana.com/mcpAdd this hosted endpoint to your MCP client using the credentials listed under Requirements.
MCP Clients
Claude Desktop — Docker
{
"mcpServers": {
"grafana": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"-e",
"GRAFANA_URL",
"-e",
"GRAFANA_SERVICE_ACCOUNT_TOKEN",
"grafana/mcp-grafana",
"-t",
"stdio"
],
"env": {
"GRAFANA_URL": "http://localhost:3000",
"GRAFANA_SERVICE_ACCOUNT_TOKEN": "<YOUR_GRAFANA_SERVICE_ACCOUNT_TOKEN>"
}
}
}
}The configuration on this page does not set GRAFANA_USERNAME or GRAFANA_PASSWORD. They are the basic-auth alternative to GRAFANA_SERVICE_ACCOUNT_TOKEN, and the project's own client example sets them in the server's env block next to GRAFANA_URL. For the Docker setup, pass each one with -e the way the token is passed.
VS Code
This connects to the server running in SSE mode, which is the Docker image's default. Start it first, publishing port 8000:
docker run --rm -p 8000:8000 -e GRAFANA_URL=http://localhost:3000 -e GRAFANA_SERVICE_ACCOUNT_TOKEN=<YOUR_GRAFANA_SERVICE_ACCOUNT_TOKEN> -e MCP_GRAFANA_SERVER_TOKEN=<YOUR_MCP_GRAFANA_SERVER_TOKEN> grafana/mcp-grafanaThen add this to your VS Code MCP configuration:
{
"servers": {
"grafana": {
"type": "sse",
"url": "http://localhost:8000/sse",
"headers": {
"Authorization": "Bearer <YOUR_MCP_GRAFANA_SERVER_TOKEN>"
}
}
}
}MCP_GRAFANA_SERVER_TOKEN makes the server reject any request without Authorization: Bearer <YOUR_MCP_GRAFANA_SERVER_TOKEN>, so the block sends that header — use the same token in both places. Without the variable the server still starts, but logs a security error.