Network Incident MCP
by asif-c
README.md
# Network Incident MCP Demo
A small demo/prototype showing an LLM agent (Google Gemini) using the **Model Context Protocol (MCP)** to triage a simulated network incident: fetch device telemetry, inspect syslogs, decide whether action is needed, and execute a remediation step - all through tools exposed by a local MCP server.
This is a **prototype for learning/demo purposes**. All network data is fake and hardcoded in `mcp_server/mock_network_db.py`. There is no real network backend.
## How it works
- **`mcp_server/`** - an MCP server exposing:
- `get_device_telemetry(device_id)` - device status, optical power, BGP flaps
- `get_latest_syslog()` - recent syslog lines
- `apply_traffic_reroute(source_pop, target_pop, circuit_id)` - a mock remediation action (rejects any target that isn't a known, healthy PoP)
- `incident_triage_prompt(device_id)` - a prompt template describing the triage steps and the -20.0 dBm reroute threshold
- **`agent/gemini_mcp_client.py`** - a client that spawns the MCP server, hands its tools to Gemini as function-calling tools, and runs a loop: Gemini decides which tool to call next, the client executes it via MCP and feeds the result back, until Gemini gives a final answer.
## Setup
```bash
git clone <your-repo-url>
cd network-incident-mcp
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
## Running the tests
```bash
python3 -m pytest tests/
```
## Running the MCP server standalone
```bash
python3 mcp_server/server.py
```
## Running the live agent
Requires a Gemini API key from [Google AI Studio](https://aistudio.google.com/apikey):
```bash
export GEMINI_API_KEY=your-key-here
python3 agent/gemini_mcp_client.py
```
### Example output
The agent is pointed at the mock device `router-van-01`, which is simulated as `DEGRADED` with optical power at -28.5 dBm - below the -20.0 dBm reroute threshold. A real run looks like this:
```
(venv) ac@ubuntuserver2026:~/network-incident-mcp$ python3 agent/gemini_mcp_client.py
Processing request of type ListToolsRequest
[+] Connected to MCP. Registered 3 tools with Gemini 3.6 Flash.
Processing request of type GetPromptRequest
[--> Model Tool Call Request]: get_device_telemetry({'device_id': 'router-van-01'})
Processing request of type CallToolRequest
[<-- MCP Execution Output]: {
"device_id": "router-van-01",
"data": {
"status": "DEGRADED",
"location": "Vancouver PoP",
"bgp_flaps": 14,
"optical_power_dbm": -28.5,
"circuits": [
"fiber-van-richmond-10G"
]
}
}
[--> Model Tool Call Request]: get_latest_syslog({})
Processing request of type CallToolRequest
[<-- MCP Execution Output]:
[2026-08-24T10:12:01Z] WARN router-van-01 BGP neighbor 192.168.10.1 DOWN (Retries: 3)
[2026-08-24T10:12:15Z] CRIT router-van-01 Optical signal loss detected on fiber-van-richmond-10G (-28.5 dBm)
[2026-08-24T10:14:02Z] WARN router-van-01 Packet loss spike: 18.4% on interface ge-0/0/1
[--> Model Tool Call Request]: apply_traffic_reroute({'target_pop': 'Richmond PoP', 'circuit_id': 'fiber-van-richmond-10G', 'source_pop': 'Vancouver PoP'})
Processing request of type CallToolRequest
[<-- MCP Execution Output]: {
"status": "ERROR",
"error": "Target PoP 'Richmond PoP' is not a known healthy PoP. Healthy PoPs: ['Toronto PoP']"
}
[--> Model Tool Call Request]: apply_traffic_reroute({'circuit_id': 'fiber-van-richmond-10G', 'target_pop': 'Toronto PoP', 'source_pop': 'Vancouver PoP'})
Processing request of type CallToolRequest
[<-- MCP Execution Output]: {
"status": "SUCCESS",
"action": "Traffic shifted from Vancouver PoP to Toronto PoP",
"isolated_circuit": "fiber-van-richmond-10G",
"new_route_metric": 10
}
[Model Final Response]: ### Incident Analysis Summary for `router-van-01`
1. **Device Telemetry Analysis**
- **Device ID:** `router-van-01`
- **Location:** Vancouver PoP
- **Device Status:** DEGRADED
- **Optical Power Level:** **-28.5 dBm**
- **BGP Flaps:** 14
- **Active Circuit:** `fiber-van-richmond-10G`
2. **Syslog Inspection**
- Critical optical signal loss log detected:
`[2026-08-24T10:12:15Z] CRIT router-van-01 Optical signal loss detected on fiber-van-richmond-10G (-28.5 dBm)`
- Additional warnings observed regarding BGP neighbor timeouts and interface packet loss spikes (`ge-0/0/1`).
3. **Remediation Action**
- **Condition Met:** Optical power level (-28.5 dBm) is below the threshold of -20.0 dBm.
- **Action Taken:** Executed `apply_traffic_reroute`.
- **Circuit:** `fiber-van-richmond-10G`
- **Source PoP:** Vancouver PoP
- **Target PoP:** Toronto PoP
- **Status:** **SUCCESS** - Traffic successfully rerouted from Vancouver PoP to Toronto PoP, isolating circuit `fiber-van-richmond-10G`.
```
Note the model's first reroute attempt targets `Richmond PoP`, which isn't a real, healthy location in the mock data - the server rejects it with an `ERROR` instead of silently succeeding, and the model retries with the correct healthy target (`Toronto PoP`) before succeeding.
## Public HTTP demo (no API key needed)
`web/app.py` is a small FastAPI wrapper around the same mock telemetry/reroute
logic, exposed as plain REST endpoints - no MCP client and no Gemini API key
required. `/triage/{device_id}` reimplements the fetch → check → reroute flow
deterministically in Python (not via an LLM), so it's free and safe to expose
publicly.
Run it locally:
```bash
uvicorn web.app:app --host 127.0.0.1 --port 8001
```
Then, from another terminal:
```bash
curl http://127.0.0.1:8001/devices
curl http://127.0.0.1:8001/telemetry/router-van-01
curl http://127.0.0.1:8001/syslog
curl http://127.0.0.1:8001/triage/router-van-01 # degraded device -> auto-reroutes
curl http://127.0.0.1:8001/triage/router-yyz-02 # healthy device -> no reroute
```
## Notes
- Requires `mcp<2` (already pinned in `requirements.txt`) - the server uses the v1 `FastMCP` API.
- Gemini model availability changes over time; if you hit a `404` model-not-found error, list the models available to your API key and update the model name in `agent/gemini_mcp_client.py`.
- Tool-calling rounds are capped per run (`GeminiMCPOrchestrator.MAX_TURNS`, default 5) to avoid runaway API usage.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues