Repository navigation
Route stdio MCP tool calls to the stored account that knows the org #1756
Description
Problem
The CLI stores several accounts and picks the right one for each command based on the targeted organization (selectAccountForOrg in packages/cli/src/lib/db/auth.ts, called from resolveOrgRegion in packages/cli/src/lib/region.ts). The stdio MCP server (@sentry/mcp-server and sentry mcp, which share the CLI's credential store after #1731) does not.
The server resolves one effective account at startup and uses it for every tool call. A token refresh after a 401 stays on that same account. Asking about an org that belongs to another stored login fails. The only workarounds are sentry auth switch plus a restart, or configuring a second MCP server with a different SENTRY_HOST or a static SENTRY_ACCESS_TOKEN.
Why it doesn't work today
ServerContextin mcp-core carries a singleaccessToken: string(packages/mcp-core/src/types.ts). All tools build their API client withapiServiceFromContext()(about 63 call sites), and the region cache (internal/tool-helpers/resolve-region-url.ts) reads the same token.- MCP tools use mcp-core's API client, not the CLI's, so the CLI's org-based selection never runs.
- mcp-core must not import the CLI (see the dependency-direction rule in
AGENTS.md), and the hosted MCP has one OAuth grant per session. So this has to be an optional capability that only the stdio host provides.
Proposed approach
- mcp-core: add an optional resolver to
ServerContext, e.g.resolveCredential({ organizationSlug }) => Promise<{ accessToken, sentryHost, sentryProtocol }>.apiServiceFromContext()takes the org and uses the resolver when present; otherwise it usesaccessToken. Key the region cache by the resolved credential. The hosted MCP stays unchanged. - CLI host (
packages/cli/src/lib/mcp.ts): implement the resolver with theselectAccountForOrgrules, running each call insidewithStoredAccount(). That function already isolates account scope per call throughwithEnvand AsyncLocalStorage, so overlapping tool calls are safe. Refresh-on-401 targets the account that made the call. An unknown org falls back to the active account. One tool call never mixes identities. - Cross-org tools (
find_organizations,whoami): query every usable account and merge the results, assentry org listdoes withlistUsableAccountsInScope(). The CLI already records which account saw each org in the regions cache (packages/cli/src/lib/db/regions.ts), so later calls route automatically. - Opt-outs and pins:
--access-token/SENTRY_ACCESS_TOKENdisables routing.--organization-slugpicks the account once at startup. An explicit server (SENTRY_HOST/SENTRY_URL) limits candidates to accounts on that server, matching the CLI.
An alternative would route inside an injected fetch by parsing /organizations/{slug}/ from request URLs. It touches fewer files, but it is implicit and misses endpoints whose paths do not include the org. The explicit resolver is preferred.
Scope
- First version: route only between accounts on the same server.
- Later: mixing self-hosted and sentry.io accounts in one server needs a host per account and the region-URL validation (
validateRegionUrl) checked against the right server.
Acceptance
- With two stored sentry.io accounts that each own a different org, one running stdio server can call org-scoped tools on both orgs without
auth switchor a restart. find_organizationslists orgs from all usable accounts.- A 401 refreshes only the account that made the call.
- The hosted MCP and static-token setups behave as before.
- Tests cover concurrent tool calls for different orgs and verify that each call sends its own account's token.
Related
- feat(mcp-server): Ship @sentry/mcp-server as a slim bundle that shares CLI auth #1731:
@sentry/mcp-serveras a slim bundle that shares CLI auth (prerequisite) - docs(openspec): Propose a shared Sentry API layer for the CLI and MCP #1669: shared API layer proposal; task group 11 (task 11.4, CLI capabilities injected into mcp-core) is the natural home
- Support multi-account mode #1396: CLI multi-account mode (done)
- Multi-account support in stdio transport #845: earlier
--profilerequest for the stdio transport, closed as not planned; this approach needs no per-process profiles
via BYK.
--
Activity
linear-code commentedon Oct 30, 2026
MCP-1134