Manages Grafana dashboards, data sources, users, alerts, and configuration through the Grafana MCP Server for visualization and monitoring operations. Use when user mentions Grafana, dashboards, metrics visualization, alerts, monitoring panels, or Grafana API interactions.
Use this skill to interact with Grafana instances through the Grafana MCP Server - a Model Context Protocol server that provides seamless access to Grafana's HTTP API for dashboards, alerts, data sources, and monitoring configuration.
The primary interface is the Grafana MCP Server deployed via AWX. This MCP server wraps Grafana's HTTP API, providing structured access to all Grafana resources without needing to manage authentication tokens or API endpoints manually.
Grafana MCP Server:
playbooks/GrafanaMCP-manage.ymlGrafana Instances: Multiple environments in the Home Lab
https://devgrafana.bjzy.mehttps://grafana.bjzy.meCommon use cases:
Integration Points:
MCP Server Access:
Security Rules:
kvProd_v2/Grafana/)Deployment Rules:
standards/05_MCP_SETUP.md)When asked to "Manage Grafana," "Configure alerts," "Handle dashboards," or "Access Grafana API":
Deploy or manage the Grafana MCP Server via AWX.
# Deploy Grafana MCP Server (container mode)
awx job_template launch 49 \
--extra_vars '{
"operation": "install",
"deployment_mode": "container"
}' \
--monitor
# Check MCP Server status
awx job_template launch 49 \
--extra_vars '{
"operation": "status"
}' \
--monitor
# Uninstall MCP Server
awx job_template launch 49 \
--extra_vars '{
"operation": "uninstall"
}' \
--monitor
Access Grafana dashboards using HTTP API when direct access is needed.
# Get Grafana API token from Vault
GRAFANA_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
GRAFANA_URL="https://grafana.bjzy.me"
# List all dashboards
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/search?type=dash-db" | jq '.'
# Get specific dashboard by UID
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/dashboards/uid/<dashboard_uid>" | jq '.'
# Export dashboard to JSON file
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/dashboards/uid/<dashboard_uid>" \
| jq '.dashboard' > dashboard-backup.json
# Import dashboard from JSON
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @dashboard.json \
"$GRAFANA_URL/api/dashboards/db"
# Delete dashboard
curl -X DELETE -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/dashboards/uid/<dashboard_uid>"
Configure and manage alert rules via HTTP API.
# List all alert rules
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/v1/provisioning/alert-rules" | jq '.'
# Get specific alert rule
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/v1/provisioning/alert-rules/<rule_uid>" | jq '.'
# Create alert rule from file
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @alert-rule.json \
"$GRAFANA_URL/api/v1/provisioning/alert-rules"
# Update alert rule
curl -X PUT -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @alert-rule.json \
"$GRAFANA_URL/api/v1/provisioning/alert-rules/<rule_uid>"
# Delete alert rule
curl -X DELETE -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/v1/provisioning/alert-rules/<rule_uid>"
Manage Grafana data sources via HTTP API.
# List all data sources
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources" | jq '.'
# Get data source by UID
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources/uid/<datasource_uid>" | jq '.'
# Create data source
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @datasource.json \
"$GRAFANA_URL/api/datasources"
# Update data source
curl -X PUT -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @datasource.json \
"$GRAFANA_URL/api/datasources/uid/<datasource_uid>"
# Test data source connectivity
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources/uid/<datasource_uid>/resources/test" | jq '.'
# Delete data source
curl -X DELETE -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources/uid/<datasource_uid>"
Manage users and organizations via HTTP API.
# List all users
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/users" | jq '.'
# Get current user info
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/user" | jq '.'
# List organization users
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/org/users" | jq '.'
# Create user
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"John Doe","email":"[email protected]","login":"john","password":"password"}' \
"$GRAFANA_URL/api/admin/users"
# List teams
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/teams/search" | jq '.'
Organize dashboards in folders via HTTP API.
# List all folders
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/folders" | jq '.'
# Get folder by UID
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/folders/<folder_uid>" | jq '.'
# Create folder
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Infrastructure"}' \
"$GRAFANA_URL/api/folders"
# Update folder
curl -X PUT -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Production Infrastructure","overwrite":true}' \
"$GRAFANA_URL/api/folders/<folder_uid>"
# Delete folder
curl -X DELETE -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/folders/<folder_uid>"
Check Grafana instance health and configuration.
# Check instance health (no auth required)
curl "$GRAFANA_URL/api/health" | jq '.'
# Get instance statistics
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/admin/stats" | jq '.'
# Get Grafana build info
curl "$GRAFANA_URL/api/frontend/settings" | jq '.buildInfo'
# Check data source health
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources/uid/<datasource_uid>/health" | jq '.'
Perform bulk export operations for backup purposes.
# Export all dashboards to directory
GRAFANA_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
GRAFANA_URL="https://grafana.bjzy.me"
BACKUP_DIR="./grafana-backup-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR/dashboards"
# Get all dashboard UIDs
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/search?type=dash-db" \
| jq -r '.[].uid' > "$BACKUP_DIR/dashboard-uids.txt"
# Export each dashboard
while read -r uid; do
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/dashboards/uid/$uid" \
| jq '.dashboard' > "$BACKUP_DIR/dashboards/$uid.json"
done < "$BACKUP_DIR/dashboard-uids.txt"
# Export all data sources
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources" \
| jq '.' > "$BACKUP_DIR/datasources.json"
# Export alert rules
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/v1/provisioning/alert-rules" \
| jq '.' > "$BACKUP_DIR/alert-rules.json"
echo "Backup completed: $BACKUP_DIR"
# Check MCP Server deployment status via AWX
awx job_template launch 49 \
--extra_vars '{"operation": "status"}' \
--monitor
# Check Docker service if deployed as container
ssh ansible@<mcp-host> "docker ps | grep grafana-mcp"
# View MCP Server logs (if container deployment)
ssh ansible@<mcp-host> "docker logs grafana-mcp-server"
# Redeploy MCP Server
awx job_template launch 49 \
--extra_vars '{"operation": "install", "deployment_mode": "container"}' \
--monitor
# Verify Grafana API token from Vault
vault kv get kvProd_v2/Grafana/API
# Test token validity
GRAFANA_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/user
# Check user permissions
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/user/orgs | jq '.'
# Generate new API token (via Grafana UI)
# Navigate to: Configuration → API Keys → Add API key
# Validate dashboard JSON structure
jq '.' dashboard.json
# Check required data sources exist
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/datasources | jq '.[].type'
# Import with overwrite flag
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dashboard": '"$(cat dashboard.json)"', "overwrite": true}' \
https://grafana.bjzy.me/api/dashboards/db
# Check import error details
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @dashboard.json \
https://grafana.bjzy.me/api/dashboards/db | jq '.message'
# Validate alert rule syntax
jq '.' alert-rule.json
# Check alert rule query expressions
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/provisioning/alert-rules/<rule_uid> \
| jq '.data'
# Test alert rule evaluation
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/eval
# List contact points (notification channels)
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/provisioning/contact-points | jq '.'
# Check alert rule state
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/provisioning/alert-rules/<rule_uid> \
| jq '.state'
# Test data source connectivity
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/datasources/uid/<datasource_uid>/health | jq '.'
# Check data source configuration
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/datasources/uid/<datasource_uid> | jq '.'
# Test Prometheus data source query
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries":[{"refId":"A","expr":"up"}]}' \
https://grafana.bjzy.me/api/ds/query
# Test Loki data source query
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"queries":[{"refId":"A","expr":"{job=\"varlogs\"}"}]}' \
https://grafana.bjzy.me/api/ds/query
# Check overall Grafana health (no auth needed)
curl https://grafana.bjzy.me/api/health | jq '.'
# Check if Grafana is reachable
curl -I https://grafana.bjzy.me
# Check Docker Swarm service status
ssh ansible@Huey "docker service ps grafana --no-trunc"
# Check Grafana service logs via Docker Swarm
ssh ansible@Huey "docker service logs grafana --tail 50"
# Verify Grafana database connectivity (PostgreSQL)
ssh ansible@Huey "docker exec \$(docker ps -q -f name=grafana) \
grafana-cli admin data-migration list"
Grafana integrates with various Home Lab services and data sources:
GRAFANA_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
GRAFANA_URL="https://grafana.bjzy.me"
# List Prometheus/Mimir data sources
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources" | jq '.[] | select(.type=="prometheus")'
# List Loki log sources
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/datasources" | jq '.[] | select(.type=="loki")'
# Find Home Lab infrastructure dashboards
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/search?query=Home%20Lab" | jq '.'
# List dashboards in Infrastructure folder
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"$GRAFANA_URL/api/search?folderIds=<folder_id>" | jq '.'
Manage development and production Grafana instances:
# Development environment
DEV_TOKEN=$(vault kv get -field=api_token kvDev_v2/Grafana/API)
DEV_URL="https://devgrafana.bjzy.me"
# Production environment
PROD_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
PROD_URL="https://grafana.bjzy.me"
# Export dashboards from dev
curl -H "Authorization: Bearer $DEV_TOKEN" \
"$DEV_URL/api/search?type=dash-db" | jq -r '.[].uid' | \
while read uid; do
curl -H "Authorization: Bearer $DEV_TOKEN" \
"$DEV_URL/api/dashboards/uid/$uid" | \
jq '.dashboard' > "dev-$uid.json"
done
# Import validated dashboards to production
for file in dev-*.json; do
curl -X POST -H "Authorization: Bearer $PROD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dashboard": '"$(cat "$file")"', "overwrite": false}' \
"$PROD_URL/api/dashboards/db"
done
Configure Grafana alerts to send notifications to Keep:
GRAFANA_TOKEN=$(vault kv get -field=api_token kvProd_v2/Grafana/API)
KEEP_WEBHOOK_URL="https://keep-api.bjzy.me/webhook/grafana"
# Create Keep contact point (webhook receiver)
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Keep AIOps",
"type": "webhook",
"settings": {
"url": "'"$KEEP_WEBHOOK_URL"'",
"httpMethod": "POST"
}
}' \
https://grafana.bjzy.me/api/v1/provisioning/contact-points
# List existing contact points
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/provisioning/contact-points | jq '.'
# Update alert rule to use Keep contact point
curl -X PUT -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d @alert-with-keep.json \
https://grafana.bjzy.me/api/v1/provisioning/alert-rules/<rule_uid>
Implement GitOps for Grafana configurations using AWX and version control:
# 1. Export current Grafana state
BACKUP_DIR="./grafana-config-$(date +%Y%m%d)"
mkdir -p "$BACKUP_DIR"/{dashboards,datasources,alerts}
# Export dashboards
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/search?type=dash-db | jq -r '.[].uid' | \
while read uid; do
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
"https://grafana.bjzy.me/api/dashboards/uid/$uid" | \
jq '.dashboard' > "$BACKUP_DIR/dashboards/$uid.json"
done
# Export data sources
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/datasources \
> "$BACKUP_DIR/datasources/all.json"
# Export alert rules
curl -H "Authorization: Bearer $GRAFANA_TOKEN" \
https://grafana.bjzy.me/api/v1/provisioning/alert-rules \
> "$BACKUP_DIR/alerts/rules.json"
# 2. Commit to version control
cd "$BACKUP_DIR"
git init
git add .
git commit -m "Grafana config snapshot $(date +%Y%m%d)"
# 3. Apply from version control (GitOps)
# This would typically be automated via AWX/Ansible
for dashboard in dashboards/*.json; do
curl -X POST -H "Authorization: Bearer $GRAFANA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dashboard": '"$(cat "$dashboard")"', "overwrite": true}' \
https://grafana.bjzy.me/api/dashboards/db
done
When the Grafana MCP Server is enabled in your agent configuration:
# User workflow:
1. User mentions: "Show me Grafana dashboards" or "Configure Grafana alerts"
2. Agent discovers Grafana MCP Server is available
3. MCP Server handles:
- Authentication (reads from Vault automatically)
- Environment selection (dev vs prod)
- API request construction
- Response formatting
4. User gets structured results without managing tokens/URLs
# Deployment workflow:
1. Deploy via AWX: awx job_template launch 49
2. MCP server reads Grafana credentials from Vault
3. Exposes structured tools for dashboards, alerts, data sources
4. Agent uses MCP tools instead of raw HTTP API calls
kvProd_v2/Grafana/ and kvDev_v2/Grafana/)standards/05_MCP_SETUP.md)vault kv get -field=api_token kvProd_v2/Grafana/APIjq to filter API responses and reduce data transferjq before importinguri module for API calls within playbooks--dry-run patterns (check before apply) when possibleOfficial documentation: https://grafana.com/docs/grafana/latest/developers/http_api/
Common API endpoints:
/api/dashboards/*, /api/search/api/datasources/*/api/v1/provisioning/alert-rules/*/api/users/*, /api/org/users/*/api/folders/*/api/health (no auth required)/api/admin/* (requires admin permissions)