MCP
The autotel monorepo ships two Model Context Protocol packages with different jobs. Pick the one you need:
| Package | Purpose |
| -------------------------------- | ---------------------------------------------------------------------- |
| autotel-mcp-instrumentation | Instrument your own MCP servers and clients with OpenTelemetry. |
| autotel-mcp | A standalone MCP server that lets AI agents query your traces, metrics, and logs. |
If you're building an MCP-based product → use autotel-mcp-instrumentation.
If you want Claude / Cursor / Windsurf to investigate observability data
→ install autotel-mcp.
autotel-mcp-instrumentation
Section titled “autotel-mcp-instrumentation”Automatic instrumentation for MCP servers and clients. W3C Trace Context
propagates through the _meta field, which works across stdio, HTTP, SSE, or
any custom transport. Bundle ~7KB total.
Installation
Section titled “Installation”npm install autotel-mcp-instrumentation @modelcontextprotocol/sdk autotelServer-side
Section titled “Server-side”import { Server } from '@modelcontextprotocol/sdk/server/index';import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio';import { instrumentMcpServer } from 'autotel-mcp-instrumentation/server';import { init } from 'autotel';
init({ service: 'mcp-weather-server', endpoint: 'http://localhost:4318' });
const server = new Server({ name: 'weather', version: '1.0.0' });
const instrumented = instrumentMcpServer(server, { captureArgs: true, captureResults: false, // off by default; PII concern});
instrumented.registerTool({ name: 'get_weather', description: 'Get current weather for a location', inputSchema: { type: 'object', properties: { location: { type: 'string' } }, required: ['location'], }, handler: async (args) => { // Auto-traced; parent context extracted from _meta const weather = await fetchWeather(args.location); return { content: [{ type: 'text', text: `Temp: ${weather.temp}°F` }] }; },});
await server.connect(new StdioServerTransport());Client-side
Section titled “Client-side”import { Client } from '@modelcontextprotocol/sdk/client/index';import { instrumentMcpClient } from 'autotel-mcp-instrumentation/client';import { init } from 'autotel';
init({ service: 'mcp-weather-client', endpoint: 'http://localhost:4318' });
const client = new Client({ name: 'weather-client', version: '1.0.0' });
const instrumented = instrumentMcpClient(client, { captureArgs: true, captureResults: false,});
// _meta is injected with traceparent/tracestate/baggage automaticallyconst result = await instrumented.callTool('get_weather', { location: 'NYC' });Configuration
Section titled “Configuration”interface McpInstrumentationConfig { captureArgs?: boolean; // default true captureResults?: boolean; // default false (PII risk) captureErrors?: boolean; // default true customAttributes?: (ctx: { type, name, args, result }) => Attributes;}Span attributes
Section titled “Span attributes”Server spans:
mcp.type—tool,resource,promptmcp.tool.name/mcp.resource.name/mcp.prompt.namemcp.tool.args(whencaptureArgs: true)mcp.tool.result(whencaptureResults: true)
Client spans:
mcp.client.operation—callTool,getResource,getPromptmcp.client.name,mcp.client.args,mcp.client.result
Distributed tracing via _meta
Section titled “Distributed tracing via _meta”Because trace context lives in the JSON payload's _meta field, the same
propagation works across stdio, HTTP, SSE, WebSocket, or any custom transport
without any header plumbing:
import { injectOtelContextToMeta, extractOtelContextFromMeta, activateTraceContext,} from 'autotel-mcp-instrumentation/context';import { context } from '@opentelemetry/api';
// Client side: injectconst request = { method: 'tools/call', params: { name: 'my-tool', arguments: {} }, _meta: injectOtelContextToMeta({}),};
// Server side: extract and activateconst ctx = activateTraceContext(request._meta);return context.with(ctx, () => runHandler(request));Custom attributes & PII redaction
Section titled “Custom attributes & PII redaction”customAttributes runs per span. Use it to redact PII or attach
business-specific tags:
const instrumented = instrumentMcpServer(server, { captureArgs: false, // disable raw arg capture customAttributes: ({ type, name, args, result }) => ({ 'tool.location': args?.location, // safe to log 'tenant.id': args?.tenantId, ...(type === 'tool' && name === 'search' ? { 'search.results.count': result?.items?.length ?? 0 } : {}), }),});Entry points
Section titled “Entry points”| Import | Contents | Size |
| -------------------------------------------- | --------------------------------- | ---- |
| autotel-mcp-instrumentation | Everything | ~7KB |
| autotel-mcp-instrumentation/server | instrumentMcpServer | ~5KB |
| autotel-mcp-instrumentation/client | instrumentMcpClient | ~4KB |
| autotel-mcp-instrumentation/context | inject*/extract*/activate* | ~2KB |
Examples
Section titled “Examples”example-mcp-server— MCP server withinstrumentMcpServer().example-mcp-client— MCP client withinstrumentMcpClient()and distributed tracing.
autotel-mcp
Section titled “autotel-mcp”A standalone MCP server that gives AI agents (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Goose) the ability to investigate your OpenTelemetry traces, metrics, and logs. It ships with a built-in OTLP collector on port 4318, so any instrumented app can send data directly. You don't need Jaeger, Tempo, or Grafana.
- Backend-agnostic. Built-in OTLP collector accepts data from any OTel-instrumented app.
- All three signals. Traces, metrics, and logs with cross-signal correlation.
- Agent-optimised. 33 tools designed for progressive investigation: discover → diagnose → correlate → root-cause.
- Zero infrastructure. In-memory by default; persistent with
--persist.
Requirements
Section titled “Requirements”- Node.js 20+
- An MCP-compatible client
Standard config
Section titled “Standard config”{ "mcpServers": { "autotel": { "command": "npx", "args": ["autotel-mcp"] } }}Claude Code
Section titled “Claude Code”claude mcp add autotel npx autotel-mcpOnce installed, ask the agent things like "What slowed down checkout in the
last hour?" or "Show traces with errors for service.name=api". The agent
will discover services, query traces, correlate logs, and return a written
investigation.
Related
Section titled “Related”- AI-Assisted Observability — patterns for letting agents investigate production traces.
- MCP example app — autotel instruments a Node app, Claude queries the traces via MCP.