# Write an On-Call Handoff From Grafana

Yes. An agent reads a day of Grafana alerts, incidents and silences and writes the handoff the next on-call engineer reads.

[Run this on Rush](https://cloud.getrush.ai/run/on-call-handoff/grafana/).

## What the agent does

Nothing is cloned. Grafana Cloud is the connection: POST /me/connections with type mcp, the name grafana, url https://mcp.grafana.com/mcp and auth mode oauth. The 202 carries authorize_url; the key's creator opens it in a browser while signed in to the Rush console as that same person. Poll GET /me/connections/{id} until status is connected. The session then names that connection. A key run is given only the connections the body names, and a pending sign-in is 422 CONNECTION_NOT_READY. The catalog describes this server as search dashboards, query Prometheus and Loki, and read alerts and incidents in Grafana Cloud.

The agent reads three sets for the last 24 hours: alert rules that fired, incidents that opened or resolved, and silences that were created. For an alert that is still firing it asks the connection for the Prometheus or Loki query on that rule, so the note says what the rule watches, not only that it is red. A silence is recorded with its end time. A resolved incident is recorded with the resolution, separate from an alert that went green on its own.

handoff.md is written for the person starting the next shift, in four blocks. Still open: each firing alert and each open incident, with the query or the incident summary and why it is still open. Fired and resolved: what cleared during the shift. Active silences: the matchers and the expiry. Watch next: anything that fired more than once, or a silence that ends during the next shift. The agent does not create a silence, close an incident or edit a dashboard. Those tools may exist on the server; this prompt does not use them.

If the connection returns a dashboard hit for an open alert, the note can name that dashboard. It does not paste panels or log lines wholesale. A handoff that takes two minutes to read is the point, so a long Loki line becomes a count and a link back to the query, and the raw tool output stays in the session transcript rather than in the file.

## Start it with one API call

`POST https://api.prix.dev/o/{org}/sessions`

```json
{
  "agent": "claude",
  "input": "Use the Grafana connection to read alerts that fired, incidents opened or resolved, and silences created in the last 24 hours. For anything still firing, include the Prometheus or Loki query the rule runs. Write handoff.md with what is still open and why, what fired and resolved, active silences and when they expire, and anything the next engineer should watch. Read only. Do not create a silence, close an incident or edit a dashboard."
}
```

1. **Get an API key.** In the console, open Settings, then API keys, and create a key for your org. Send it in the Authorization header as a Bearer token.
2. **Send the request.** POST the body in request.json to https://api.prix.dev/o/{org}/sessions, with your repository as the resources URL. The run starts in its own cloud sandbox.
3. **Read what came back.** Follow the run on its live stream or wait for the run.completed webhook, then read the result and its trajectory.

## What comes back

The session finishes with handoff.md as an artifact. The artifact has a name, a mime type and a url on api.prix.dev that downloads that one file with no key until url_expires_at, about an hour. A later GET of the session mints a new url. GET /o/{org}/sessions/{id}/artifacts/handoff.md with the key downloads it too. status on the session is the run's state; the file is the handoff.

The note is present tense and short. Open items name the alert or incident and the query or summary the connection returned. Resolved items are a separate list so the next person does not re-open them. Each silence has an expiry. The watch list is only what repeated or what expires on the next shift. No page count or duration is invented; the file contains what the connection returned for that window.

Before the note is forwarded, the outgoing engineer checks that every still-firing alert they know is in the open list, that a silence they created has the right expiry, and that a resolved incident was not left under open. The transcript (GET the session's messages) has the tool calls, so a missing incident is a query that returned nothing, which is visible, rather than a line the agent skipped in silence.

## Run it on every end of a shift

The rotation tool you use can POST this body to https://api.prix.dev/o/{org}/sessions when a shift ends. Send an Idempotency-Key of the shift id so a retried webhook does not write two handoffs. The same key with another body is 409 IDEMPOTENCY_CONFLICT. Leave resources off: there is no repo, and no GitHub installation is required.

The API key's creator sets a public https webhook_url. When the turn finishes, Rush POSTs run.completed, run.failed or run.cancelled, within about 30 seconds, signed with the whsec_ secret. Answer 2xx within 5 seconds or the delivery is retried at 2, 4 and 6 minutes with the same webhook-id. Put the artifact link in the handoff channel from the session, not from data.result, because result is cut at 16 KiB.

## Why run it on Rush?

A handoff written from memory drops the silence that expires at 03:00 and the incident that was resolved in another tab. Here the agent reads alerts, incidents and silences through the Grafana connection in a sandbox, and the session stores each tool result. The next engineer can open the file and, if a line looks wrong, open the transcript and see the query that produced it.

Shifts overlap. Two rotations can each start a session at the same time, each with its own sandbox and its own handoff.md, up to max_concurrent on the key (4 unless the key sets another limit). Past that the API answers 429. A parked sandbox is kept for 7 idle days and costs nothing while parked, so the incoming engineer can POST a follow-up on the same session and ask about one alert without a new 24-hour read.

## Frequently asked questions

### Does this work with Grafana I run myself?

This page uses the Grafana Cloud MCP server at https://mcp.grafana.com/mcp, which the catalog lists for Cloud. A self-managed Grafana is a different server. You can name an inline MCP url on the session for that one run, with auth mode bearer if it needs a token, but that is a different connection from the one this job names.

### Will it create silences or close incidents?

The prompt says read only, and it says not to create a silence, close an incident or edit a dashboard. The file is the whole output. Silences already in Grafana are listed with their expiry; new ones are not added.

### What if the stack has no incidents, only alerts?

The open and resolved sections then come from alert state, and the incident section says the connection returned none. The agent does not invent an incident product you do not have. Silences and the Prometheus or Loki query on a firing rule are still written.

### Who can finish the Grafana sign-in?

The person who created the connection, in a browser that is signed in to the Rush console as that same person. A browser with no session, or someone else's session, cannot finish it. status stays pending until they do, or failed with connection_expired if 10 minutes pass, and you start the connection again.
