Repository navigation
fix(mcp): Accept 1h and minute periods; guide models to find_organizations on missing org - #1678
Merged
Merged
Conversation
`search_issues` limits `period` to an enum without `1h`, and the shared `ParamPeriod` regex rejects minute windows such as `30m`. The MCP SDK rejects these before the handler runs. In `sentry/mcp-server` over the 7 days to 2026-10-26, about 26K `search_issues` calls failed on `period: "1h"`. A single user sent about 25K of those; the other ~50 users sent about 500. Minute periods (`30m`, `15m`, `10m`, ...) failed about 1.5K times for ~300 users on `search_errors`, `search_logs`, and `search_traces`. Sentry's `statsPeriod` already treats `m` as minutes: a read-only check returned 28 errors for `30m` against 1,269 for `24h`, and the issues endpoint accepts `statsPeriod=1h`. Add `1h` to the `search_issues` enum and accept `m` in `ParamPeriod`. The other `search_issues` windows stay bounded. Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
Sessions without an organization constraint need `organizationSlug` on most tools. When a call omits it, the MCP SDK rejects the arguments before the handler runs and returns zod's generic message, such as `organizationSlug: Invalid input: expected string, received undefined`. In `sentry/mcp-server` over the 7 days to 2026-10-26, about 24K tool calls failed this way. A single user sent about 17.7K of them. The rest came from about 860 users, mostly on `search_issues`, `search_errors`, and `find_projects`. The SDK validates before the handler, so the zod issue message is the only place to add guidance. A missing or null slug now returns `Required. Call find_organizations() to list your organizations, then retry with organizationSlug set to one of their slugs.` Other invalid values keep their current messages. The JSON schema and token count do not change. Co-Authored-By: Burak Yigit Kaya <126780+BYK@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
BYK
approved these changes
Oct 27, 2026
BYK
added a commit
that referenced
this pull request
Nov 3, 2026
…1836) When a tool call leaves out `organizationSlug` and the login can reach exactly one organization, the call now uses that organization. When the login can reach several, a tool that requires the slug fails with a retry the model can run as is, plus the other organizations. This is the MCP version of the CLI recovery in #1634, and it finishes the part #1678 held back. The server never chooses between organizations. ## Why now Over the last 7 days (`sentry/mcp-server` spans, extrapolated counts): - `organizationSlug: Required` failures: about 4.3K, from search_issues, find_projects, search_errors, search_logs, and calls through execute_sentry_tool. `get_sentry_resource` adds about 1.9K more with "`organizationSlug` is required when not using a URL". - The script that sent about 89% of the earlier ~31K/week has stopped. The rest is spread out: no user accounts for more than 2 of the 40 sampled failures. ## How it works - **No schema or handler edits.** `getFilteredInputSchema` makes a required `organizationSlug` optional at registration time, so the MCP SDK no longer rejects the call before our code runs. Then `prepareToolCallParams` runs `applyDefaultOrganization`. Both top-level calls and `execute_sentry_tool` go through it, before `withRoutedCredential`, so stdio account routing (#1802) gets the defaulted slug. - It runs only when the call has no slug after constraint injection and no Sentry URL parameter (it reuses `getTargetOrganizationSlug`). Org-scoped sessions never reach it. - **One organization:** the call uses its slug. If the tool takes `regionUrl` and the caller didn't set one, the call also gets the organization's `regionUrl`. On self-hosted that value is empty, so `regionUrl` stays unset. - **Several organizations:** for a required slug, the error looks like ``Retry example: `search_issues(organizationSlug='org-a', period='1h')` `` and lists the other organizations. Catalog tools get the `execute_sentry_tool(name=…, arguments=…)` form, and values equal to a schema default are left out. For an optional slug (URL-or-ID tools such as `get_sentry_resource`), the call runs as before. - **Listing fails** (for example, a token without `org:read`): the error falls back to the find_organizations hint from #1678. - **Multiple logins:** organizations from every account are merged. ## Fit with #1669 - The organization list comes from `SentryApiService.listOrganizations`, which already uses the shared `endpoints/organizations` wrapper and transport (#1722, #1737). No new endpoint code. - The resolve step lives in mcp-core's constraint and param-prep layer. The design keeps that layer in mcp-core ("an MCP tool fills them from tool parameters and session constraints"), so 11.3 can keep it as is. - The MCP hosts don't wire a `CacheStore` yet (7.1 is still open). Instead, the list is memoized per context and credential for 5 minutes, which matches the `stable` tier. When 7.1 lands, the `/organizations/` request gets cached per identity on its own, and this memo can be dropped. It doesn't conflict with 8.4–8.7 or 11.x. - This doesn't complete a task in the plan. The closest is 11.3's resolve step. ## Token cost `measure-tokens` is unchanged at 9,014. That script reads the raw tool schemas, and those didn't change. In the registered schemas, `organizationSlug` is no longer in the `required` list on 8 direct tools, which comes to 5,014 → 4,990 input-schema tokens. ## Open questions - A `null` slug still gets the find_organizations hint. Accepting `null` would add `anyOf` to every schema. - When an optional-slug tool like `get_sentry_resource` is called by a user with several organizations, it keeps its own error. It doesn't list the organizations yet. <!-- junior-request-attribution:start --> via @BYK. <!-- junior-request-attribution:end --> <!-- junior-session-footer:start --> <!-- junior-conversation-id:agent%3A0222050e9c46ef2289687231ff960e16 --> -- [View Session](https://junior-prod.sentry.dev/conversations/agent%3A0222050e9c46ef2289687231ff960e16) [[Sentry]](https://sentry.sentry.io/explore/conversations/agent%3A0222050e9c46ef2289687231ff960e16/?project=4510944073809921) <!-- junior-session-footer:end --> --------- Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com> Co-authored-by: BYK <126780+BYK@users.noreply.github.com>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Telemetry from
sentry/mcp-server(spans over 7 days, extrapolated from 0.3 sampling, so user counts are lower bounds):organizationSlug: about 23.8K failures from 861+ users. One user sent ~17.7K of them, allsearch_issueswithperiod:"1h". Without them it's ~6.1K failures across ~860 users. All of these came in on the unscoped/mcpURL. They fail in the MCP SDK's input validation before any handler runs, so the zod error message is the only place to add guidance without changing the schema.period: "1h"onsearch_issues: about 25.6K failures from ~50 users, mostly that same user.30m,15mand10monsearch_errors,search_logsandsearch_traceswere never accepted. That's about 1.5K failures from ~300 users. Sentry readsmas minutes (read-only GET check:30mreturned 28 errors, against 1,269 for24h), and the issues endpoint acceptsstatsPeriod=1h.Changes
SEARCH_ISSUES_PERIOD_VALUESnow includes1h.ParamPeriodnow accepts minutes (/^\d+[mhdw]$/), and the rejection message says "(minutes)".organizationSlugnow returns:Required. Call find_organizations() to list your organizations, then retry with organizationSlug set to one of their slugs.This works on SDK v1 and v2 and doesn't change the JSON schema.Held back
organizationSlugoptional on ~50 tools, and fetching the org list plus a region lookup on every call that has no org. That's the org endpoint, cache and region-routing code that docs(openspec): Expose the CLI's commands as the MCP, on @sentry/api #1669 reworks, so it's left for that work.Checks
pnpm run tscandpnpm run lintpass.Risk
A model that means months by
3mwould get 3 minutes of data. Telemetry shows callers mean minutes; there are only a handful of6m/12m. None of this fixes the stuck script.via BYK.
--
View Junior Session [Sentry]