Inspiration
At 2 AM, when production goes down, no engineer should spend 45 minutes manually reading logs they barely remember how to navigate. That's the reality of on-call SRE work today groggy context-switching, Slack war rooms, runbook archaeology.
The question I couldn't stop thinking about: what if the investigation happened automatically, and the engineer only had to make one decision?
That's SPARK.
What it does
SPARK is an autonomous incident response agent. When Dynatrace fires an alert:
- Detects — Dynatrace MCP server surfaces the problem: severity, affected entities, evidence
- Diagnoses — Gemini 2.5 Flash on Vertex AI calls 4 tools in sequence:
get_problem-> problem details and affected servicesquery_metrics-> memory, latency, CPU time-seriessearch_logs-> application logs around the incident windowget_recent_deployments-> GitLab pipeline history for the past 3 hours
- Correlates — cross-references deployment timestamp with anomaly start time
- Briefs — posts a single-screen summary: root cause, confidence score (0–100%), rollback target
- Notifies — sends an approval card to Slack (
#all-spark) with one-tap Approve / Reject - Executes — on approval, triggers the GitLab rollback pipeline automatically
Total time: alert → rollback in under 60 seconds. Human always in the loop. Always.
How I built it
Tech Stack
AI Agent
- Google ADK
- Gemini 2.5 Flash
- Vertex AI
Observability
- Dynatrace MCP
CI/CD
- GitLab REST API
Infrastructure
- Google Cloud Run
Notifications
- Slack Block Kit
Frontend
- React + Vite
Architecture Flow
- Dynatrace detects an incident.
- Cloud Run webhook receives the alert.
- Google ADK launches Gemini 2.5 Flash.
- Agent gathers:
- Problem details
- Metrics
- Logs
- Deployment history
- SPARK generates a root-cause briefing.
- Slack approval card is sent.
- Engineer approves or rejects.
- GitLab rollback executes automatically.
- Resolution and post-mortem are recorded.
Challenges I ran into
1. Multi-worker memory isolation — Gunicorn with 2 workers meant sessions created
in Worker 1 were invisible to Worker 2. Every poll request potentially hit a different
process. Demo appeared broken. Fixed by switching to --workers 1 --threads 8.
2. Dynatrace MCP in a headless Cloud Run environment — The MCP server uses browser OAuth by default. We built a fallback chain: MCP → OAuth2 client credentials → realistic mock data, so the agent works end-to-end in all environments.
3. Slack interactive buttons — Slack requires a registered Interactivity Request URL
to process button clicks. Built a direct URL-action fallback (/approve/<incident_id>)
so buttons work immediately without additional Slack App configuration.
4. The Foursquare scenario — Most agents would see an incident and immediately recommend a rollback. Foursquare's 2010 MongoDB OOM had no recent deploy — the root cause was purely a capacity issue. Getting the agent to correctly say "don't rollback, fix the index" required careful prompt design around the correlation logic.
Real-world benchmark: 5 actual production post-mortems
We tested against incidents from github.com/danluu/post-mortemslink — real failures at
real companies, with real resolution times:
Benchmark Results:
rust-lang
- Human MTTR: 13 min
- SPARK: 16 sec
- Score: 100%
Cloudflare
- Human MTTR: ~60 min
- SPARK: 22 sec
- Score: 87%
PagerDuty
- Human MTTR: ~30 min
- SPARK: 19 sec
- Score: 86%
Foursquare
- Human MTTR: 17 hrs
- SPARK: 38 sec
- Score: 77%
CircleCI
- Human MTTR: Hours
- SPARK: 35 sec
- Score: 52%
Average: 80% across 5 incidents.
Average: 80% across 5 real incidents. 5/5 correct rollback decisions.
The Foursquare result is the one i am most proud of: the agent correctly identified that no deployment caused the outage and recommended scaling infrastructure instead of rolling back the same conclusion human engineers took 17 hours to reach.
$$\text{MTTR reduction} = \frac{45\text{ min} - 0.5\text{ min}}{45\text{ min}} \approx 98.9\%$$
What I learned
Tool sequencing matters more than model size. The agent's accuracy came from the order of tool calls — problem details first, then metrics, then logs, then deployments — not from a larger model. The correlation logic is in the prompt, not the weights.
Human-in-the-loop is a feature, not a limitation. Every auto-remediation system eventually causes a worse incident by acting on a misdiagnosis. Keeping the engineer as the final gate — with all context pre-loaded — is the right design for production.
MCP changes what's possible for observability agents. Before MCP, integrating Dynatrace meant building and maintaining a custom REST wrapper. With the
@dynatrace-oss/dynatrace-mcp-server, the agent gets structured, schema-defined access to problems, metrics, and logs with zero glue code.The hardest incidents don't have a deploy to blame. Building for the Foursquare scenario forced us to make the agent reason about absence of evidence — a much harder problem than correlating timestamps.
What's next for SPARK — SRE Agent
- Multi-service incident graphs — when an alert spans 3 microservices, trace the dependency chain and identify the blast radius before recommending a fix
- Learning from decisions — store engineer approval/rejection patterns to improve confidence calibration over time
- Proactive alerting — run the diagnosis loop on anomaly precursors before Dynatrace fires a P1, giving engineers a 10-minute head start
- Expand beyond rollbacks — scale operations, config patching, feature flag toggling as additional approved action types
Built With
- dynatrace-mcp
- gemini-2.5-flash
- gitlab-ci-cd
- google-cloud
- google-cloud-agent-builder
- python
- react-js
- vertex-ai

Log in or sign up for Devpost to join the conversation.