| 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 — 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):
{
"mcpServers": {
"opentelemetry-mcp": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
}
}
}
Cursor/Windsurf (Settings → MCP):
{
"opentelemetry-mcp": {
"command": "uvx",
"args": ["opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
}
}
Gemini CLI (~/.gemini/config.json):
{
"mcpServers": {
"opentelemetry-mcp": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "tempo",
"BACKEND_URL": "http://localhost:3200"
}
}
}
}
Global Installation
pipx install opentelemetry-mcp
pip install opentelemetry-mcp
opentelemetry-mcp --help
Development Setup
git clone https://github.com/traceloop/opentelemetry-mcp-server.git
cd opentelemetry-mcp-server
uv sync
pip install -e ".[dev]"
Configuration
Backend Types
Environment Variables
Create .env file:
BACKEND_TYPE=jaeger
BACKEND_URL=http://localhost:16686
BACKEND_API_KEY=${TRACELOOP_API_KEY}
BACKEND_HEADERS={"Authorization": "Bearer ${YOUR_TOKEN}"}
CLI Configuration
Override environment variables with CLI arguments:
opentelemetry-mcp --backend jaeger --url http://localhost:16686
opentelemetry-mcp --backend traceloop --url https://api.traceloop.com --api-key ${TRACELOOP_API_KEY}
opentelemetry-mcp --backend tempo --url http://localhost:3200 --headers '{"X-Scope-OrgID": "my-org"}'
Local Development Configuration
For Claude Desktop with local repository:
{
"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:
"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:
filters = [
{
"attribute": "status.code",
"operator": "eq",
"value": "ERROR"
}
]
filters = [
{
"attribute": "duration",
"operator": "gte",
"value": 1000000
}
]
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:
{
"service_name": "api-gateway",
"operation_name": "SELECT",
"min_duration": 100000,
"start_time": "2h"
}
3. get_trace
Retrieve complete trace details by ID.
Parameters:
trace_id (required): Trace ID to fetch
Example:
{
"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:
{
"model": "gpt-4",
"start_time": "24h"
}
{
"service_name": "my-service",
"start_time": "7d"
}
5. list_services
List all instrumented services.
Example:
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:
{
"start_time": "30m",
"limit": 50
}
{
"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:
{
"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:
{
"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:
{
"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:
{
"model": "gpt-4",
"limit": 10,
"start_time": "1h"
}
Common Patterns
Time Ranges
Specify time ranges using relative or absolute formats:
"start_time": "1h"
"start_time": "30m"
"start_time": "24h"
"start_time": "7d"
"start_time": "2024-01-15T10:00:00Z"
"end_time": "2024-01-15T11:00:00Z"
Filter Operators
Available operators for advanced filtering:
{"attribute": "http.method", "operator": "eq", "value": "POST"}
{"attribute": "http.status_code", "operator": "gte", "value": 500}
{"attribute": "duration", "operator": "lt", "value": 1000000}
{"attribute": "http.url", "operator": "contains", "value": "/api/"}
{"attribute": "status.code", "operator": "ne", "value": "OK"}
LLM Cost Analysis
Track token usage and costs:
{
"tool": "get_llm_usage",
"params": {
"start_time": "24h",
"end_time": "now"
}
}
{
"tool": "get_llm_expensive_traces",
"params": {
"model": "gpt-4",
"limit": 10,
"start_time": "7d"
}
}
{
"tool": "list_llm_models",
"params": {"start_time": "24h"}
}
{
"tool": "get_llm_model_stats",
"params": {
"model": "gpt-4",
"start_time": "24h"
}
}
Error Investigation
Debug failures efficiently:
{
"tool": "find_errors",
"params": {
"service_name": "api-gateway",
"start_time": "1h",
"limit": 20
}
}
{
"tool": "get_trace",
"params": {
"trace_id": "error-trace-id-from-above"
}
}
{
"tool": "search_traces",
"params": {
"filters": [
{
"attribute": "error.type",
"operator": "eq",
"value": "TimeoutError"
}
],
"start_time": "24h"
}
}
Performance Optimization
Identify bottlenecks:
{
"tool": "search_traces",
"params": {
"min_duration": 5000000,
"start_time": "1h",
"limit": 20
}
}
{
"tool": "get_llm_slow_traces",
"params": {
"limit": 10,
"start_time": "24h"
}
}
{
"tool": "search_spans",
"params": {
"service_name": "database",
"min_duration": 100000,
"start_time": "1h"
}
}
Real-World Examples
Example 1: Debug Production Error
User says: "We're seeing 500 errors in production, help me debug"
{
"tool": "find_errors",
"params": {
"start_time": "30m",
"limit": 50
}
}
{
"tool": "search_traces",
"params": {
"filters": [
{
"attribute": "http.status_code",
"operator": "gte",
"value": 500
}
],
"start_time": "30m"
}
}
{
"tool": "get_trace",
"params": {
"trace_id": "<trace-id-from-step-1>"
}
}
Example 2: Optimize LLM Costs
User says: "Our OpenAI bill is too high, find what's expensive"
{
"tool": "get_llm_usage",
"params": {
"start_time": "7d"
}
}
{
"tool": "get_llm_expensive_traces",
"params": {
"limit": 20,
"start_time": "7d"
}
}
{
"tool": "get_llm_model_stats",
"params": {
"model": "gpt-4",
"start_time": "7d"
}
}
{
"tool": "get_trace",
"params": {
"trace_id": "<expensive-trace-id>"
}
}
Example 3: Service Discovery
User says: "What services are instrumented and how are they performing?"
{
"tool": "list_services"
}
{
"tool": "find_errors",
"params": {
"service_name": "api-gateway",
"start_time": "1h"
}
}
{
"tool": "search_traces",
"params": {
"service_name": "api-gateway",
"min_duration": 1000000,
"start_time": "1h"
}
}
Example 4: Monitor Model Performance
User says: "How is gpt-4 performing compared to yesterday?"
{
"tool": "get_llm_model_stats",
"params": {
"model": "gpt-4",
"start_time": "24h"
}
}
{
"tool": "get_llm_model_stats",
"params": {
"model": "gpt-4",
"start_time": "48h",
"end_time": "24h"
}
}
{
"tool": "get_llm_slow_traces",
"params": {
"model": "gpt-4",
"limit": 10,
"start_time": "24h"
}
}
Troubleshooting
Connection Issues
Problem: "Failed to connect to backend"
Solution:
curl http://localhost:16686/api/services
echo $BACKEND_TYPE
echo $BACKEND_URL
echo $BACKEND_API_KEY
No Results Returned
Problem: Search returns empty results
Solutions:
{
"tool": "list_services"
}
{
"tool": "search_traces",
"params": {
"start_time": "24h"
}
}
{
"tool": "search_traces",
"params": {
"service_name": "my-service"
}
}
Permission Errors (Traceloop/Tempo)
Problem: "Unauthorized" or "Forbidden"
Solution:
printenv | grep BACKEND_API_KEY
export BACKEND_HEADERS='{"X-Scope-OrgID": "your-org-id"}'
opentelemetry-mcp --backend traceloop \
--url https://api.traceloop.com \
--api-key ${TRACELOOP_API_KEY}
Jaeger Span Search Requires Service Name
Problem: "service_name is required for Jaeger span search"
Solution:
{
"tool": "search_spans",
"params": {
"service_name": "my-service",
"operation_name": "database-query"
}
}
Invalid Time Format
Problem: "Invalid time format"
Solution:
"start_time": "1h"
"start_time": "1 hour"
"start_time": "2024-01-15T10:00:00Z"
"start_time": "2024-01-15 10:00:00"
LLM Tools Return No Data
Problem: LLM-specific tools return empty results
Solution:
{
"tool": "list_llm_models",
"params": {
"start_time": "7d"
}
}
Duration Filtering Issues
Problem: Duration filters not working as expected
Solution:
1_000_000 microseconds = 1 second
100_000 microseconds = 100 milliseconds
1_000 microseconds = 1 millisecond
{
"min_duration": 5000000
}
{
"min_duration": 5000
}
MCP Server Not Starting
Problem: Server fails to start in Claude/Cursor
Solution:
opentelemetry-mcp --backend jaeger --url http://localhost:16686
python --version
pipx uninstall opentelemetry-mcp
pipx install opentelemetry-mcp
Advanced Configuration
Multiple Backends
Configure different backends for different environments:
{
"mcpServers": {
"otel-jaeger-local": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "jaeger",
"BACKEND_URL": "http://localhost:16686"
}
},
"otel-traceloop-prod": {
"command": "pipx",
"args": ["run", "opentelemetry-mcp"],
"env": {
"BACKEND_TYPE": "traceloop",
"BACKEND_URL": "https://api.traceloop.com",
"BACKEND_API_KEY": "${TRACELOOP_API_KEY}"
}
}
}
}
Custom Headers for Authentication
export BACKEND_HEADERS='{"Authorization": "Bearer ${YOUR_TOKEN}", "X-Scope-OrgID": "my-org"}'
{
"env": {
"BACKEND_TYPE": "tempo",
"BACKEND_URL": "http://tempo.example.com:3200",
"BACKEND_HEADERS": "{\"X-Scope-OrgID\": \"production\"}"
}
}
Resources