Grafana OnCall Provider
Grafana OnCall is the recommended provider for self-hosted hrida-ai-studio deployments. It runs in the same Docker Compose stack as hrida-ai-studio, sharing the existing PostgreSQL and Redis containers.
What You Get
- On-call rotation schedules and escalation policies
- Alert routing from Prometheus, Grafana alerting, or any HTTP integration
- Incident timeline with full message history
- MCP tool server via hrida-mcpo so agents can list, acknowledge, and resolve incidents
Prerequisites
docker-compose.yamlalready running (hrida-ai-studio + postgres + redis-valkey + keycloak)- Docker Compose v2
docker-compose.otel.yamlif you want Grafana UI at port 3001
Step 1 — Environment Variables
Add to your .env file:
# OnCall internal secrets — generate random strings of the specified length
ONCALL_SECRET_KEY=<50-character random string>
ONCALL_MIRAGE_SECRET_KEY=<50-character random string>
ONCALL_MIRAGE_CIPHER_IV=<exactly 16 characters>
# Filled in after steps 4 and 5 below
GRAFANA_ONCALL_TOKEN=
ONCALL_API_TOKEN=
# Webhook shared secret — create any random string
HRIDA_ONCALL_WEBHOOK_TOKEN=<random string>Step 2 — Start the Stack
docker compose \
-f docker-compose.yaml \
-f docker-compose.oncall.yaml \
up -dAdd -f docker-compose.otel.yaml to also get the Grafana UI.
What happens on first start:
| Container | Role | Exits after? |
|---|---|---|
oncall-db-init | Creates the oncall database in your existing postgres | Yes |
oncall-migrate | Runs schema migrations | Yes |
oncall | OnCall API server (port 8090) | No — stays running |
oncall-celery | Background worker (escalations, notifications) | No — stays running |
hrida-mcpo-oncall | MCP tool server wrapping OnCall API (port 8091) | No — stays running |
Step 3 — Verify OnCall is Running
http://localhost:8090 # OnCall API (JSON, not a UI)
http://localhost:3001 # Grafana UI (only if using docker-compose.otel.yaml)
Step 4 — Install the OnCall Plugin in Grafana
If you don't need the Grafana UI, skip to Step 5.
- Open
http://localhost:3001and log in withadmin/admin@123. - Go to Administration → Plugins, search for Grafana OnCall.
- Click Install, then Enable.
- When prompted for the OnCall API URL, enter
http://oncall:8090(Docker internal network). - Create a Service Account with the Admin role.
- Generate a token, then set
GRAFANA_ONCALL_TOKENin your.envand restart:
docker compose -f docker-compose.yaml -f docker-compose.oncall.yaml restart oncall oncall-celeryStep 5 — Create an OnCall API Token
- Open the OnCall UI (via Grafana → OnCall menu, or
http://localhost:8090). - Go to Settings → API Tokens.
- Create a token — copy it and set
ONCALL_API_TOKENin your.env. - Restart hrida-ai-studio:
docker compose -f docker-compose.yaml restart hrida-ai-studioStep 6 — Configure the Provider in hrida-ai-studio
- Go to Admin Panel → Incidents → Providers.
- Click + Add Provider and select Grafana OnCall.
- Fill in:
- Name: e.g.
Production OnCall - OnCall API URL:
http://oncall:8080(Docker network) or your external URL - API Token: the token from Step 5
- Webhook Secret: the value of
HRIDA_ONCALL_WEBHOOK_TOKENfrom your.env
- Name: e.g.
- Click Save — the card shows the Webhook URL.
Step 7 — Configure the Outgoing Webhook in OnCall
This tells OnCall to POST state changes to hrida-ai-studio.
- In the OnCall UI, go to Outgoing Webhooks → Create.
- Set:
| Field | Value |
|---|---|
| URL | The Webhook URL from the provider card |
| HTTP Method | POST |
| Trigger type | Alert group status change |
| Authorization header | Bearer <HRIDA_ONCALL_WEBHOOK_TOKEN> |
- Save. OnCall will now POST to hrida-ai-studio on every incident state change.
If you had hrida-ai-studio configured before the plugin system was added, your OnCall webhook may still point to /api/v1/webhooks/oncall. This legacy URL still works — it automatically redirects to your first enabled OnCall provider.
Webhook Authentication
OnCall sends a Bearer token in the Authorization header:
Authorization: Bearer <HRIDA_ONCALL_WEBHOOK_TOKEN>
hrida-ai-studio validates this with a constant-time comparison (hmac.compare_digest) against the webhook_secret stored in the provider config.
Agent Tools (via hrida-mcpo)
Add the mcpo sidecar as a tool server in Admin Panel → Settings → Tool Servers:
http://hrida-mcpo-oncall:8000 (Docker internal network)
http://localhost:8091 (host machine)
| Tool | Description |
|---|---|
list_alert_groups | List incidents filtered by state |
get_alert_group | Get full details of one incident |
acknowledge_alert_group | Acknowledge a firing incident |
resolve_alert_group | Resolve an incident |
list_schedules | List on-call rotation schedules |
list_users | List users registered in OnCall |
list_on_call_shifts | List upcoming on-call shifts |
Ports
| Service | Default port | Override env var |
|---|---|---|
| OnCall API | 8090 | ONCALL_PORT |
| hrida-mcpo-oncall | 8091 | MCPO_ONCALL_PORT |
| Grafana UI | 3001 | (otel stack) |
Environment Variable Reference
| Variable | Required | Description |
|---|---|---|
ONCALL_SECRET_KEY | Yes | 50-char secret for OnCall's Django app |
ONCALL_MIRAGE_SECRET_KEY | Yes | 50-char secret for encrypted DB fields |
ONCALL_MIRAGE_CIPHER_IV | Yes | Exactly 16-char IV for encryption |
GRAFANA_ONCALL_TOKEN | Yes (if using Grafana UI) | Grafana service-account token |
HRIDA_ONCALL_WEBHOOK_TOKEN | Yes | Shared secret on outgoing webhook |
ONCALL_API_TOKEN | Yes | OnCall API key for the incidents panel |
ONCALL_PORT | No | External port (default: 8090) |
MCPO_ONCALL_PORT | No | mcpo port (default: 8091) |
ONCALL_BASE_URL | No | Public URL for OnCall callbacks (default: http://localhost:8090) |
Troubleshooting
Incidents panel shows "No providers configured" → You haven't saved an OnCall provider yet in Admin Panel → Incidents → Providers.
Webhook delivers 401 Unauthorized
→ The Authorization: Bearer ... header in OnCall's outgoing webhook doesn't match the webhook_secret in your provider config. Both must be the same value as HRIDA_ONCALL_WEBHOOK_TOKEN.
oncall-migrate container keeps restarting
→ The oncall database may not have been created. Check docker logs hrida-oncall-db-init. The postgres container must be running and accepting connections before migration runs.
Celery worker not processing escalations
→ Check docker logs hrida-oncall-celery. Redis must be reachable at redis://redis-valkey:6379/2.