feat: adopt @sentry/api SDK for 38 of 40 API call sites#931
feat: adopt @sentry/api SDK for 38 of 40 API call sites#931MathurAditya724 wants to merge 35 commits into
Conversation
|
fix-ci: starting attempt 1/3 |
|
fix-ci: result — fixed 7 test failures across 5 test files. Root causes:
All 69 tests in the 5 affected files pass. Client unit tests (72/72) still pass. |
|
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 |
|
Bumped |
eef83a3 to
67afdaa
Compare
Bump @sentry/api to ^0.172.0 which exports the SdkResult type from getsentry/sentry-api-schema#74. The SDK functions return RequestResult whose conditional generic encoding (TData[keyof TData]) is not structurally assignable to SdkResult, so unwrapSdkResult keeps `any` for the parameter type. Updated the JSDoc to reference SdkResult as the runtime contract and explain why the type mismatch exists. Co-Authored-By: Claude (claude-opus-4-6)
Address Warden review findings:
- unwrapSdkResult now uses the API's detail text as the error message
when available (e.g. 'The requested resource does not exist') instead
of the internal context label ('getIssue: 404 Not Found'). Falls back
to the context-prefixed message when no detail is present.
- Remove dead code in listOrganizations: queryParams, queryString, and
path variables were left over from the pre-SDK migration and are no
longer referenced.
Co-Authored-By: Claude (claude-opus-4-6)
…ry casts sentry#116782 fixed issue_id from int to str and added per_page to the List Organizations spec. With 0.174.0 these casts are no longer needed: - 8x `issue_id: issueId as unknown as number` → plain issueId - 3x `as Parameters<typeof sdkListYourOrganizations>[0]` (per_page now declared) - 1x `as Parameters<typeof sdkListAnIssueSEvents>[0]` (issue_id was the only reason) returnIds and allowAggregateConditions are now typed as boolean in the spec, so update the values passed (true/false instead of strings) and strengthen the remaining casts for project/-1 and useRpc to `as unknown as`.
Bump @sentry/api to ^0.175.0 which adds the organization tags endpoint to the OpenAPI spec. Migrate listTags from requestJSON to sdkListAnOrganizationSTags, reducing the remaining requestJSON methods from 3 to 2 (getAuthenticatedUser and regions endpoint). Co-Authored-By: Claude (claude-opus-4-6)
The events explore API expects the string '0' to disable aggregate conditions. A boolean false could be serialized differently by the SDK's request builder. Co-Authored-By: Claude (claude-opus-4-6)
Neither param is read by the backend: - project: "-1" in listReplayIdsForIssue — not in ReplayCountQueryParamsValidator - useRpc: "1" in searchSpans — not referenced anywhere in organization_events.py Removing them also drops the two remaining as-unknown-as casts on those call sites.
…s to requestJSON searchReplays was building a Record<string,unknown> query object and casting the entire SDK call. All replay params are already in the spec so the cast was only needed because of the dynamic object construction. Inline the query directly — the only remaining targeted cast is for field[], which the spec types as a strict enum but the API accepts arbitrary strings at runtime. Also reverts listTags to requestJSON. sdkListAnOrganizationSTags was removed from the public spec in @sentry/api ≥0.175.0, so the SDK function no longer exists. The endpoint has no SDK equivalent; requestJSON is the right fallback.
project is processed by OrganizationEventsEndpointBase.get_snuba_params(), not by the endpoint's own validator. -1 is the all-accessible-projects sentinel — without it the API narrows to membership-only projects, which misses replays for issues in projects the caller can access but isn't a member of.
Handle SDK response shapes and replay query validation after rebasing the API SDK branch onto main. Keep API detail messages in tests and preserve multi-environment replay queries. Co-Authored-By: GPT-5 Codex <codex@openai.com>
b52d182 to
950be09
Compare
…ionId names The operationId migration in getsentry/sentry shipped clean REST-token operationIds (listProjectIssues, getOrganizationIssue, getOrganizationReplayCount, startOrganizationIssueAutofix, ...), now published in @sentry/api 0.228.0. Rename the imported SDK functions from the old normalized names (listAProject_sIssues, retrieveAnIssue, retrieveACountOfReplaysForAGivenIssueOrTransaction, ...) to the tokens. The sdk* aliases are unchanged, so all call sites stay as-is. Verified: tsc clean (0 source errors); api-client tests 93/93 pass.
Replace the hand-rolled Link-header regex in getNextCursor with the SDK's parseSentryLinkHeader helper (exported from @sentry/api). It honors the same results="true" qualifier; getNextCursor stays a thin adapter normalizing the helper's undefined nextCursor to null, so all 4 call sites and the string|null contract are unchanged. Verified: tsc clean; client tests 93/93; full mcp-core suite unchanged (1159 pass, 2 pre-existing autofix failures).
unwrapSdkResult took `result: any` and returned `result.data as T` with no
constraint, so the SDK's generated response type was erased to unknown at the
seam and re-derived by hand at every call site.
Type the param with a minimal structural shape ({ data?, error?, response? })
that the SDK's RequestResult satisfies — sidestepping the strict SdkResult
assignability issue that motivated the any — so TData infers from the SDK's
`data` field and the generated response type flows to callers. Removes the
explicit-any (and its eslint-disable). Pure type change; behavior unchanged.
Verified: tsc 0 source errors; TData proven a real inferred type (dropping the
cast errors 'TData | undefined not assignable to TData'); client tests 93/93.
…o NaN
searchReplays sent project: [Number(projectId)] to the SDK. The SDK types the
replays project param as Array<number | string> ("a list of project IDs or
slugs"), and the pre-SDK implementation forwarded projectId as a string — so
Number() turns a slug into NaN and breaks slug-based filtering for direct
callers. Pass projectId through unchanged.
(Leaving getFlamegraph/profile-chunks as-is: their callers resolve slug->numeric
ID upstream by design, and the chunks SDK param is number, not number|string.)
Adds a regression test asserting a slug passes through as project=<slug>; it
fails ('NaN') against the old code. Verified: tsc clean; client tests 94/94.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
There are 3 total unresolved issues (including 1 from previous review).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 52b2cd5. Configure here.
…ode engine
Addresses three cursor findings:
- getFlamegraph: SDK types project as Array<number|string> (IDs or slugs) and
the prior code forwarded projectId.toString(); forward projectId as-is so a
slug doesn't become NaN.
- getProfileChunk: same regression. The SDK under-types its project as a scalar
number (vs the sibling flamegraph endpoint's number|string), so forward with a
narrowing cast + comment; the value serializes to the query string regardless.
- engines.node: @sentry/api requires Node >=22 but the workspace declared >=20.
Bump root + mcp-core/mcp-server/mcp-server-evals/mcp-server-mocks to >=22.
Adds regression tests for both profiling methods (assert the outgoing project
param is the slug, captured before response parsing); both fail ('NaN') against
the old code. Verified: tsc clean; client tests 96/96.
getsentry/sentry#118051 fixed the profiling-chunks `project` param to be documented as an ID-or-slug (string) instead of a scalar int, so @sentry/api 0.232.0 now types getProfileChunk's `project` as string. Replace the temporary `projectId as number` cast with `String(projectId)` — numeric ids serialize as-is, slugs are preserved, no cast. The slug guard test still passes. Verified: tsc clean (no other breakage from 0.228->0.232); full mcp-core suite unchanged (1162 pass; the 2 fails remain the pre-existing autofix run_id/sentry_run_id tests, tracked separately).
The autofix POST endpoint's response type (AutofixPostResponse) is
{ run_id: int, sentry_run_id: str | None } — it returns both fields. The
generated @sentry/api zod schema (which AutofixRunSchema wraps) therefore
requires the sentry_run_id key, but our mocks/fixtures predated it and returned
only { run_id }, so the schema parse failed in tests.
Add sentry_run_id to the three autofix POST mocks (server-mocks + the two test
fixtures). No runtime change — the MCP still keys off run_id; this just makes the
fixtures match the real response shape. (GET-state mocks keep run_id only, which
their schema expects.)
Verified: full mcp-core suite green (1164 pass, 0 fail); tsc clean.

Adds
@sentry/api@^0.175.0and migrates 38 of 40 API methods inSentryApiServicefrom rawfetch(viarequestJSON) to the typed SDK functions. The remaining 2 methods use internal/undocumented endpoints with no SDK equivalent.What changed
Two helper methods added to
SentryApiService:getSdkConfig(opts?)— buildsbaseUrl+ auth headers (includingX-Sentry-MCP-Client-*identity headers) per call, supporting multi-region host overridesunwrapSdkResult(result, context)— converts SDK discriminated-union results to the existing MCP error hierarchy (ApiError,ApiNotFoundError,ApiServerError, etc.), using the API detail text as the user-facing message when available17 direct replacements (no casts)
listOrganizations,getOrganization,listTeams,createTeam,listProjects,getProject,createProject,updateProject,addTeamToProject,createClientKey,listClientKeys,listReleases,listIssues,getEventForIssue,getLatestEventForIssue,listEventsForIssue,startAutofix,getAutofixState11 replacements with type casts
searchReplays,getIssue,getIssueTagValues,getIssueExternalLinks,getReplayDetails,listReplayIdsForIssue,getReplayRecordingSegments,updateIssue,searchErrors,searchSpans,searchEvents10 new replacements (from SDK v0.171.0+)
listTags→listAnOrganization_sTags(with cast foruseCacheparam)listTraceItemAttributes→listTraceItemAttributes(replacesfetchTraceItemAttributesByTypeprivate helper)listEventAttachments→listAnEvent_sAttachmentsgetEventAttachment— metadata vialistEventAttachments; binary download stays on rawrequest()getTraceMeta→retrieveTraceMetadatagetTrace→retrieveATrace(with cast forlimit/projectparams)getFlamegraph→retrieveAFlamegraphForAnOrganizationgetTransactionProfile→retrieveAProfilegetProfileChunk→retrieveProfileChunksForAnOrganizationlistReleases(project-level) →listAProject_sReleaseslistIssues(project-level) →listAProject_sIssues(with cast for extra query params)2 methods still on
requestJSONgetAuthenticatedUser, regions endpoint — no SDK equivalent exists for these.Schema improvements
TagSchema/TagListSchemarebased onzTagKeyDetailsDictfrom@sentry/api/zodEventsResponseSchema,ExternalIssueListSchema,AutofixRunSchemause SDK-generated Zod schemasPreserved behavior
unwrapSdkResultmaps HTTP errors to the existingApiError/ApiNotFoundError/ApiServerErrortypes, using API detail text as the messagegetSdkConfigbuilds per-call base URLs fromopts.hostoverridesX-Sentry-MCP-Client-Id/Name/Familyheaders forwarded through SDK callsTesting
client.ts)Dependencies
@sentry/api@^0.175.0— latest version, includes SDK wrappers for organization tags, trace, profiling, project-level issues/releases, and event attachment endpoints