MCP OpenTelemetry Gateway
Allows exporting generated OpenTelemetry traces to Grafana Tempo through its OTLP/HTTP trace endpoint.
Allows exporting generated OpenTelemetry traces to Jaeger through its OTLP/HTTP trace endpoint.
Emits an OpenTelemetry span for every MCP tool call and exports traces via OTLP/HTTP to an OpenTelemetry Collector or compatible backend.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP OpenTelemetry GatewayStart the gateway for my file tools and export traces to http://localhost:4318"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP OpenTelemetry Gateway
A standalone MCP tool gateway. Replace an existing MCP tool-server entry with this gateway to automatically emit an OpenTelemetry span for every tool call that passes through it. The gateway forwards requests to the original server.
Agent client --MCP/stdio or HTTP--> Gateway --MCP--> Existing tool server
|
+--OTLP/HTTP protobuf--> Collector / trace backendNo vendor-specific service, model API, database, kernel sensor, privileged installation or AI inference is required. This is a tools-only gateway, not a full MCP proxy or host activity monitor. It does not capture local shell calls that bypass it, model conversations, filesystem events or another MCP connection's traffic.
Version 0.4 also provides MCP command/file execution tools and correlated logs. Use runtime mode when you want commands and file operations to happen through MCP, without installing a separate host collector. A tested Codex launch profile makes this its execution route; other harnesses require their own tool restrictions.
Version 0.5 adds an optional headless Codex analyst. It reviews bounded batches of recorded activity, validates evidence references, and exports AI findings as OTLP logs. It runs separately from tool execution and does not take automated actions. It requires a signed-in Codex CLI.
Install
Python 3.11+:
git clone https://github.com/terraxinyun-org/mcp-otel-gateway.git
cd mcp-otel-gateway
python3 -m venv .venv
.venv/bin/pip install .Install from this repository; the package is not published to PyPI. Runtime dependencies are the
official MCP SDK and OpenTelemetry SDK/HTTP exporter, with tested direct versions
pinned in pyproject.toml. No measured CPU/RAM overhead claim is made.
Related MCP server: SelfHeal MCP
Configure an upstream
Copy examples/upstream.json to a private configuration file and replace command
and args with your existing tool server's executable and arguments. Use absolute
paths. Set cwd if the upstream needs a specific working directory.
For an existing HTTP MCP server use examples/upstream-http.json. It supports
Streamable HTTP and static authorization from environment references:
{
"name": "company-tools",
"agent_name": "engineering-agent",
"transport": "streamable_http",
"url": "https://tools.example.com/mcp",
"headers_from_env": {"Authorization": "UPSTREAM_AUTHORIZATION"}
}Supply UPSTREAM_AUTHORIZATION securely as the complete header value (for example
Bearer …). Do not put real credentials in the example files. OAuth interactive
login/token refresh is not implemented by this gateway. HTTP is allowed only on
loopback; remote upstreams and export destinations require HTTPS.
Local subprocesses receive basic runtime environment variables plus the explicit
pass_env allowlist. Exporter credentials are not inherited by default. This is
environment hygiene, NOT a sandbox: the upstream still runs as the same OS user
and can access that user's files, including credential files under HOME.
Add it to your MCP client
Use examples/mcp-client.json as the client configuration template. Configure the
gateway executable, upstream file and OTLP destination. Client configuration
locations/formats vary; the example uses the common mcpServers JSON shape.
Replace the old tool-server connection rather than leaving both routes enabled. The gateway preserves upstream tool names, schemas, descriptions, annotations and tool results. Use one gateway entry per upstream. Restart the MCP connection when changing upstream configuration.
By default the client starts the gateway over stdio, without a listening port. For harnesses that use a URL, version 0.2 adds authenticated Streamable HTTP on loopback, with HTTPS reverse-proxy support. HTTP mode is single-trust-domain, not a multi-tenant authorization service.
See Harness compatibility for Claude Code, Codex, Gemini CLI, Cursor, VS Code and OpenCode configuration templates, HTTP setup, protocol test coverage and feature limits. Templates are documented integrations, not a claim that every application/version has been tested in a live model session.
Choose a telemetry destination
Supported output is OTLP traces and optional logs over HTTP/protobuf. A compatible backend can ingest this directly; other systems need an OpenTelemetry Collector exporter or another supported bridge. This does not promise support for every vendor API.
Environment variable | Meaning |
| Base URL, e.g. |
| Exact trace URL; overrides the base URL |
| Export authorization headers; standard comma-separated, percent-encoded values |
| Trace-specific authorization headers |
| Export request timeout in seconds |
| Trace-specific timeout |
| Custom CA certificate path when required |
| Service name, defaults to |
| Operator-controlled resource tags, e.g. |
Set OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf if explicitly configuring a
protocol. gRPC is not bundled; use a Collector to bridge transports. A destination
is required so the gateway cannot start while silently exporting nowhere.
Jaeger, SigNoz and Grafana Tempo are examples of compatible trace backends. Their credentials, endpoint paths and storage setup vary. Point the exporter at your backend's OTLP trace endpoint and supply its required authorization headers.
Local Jaeger demo
For Grafana Cloud, see the setup guide and importable dashboard. Version 0.3 adds optional bounded content capture and an explicit saved-lab-evidence exporter; no production monitoring settings are changed by installing it.
On a host with Docker Compose:
docker compose -f examples/compose.yaml up -d
export OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318
.venv/bin/python examples/smoke.pyOpen http://localhost:16686 and search for service mcp-otel-gateway.
The demo tool returns {"sum": 7}; its span is named mcp.tools.call.
The smoke command checks the MCP result; verify trace arrival in the UI.
This Jaeger setup is local-only and uses ephemeral in-memory storage.
It is not a production deployment. Docker must run on the same network host as
the gateway for these loopback settings. examples/collector.yaml is an alternative
Collector configuration for decoding and inspecting spans without a UI.
What is exported
Each call produces a CLIENT span with timestamps, duration, status and these attributes. Successful calls are OK; tool errors, timeouts, cancellations and upstream failures are ERROR. Errors contain a category, not an exception message.
Attribute | Source |
| Gateway |
| Requested upstream tool name, capped at 256 characters |
| Operator configuration; not verified agent identity |
| Operator's upstream label |
| Gateway |
| Operator configuration, false by default |
| Whether the caller supplied traceparent |
| Error category, when applicable |
Resource attributes include service.name, service.version, a random
service.instance.id for this gateway process and
agent_monitor.coverage=gateway_tool_calls_only.
By default arguments, outputs, tool descriptions, URLs, headers, credentials and exception stacks are NOT copied into spans. Tool names and operator-supplied resource labels are still metadata: do not put secrets into them. This is content omission, not a universal PII redaction engine. The upstream still receives full arguments and the requesting client receives full tool results.
To inspect tool content, explicitly set capture_content: true in the upstream
JSON. Bounded argument/result events then undergo best-effort redaction before
export. This can still disclose sensitive business data and undetected secrets;
see the capture limits. No raw-capture mode is provided.
Capture does not modify the data delivered to the tool or the caller.
Optional W3C traceparent / tracestate in a tools/call request's _meta join
the caller's trace. Without valid context each call starts a new trace. The gateway
forwards its resulting trace context in upstream _meta; the upstream must
instrument/extract it to continue the trace. Baggage and unrelated metadata are
not forwarded. Trace context is untrusted correlation data, never authorization.
The SDK's evolving GenAI names are isolated to this package's instrumentation.
Reliability and limits
Export is asynchronous: an in-memory queue of 2,048 spans, batches of up to 128, and a 1-second scheduling interval. Tool calls do not wait for backend export.
All gateway calls are sampled even if the parent is unsampled. Export failure, queue overflow or process termination can still lose telemetry. This is not a durable or tamper-proof audit log. Use a local Collector with persistent queues for stronger delivery, and monitor both SDK/Collector diagnostics.
Failed export logs a warning to stderr; tool execution continues. The SDK has bounded request/retry behavior. Closing the gateway attempts to flush traces.
Tool errors preserve upstream results. Transport failures return a sanitized error. A timeout does not undo side effects already performed by the upstream.
Supported upstream tools must be ordinary request/response tools. Resources, prompts, roots, sampling, elicitation, subscriptions, task-based tools, continuation workflows and progress forwarding are not supported. This is not a transparent replacement for servers requiring those capabilities.
Tools/list is forwarded on request; list-change notifications are not relayed.
Logs are opt-in with
export_logs: true. Metrics are not exported. The gateway does not classify threats or perform OS containment/microVM provisioning. The optional headless analyst provides post-execution AI review of captured evidence.No cloud service or live MCP client configuration is changed by installing this package.
Verification
.venv/bin/pip install '.[test]'
.venv/bin/pytest -qIntegration tests launch the real gateway and upstream subprocesses, exercise stdio and Streamable HTTP, decode exported OTLP protobuf at a local HTTP receiver, and verify tool results, error status, trace parentage, authorization headers and omission of sensitive argument/result values. Other tests cover timeout behavior, export failure isolation and credential allowlisting.
GitHub Actions
ci/github-actions-tests.yml contains a CI template for Python 3.11, 3.12 and
3.13. It is not active yet: the token used for the initial publication does not
have GitHub's workflow permission. A maintainer with workflow write access can
move it to .github/workflows/tests.yml to enable tests on pushes and pull
requests. The current local validation results are in VALIDATION.md.
References: MCP Python SDK, OTel Python exporters, Jaeger quickstart.
License
MIT. Copyright (c) 2026 Terraxinyun.
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP Gateway: wrap any MCP server with cold-start retries, uptime SLA, and per-execution MPP billing.
Remote MCP for GenAI span mapping, provider normalization, dashboard schemas, and receipts.
Enable secure connectivity between Sentry issues and debugging data, and LLM clients, using a Model Context Protocol (MCP) server.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes internal tools from agent harnesses (Claude Code, Codex, etc.) as a standard MCP server by intercepting LLM API calls.1MIT
- AlicenseAqualityDmaintenanceSelf-healing proxy for MCP servers that wraps tool calls with automatic retry, circuit breaker protection, and observability.526 npmMIT

AISIX AI Gatewayofficial
AlicenseAqualityAmaintenanceSelf-hosted MCP gateway that registers upstream MCP servers and fronts them behind one governed Streamable HTTP endpoint: per-tool access control by caller API key, guardrails over tool arguments and results, rate limits, and usage logs. The same Rust gateway also proxies LLM and A2A agent traffic.41165Apache 2.0- AlicenseNot gradedqualityBmaintenanceEnables per-profile tool filtering and enforcement for one or more upstream MCP servers, exposing only allowed tools and rejecting blocked calls, with Streamable HTTP serving and observability.434,515 npmMIT