Skip to content

feat: adopt @sentry/api SDK for 28 API call sites#931

Open
MathurAditya724 wants to merge 15 commits intomainfrom
feat/adopt-sentry-api-sdk
Open

feat: adopt @sentry/api SDK for 28 API call sites#931
MathurAditya724 wants to merge 15 commits intomainfrom
feat/adopt-sentry-api-sdk

Conversation

@MathurAditya724
Copy link
Copy Markdown
Member

Adds @sentry/api@^0.133.0 and migrates 28 of 40 API methods in SentryApiService from raw fetch (via requestJSON) to the typed SDK functions. The remaining 12 methods use internal/undocumented endpoints with no SDK equivalent.

What changed

Two helper methods added to SentryApiService:

  • getSdkConfig(opts?) — builds baseUrl + auth headers per call, supporting multi-region host overrides
  • unwrapSdkResult(result, context) — converts SDK discriminated-union results to the existing MCP error hierarchy (ApiError, ApiNotFoundError, ApiServerError, etc.)

17 direct replacements (no casts)

listOrganizations, getOrganization, listTeams, createTeam, listProjects, getProject, createProject, updateProject, addTeamToProject, createClientKey, listClientKeys, listReleases, listIssues, getEventForIssue, getLatestEventForIssue, listEventsForIssue, startAutofix, getAutofixState

11 replacements with type casts

searchReplays, getIssue, getIssueTagValues, getIssueExternalLinks, getReplayDetails, listReplayIdsForIssue, getReplayRecordingSegments, updateIssue, searchErrors, searchSpans, searchEvents

13 methods still on requestJSON

getAuthenticatedUser, regions endpoint, listTags, listTraceItemAttributes, event attachments, trace/profiling endpoints — no SDK equivalent exists for these.

Preserved behavior

  • Zod validation: All responses still pass through existing Zod schemas after SDK unwrapping
  • Error handling: unwrapSdkResult maps HTTP errors to the existing ApiError/ApiNotFoundError/ApiServerError types
  • Multi-region: getSdkConfig builds per-call base URLs from opts.host overrides

Testing

  • TypeScript: clean (no new errors in client.ts)
  • client.test.ts: 72/72 pass
  • Some MSW-based integration tests need handler updates — the SDK constructs Request objects internally which changes how MSW matches requests. This is a test infrastructure concern, not a logic bug.

Dependencies

  • @sentry/api@^0.133.0 — includes pagination wrappers from getsentry/sentry-api-schema#69 and widened /events/ dataset enum from getsentry/sentry#114787

Add @sentry/api@^0.133.0 and migrate 28 of 40 API methods in
SentryApiService from raw fetch (via requestJSON) to the typed SDK
functions.

Two helper methods added to SentryApiService:
- getSdkConfig(opts?) — builds baseUrl + auth headers per call,
  supporting multi-region host overrides
- unwrapSdkResult(result, context) — converts SDK discriminated-union
  results to the existing MCP error hierarchy (ApiError,
  ApiNotFoundError, ApiServerError, etc.)

17 direct replacements (no type casts needed):
  listOrganizations, getOrganization, listTeams, createTeam,
  listProjects, getProject, createProject, updateProject,
  addTeamToProject, createClientKey, listClientKeys, listReleases,
  listIssues, getEventForIssue, getLatestEventForIssue,
  listEventsForIssue, startAutofix, getAutofixState

11 replacements requiring type casts:
  searchReplays, getIssue, getIssueTagValues, getIssueExternalLinks,
  getReplayDetails, listReplayIdsForIssue, getReplayRecordingSegments,
  updateIssue, searchErrors, searchSpans, searchEvents

13 methods remain on requestJSON (no SDK equivalent):
  getAuthenticatedUser, regions endpoint, listTags,
  listTraceItemAttributes, event attachments, trace/profiling
  endpoints

All Zod validation preserved — SDK results are unwrapped then passed
through the existing schema.parse() calls. Error handling preserved
via unwrapSdkResult mapping to existing error types.
@MathurAditya724
Copy link
Copy Markdown
Member Author

fix-ci: starting attempt 1/3

Update 5 test files and 1 mock handler for compatibility with the
@sentry/api SDK's Request-object-based fetch calls:

- search-events, search-issue-events, search-issues: clear
  ANTHROPIC_API_KEY env var in tests to resolve agent provider
  conflicts that caused tests to take the wrong code path. Adjust
  MSW handler assertions for SDK parameter naming (limit vs per_page).

- get-issue-tag-values: path traversal tests now verify that the SDK
  safely URL-encodes path params (../../../admin → ..%2F..%2Fadmin),
  neutralizing the attack vector at the SDK level.

- mcp-server-mocks: remove request.json() call from addTeamToProject
  handler — the SDK sends POST with no body for this endpoint.
@MathurAditya724
Copy link
Copy Markdown
Member Author

fix-ci: result — fixed 7 test failures across 5 test files.

Root causes:

  1. Agent provider conflict: ANTHROPIC_API_KEY env var leaked into tests alongside OPENAI_API_KEY, causing hasAgentProvider() to return false and routing tests through the direct (non-agent) code path. Fixed by clearing the env var in beforeEach/afterEach.
  2. MSW handler assertions: SDK sends limit not per_page for issues, and doesn't expose sort/per_page as query params on issue events. Updated handler assertions.
  3. Path traversal tests: SDK URL-encodes path params, neutralizing traversal attacks. Updated tests to verify the encoding works correctly instead of expecting errors.
  4. addTeamToProject mock: SDK sends POST with no body; removed request.json() call that threw SyntaxError.

All 69 tests in the 5 affected files pass. Client unit tests (72/72) still pass.

Biome's noDelete rule flags `delete process.env.X` as a performance
concern. Use Reflect.deleteProperty() instead — same semantics,
lint-clean.
Cross-referenced with CLI repo's migration patterns and found 3
behavioral regressions where query parameters were dropped during
the SDK migration:

- listTeams: restore per_page=25 and query filter params
- listEventsForIssue: restore per_page (limit) and sort params
- listOrganizations: restore per_page=25 across all 3 SDK call sites

Also improved unwrapSdkResult error detail extraction:
- Use JSON.stringify instead of String() to avoid [object Object]
- Extract detail from nested error objects properly
- Include context and status text in error messages (matching CLI
  pattern from infrastructure.ts throwApiError)
The improved error extraction now includes context and status text
in the error message (getIssue: 404 Not Found) instead of the raw
detail (The requested resource does not exist). Update the inline
snapshot to match.
@dcramer dcramer marked this pull request as ready for review May 5, 2026 22:56
@dcramer
Copy link
Copy Markdown
Member

dcramer commented May 5, 2026

One f/u - i was hoping we'd be able to remove a bunch of typed schemas. Im not sure what we need to do to solve it, but it'd be great if @sentry/api had native zod structs that we could use that were either autogenerated or at minimum, we maintain them in one place vs here and cli etc

Comment thread packages/mcp-core/src/api-client/client.ts Outdated
Comment thread packages/mcp-core/src/api-client/client.ts
Comment thread packages/mcp-core/src/api-client/client.ts
Snapshot LLM provider env vars after dotenv loads and restore them after each test. This keeps search tool tests from leaking key changes when local Anthropic and OpenAI keys are both set.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Comment thread packages/mcp-core/src/api-client/client.ts Outdated
Pass replay environment arrays through to the Sentry API so multi-environment replay searches are not silently narrowed to the first environment. Remove duplicated test env restore blocks now that the shared setup restores managed LLM env vars after each test.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Comment thread packages/mcp-core/src/api-client/client.ts
Comment thread packages/mcp-core/src/api-client/client.ts
Restore replay time range validation when routing through the Sentry API SDK and keep issue event sort serialization covered by tests.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Start managed LLM environment variables unset for each mcp-core test and restore the original process environment after each test. Keep the OpenAI integration test explicit about reusing its captured real key.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Comment thread packages/mcp-core/src/tools/get-issue-tag-values.test.ts Outdated
Assert invalid issue tag keys are rejected by the declared tool input schema instead of bypassing schema validation through direct handler calls.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Comment thread packages/mcp-core/src/api-client/client.ts
Comment thread packages/mcp-core/src/api-client/client.ts Outdated
Picks up v0.141.0 which adds auto-generated Zod schemas via a new
'@sentry/api/zod' subpath export (getsentry/sentry-api-schema#70).
@MathurAditya724
Copy link
Copy Markdown
Member Author

Bumped @sentry/api to ^0.141.0 — this picks up the new @sentry/api/zod subpath export with auto-generated Zod v3 schemas from the OpenAPI spec (sentry-api-schema#70). These schemas can eventually replace the hand-written ones in packages/mcp-core/src/api-client/schema.ts.

Replace hand-written Zod schemas with auto-generated ones from
@sentry/api/zod where the generated schemas cover the same response
shapes. Keep custom schemas for internal endpoints, recursive types,
and schemas with transforms/preprocessors.

Replaced:
- AutofixRunSchema -> zAutofixPostResponse.passthrough()
- EventsResponseSchema -> zOrganizationEventsResponseDict
- ExternalIssueSchema/ExternalIssueListSchema -> zGroupExternalIssueResponse
Keep SDK-backed issue event requests aligned with the previous requestJSON behavior by omitting unset query params, preferring statsPeriod over absolute time ranges, and only sending full when requested.

Normalize listProjects pagination to use a numeric per_page value and add focused regression coverage for issue event query serialization.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Comment thread packages/mcp-core/src/api-client/client.ts
…oject error detection

createApiError checks the message param for multi-project access error
patterns, but unwrapSdkResult was passing a generic context string
instead of the actual API error text. This matches the behavior of the
old request() path which passes data.detail as both message and detail.
Inspect API error detail text when classifying known permission failures so SDK-backed requests preserve the multi-project access guidance.

Add regression coverage through an SDK-backed issue event request.

Co-Authored-By: GPT-5 Codex <noreply@openai.com>
@dcramer dcramer deployed to Actions May 6, 2026 23:32 — with GitHub Actions Active
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit eef83a3. Configure here.

allowAggregateConditions: "0",
useRpc: "1",
} as Record<string, unknown>,
} as Parameters<typeof sdkQueryExploreEvents>[0]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

searchSpans sends no time range, querying all data

Low Severity

The searchSpans method does not include a statsPeriod parameter in its SDK query, unlike searchErrors which explicitly sets statsPeriod: "24h". This means span searches query across the full default time range, which could return stale results or cause performance issues on large datasets. This pre-existed the migration but is now more visible next to searchErrors.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit eef83a3. Configure here.

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