Skip to content

fix(jaegermcp): Enforce response limits#8242

Merged
yurishkuro merged 6 commits intojaegertracing:mainfrom
abhay1999:fix/mcp-enforce-limits
Mar 26, 2026
Merged

fix(jaegermcp): Enforce response limits#8242
yurishkuro merged 6 commits intojaegertracing:mainfrom
abhay1999:fix/mcp-enforce-limits

Conversation

@abhay1999
Copy link
Copy Markdown
Contributor

@abhay1999 abhay1999 commented Mar 24, 2026

What this PR does

MaxSpanDetailsPerRequest and MaxSearchResults were defined in the config but not consistently enforced across all MCP handlers. This PR wires the limits all the way through.

Changes

get_trace_errors.go

  • Continues iterating all spans to count total errors, but caps the Spans slice at maxSpanDetailsPerRequest
  • ErrorCount now reflects the true total error count, not the truncated slice length

get_trace_topology.go

  • Breaks collection loop once maxSpanDetailsPerRequest is reached

search_traces.go

  • Breaks aggregation loop once maxResults is reached
  • Fixed searchDepth clamping: guards with maxResults > 0 so unlimited (0) is not incorrectly clamped to 0

server.go

  • Wires MaxSpanDetailsPerRequest into NewGetTraceErrorsHandler and NewGetTraceTopologyHandler constructors

Tests added

  • TestGetTraceErrorsHandler_Handle_LimitEnforced — 5 error spans, limit 3, asserts ErrorCount==5 and len(Spans)<=3
  • TestGetTraceTopologyHandler_Handle_LimitEnforced — 6-span trace, limit 3, asserts len(Spans)<=3
  • TestSearchTracesHandler_Handle_LimitEnforced — 5 traces, limit 3, asserts len(Traces)<=3

Fixes #8118

MaxSpanDetailsPerRequest and MaxSearchResults were defined in the config
but not consistently enforced across all MCP handlers:

- get_trace_errors: collected all error spans without any cap; now
  continues iterating to count total errors but caps Spans slice at
  maxSpanDetailsPerRequest. ErrorCount reflects the true total.
- get_trace_topology: collected all spans without any cap; now breaks
  once maxSpanDetailsPerRequest is reached
- search_traces: aggregation loop had no hard cap; now breaks once
  maxResults is reached. Fixed searchDepth clamping to guard with
  maxResults > 0 so unlimited (0) is not incorrectly clamped to 0.
- server.go: wire MaxSpanDetailsPerRequest into NewGetTraceErrorsHandler
  and NewGetTraceTopologyHandler constructors

Tests added:
- TestGetTraceErrorsHandler_Handle_LimitEnforced: 5 error spans, limit 3,
  asserts ErrorCount==5 and len(Spans)<=3
- TestGetTraceTopologyHandler_Handle_LimitEnforced: 6-span trace, limit 3,
  asserts len(Spans)<=3
- TestSearchTracesHandler_Handle_LimitEnforced: 5 traces, limit 3,
  asserts len(Traces)<=3

Fixes jaegertracing#8118

Signed-off-by: abhay1999 <abhaychaurasiya19@gmail.com>
@abhay1999 abhay1999 requested a review from a team as a code owner March 24, 2026 16:17
Copilot AI review requested due to automatic review settings March 24, 2026 16:17
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 enforces configured response-size limits in the Jaeger MCP extension handlers so MCP tool outputs stay bounded and consistent with MaxSpanDetailsPerRequest / MaxSearchResults.

Changes:

  • Wire MaxSpanDetailsPerRequest into get_trace_errors and get_trace_topology handlers and enforce span caps.
  • Enforce MaxSearchResults in search_traces result aggregation and fix searchDepth clamping for the “unlimited” (0) case.
  • Add unit tests covering the new limit enforcement behavior.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
cmd/jaeger/internal/extension/jaegermcp/server.go Pass configured span limits into newly updated handler constructors.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_errors.go Track total error count while capping collected span details.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_errors_test.go Add test for get_trace_errors truncation + total error count.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_topology.go Add span-detail limit to handler and stop collecting spans after cap.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/get_trace_topology_test.go Add test ensuring topology output is capped by the limit.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/search_traces.go Stop adding summaries after maxResults; guard searchDepth clamp when maxResults==0.
cmd/jaeger/internal/extension/jaegermcp/internal/handlers/search_traces_test.go Add test ensuring search results are capped.

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

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 24, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.65%. Comparing base (4cf3087) to head (b7d1c8a).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8242   +/-   ##
=======================================
  Coverage   95.65%   95.65%           
=======================================
  Files         319      319           
  Lines       16795    16804    +9     
=======================================
+ Hits        16065    16074    +9     
  Misses        577      577           
  Partials      153      153           
Flag Coverage Δ
badger_direct 9.06% <ø> (ø)
badger_e2e 1.04% <ø> (ø)
cassandra-4.x-direct-manual 13.25% <ø> (ø)
cassandra-4.x-e2e-auto 1.03% <ø> (ø)
cassandra-4.x-e2e-manual 1.03% <ø> (ø)
cassandra-5.x-direct-manual 13.25% <ø> (ø)
cassandra-5.x-e2e-auto 1.03% <ø> (ø)
cassandra-5.x-e2e-manual 1.03% <ø> (ø)
clickhouse 1.16% <ø> (ø)
elasticsearch-6.x-direct 16.84% <ø> (ø)
elasticsearch-7.x-direct 16.87% <ø> (ø)
elasticsearch-8.x-direct 17.02% <ø> (ø)
elasticsearch-8.x-e2e 1.04% <ø> (ø)
elasticsearch-9.x-e2e 1.04% <ø> (ø)
grpc_direct 7.79% <ø> (ø)
grpc_e2e 1.04% <ø> (ø)
kafka-3.x-v2 1.04% <ø> (ø)
memory_v2 1.04% <ø> (ø)
opensearch-1.x-direct 16.91% <ø> (ø)
opensearch-2.x-direct 16.91% <ø> (ø)
opensearch-2.x-e2e 1.04% <ø> (ø)
opensearch-3.x-e2e 1.04% <ø> (ø)
query 1.04% <ø> (ø)
tailsampling-processor 0.52% <ø> (ø)
unittests 94.34% <100.00%> (+<0.01%) ⬆️

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.

abhay1999 and others added 2 commits March 25, 2026 08:15
- Replace AggregateTraces with AggregateTracesWithLimit in
  get_trace_errors and get_trace_topology handlers so that
  memory is bounded at aggregation time, not just at response time.
- Tighten limit-enforcement tests to use assert.Equal instead of
  assert.LessOrEqual, ensuring the handler returns exactly
  maxSpanDetailsPerRequest spans when the trace exceeds the limit.

Signed-off-by: abhay1999 <abhaychaurasiya19@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace assert.Equal(t, N, len(x)) with assert.Len(t, x, N) in all
three limit-enforcement tests as required by the testifylint linter.

Signed-off-by: abhay1999 <abhaychaurasiya19@gmail.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 25, 2026 02:54
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

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


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

- Revert get_trace_errors to AggregateTraces (unbounded) so ErrorCount
  reflects the true total of error spans in the full trace; Spans is
  already capped inside the iteration loop via maxSpanDetailsPerRequest.
- Update test to assert ErrorCount==5 (full trace) and len(Spans)==3
  (capped), matching the intended split semantics.
- Remove the redundant `h.maxResults > 0` guard in search_traces since
  config validation already enforces MaxSearchResults in [1, 1000].

Signed-off-by: abhay1999 <abhaychaurasiya19@gmail.com>
@yurishkuro yurishkuro added the changelog:experimental Change to an experimental part of the code label Mar 26, 2026
@yurishkuro yurishkuro changed the title fix(jaegermcp): enforce response limits and add test coverage fix(jaegermcp): Enforce response limits and add test coverage Mar 26, 2026
@yurishkuro yurishkuro changed the title fix(jaegermcp): Enforce response limits and add test coverage fix(jaegermcp): Enforce response limits Mar 26, 2026
@yurishkuro yurishkuro merged commit 8a4c314 into jaegertracing:main Mar 26, 2026
72 of 73 checks passed
@abhay1999 abhay1999 deleted the fix/mcp-enforce-limits branch March 26, 2026 14:46
lopster568 added a commit to lopster568/jaeger that referenced this pull request Mar 26, 2026
When MaxSearchResults is 0 (unlimited), the searchDepth clamp
`if searchDepth > h.maxResults` evaluates as `10 > 0 == true` and
sets searchDepth to 0. This causes the storage query to return no
results even though the config intends no limit.

Guard the clamp with `h.maxResults > 0` so that an unlimited config
preserves the requested or default search depth.

Found while reviewing jaegertracing#8242.

Signed-off-by: Roshan <rosh.s568@gmail.com>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Roshan <rosh.s568@gmail.com>
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.

jaeger_mcp: Enforce MaxSpanDetailsPerRequest and MaxSearchResults at handler layer

3 participants