Skip to main content
Version: Beta

Grafana

DiscoveryMCP

Discover and manage Grafana dashboards, datasources, folders, and instances in your Devgraph knowledge graph.

Overview

The Grafana molecule connects to Grafana's API to automatically discover observability resources. It creates entities for dashboards, datasources, folders, and the Grafana instance itself.

Key Features:

  • Discover dashboards, datasources, folders, and alert rules
  • Filter dashboards by tags, folder IDs, or UIDs
  • Track dashboard organization and folder structure
  • Link dashboards to datasources and folders
  • Support for multiple Grafana instances

Quick Start

providers:
- name: grafana
type: grafana
every: 300
config:
namespace: default
base_url: https://grafana.example.com
api_key: ${GRAFANA_API_KEY}

Configuration

Basic Configuration

providers:
- name: grafana-prod
type: grafana
every: 300
config:
namespace: production
base_url: https://grafana.example.com
api_key: ${GRAFANA_API_KEY}
org_id: 1
discover_dashboards: true
discover_datasources: true
discover_folders: true
discover_alerts: true

Filtered Discovery

providers:
- name: grafana-filtered
type: grafana
every: 600
config:
namespace: default
base_url: https://grafana.example.com
api_key: ${GRAFANA_API_KEY}
selectors:
- tags: ["production", "critical"]
folder_ids: [1, 5, 12]
- dashboard_uids: ["abc123", "def456"]

Configuration Options

OptionTypeRequiredDefaultDescription
namespacestringNodefaultNamespace for created entities
base_urlstringYes-Grafana instance URL
api_keystringYes-Grafana API key or service account token
org_idintegerNo1Grafana organization ID
discover_dashboardsbooleanNotrueEnable dashboard discovery
discover_datasourcesbooleanNotrueEnable datasource discovery
discover_foldersbooleanNotrueEnable folder discovery
discover_alertsbooleanNotrueEnable alert rule discovery
selectorslistNo[]Dashboard filter criteria

Selector Options

Filter which dashboards to discover:

OptionTypeRequiredDescription
tagslist[string]NoDashboard tags to include
folder_idslist[integer]NoFolder IDs to include (empty = all)
dashboard_uidslist[string]NoSpecific dashboard UIDs to include

Filter Logic: A dashboard is included if it matches ANY selector. Within a selector, ALL criteria must match.

Authentication

Create API Key

  1. In Grafana, go to Configuration → API Keys
  2. Click "Add API key"
  3. Set name and role:
    • Viewer role is sufficient for discovery
    • Admin role if you need full access
  4. Set expiration or choose "No expiration"
  5. Copy the key immediately (shown only once)
export GRAFANA_API_KEY="eyJrIjoixxxxxxx"

For Grafana 9.0+, use service account tokens:

  1. Go to Configuration → Service Accounts
  2. Create new service account
  3. Add permissions: dashboards:read, datasources:read
  4. Create token
  5. Copy token
api_key: ${GRAFANA_SERVICE_TOKEN}

Entities Created

GrafanaInstance

Represents the Grafana instance.

apiVersion: entities.devgraph.ai/v1
kind: GrafanaInstance
metadata:
name: grafana-example-com
namespace: default
labels:
provider: grafana
spec:
url: https://grafana.example.com
version: "9.5.3"
org_id: 1

GrafanaDashboard

Represents a Grafana dashboard.

apiVersion: entities.devgraph.ai/v1
kind: GrafanaDashboard
metadata:
name: dashboard-abc123
namespace: default
labels:
provider: grafana
dashboard_uid: abc123
tag_production: "true"
tag_critical: "true"
spec:
uid: abc123
id: 42
title: "Production API Metrics"
url: https://grafana.example.com/d/abc123/production-api-metrics
folder_id: 5
folder_uid: folder-xyz
folder_title: "Production Dashboards"
tags: ["production", "critical"]
is_starred: false

GrafanaDatasource

Represents a data source.

apiVersion: entities.devgraph.ai/v1
kind: GrafanaDatasource
metadata:
name: datasource-prom123
namespace: default
labels:
provider: grafana
datasource_type: prometheus
datasource_uid: prom123
spec:
uid: prom123
id: 1
name: "Production Prometheus"
type: prometheus
url: http://prometheus:9090
is_default: true
json_data:
timeInterval: "30s"

GrafanaFolder

Represents a dashboard folder.

apiVersion: entities.devgraph.ai/v1
kind: GrafanaFolder
metadata:
name: folder-xyz
namespace: default
labels:
provider: grafana
folder_uid: xyz
spec:
uid: xyz
id: 5
title: "Production Dashboards"
url: https://grafana.example.com/dashboards/f/xyz/production-dashboards

Relationships

Dashboard → Instance

GrafanaDashboard --HOSTED_BY--> GrafanaInstance

Datasource → Instance

GrafanaDatasource --HOSTED_BY--> GrafanaInstance

Folder → Instance

GrafanaFolder --HOSTED_BY--> GrafanaInstance

Dashboard → Folder

GrafanaDashboard --IN_FOLDER--> GrafanaFolder

Filtering Dashboards

By Tags

Discover only dashboards with specific tags:

selectors:
- tags: ["production"] # Dashboards tagged "production"
- tags: ["critical", "infrastructure"] # Has critical OR infrastructure

By Folder

Discover only dashboards in specific folders:

selectors:
- folder_ids: [1, 5, 12] # Only these folder IDs

By UID

Discover specific dashboards:

selectors:
- dashboard_uids: ["abc123", "def456", "ghi789"]

Combined Filters

All criteria in a selector must match:

selectors:
# Production dashboards in folder 5
- tags: ["production"]
folder_ids: [5]

# Critical dashboards in folder 12
- tags: ["critical"]
folder_ids: [12]

Discover Everything

Omit selectors or use empty list:

selectors: []  # Discover all dashboards

Use Cases

Multi-Environment Discovery

# Production
- name: grafana-prod
type: grafana
config:
namespace: production
base_url: https://grafana-prod.example.com
api_key: ${GRAFANA_PROD_KEY}

# Staging
- name: grafana-staging
type: grafana
config:
namespace: staging
base_url: https://grafana-staging.example.com
api_key: ${GRAFANA_STAGING_KEY}

Critical Dashboards Only

selectors:
- tags: ["critical", "sla"]

Team-Based Organization

selectors:
- folder_ids: [5] # Platform team folder
tags: ["platform"]
- folder_ids: [12] # Product team folder
tags: ["product"]

Selective Discovery

# Only discover dashboards and datasources, skip folders/alerts
discover_dashboards: true
discover_datasources: true
discover_folders: false
discover_alerts: false

Troubleshooting

Authentication Errors

Symptom: "401 Unauthorized" or "403 Forbidden"

Solutions:

  1. Verify API key is correct and not expired
  2. Check API key has sufficient permissions (Viewer or Admin role)
  3. For service accounts, verify token has correct scopes
  4. Test API key manually:
curl -H "Authorization: Bearer $GRAFANA_API_KEY" \
https://grafana.example.com/api/health

Missing Dashboards

Symptom: Expected dashboards not appearing

Solutions:

  1. Check selectors match dashboard properties (tags, folder_ids, UIDs)
  2. Verify discover_dashboards: true
  3. Review logs for API errors
  4. Check if dashboards exist in specified folders
  5. Test API manually:
curl -H "Authorization: Bearer $GRAFANA_API_KEY" \
https://grafana.example.com/api/search?type=dash-db

SSL/TLS Errors

Symptom: Certificate verification errors

Solutions:

  1. Ensure Grafana URL uses HTTPS
  2. Verify certificate is valid
  3. For self-signed certificates, add to system trust store

Rate Limiting

Grafana APIs generally don't have strict rate limits, but:

  • Set reasonable reconciliation intervals (every: 300 or higher)
  • Avoid running too many providers against same instance

Performance Tips

  1. Use selectors: Filter dashboards at API level
  2. Disable unused discovery: Set discover_*: false for unused resources
  3. Adjust interval: Balance freshness vs. load
  4. Folder organization: Well-organized folders make selective discovery easier

Integration Examples

Use dashboard tags or labels to link to services:

# Dashboard entity has tags
labels:
tag_service-api: "true"

# Create custom relation
Service --MONITORED_BY--> GrafanaDashboard

Dashboard descriptions or tags can reference repos:

# Use field-selected relation
GrafanaDashboard --MONITORS--> Service --IMPLEMENTED_BY--> GithubRepository

Track SLO Dashboards

Tag SLO dashboards and query them:

selectors:
- tags: ["slo", "sla"]

# Query for SLO dashboards
kind: GrafanaDashboard
labels:
tag_slo: "true"

Advanced Configuration

Multiple Organizations

Configure multiple providers for different Grafana orgs:

- name: grafana-org1
type: grafana
config:
namespace: org1
base_url: https://grafana.example.com
api_key: ${GRAFANA_ORG1_KEY}
org_id: 1

- name: grafana-org2
type: grafana
config:
namespace: org2
base_url: https://grafana.example.com
api_key: ${GRAFANA_ORG2_KEY}
org_id: 2

Custom Timeout

For slow Grafana instances:

# Currently uses default timeout
# Future enhancement: Add timeout config option

Next Steps