feat(tools): Add cursor pagination, spans resource type, and dynamic tool names#820
feat(tools): Add cursor pagination, spans resource type, and dynamic tool names#820
Conversation
Both tools shared a 100-result cap with no way to page through large
result sets. This adds cursor-based pagination using Sentry's Link
headers so users can iterate through all matching events.
Key changes:
- Add parseLinkCursor() to extract next cursor from Link headers
- Add requestJSONWithPagination() in the API client
- searchEvents() now accepts cursor param and returns { body, nextCursor }
- Raise limit max from 100 to 1000 on both tools
- Add pagination section to all three formatters (errors, logs, spans)
- Mock server returns Link headers to simulate pagination
Co-Authored-By: Claude <noreply@anthropic.com>
Replace the generic "use search_events" hint with a concrete list_events call showing the trace query, dataset, and pagination parameters so AI assistants can page through all spans in a trace. Co-Authored-By: Claude <noreply@anthropic.com>
search_events and list_events are mutually exclusive — only one is registered depending on whether AI keys are configured. Since search_events re-runs the LLM agent on every call, adding cursor pagination to it would be wasteful and non-deterministic. Cursor pagination only applies to list_events. Co-Authored-By: Claude <noreply@anthropic.com>
…nces - Add `spans` resource type to `get_sentry_resource` that renders the complete span tree (up to 1000 spans) for a trace, unlike `get_trace_details` which shows only ~20 selected spans. - Fix hardcoded tool name references (`search_events`, `search_issues`, `list_events`, `list_issues`) in handler output text. These tool pairs are mutually exclusive based on agent provider config, so referencing the wrong one causes the LLM to call a non-existent tool. Added `getEventsToolName()` and `getIssuesToolName()` helpers that use `hasAgentProvider()` to resolve the correct name at runtime. - Extract shared trace rendering utilities (`SelectedSpan`, `renderSpanTree`, `selectInterestingSpans`, `buildFullSpanTree`, etc.) into `trace-rendering.ts` to enable reuse between `get_trace_details` and the new `spans` resource type. - When `get_sentry_resource` handles a `trace` type, it now suggests `get_sentry_resource(resourceType='spans', ...)` for the complete span tree instead of referencing `list_events`/`search_events`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| apiService: traceApiService, | ||
| suggestSpansResource: true, | ||
| }); | ||
| } |
There was a problem hiding this comment.
Missing trace ID validation in get_sentry_resource trace case
Medium Severity
The "trace" case in get_sentry_resource handler no longer validates the trace ID format. The old code delegated to getTraceDetails.handler, which validates the ID is a 32-character hex string. The new inlined implementation omits this check, while the "spans" case (added in the same PR) correctly includes it. Invalid trace IDs now produce cryptic API errors instead of a friendly UserInputError.
Additional Locations (1)
| sections.push("```"); | ||
| sections.push( | ||
| "Use the returned `cursor` value to fetch subsequent pages until all spans are retrieved.", | ||
| ); |
There was a problem hiding this comment.
Trace output suggests wrong parameters for search_events tool
Medium Severity
When suggestSpansResource is false, formatTraceOutput suggests calling getEventsToolName() with dataset, query, sort, and cursor parameters. These parameters only exist on list_events. When hasAgentProvider() is true, the resolved name is search_events, which accepts naturalLanguageQuery instead — it has none of dataset, query, sort, or cursor. This gives LLMs an incorrect function call example in non-experimental mode with an agent provider.
…ilities Covers formatSpanDisplayName, renderSpanTree, getAllSpansFlattened, selectInterestingSpans, and buildFullSpanTree with 37 tests including edge cases for filtering, hierarchy, mixed span/issue arrays, and default field handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| if (parsed.transaction) { | ||
| throw new UserInputError( | ||
| `Detected a performance summary URL for transaction "${parsed.transaction}". Use \`search_events\` to find traces and performance data for this transaction.`, | ||
| `Detected a performance summary URL for transaction "${parsed.transaction}". Use \`${getEventsToolName()}\` to find traces and performance data for this transaction.`, |
There was a problem hiding this comment.
Add top-level skills that translate natural-language issue and event searches into direct list_issues and list_events calls. This preserves the useful query-planning behavior from the embedded search agents while we prepare a larger overhaul that can remove the AI search tools themselves. Co-Authored-By: Codex <noreply@openai.com>


Add cursor-based pagination to event tools, a new
spansresource type, and fix hardcoded tool name references that caused LLMs to call non-existent tools.Cursor pagination for events — Both
search_eventsandlist_eventshad a 100-result cap with no way to page through large result sets. This adds cursor-based pagination using Sentry'sLinkheaders (parseLinkCursor(),requestJSONWithPagination()), raises the limit max to 1000, and includes pagination metadata in formatter output. Cursor pagination was then scoped tolist_eventsonly, sincesearch_eventsre-runs the LLM agent on every call making pagination wasteful and non-deterministic.spansresource type onget_sentry_resource—get_sentry_resource(resourceType='spans', resourceId=traceId)renders the complete span tree (up to 1000 spans from the API), unlikeget_trace_detailswhich shows only ~20 selected spans. Shared trace rendering utilities (SelectedSpan,renderSpanTree,selectInterestingSpans,buildFullSpanTree) were extracted intotrace-rendering.tsfor reuse.Dynamic tool name references — Tool handler outputs hardcoded references to
search_events/list_eventsandsearch_issues/list_issues, but these are mutually exclusive pairs (only one is registered based on agent provider config). AddedgetEventsToolName()andgetIssuesToolName()helpers that resolve the correct name at runtime viahasAgentProvider(). Fixed references inget-trace-details.ts,get-sentry-resource.ts,get-profile.ts, andsearch-issues/formatters.ts.