Skip to main content
Glama
README.md
# Incident Triage MCP Server

An AI-assisted **Incident Triage MCP Server** that helps engineers investigate service incidents using semantic log search, error aggregation, RAG-based diagnosis, and runbook recommendations.

The project demonstrates how **Model Context Protocol (MCP)** can be applied to a real-world operational engineering workflow rather than a generic chatbot.

The server operates against synthetic messaging/CPaaS service logs and exposes four MCP tools that can be invoked from an MCP client or directly from the terminal using the FastMCP CLI.

---

## ๐Ÿš€ What This Project Does

Instead of manually searching through hundreds of log lines, an engineer can ask questions such as:

```text
Why is messaging-service failing?

Find logs related to queue backlog.

What's the runbook for a connection timeout?

What is the likely root cause of the messaging-service incident?
```

The MCP server converts these requests into structured tool calls against the incident data.

The important distinction is that the system **does not ask an LLM to guess from nothing**.

It combines:

* Deterministic log processing
* Semantic search
* Structured error aggregation
* Retrieval-Augmented Generation (RAG)
* LLM-based incident analysis
* Semantic runbook matching

---

# ๐Ÿ—๏ธ Architecture

```text
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚       MCP Client        โ”‚
                         โ”‚                         โ”‚
                         โ”‚  Claude / FastMCP CLI   โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                      โ”‚
                                      โ”‚ MCP / stdio
                                      โ–ผ
                         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                         โ”‚     Incident Triage     โ”‚
                         โ”‚       MCP Server        โ”‚
                         โ”‚       server.py         โ”‚
                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                      โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚                       โ”‚                       โ”‚
              โ–ผ                       โ–ผ                       โ–ผ
       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚ Log Search   โ”‚       โ”‚ Error        โ”‚       โ”‚ Runbook      โ”‚
       โ”‚              โ”‚       โ”‚ Summary      โ”‚       โ”‚ Search       โ”‚
       โ”‚ Embeddings   โ”‚       โ”‚ Plain Code   โ”‚       โ”‚ Embeddings   โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
              โ”‚                                              โ”‚
              โ–ผ                                              โ–ผ
       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                               โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚ logs.jsonl   โ”‚                               โ”‚runbooks.json โ”‚
       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                               โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

                                      โ”‚
                                      โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚ Incident        โ”‚
                              โ”‚ Diagnosis       โ”‚
                              โ”‚                 โ”‚
                              โ”‚ Retrieve Logs   โ”‚
                              โ”‚       โ†“         โ”‚
                              โ”‚ Anthropic LLM   โ”‚
                              โ”‚       โ†“         โ”‚
                              โ”‚ Root Cause +    โ”‚
                              โ”‚ Next Steps      โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

---

# ๐Ÿ”ง MCP Tools

The server exposes four tools.

## 1. `search_logs`

Performs semantic search over service logs using `sentence-transformers`.

Example:

```bash
fastmcp call server.py search_logs query="queue backlog"
```

The query is converted into an embedding and compared with log embeddings.

This allows queries such as:

```text
queue is stuck
```

to find logs containing concepts such as:

```text
consumer lag
queue backlog
```

without depending entirely on exact keyword matching.

---

## 2. `get_error_summary`

Provides a deterministic aggregation of errors.

Example:

```bash
fastmcp call server.py get_error_summary
```

Example result:

```text
Error summary:

db_deadlock: 38
rate_limit_exceeded: 37
queue_backlog: 37
auth_token_expired: 32
connection_timeout: 24
```

No LLM is involved here.

This is intentional.

Simple counting does not require AI.

---

## 3. `diagnose_incident`

Performs RAG-based incident diagnosis.

Example:

```bash
fastmcp call server.py diagnose_incident \
  service="messaging-service" \
  hours=24
```

The flow is:

```text
Service
   โ”‚
   โ–ผ
Retrieve recent errors
   โ”‚
   โ–ผ
Build incident context
   โ”‚
   โ–ผ
Send context to Anthropic
   โ”‚
   โ–ผ
Root cause hypothesis
   โ”‚
   โ–ผ
Immediate next steps
```

The LLM receives retrieved incident evidence rather than being asked to diagnose the problem without context.

If `ANTHROPIC_API_KEY` is not available, the POC falls back to a raw error-frequency summary.

---

## 4. `suggest_runbook`

Uses semantic similarity to find the most relevant operational runbooks.

Example:

```bash
fastmcp call server.py suggest_runbook \
  query="connection to provider keeps timing out"
```

Example:

```text
Downstream Connection Timeout
Provider Auth Token Expired
Provider Rate Limiting
```

This allows engineers to describe an incident naturally instead of remembering the exact runbook title.

---

# ๐Ÿง  AI vs Traditional Logic

One of the goals of this POC is to demonstrate that **not everything needs an LLM**.

| Capability          | Approach           | Why                                 |
| ------------------- | ------------------ | ----------------------------------- |
| `search_logs`       | Embeddings         | Semantic matching                   |
| `get_error_summary` | Python aggregation | No AI required                      |
| `diagnose_incident` | RAG + Anthropic    | Converts evidence into a diagnosis  |
| `suggest_runbook`   | Embeddings         | Handles different incident phrasing |

This creates a practical hybrid architecture:

```text
                 Incident Triage
                       โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚            โ”‚            โ”‚
      Deterministic  Semantic      LLM
         Logic       Retrieval    Reasoning
          โ”‚            โ”‚            โ”‚
      Aggregation   Embeddings      RAG
```

---

# ๐Ÿ“ Project Structure

```text
incident-mcp/
โ”‚
โ”œโ”€โ”€ server.py
โ”œโ”€โ”€ requirements.txt
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ .gitignore
โ”‚
โ””โ”€โ”€ data/
    โ”œโ”€โ”€ generate_logs.py
    โ””โ”€โ”€ runbooks.json
```

`logs.jsonl` is generated locally and should not be committed to Git.

---

# ๐Ÿ› ๏ธ Technology Stack

* Python 3.12
* FastMCP
* Model Context Protocol
* Sentence Transformers
* `all-MiniLM-L6-v2`
* PyTorch
* NumPy
* SciPy
* Anthropic API
* python-dotenv
* JSONL
* Synthetic operational logs

---

# โš™๏ธ Local Setup

## 1. Clone the repository

```bash
git clone git@github.com:balachoudry-tech/incident_mcp_ai.git
cd incident_mcp_ai
```

---

## 2. Create a virtual environment

Python 3.12 is recommended.

```bash
python3.12 -m venv .venv
```

Activate it:

### macOS / Linux

```bash
source .venv/bin/activate
```

### Windows

```powershell
.venv\Scripts\activate
```

---

## 3. Install dependencies

```bash
pip install -r requirements.txt
```

The dependency versions are pinned to the versions used by the working POC environment.

---

# ๐Ÿ“Š Generate Synthetic Logs

Generate the incident data:

```bash
python data/generate_logs.py
```

This creates:

```text
data/logs.jsonl
```

The generated logs simulate operational failures across messaging/CPaaS services.

---

# ๐Ÿ” Configure Anthropic

Create a `.env` file in the project root:

```env
ANTHROPIC_API_KEY=your_api_key_here
```

The `.env` file is intentionally excluded from Git.

The application loads the key using `python-dotenv`.

Never commit your API key.

---

# โ–ถ๏ธ Run the MCP Server

The server uses **stdio transport**.

```bash
python server.py
```

When started directly, the server waits for an MCP client.

You may see:

```text
Starting MCP server 'incident-triage'
with transport 'stdio'
```

This is expected.

The server is not a traditional HTTP API.

---

# ๐Ÿงช Test from Terminal

The POC can be tested without Claude Desktop using the FastMCP CLI.

## List available tools

```bash
fastmcp list server.py
```

Expected tools:

```text
search_logs
get_error_summary
diagnose_incident
suggest_runbook
```

---

## Test error summary

```bash
fastmcp call server.py get_error_summary
```

---

## Test semantic search

```bash
fastmcp call server.py search_logs \
  query="queue backlog"
```

You can also specify the number of results:

```bash
fastmcp call server.py search_logs \
  query="queue backlog" \
  top_k=5
```

---

## Test runbook search

```bash
fastmcp call server.py suggest_runbook \
  query="connection to provider keeps timing out"
```

---

## Test incident diagnosis

```bash
fastmcp call server.py diagnose_incident \
  service="messaging-service" \
  hours=24
```

With `ANTHROPIC_API_KEY` configured, this executes the RAG + Anthropic diagnosis flow.

---

# ๐Ÿ”„ Incident Diagnosis Flow

A typical diagnosis follows this flow:

```text
1. Engineer asks about a service
             โ”‚
             โ–ผ
2. Retrieve recent service errors
             โ”‚
             โ–ผ
3. Build incident context
             โ”‚
             โ–ผ
4. Send relevant context to LLM
             โ”‚
             โ–ผ
5. LLM analyzes relationships
             โ”‚
             โ–ผ
6. Generate root-cause hypothesis
             โ”‚
             โ–ผ
7. Recommend immediate next steps
```

For example:

```text
Carrier timeout
       โ”‚
       โ–ผ
Delivery retries
       โ”‚
       โ–ผ
Rate limiting
       โ”‚
       โ–ผ
Retry contention
       โ”‚
       โ–ผ
Database deadlocks
       โ”‚
       โ–ผ
Queue backlog
```

The LLM can use these correlated signals to produce a higher-level incident hypothesis.

---

# ๐Ÿ“ฆ Why No Vector Database?

This POC intentionally does not use a vector database.

The log dataset is small enough that embeddings can be:

```text
Loaded
  โ†“
Computed
  โ†“
Stored in memory
  โ†“
Compared using similarity
```

For a small proof of concept, this keeps the architecture simple.

A persistent vector index would become useful as the dataset grows.

---

# ๐Ÿ”’ Security Notes

This is a proof of concept.

The following production concerns are intentionally outside the scope:

* Authentication
* Authorization
* Multi-tenancy
* Secret management
* Tool-level permissions
* Audit logging
* Production observability
* Persistent vector storage
* Real log ingestion
* Production-grade error handling

API keys should never be committed to the repository.

---

# ๐Ÿš€ Production Evolution

The POC can later evolve toward:

```text
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Real Log Sources     โ”‚
                    โ”‚                      โ”‚
                    โ”‚ CloudWatch           โ”‚
                    โ”‚ Elasticsearch        โ”‚
                    โ”‚ Loki                 โ”‚
                    โ”‚ OpenSearch            โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
                               โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Log Processing       โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
                               โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ Persistent Vector DB โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
                               โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ MCP Server           โ”‚
                    โ”‚                      โ”‚
                    โ”‚ Search               โ”‚
                    โ”‚ Summarize            โ”‚
                    โ”‚ Diagnose             โ”‚
                    โ”‚ Runbooks             โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                               โ”‚
                               โ–ผ
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚ MCP Client           โ”‚
                    โ”‚ / Incident Platform  โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
```

Potential future improvements include:

* Real production log sources
* Persistent vector indexes
* Authentication and authorization
* Tool-level access control
* Structured tracing
* Incident correlation IDs
* Confidence scoring
* Better "insufficient evidence" handling
* Audit trails
* Production observability
* Multi-service incident correlation

---

# ๐ŸŽฏ What This POC Demonstrates

This project demonstrates several practical AI engineering patterns:

### MCP

Building operational capabilities as reusable MCP tools.

### Semantic Search

Using embeddings to search logs based on meaning rather than exact keywords.

### RAG

Retrieving relevant operational evidence before asking an LLM to reason about an incident.

### Tool Selection

Using deterministic code where deterministic code is sufficient and AI where reasoning provides additional value.

### Operational AI

Applying GenAI to an engineering workflow where the output is grounded in actual incident evidence.

---

# โš ๏ธ Disclaimer

The logs and incidents in this repository are **synthetic** and are intended only for demonstration and learning purposes.

The diagnosis generated by the LLM should not be treated as an authoritative production incident response.

---

# ๐Ÿ“„ License

Add the project's license here if/when one is selected.

---

## Author

Built as an engineering-focused MCP/RAG POC demonstrating AI-assisted incident triage for high-throughput messaging/CPaaS systems.