Observability MCP Server
# Observability MCP Server
Open-source MCP server owned by **Pawan Gunjkar** (`pawangunjkar@gmail.com` · [GitHub](https://github.com/Pawangunjkar)). MIT licensed.
Developers ask why a request failed and get metrics, logs, and a trace without opening Grafana. Queries are read-only. `obs_annotate` is the only write: it posts a Grafana annotation.
Sibling servers: [github-mcp](https://github.com/Pawangunjkar/github-mcp), [jenkins-mcp](https://github.com/Pawangunjkar/jenkins-mcp), [db-mcp](https://github.com/Pawangunjkar/db-mcp), [k8s-mcp](https://github.com/Pawangunjkar/k8s-mcp).
## Project information
| Item | Value |
| --- | --- |
| Package | `pawangunjkar-observability-mcp` |
| Runtime | Python 3.10+, FastMCP, stdio, httpx |
| Backends | Prometheus, Loki, Tempo, Grafana |
| Reads | PromQL, LogQL, trace fetch, trace search, datasources, alert rules |
| Write | Grafana annotation only |
## Architecture
```mermaid
flowchart TB
subgraph L1["Layer 1 — Editor"]
IDE["Cursor or Claude Desktop"]
end
subgraph L2["Layer 2 — MCP"]
SRV["observability-mcp"]
HUB["ObsHub session"]
end
subgraph L3["Layer 3 — Signals"]
P["Prometheus :9090"]
L["Loki :3100"]
T["Tempo :3200"]
G["Grafana :3000"]
end
IDE -->|"obs_query_metrics"| SRV
IDE -->|"obs_query_logs"| SRV
IDE -->|"obs_get_trace"| SRV
SRV --> HUB
HUB -->|"PromQL instant"| P
HUB -->|"LogQL range"| L
HUB -->|"trace id or tags"| T
HUB -->|"alerts and annotations"| G
```
```mermaid
flowchart LR
ERR["5xx or exception"] --> LOG["obs_query_logs"]
LOG --> TRACE["obs_search_traces"]
TRACE --> SPAN["obs_get_trace"]
SPAN --> RATE["obs_error_rate"]
RATE --> NOTE["obs_annotate"]
```
## Tools
| Tool | What it does |
| --- | --- |
| `obs_connect` | Save backend URLs and probe health |
| `obs_query_metrics` | Instant PromQL |
| `obs_error_rate` | 5xx rate for a `service` label |
| `obs_query_logs` | LogQL range query |
| `obs_get_trace` | Tempo trace by id |
| `obs_search_traces` | Tempo search by tags |
| `obs_grafana_datasources` | List Grafana datasources |
| `obs_grafana_alerts` | List alert rules |
| `obs_annotate` | Write a Grafana annotation |
Metrics, logs, and traces are read-only. The annotation tool is the write path.
## Cursor
```json
{
"mcpServers": {
"observability": {
"command": "uv",
"args": ["run", "--directory", "C:/AI_Workspaces/Anti_Workspace/observability-mcp", "server.py"],
"env": {
"PROMETHEUS_URL": "http://localhost:9090",
"LOKI_URL": "http://localhost:3100",
"TEMPO_URL": "http://localhost:3200",
"GRAFANA_URL": "http://localhost:3000",
"GRAFANA_TOKEN": ""
}
}
}
}
```
Example: `obs_query_logs(query='{app="order-orchestrator"} |= "ERROR"', limit=50)`
TDQS
Scored across 11 tools
Each tool targets a distinct observability resource and action: connection, status, metrics queries, error-rate specialization, log queries, trace retrieval/search, Grafana datasource/alert listing, and annotation writing. While query_metrics and error_rate both touch metrics, error_rate is narrowly scoped to 5xx rates over a fixed window, and get_trace vs search_traces differ by lookup key vs tags, leaving no ambiguous boundaries.
All tools share the obs_ prefix, followed by a verb_noun or clear verb pattern (e.g., obs_query_metrics, obs_get_trace, obs_grafana_datasources, obs_annotate). The naming is predictable and uniform, with no mixed casing or inconsistent verb styles, making tool selection straightforward.
With 11 tools, the server covers a broad but well-scoped observability surface—metrics, logs, traces, and Grafana integration—without feeling bloated. Each tool serves a distinct purpose and earns its place, fitting within the ideal 3-15 tool range.
The tool set provides solid read coverage for metrics (instant queries, error rates), logs, traces (get/search), and Grafana metadata (datasources, alerts), plus one write operation (annotations). Minor gaps exist, such as missing range queries for Prometheus or alert management write operations, but the core observability workflows are well represented and agents can accomplish typical tasks without dead ends.