ContextCast
Predict what engineers will need before they ask.
ContextCast is an AI-powered proactive context prediction engine built on Splunk. It watches your operational data stream, builds a live knowledge graph of your systems, and the moment an alert fires or a deployment lands it predicts exactly what the responding engineer will need next: the right runbook, the dependent service dashboard, the last three deployments, the colleague who resolved the same incident six weeks ago. All of it surfaces before the engineer opens a single tab.
Built for the Splunk Agentic Ops Hackathon 2026. Tracks: Observability and Platform and Developer Experience. Splunk AI used: MCP Server, foundation-sec-1.1-8b-instruct, CDTSM, Splunk SDK, Custom SPL Command, HEC.
The Problem
When a production alert fires, engineers do not lack intelligence. They lack context. The sequence is always the same: Splunk fires an alert, the engineer opens Jira to find related tickets, then GitHub for recent commits, then Slack to find who was oncall last time, then Confluence for the runbook, then back to Splunk for the right dashboard. Studies show engineers spend 40 to 60 percent of incident time just gathering information, not analyzing it. The average recovery time from a single context switch is 23 minutes (Gloria Mark, UC Irvine). During a SEV-1 engineers switch between 8 to 12 tools. Total cognitive cost: 70 percent of MTTR is spent on diagnosis, not resolution.
The root cause is not tooling. It is that every tool waits to be asked. None of them predict.
Weather forecasts do not wait for you to notice it is raining. ContextCast does not wait for you to ask what is relevant. It tells you before you realize you need it.
The Solution
ContextCast introduces the concept of a Context Pack: a pre-assembled, confidence-ranked bundle of everything an engineer needs for a given trigger. A Context Pack contains:
- Top-k predicted context items ranked by confidence score
- Pre-built SPL queries ready to run against live Splunk data
- AI-generated root cause summary via Splunk hosted foundation-sec-1.1-8b-instruct
- Runbook links extracted from the knowledge graph
- Related incident timeline with resolution history
- Engineer-personalized context based on past work patterns
Context Packs are generated automatically when Splunk saved searches detect anomalies, when deployments land, or when incidents are created. They are delivered to engineers via the ContextCast dashboard and via MCP agent tool calls.
How We Built It
Layer 1: Data Ingestion
We started by defining a canonical event schema called CCEvent. Every external signal, whether a GitHub push, a Jira ticket update, or a Slack message in an incident channel, gets normalized into this schema and forwarded to Splunk via HEC.
ingestion/hec_client.py handles single events and batches with proper error handling and health checks. ingestion/ingestors.py contains three ingestor classes (GitHubIngestor, JiraIngestor, SlackIngestor) that each accept webhook payloads, extract the relevant fields, wrap them in a CCEvent, and send to HEC. We also wrote ingestion/contextcast_input.py as a proper Splunk modular input so the app can poll GitHub and Jira directly from inside Splunk without the external server.
Sourcetypes: contextcast:github, contextcast:jira, contextcast:slack, contextcast:pack.
Layer 2: Knowledge Graph
The central insight of ContextCast is that raw logs are not enough. What matters is the relationships: this service depends on that one, this deployment caused this incident, this engineer resolved it using this runbook. A flat index cannot answer that. A knowledge graph can.
knowledge_graph/graph.py implements ContextGraph on top of NetworkX MultiDiGraph. Nodes represent six entity types: service, incident, engineer, deployment, runbook, alert. Edges carry semantic types: DEPENDS_ON, CAUSED, RESOLVED_BY, WORKED_BY, DEPLOYED_TO, SIMILAR_TO, AFFECTED, MENTIONED. All writes go through typed upsert methods so the schema stays consistent.
knowledge_graph/builder.py implements GraphBuilder, which reads CCEvents from the normalized stream and calls the correct upsert methods. It also exposes build_from_splunk() which uses the Splunk Python SDK to backfill the graph from historical index data. The graph persists to disk as a JSON node-link file so state survives restarts.
Layer 3: Prediction Engine
Given a trigger (an alert, a service name, an incident key), the prediction engine returns a ranked list of context items the engineer will most likely need next. We combined four signals:
Signal 1: Graph Traversal. BFS from the trigger node up to 2 hops, with exponential confidence decay by depth. A direct dependency (depth 1) starts at 0.9 confidence. A 2-hop neighbor starts at 0.5. This captures structural relationships: if checkout is the trigger, payment and inventory surface immediately because they are direct dependencies.
Signal 2: Co-occurrence. We scan the incident history in the graph and count how often pairs of nodes appear together in the same incident subgraph. Nodes that have co-occurred in many past incidents get a co-occurrence boost capped at 0.7. This captures patterns the graph structure alone cannot express.
Signal 3: Engineer Markov Chain. For each engineer we build a transition matrix from their past activity: which nodes they pushed to, worked on, or mentioned. When an engineer is specified in the predict request, their personal transition counts boost confidence for nodes they have touched before. This is the personalization layer.
Signal 4: PageRank Boost. After the three primary signals are combined, we run PageRank on the full graph and add a small structural importance boost (up to 0.15) for nodes that are central to the dependency topology. This prevents low-traffic but structurally critical nodes from being buried.
The four signals are merged by taking the maximum confidence per node (not additive), then all predictions are sorted by final confidence and the top-k are returned.
Layer 4: Context Pack Generator
context_pack/generator.py takes the raw prediction list and assembles a full Context Pack. For each trigger type it generates a set of relevant SPL queries: error rate timechart, deployment history, incident timeline, plus a prediction-specific query per top-5 predicted nodes. It also appends two special queries: a CDTSM zero-shot anomaly forecast and a foundation-sec-1.1-8b-instruct incident summary query that runs entirely inside Splunk. If a live Splunk service is connected it executes the top 3 queries and attaches the results.
Layer 5: MCP Server Integration
We registered five tools with the Splunk MCP Server so AI agents can drive ContextCast as a tool in an agentic loop:
contextcast_predict: returns top-k predictions for a triggercontextcast_graph_query: traverses the knowledge graph for a nodecontextcast_get_pack: generates and returns a full Context Packcontextcast_run_spl: executes a SPL query and returns resultscontextcast_graph_stats: returns graph statistics and top nodes by PageRank
mcp_server/mcp_tools.py is the single handler file. It reads a JSON payload from stdin, dispatches to the correct function, and writes JSON to stdout, which is exactly how Splunk MCP Server invokes custom tools. mcp_server/tools.conf registers all five tools. mcp_server/tool_input_payload_signatures.json defines their parameter schemas so the MCP Server can validate inputs and surface them in the AI Assistant UI.
Custom SPL Search Command
contextcast_app/bin/contextcast_predict.py implements a Splunk streaming search command so any SPL pipeline can invoke the prediction engine inline. It adds fields to each event: cc_predictions (JSON array), cc_top_node, cc_top_label, cc_top_reason, cc_top_confidence, cc_top_spl. With generate_pack=true it attaches the full Context Pack as cc_pack_json. Engineers can use it in saved searches, alerts, and real-time searches without leaving SPL.
FastAPI Webhook Server
main.py is the external-facing server. It receives webhooks from GitHub, Jira, and Slack, normalizes them, sends to HEC, and updates the knowledge graph in background tasks. It also exposes the prediction and Context Pack REST API for direct integration. A /webhook/splunk_alert endpoint receives forwarded Splunk alert payloads, triggers Context Pack generation, and writes the result back to HEC as contextcast:pack.
Splunk App and Dashboard
The contextcast_app directory is a complete, installable Splunk app. savedsearches.conf defines four scheduled searches: anomaly detection using CDTSM zero-shot forecasting, AI incident summaries using foundation-sec-1.1-8b-instruct, high-risk deployment detection, and a graph rebuild trigger. The dashboard (contextcast_dashboard.xml) has six panels: KPI row, predictions confidence heatmap table, event activity timechart, CDTSM anomaly chart, AI incident analysis table, and engineer activity heatmap.
Architecture
EXTERNAL SOURCES LAYER 1: INGESTION
GitHub webhooks ------> FastAPI Webhook Server (main.py)
Jira webhooks ------> GitHubIngestor / JiraIngestor / SlackIngestor
Slack events ------> HECClient ------> Splunk index=contextcast
Splunk alerts <------ /webhook/splunk_alert
SPLUNK ENTERPRISE
index=contextcast (sourcetypes: github, jira, slack, pack)
|
Saved Searches
- Service Anomaly Detection (CDTSM zero-shot forecasting)
- Incident AI Summary (foundation-sec-1.1-8b-instruct)
- High-Risk Deployments
|
Splunk Hosted Models
foundation-sec-1.1-8b-instruct -> incident summarization
CDTSM (Cisco Deep Time Series) -> anomaly detection
|
Splunk MCP Server
tools.conf + tool_input_payload_signatures.json
contextcast_predict
contextcast_graph_query
contextcast_get_pack
contextcast_run_spl
contextcast_graph_stats
|
Custom SPL Command
| contextcast_predict trigger=svc:checkout top_k=5
adds cc_predictions, cc_top_* fields to pipeline
CONTEXTCAST PREDICTION STACK (Python)
Layer 5: MCP Tool Handler (mcp_server/mcp_tools.py)
|
Layer 4: Context Pack Generator (context_pack/generator.py)
assembles predictions + SPL queries + AI summary + runbooks
|
Layer 3: Prediction Engine (prediction_engine/predictor.py)
Signal 1: Graph traversal (BFS, depth-weighted decay)
Signal 2: Co-occurrence (past incident patterns)
Signal 3: Markov chain (per-engineer personalization)
Signal 4: PageRank boost (structural importance)
|
Layer 2: Knowledge Graph (knowledge_graph/graph.py)
Nodes: service, incident, engineer, deployment, runbook, alert
Edges: DEPENDS_ON, CAUSED, RESOLVED_BY, WORKED_BY, DEPLOYED_TO, SIMILAR_TO
|
Layer 1: Graph Builder (knowledge_graph/builder.py)
reads CCEvents, upserts nodes and edges
build_from_splunk() backfills from historical index
DASHBOARD contextcast_dashboard.xml
KPI row | Predictions heatmap | Anomaly chart
AI Incident Analysis | Deployment risk | Engineer heatmap
Splunk AI Capabilities
| Capability | Where Used | Prize Target |
|---|---|---|
| Splunk MCP Server | mcp_server/tools.conf and mcp_tools.py, 5 registered tools | Best MCP Server $1K |
| foundation-sec-1.1-8b-instruct | savedsearches.conf AI Summary, Context Pack SPL queries | Best Hosted Models $1K |
| CDTSM Cisco Deep Time Series | savedsearches.conf anomaly detection, dashboard anomaly panel | Best Hosted Models |
| Splunk AI Assistant | NL to SPL translation, SPL explanation in dashboard | Platform track |
| Splunk SDK splunklib | contextcast_input.py modular input, contextcast_predict.py command, builder.py | Best Developer Tools $1K |
| Custom SPL Streaming Command | contextcast_predict adds cc_predictions fields to any pipeline | Best Developer Tools |
| HEC HTTP Event Collector | hec_client.py, all event ingestion from GitHub Jira Slack | Core platform |
Project Structure
contextcast/
main.py FastAPI server, webhooks and REST API
requirements.txt
Dockerfile
docker-compose.yml
.env.example
architecture.md
ingestion/
hec_client.py Splunk HEC client, single and batch
ingestors.py GitHub, Jira, Slack event normalizers
contextcast_input.py Splunk modular input for polling
knowledge_graph/
graph.py ContextGraph NetworkX MultiDiGraph
builder.py CCEvent to graph node and edge builder
prediction_engine/
predictor.py 4-signal prediction engine
context_pack/
generator.py Context Pack assembler
mcp_server/
mcp_tools.py MCP tool handler, stdin/stdout JSON dispatch
tools.conf Splunk MCP tool registry
tool_input_payload_signatures.json Tool parameter schemas
contextcast_app/
bin/
contextcast_predict.py Custom Splunk SPL streaming command
default/
app.conf
inputs.conf
transforms.conf
savedsearches.conf 4 scheduled searches with hosted AI models
data/ui/views/
contextcast_dashboard.xml Dark theme, 6-panel dashboard
tests/
test_graph.py 9 graph tests
test_predictor.py 12 predictor tests
test_api.py 13 API and webhook tests
Setup
Prerequisites
- Python 3.11 or higher
- Splunk Enterprise free trial with Developer License, or Splunk Cloud
- HEC enabled on your Splunk instance (Settings, Data Inputs, HTTP Event Collector)
1. Clone and install
git clone https://github.com/Tasfia-17/ContextCast
cd ContextCast
pip install -r requirements.txt
2. Configure environment
cp .env.example .env
Edit .env and fill in:
SPLUNK_HEC_HOST=localhost
SPLUNK_HEC_PORT=8088
SPLUNK_HEC_TOKEN=your-hec-token
SPLUNK_HOST=localhost
SPLUNK_PORT=8089
SPLUNK_USERNAME=admin
SPLUNK_PASSWORD=your-password
GITHUB_WEBHOOK_SECRET=your-secret
3. Create the Splunk index
In Splunk: Settings > Indexes > New Index. Name it contextcast.
4. Run the API server
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
Or with Docker:
docker-compose up
5. Install the Splunk app
cp -r contextcast_app $SPLUNK_HOME/etc/apps/contextcast
$SPLUNK_HOME/bin/splunk restart
6. Configure webhooks
Point your GitHub repo webhooks to:
POST http://your-server:8000/webhook/github
Header: X-GitHub-Event (set automatically by GitHub)
Jira webhooks:
POST http://your-server:8000/webhook/jira
Slack Event Subscriptions:
POST http://your-server:8000/webhook/slack
Splunk saved search alert action webhook:
POST http://your-server:8000/webhook/splunk_alert
7. Install MCP Server tools
cp mcp_server/tools.conf $SPLUNK_HOME/etc/apps/contextcast/default/
cp mcp_server/tool_input_payload_signatures.json $SPLUNK_HOME/etc/apps/contextcast/default/
cp mcp_server/mcp_tools.py $SPLUNK_HOME/etc/apps/contextcast/bin/
$SPLUNK_HOME/bin/splunk restart
API Reference
| Endpoint | Method | Description |
|---|---|---|
| /health | GET | Health check, graph stats, HEC status |
| /api/predict | POST | Get top-k predictions for a trigger |
| /api/context-pack | POST | Get full Context Pack |
| /api/graph/stats | GET | Knowledge graph node and edge counts |
| /api/graph/node/{node_id} | GET | Node data and neighbors |
Predict request:
{
"trigger": "svc:checkout",
"engineer": "alice",
"top_k": 8
}
Prediction response:
{
"trigger": "svc:checkout",
"predictions": [
{
"node_id": "svc:payment",
"node_type": "service",
"label": "payment",
"reason": "Graph neighbor (depth 1, via DEPENDS_ON)",
"confidence": 0.9,
"spl_hint": "index=contextcast entity_id=\"svc:payment\" | timechart span=5m count by cc_type"
}
]
}
Node ID prefixes: svc: for services, inc: for incidents, eng: for engineers, deploy: for deployments, rb: for runbooks, alert: for alerts.
SPL Usage
Add predictions to any search pipeline:
index=main alert_name=*
| contextcast_predict trigger_field=service engineer=alice top_k=5
Generate a full Context Pack inline:
index=contextcast cc_type=deployment
| contextcast_predict trigger="svc:checkout" generate_pack=true
AI incident summary using Splunk hosted model:
index=contextcast sourcetype="contextcast:jira"
| spath
| ai model="foundation-sec-1.1-8b-instruct"
prompt="SRE analysis, summarize this incident and identify root cause in 2 sentences: {attributes.summary}"
input_field=attributes.summary
output_field=ai_analysis
| table _time, attributes.key, attributes.priority, summary, ai_analysis
Zero-shot anomaly detection using CDTSM:
index=main service="checkout"
| timechart span=5m count as requests
| apply CDTSM requests mode=anomaly conf_interval=90 method=quantile
MCP Agent Tool Usage
{"function": "predict_context", "params": {"trigger": "svc:checkout", "engineer": "alice"}}
{"function": "get_context_pack", "params": {"trigger": "inc:INC-1234", "include_live_data": true}}
{"function": "graph_query", "params": {"node_id": "svc:checkout", "edge_type": "DEPENDS_ON"}}
{"function": "run_contextual_spl", "params": {"spl": "index=contextcast | stats count by cc_type", "earliest": "-1h"}}
{"function": "graph_stats", "params": {"node_type": "service"}}
Tests
pytest tests/ -q
Expected output: 34 passed.
Test coverage:
test_graph.py: node upsert idempotency, dependency edges, BFS traversal, incident context, service context, PageRank, save/load persistence, stub node creationtest_predictor.py: sorted confidence, confidence range, trigger exclusion, incident triggers, engineer personalization, SPL hint generation, to_dict schematest_api.py: all REST endpoints, webhook handlers for GitHub/Jira/Slack/Splunk, Slack URL challenge, response schema validation
Log in or sign up for Devpost to join the conversation.