- name
- opentelemetry-mcp-server
- description
- Query and analyze OpenTelemetry traces (Jaeger, Tempo, Traceloop) with AI assistance for debugging and observability
- triggers
- ["search opentelemetry traces","analyze llm token usage","debug distributed traces","find slow traces","query jaeger backend","analyze opentelemetry spans","check trace errors","review llm model performance"]
# OpenTelemetry MCP Server
> Skill by [ara.so](https://ara.so) — MCP Skills collection.
A Model Context Protocol (MCP) server that enables AI assistants to query and analyze OpenTelemetry traces across multiple backends (Jaeger, Grafana Tempo, Traceloop). Specialized for LLM observability with support for token tracking, error debugging, and performance analysis.
## What This Project Does
The OpenTelemetry MCP Server provides tools for:
- **Trace Search**: Query distributed traces with advanced filtering
- **Span Analysis**: Deep-dive into individual operations
- **LLM Observability**: Track token usage, model performance, and costs
- **Error Detection**: Find and analyze failed requests
- **Performance Monitoring**: Identify slow operations and bottlenecks
Supports multiple backends: Jaeger, Grafana Tempo, and Traceloop cloud.
## Installation
### Quick Start (No Installation)
Configure your MCP client to run directly from PyPI using `pipx` or `uvx`:
**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
```json
{
"mcpServers": {
"opentelemetry-mcp": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
}
}
}
```
**Cursor/Windsurf** (Settings → MCP):
```json
{
"opentelemetry-mcp": {
"command": "uvx",
"args": ["opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
}
}
```
**Gemini CLI** (`~/.gemini/config.json`):
```json
{
"mcpServers": {
"opentelemetry-mcp": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "tempo",
"BACKEND_URL": "http://localhost:3200"
}
}
}
}
```
### Global Installation
```bash
# Install with pipx (recommended)
pipx install opentelemetry-mcp
# Or with pip
pip install opentelemetry-mcp
# Verify installation
opentelemetry-mcp --help
```
### Development Setup
```bash
# Clone repository
git clone https://github.com/traceloop/opentelemetry-mcp-server.git
cd opentelemetry-mcp-server
# Install with uv
uv sync
# Or pip with dev dependencies
pip install -e ".[dev]"
```
## Configuration
### Backend Types
| Backend | Type | URL Example | Auth Required |
|-----------|-------------|----------------------------|---------------|
| Jaeger | Local | http://localhost:16686 | No |
| Tempo | Local/Cloud | http://localhost:3200 | Optional |
| Traceloop | Cloud | https://api.traceloop.com | Yes (API key) |
### Environment Variables
Create `.env` file:
```bash
# Required
BACKEND_TYPE=jaeger # or tempo, traceloop
BACKEND_URL=http://localhost:16686
# Optional (for Traceloop or authenticated backends)
BACKEND_API_KEY=${TRACELOOP_API_KEY}
# Optional: Custom headers
BACKEND_HEADERS={"Authorization": "Bearer ${YOUR_TOKEN}"}
```
### CLI Configuration
Override environment variables with CLI arguments:
```bash
# Jaeger backend
opentelemetry-mcp --backend jaeger --url http://localhost:16686
# Traceloop with API key
opentelemetry-mcp --backend traceloop --url https://api.traceloop.com --api-key ${TRACELOOP_API_KEY}
# Tempo with custom headers
opentelemetry-mcp --backend tempo --url http://localhost:3200 --headers '{"X-Scope-OrgID": "my-org"}'
```
### Local Development Configuration
For Claude Desktop with local repository:
```json
{
"mcpServers": {
"opentelemetry-mcp": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/opentelemetry-mcp-server",
"run",
"opentelemetry-mcp"
],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
}
}
}
```
## Available Tools
### 1. search_traces
Search traces with advanced filtering.
**Parameters:**
- `service_name` (optional): Filter by service
- `operation_name` (optional): Filter by operation
- `tags` (optional): Key-value tag filters
- `min_duration` (optional): Minimum duration in microseconds
- `max_duration` (optional): Maximum duration in microseconds
- `start_time` (optional): Start time (ISO 8601 or relative like "1h")
- `end_time` (optional): End time (ISO 8601)
- `limit` (optional): Max results (default: 20)
- `filters` (optional): Advanced filter expressions
**Example Usage:**
```python
# Natural language queries that trigger this tool:
"Show me traces from the api-gateway service in the last hour"
"Find traces with errors from my-service"
"Search for slow requests taking more than 5 seconds"
```
**Filter Examples:**
```python
# Find errors
filters = [
{
"attribute": "status.code",
"operator": "eq",
"value": "ERROR"
}
]
# Duration range
filters = [
{
"attribute": "duration",
"operator": "gte",
"value": 1000000 # 1 second in microseconds
}
]
# Tag matching
filters = [
{
"attribute": "http.status_code",
"operator": "gte",
"value": 500
}
]
```
### 2. search_spans
Search individual spans within traces.
**Parameters:**
- `service_name` (required for Jaeger): Service to search
- `operation_name` (optional): Operation filter
- `tags` (optional): Tag filters
- `min_duration` (optional): Minimum duration
- `max_duration` (optional): Maximum duration
- `start_time` (optional): Start time
- `end_time` (optional): End time
- `limit` (optional): Max results
**Example:**
```python
# "Find database query spans slower than 100ms"
{
"service_name": "api-gateway",
"operation_name": "SELECT",
"min_duration": 100000, # 100ms in microseconds
"start_time": "2h"
}
```
### 3. get_trace
Retrieve complete trace details by ID.
**Parameters:**
- `trace_id` (required): Trace ID to fetch
**Example:**
```python
# "Get details for trace abc123def456"
{
"trace_id": "abc123def456"
}
```
### 4. get_llm_usage
Aggregate LLM token usage metrics.
**Parameters:**
- `service_name` (optional): Filter by service
- `model` (optional): Filter by model (e.g., "gpt-4")
- `start_time` (optional): Start time
- `end_time` (optional): End time
**Example:**
```python
# "Show me token usage for gpt-4 today"
{
"model": "gpt-4",
"start_time": "24h"
}
# "What's the total token cost for my-service this week"
{
"service_name": "my-service",
"start_time": "7d"
}
```
### 5. list_services
List all instrumented services.
**Example:**
```python
# "What services are being traced?"
# No parameters required
```
### 6. find_errors
Find traces containing errors.
**Parameters:**
- `service_name` (optional): Filter by service
- `start_time` (optional): Start time (default: 1h)
- `end_time` (optional): End time
- `limit` (optional): Max results
**Example:**
```python
# "Show me errors from the last 30 minutes"
{
"start_time": "30m",
"limit": 50
}
# "Find errors in the checkout-service"
{
"service_name": "checkout-service",
"start_time": "1h"
}
```
### 7. list_llm_models
Discover which LLM models are in use.
**Parameters:**
- `start_time` (optional): Start time
- `end_time` (optional): End time
**Example:**
```python
# "What LLM models are we using?"
{
"start_time": "24h"
}
```
### 8. get_llm_model_stats
Get performance statistics per model.
**Parameters:**
- `model` (optional): Specific model to analyze
- `start_time` (optional): Start time
- `end_time` (optional): End time
**Example:**
```python
# "Compare performance of gpt-4 vs gpt-3.5-turbo"
# Call twice, once per model:
{
"model": "gpt-4",
"start_time": "24h"
}
```
### 9. get_llm_expensive_traces
Find traces with highest token usage.
**Parameters:**
- `service_name` (optional): Filter by service
- `model` (optional): Filter by model
- `start_time` (optional): Start time
- `end_time` (optional): End time
- `limit` (optional): Number of traces (default: 10)
**Example:**
```python
# "Show me the 5 most expensive LLM calls today"
{
"limit": 5,
"start_time": "24h"
}
```
### 10. get_llm_slow_traces
Find slowest LLM operations.
**Parameters:**
- `service_name` (optional): Filter by service
- `model` (optional): Filter by model
- `start_time` (optional): Start time
- `end_time` (optional): End time
- `limit` (optional): Number of traces (default: 10)
**Example:**
```python
# "What are the slowest gpt-4 requests?"
{
"model": "gpt-4",
"limit": 10,
"start_time": "1h"
}
```
## Common Patterns
### Time Ranges
Specify time ranges using relative or absolute formats:
```python
# Relative (most common)
"start_time": "1h" # Last hour
"start_time": "30m" # Last 30 minutes
"start_time": "24h" # Last 24 hours
"start_time": "7d" # Last 7 days
# Absolute (ISO 8601)
"start_time": "2024-01-15T10:00:00Z"
"end_time": "2024-01-15T11:00:00Z"
```
### Filter Operators
Available operators for advanced filtering:
```python
# Equality
{"attribute": "http.method", "operator": "eq", "value": "POST"}
# Comparison
在 GitHub 查看