Skip to content

[jaegermcp] Fix MCP server integration with Claude Code#8191

Merged
yurishkuro merged 17 commits intojaegertracing:mainfrom
yurishkuro:mcp-sse2
Mar 18, 2026
Merged

[jaegermcp] Fix MCP server integration with Claude Code#8191
yurishkuro merged 17 commits intojaegertracing:mainfrom
yurishkuro:mcp-sse2

Conversation

@yurishkuro
Copy link
Copy Markdown
Member

@yurishkuro yurishkuro commented Mar 18, 2026

Changes

  • get_trace_topology output format. Changed from a nested root_span/orphans tree to a flat, depth-first ordered list of spans. Each span now has a path field containing slash-delimited span IDs from the root down to that span (e.g. rootID/parentID/spanID), encoding the tree structure without recursion. The depth parameter and truncated_children field are preserved.
  • MCP request logging. Every MCP method call is now logged with session ID, method name, duration, and error if any.
  • Removed /health HTTP endpoint.
  • Standard HTTP server configuration. The extension now uses the collector's confighttp infrastructure, enabling TLS, CORS, and other standard HTTP options to be configured via the extension's http: config block.

Test in Claude

❯ which services are in my Jaeger instance

⏺ Your Jaeger instance has the following services:

  1. customer
  2. driver
  3. frontend
  4. jaeger
  5. mysql
  6. redis-manual
  7. route

  This looks like the HotROD demo application (a ride-sharing example), plus the jaeger service itself for internal tracing.

❯ how many traces  for frontend service

⏺ In the last hour, there are 6 traces for the frontend service:

  ┌───────────┬──────────┬────────┬──────────┬───────┐
  │ Span Name │ Duration │ Errors │ Services │ Spans │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /dispatch │ 1,114 ms │ Yes    │ 6        │ 40    │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /config   │ <1 ms    │ No     │ 1        │ 1     │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /config   │ <1 ms    │ No     │ 1        │ 1     │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /config   │ <1 ms    │ No     │ 1        │ 1     │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /dispatch │ 901 ms   │ Yes    │ 6        │ 39    │
  ├───────────┼──────────┼────────┼──────────┼───────┤
  │ /dispatch │ 760 ms   │ Yes    │ 6        │ 40    │
  └───────────┴──────────┴────────┴──────────┴───────┘

  Notable: all 3 /dispatch traces have errors, while the /config traces are clean.

❯ how many errors in the longest trace?

⏺ The longest trace has 3 errors, all of the same type:

  - Service: redis-manual
  - Span: GetDriver
  - Error: redis timeout
  - Affected drivers: T717023C, T732667C, T781220C

  All three errors occurred within ~170ms of each other, suggesting a Redis connectivity issue that caused timeouts when looking up
  driver information.

❯ find the longest trace from frontend service, list spans that have errors and show their parent spans as "service/span_name"

⏺ Here are the results for the longest frontend trace (e07fc217a00814b4ef552a10466da417, 908 ms, 39 spans, 6 services):

  ---
  Error Spans (2 errors)

  Both errors are redis timeout exceptions in the redis-manual service:

  ┌─────┬──────────────┬───────────────────────────┬─────────────────────────────────────┬─────────────────────────────────────────┐
  │  #  │   Service    │           Span            │                Error                │               Parent Span               │
  ├─────┼──────────────┼───────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────────┤
  │ 1   │ redis-manual │ GetDriver (span 68a98f61) │ redis timeout for driverID T772373C │ driver/driver.DriverService/FindNearest │
  ├─────┼──────────────┼───────────────────────────┼─────────────────────────────────────┼─────────────────────────────────────────┤
  │ 2   │ redis-manual │ GetDriver (span 0d18a2ce) │ redis timeout for driverID T710636C │ driver/driver.DriverService/FindNearest │
  └─────┴──────────────┴───────────────────────────┴─────────────────────────────────────┴─────────────────────────────────────────┘

  ---
  Both error spans share the same parent: driver/driver.DriverService/FindNearest (span 42117b7675f3f8f8). The driver service was
  looking up nearby drivers in Redis, and 2 out of the ~13 GetDriver lookups timed out.

Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
@yurishkuro yurishkuro requested a review from a team as a code owner March 18, 2026 00:50
Copilot AI review requested due to automatic review settings March 18, 2026 00:50
@yurishkuro yurishkuro added the changelog:experimental Change to an experimental part of the code label Mar 18, 2026

This comment was marked as outdated.

Signed-off-by: Yuri Shkuro <github@ysh.us>
@yurishkuro yurishkuro changed the title Mcp sse2 [jaegermcp] Improve HTTP server setup and add logging middleware Mar 18, 2026
Signed-off-by: Yuri Shkuro <github@ysh.us>
Copilot AI review requested due to automatic review settings March 18, 2026 01:01
Signed-off-by: Yuri Shkuro <github@ysh.us>

This comment was marked as outdated.

Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Copilot AI review requested due to automatic review settings March 18, 2026 01:48

This comment was marked as outdated.

Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Copilot AI review requested due to automatic review settings March 18, 2026 02:17
Signed-off-by: Yuri Shkuro <github@ysh.us>

This comment was marked as outdated.

Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Copilot AI review requested due to automatic review settings March 18, 2026 02:25

This comment was marked as outdated.

@yurishkuro yurishkuro changed the title [jaegermcp] Improve HTTP server setup and add logging middleware [jaegermcp] Fix MCP server integration with Claude Code Mar 18, 2026
Signed-off-by: Yuri Shkuro <github@ysh.us>
Signed-off-by: Yuri Shkuro <github@ysh.us>
Copilot AI review requested due to automatic review settings March 18, 2026 03:04
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Jaeger MCP extension to improve compatibility with Claude Code and align HTTP serving with OpenTelemetry Collector’s standard confighttp infrastructure.

Changes:

  • Reworked get_trace_topology output from a recursive tree into a flat, depth-first list with a path field encoding ancestry.
  • Added MCP request/response logging middleware (session ID, method, duration, error).
  • Removed the dedicated /health HTTP endpoint and shifted to standard confighttp server setup.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cmd/jaeger/internal/extension/jaegermcp/server.go Switches HTTP lifecycle to confighttp and wires in MCP logging middleware; removes /health endpoint.
cmd/jaeger/internal/extension/jaegermcp/server_test.go Updates test server helpers/readiness checks and removes /health/CORS tests accordingly.
cmd/jaeger/internal/extension/jaegermcp/logging_middleware.go Implements middleware that logs all MCP method calls and results with timing.
cmd/jaeger/internal/extension/jaegermcp/logging_middleware_test.go Adds coverage asserting the middleware emits request/response log entries.
cmd/jaeger/internal/extension/jaegermcp/internal/types/get_trace_topology.go Changes topology response schema to a flat list of TopologySpan with path.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_topology.go Implements flat DFS topology construction with deterministic ordering and depth truncation.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_topology_test.go Updates tests to validate the new flat path encoding, ordering, and truncation semantics.
cmd/jaeger/internal/extension/jaegermcp/README.md Removes /health from documented endpoints and adds Claude Code setup example.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.


s.telset.Logger.Info("Jaeger MCP server started successfully",
zap.String("endpoint", s.config.HTTP.NetAddr.Endpoint),
zap.String("mcp_endpoint", "http://"+s.config.HTTP.NetAddr.Endpoint+"/mcp"))
Comment on lines +81 to +90
func waitForServer(t *testing.T, addr string) {
t.Helper()
require.Eventually(t, func() bool {
resp, err := http.Get(fmt.Sprintf("http://%s/mcp", addr))
if err != nil {
return false
}
require.NoError(t, resp.Body.Close())
return true
}, 1*time.Second, 10*time.Millisecond, "Server should be ready")
@yurishkuro yurishkuro merged commit af51e32 into jaegertracing:main Mar 18, 2026
75 checks passed
@yurishkuro yurishkuro deleted the mcp-sse2 branch March 18, 2026 03:20
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 88.88889% with 13 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.62%. Comparing base (6275e86) to head (1b2b075).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...internal/extension/jaegermcp/logging_middleware.go 73.07% 5 Missing and 2 partials ⚠️
cmd/jaeger/internal/extension/jaegermcp/server.go 88.23% 3 Missing and 1 partial ⚠️
.../jaegermcp/internal/handlers/get_trace_topology.go 96.49% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8191      +/-   ##
==========================================
- Coverage   95.67%   95.62%   -0.05%     
==========================================
  Files         317      318       +1     
  Lines       16750    16771      +21     
==========================================
+ Hits        16026    16038      +12     
- Misses        571      578       +7     
- Partials      153      155       +2     
Flag Coverage Δ
badger_v1 9.05% <ø> (ø)
badger_v2 1.04% <ø> (ø)
cassandra-4.x-v1-manual 13.25% <ø> (ø)
cassandra-4.x-v2-auto 1.03% <ø> (ø)
cassandra-4.x-v2-manual 1.03% <ø> (ø)
cassandra-5.x-v1-manual 13.25% <ø> (ø)
cassandra-5.x-v2-auto 1.03% <ø> (ø)
cassandra-5.x-v2-manual 1.03% <ø> (ø)
clickhouse 1.16% <ø> (ø)
elasticsearch-6.x-v1 16.83% <ø> (ø)
elasticsearch-7.x-v1 16.86% <ø> (ø)
elasticsearch-8.x-v1 17.01% <ø> (ø)
elasticsearch-8.x-v2 1.04% <ø> (ø)
elasticsearch-9.x-v2 1.04% <ø> (ø)
grpc_v1 7.79% <ø> (ø)
grpc_v2 1.04% <ø> (ø)
kafka-3.x-v2 1.11% <ø> (+0.06%) ⬆️
memory_v2 1.04% <ø> (ø)
opensearch-1.x-v1 16.91% <ø> (ø)
opensearch-2.x-v1 16.91% <ø> (ø)
opensearch-2.x-v2 1.04% <ø> (ø)
opensearch-3.x-v2 1.04% <ø> (ø)
query 1.04% <ø> (ø)
tailsampling-processor 0.52% <ø> (ø)
unittests 94.31% <88.88%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog:experimental Change to an experimental part of the code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants