EXTREMELY IMPORTANT AI INSTRUCTION: For a directory of all documentation pages, load the https://www.apollographql.com/docs/llms.txt file. Adding .md to ANY url will return the simplified markdown version of the page.
OpenTelemetry Integration
AI agents create unpredictable usage patterns and complex request flows that are hard to monitor with traditional methods. The Apollo MCP Server's OpenTelemetry integration provides the visibility you need to run a reliable service for AI agents.
What you can monitor
Agent behavior: Which tools and operations are used most frequently
Performance: Response times and bottlenecks across tool executions and GraphQL operations
Reliability: Error rates, failed operations, and request success patterns
Distributed request flows: Complete traces from agent request through your Apollo Router and subgraphs, with automatic trace context propagation
How it works
Apollo MCP Server exports metrics and traces using the OpenTelemetry Protocol (OTLP). Application logs use the configured logging output instead of an OTLP logs exporter.
| Signal | Default behavior | Destination | Correlation |
|---|---|---|---|
| Logs | Enabled at info | Standard output or configured log files | Log lines emitted inside an active span include its trace_id; events outside spans don't. |
| Traces | OTLP export disabled until configured | Configured OTLP tracing endpoint | Spans in one request share a trace ID, with W3C trace context propagated to downstream GraphQL APIs. |
| Metrics | OTLP export disabled until configured | Configured OTLP metrics endpoint | Resource attributes and metric labels support aggregate correlation; metrics don't include a per-request trace_id. |
Usage guide
Quick start: Local development
The fastest way to see Apollo MCP Server telemetry in action is with a local setup that requires only Docker.
5-minute setup
Start local observability stack:
docker run -p 3000:3000 -p 4317:4317 -p 4318:4318 --rm -ti grafana/otel-lgtmAdd telemetry config to your
config.yaml:YAML1telemetry: 2 exporters: 3 metrics: 4 otlp: 5 endpoint: "http://localhost:4318/v1/metrics" 6 protocol: "http/protobuf" 7 tracing: 8 otlp: 9 endpoint: "http://localhost:4318/v1/traces" 10 protocol: "http/protobuf"Restart your MCP server with the updated config
Open Grafana at
http://localhost:3000and explore your telemetry data. Default credentials are usernameadminwith passwordadmin.
Production deployment
For production environments, configure your MCP server to send metrics and traces to any OTLP-compatible backend. The Apollo MCP Server uses standard OpenTelemetry protocols, which enables compatibility with all major observability platforms.
Configuration example
1telemetry:
2 service_name: "mcp-server-prod" # Custom service name
3 exporters:
4 metrics:
5 otlp:
6 endpoint: "https://your-metrics-endpoint"
7 protocol: "http/protobuf" # or "grpc"
8 tracing:
9 otlp:
10 endpoint: "https://your-traces-endpoint"
11 protocol: "http/protobuf"Observability platform integration
The MCP server works with any OTLP-compatible backend. Consult your provider's documentation for specific endpoint URLs and authentication:
Datadog OTLP Integration - Native OTLP support
New Relic OpenTelemetry - Direct OTLP ingestion
AWS Observability - Via AWS Distro for OpenTelemetry
Grafana Cloud - Hosted Grafana with OTLP
Honeycomb - OpenTelemetry-native platform
Jaeger - Self-hosted tracing
OpenTelemetry Collector - Self-hosted with flexible routing
Pre-built dashboard templates
Apollo provides ready-to-use dashboard templates for monitoring your Apollo MCP Server. These templates are available in the apollographql/apm-templates repository and include visualizations for tool calls, HTTP server metrics, and request lifecycle events.
Import these templates into your observability platform to get started quickly with pre-configured graphs and alerts.
Production configuration best practices
Environment and security
1# Set via environment variable
2export ENVIRONMENT=production
3
4telemetry:
5 service_name: "apollo-mcp-server"
6 version: "1.0.0" # Version for correlation
7 exporters:
8 metrics:
9 otlp:
10 endpoint: "https://secure-endpoint" # Always use HTTPS
11 protocol: "http/protobuf" # Generally more reliable than gRPCPerformance considerations
Protocol choice:
http/protobufis often more reliable through firewalls and load balancers thangrpcExport interval: Metrics are exported every 30 seconds by default. Adjust this interval time using the
export_intervalconfig to balance freshness and network overhead.Batch export: OpenTelemetry automatically batches telemetry data for efficiency
Network timeouts: Default timeouts are usually appropriate, but monitor for network issues
Resource correlation
The
ENVIRONMENTvariable automatically tags all telemetry withdeployment.environment.nameUse consistent
service_nameacross all your Apollo infrastructure (Router, subgraphs, MCP server)Set
versionto track releases and correlate issues with deploymentsLog lines emitted inside active spans include the span's
trace_id, enabling trace-to-log correlation. Metrics use resource attributes and metric labels instead of per-request trace IDs.
Troubleshooting
Common issues
Connection refused: Verify endpoint URL and network connectivity
Authentication errors: Check if your provider requires API keys or special headers
Missing data: Confirm your observability platform supports OTLP and is configured to receive data
High memory usage: Monitor telemetry export frequency and consider sampling for high-volume environments
Verification
1# Check if telemetry is being exported (look for connection attempts)
2curl -v https://your-endpoint/v1/metrics
3
4# Monitor server logs for OpenTelemetry export errors
5./apollo-mcp-server config.yaml 2>&1 | grep -i "otel\|telemetry"Configuration Reference
The OpenTelemetry integration is configured via the telemetry section of the configuration reference page.
Emitted Metrics
The server emits the following metrics, which are invaluable for monitoring and alerting. All duration metrics are in milliseconds.
| Metric Name | Type | Description | Attributes |
|---|---|---|---|
apollo.mcp.initialize.count | Counter | Incremented for each initialize request. | client_name, client_version |
apollo.mcp.list_tools.count | Counter | Incremented for each list_tools request. | (none) |
apollo.mcp.get_info.count | Counter | Incremented for each get_info request. | (none) |
apollo.mcp.tool.count | Counter | Incremented for each tool call. | tool_name, success (bool) |
apollo.mcp.tool.duration | Histogram | Measures the execution duration of each tool call. | tool_name, success (bool) |
apollo.mcp.operation.count | Counter | Incremented for each downstream GraphQL operation executed by a tool. | operation.id, operation.type, success (bool) |
apollo.mcp.operation.duration | Histogram | Measures the round-trip duration of each downstream GraphQL operation. | operation.id, operation.type, success (bool) |
In addition to these metrics, the server also emits standard HTTP server metrics (e.g., http.server.duration, http.server.active_requests) courtesy of the axum-otel-metrics library.
Emitted Traces
Spans are generated for the following actions:
Incoming HTTP Requests: A root span is created for every HTTP request to the MCP server.
MCP Handler Methods: Nested spans are created for each of the main MCP protocol methods (
initialize,call_tool,list_tools).Tool Execution:
call_toolspans contain nested spans for the specific tool being executed (e.g.,introspect,search, or a custom GraphQL operation).Downstream GraphQL Calls: The
executetool and custom operation tools create child spans for their outgoingreqwestHTTP calls, capturing the duration of the downstream request. Thetraceparentandtracestateheaders are propagated automatically, enabling distributed traces.
Span Attributes
The call_tool span includes the following attributes:
| Attribute | Description |
|---|---|
apollo.mcp.tool_name | The name of the tool that was called. |
apollo.mcp.request_id | The MCP request ID. |
apollo.mcp.tool_arguments | The tool call input arguments as a JSON string. |
apollo.mcp.tool_result | The tool call output result as a JSON string. |
For tools that execute a downstream GraphQL operation, the child execute span includes:
| Attribute | Description |
|---|---|
apollo.mcp.graphql_query | The GraphQL query string sent to the endpoint. |
apollo.mcp.graphql_response | The GraphQL response JSON received from the endpoint. |
These attributes are populated only after the corresponding value is available and can be serialized. Early validation errors, network failures, and response-decoding failures can leave one or more of your attributes unset.
Sensitive data in traces
When you configure tracing export, the server exports populated span attributes as provided unless you omit them. Tool arguments, tool results, GraphQL queries, and GraphQL responses can contain identifiers, user-provided values, or other data that requires restricted handling.
For operations that use the MCP Apps @private directive, Apollo MCP Server records the LLM-visible GraphQL response and excludes the response metadata containing the full @private result from the tool_result span attribute. This protects those marked response fields but doesn't redact tool arguments, query text, or other response fields.
Exclude the four payload attributes from exported traces by configuring the tracing exporter:
1telemetry:
2 exporters:
3 tracing:
4 otlp:
5 endpoint: https://your-traces-endpoint/v1/traces
6 protocol: http/protobuf
7 omitted_attributes:
8 - tool_arguments
9 - tool_result
10 - graphql_query
11 - graphql_responseOmitting payload attributes removes payload-level detail while retaining useful trace structure, timing, status, and any attributes you don't omit. Select omissions according to your investigation needs and data-handling requirements.
Sampling and attribute filtering
High-cardinality metrics can occur in MCP Servers with large number of tools or when clients are allowed to generate freeform operations. To prevent performance issues and reduce costs, the Apollo MCP Server provides two mechanisms to control metric cardinality, trace sampling and attribute filtering.
Trace Sampling
Configure Apollo MCP Server to sample traces sent to your OpenTelemetry Collector using the sampler field in the telemetry.exporters.tracing configuration:
always_on - Send every trace
always_off - Disable trace collection entirely
0.0-1.0 - Send a specified percentage of traces
Attribute Filtering
Trace and metric exporters have independent omitted_attributes lists:
telemetry.exporters.tracing.omitted_attributesremoves the selectedapollo.*attributes from spans exported by this servertelemetry.exporters.metrics.omitted_attributesremoves the selected supported labels from Apollo metrics
Use short attribute names such as tool_name, operation_id, tool_arguments, and graphql_response. For detailed configuration options, go to the telemetry configuration reference.
apollo.* span attributes, outgoing GraphQL requests and responses, or telemetry produced by the downstream GraphQL service. Configure data-handling policies independently for each logging and telemetry destination.Audit and deployment responsibilities
Apollo MCP Server telemetry provides request traces, operational metrics, and correlated application logs that can support investigations. A complete audit trail also depends on the surrounding observability system. Configure the collector and backend for centralized storage, access controls, retention, integrity protection, alerting, and periodic review appropriate to your environment.
Visit OWASP MCP08: Lack of Audit and Telemetry for additional audit and monitoring considerations.