Skip to content

feat: add OpenTelemetry tracing#26

Merged
mattpodwysocki merged 2 commits intomainfrom
feat/otel-tracing
Apr 15, 2026
Merged

feat: add OpenTelemetry tracing#26
mattpodwysocki merged 2 commits intomainfrom
feat/otel-tracing

Conversation

@mattpodwysocki
Copy link
Copy Markdown
Contributor

Summary

Adds OpenTelemetry tracing to mcp-docs-server, consistent with the implementation in mcp-server and mcp-devkit-server.

  • src/utils/tracing.ts (new) — initializeTracing(), shutdownTracing(), getTracer(), and withToolSpan(). Suppresses OTEL diagnostic output at module load time to protect MCP stdio.
  • BaseTool.run() — wraps every tool execution in a tool.<name> span via withToolSpan(); sets tool.error=true attribute when a tool returns isError: true.
  • src/index.ts — calls initializeTracing() on startup, shutdownTracing() on graceful exit.
  • src/utils/index.ts — exports tracing utilities from @mapbox/mcp-docs-server/utils.

Tracing is a no-op by default. It activates only when OTEL_EXPORTER_OTLP_ENDPOINT or OTEL_EXPORTER_CONSOLE_ENABLED=true is set. Uses OTEL 2.x (resourceFromAttributes instead of the removed Resource class).

Test plan

  • npm run build passes
  • npm test — 58 tests pass (tracing is no-op in test env via VITEST guard)
  • CI green

🤖 Generated with Claude Code

@mattpodwysocki mattpodwysocki requested a review from a team as a code owner April 14, 2026 03:02
zmofei
zmofei previously approved these changes Apr 15, 2026
Copy link
Copy Markdown
Member

@zmofei zmofei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Clean implementation, consistent with sibling repos. One minor issue:

src/tools/BaseTool.ts — missing tool.error attribute in catch block

The try path sets span.setAttribute('tool.error', true) when result.isError, but the catch path (which also returns isError: true) doesn't set it. Since the inner catch returns rather than re-throws, withToolSpan sees a successful completion and marks the span SpanStatusCode.OK.

Validation failures and unexpected exceptions will produce spans that look successful — no tool.error attribute, status OK.

Suggested fix:

} catch (error) {
  span.setAttribute('tool.error', true);
  return {
    isError: true,
    content: [{ type: 'text', text: (error as Error).message }]
  };
}

Not blocking — can be a follow-up.

@mattpodwysocki
Copy link
Copy Markdown
Contributor Author

Fixed in 708d3b4 — added span.setAttribute('tool.error', true) to the catch block. Good catch, that was a real gap.

zmofei
zmofei previously approved these changes Apr 15, 2026
mattpodwysocki and others added 2 commits April 15, 2026 13:49
- Add src/utils/tracing.ts with initializeTracing(), shutdownTracing(),
  getTracer(), and withToolSpan() — consistent with mcp-server and mcp-devkit-server
- BaseTool.run() wraps every execution in a tool.<name> span via withToolSpan();
  sets tool.error=true attribute on tool-level errors
- index.ts initializes tracing on startup and shuts it down on graceful exit
- OTEL is a no-op unless OTEL_EXPORTER_OTLP_ENDPOINT or
  OTEL_EXPORTER_CONSOLE_ENABLED=true is set; diagnostics suppressed on stdio
- Export tracing utilities from @mapbox/mcp-docs-server/utils barrel
- Add OTEL 2.x dependencies: api@^1.9.1, resources@^2.6.1,
  sdk-trace-base@^2.6.1, sdk-node@^0.214.0, instrumentation@^0.214.0,
  exporter-trace-otlp-http@^0.214.0, auto-instrumentations-node@^0.72.0,
  semantic-conventions@^1.40.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The catch path was returning isError: true without marking the span,
causing validation failures and unexpected exceptions to appear as
successful spans in tracing backends.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@mattpodwysocki mattpodwysocki merged commit 50ef224 into main Apr 15, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants