How the stdio MCP server (@sentry/mcp-server) authenticates with Sentry.
Sign in once with npx -y @sentry/mcp-server auth login. The package runs
the Sentry CLI's own auth commands and stores the session in the CLI's
credential store, so the package and the CLI (which runs the same server as
sentry mcp) share one login.
The server uses the CLI's credential resolution, with one difference: an env
token wins over a stored login, as if SENTRY_FORCE_ENV_TOKEN=1 were set. An
MCP client passes the token in its server config to pick the account, so a
stored login must not silently replace it.
SENTRY_AUTH_TOKEN(or the legacySENTRY_TOKEN) — used when set, even when a stored login exists.- Stored login — the account from
auth login, used when no env token is set.
A [auth] token from a repo-local .sentryclirc is not forced: it comes from
the repository, not the MCP client, so a stored login still wins over it, as
for every other CLI command.
Both go through the CLI's refreshToken(), which enforces the same host
scoping as every CLI command. When a tool call gets a 401 from Sentry, the
server forces a refresh and later calls use the new token, so a long-running
server survives token rotation without a restart. An env token is never
refreshed; the forced refresh re-reads it.
To run the server with a token instead of a login, configure the MCP client with environment variables:
{
"command": "npx",
"args": ["-y", "@sentry/mcp-server@latest"],
"env": {
"SENTRY_AUTH_TOKEN": "sntryu_..."
}
}Org auth tokens (sntrys_) record the Sentry URL they were issued for; the
server refuses to send one to a different host (HostScopeError).
Older @sentry/mcp-server releases took a static token from --access-token
or SENTRY_ACCESS_TOKEN. Both still work, as an alias: the server runs as if
SENTRY_AUTH_TOKEN=<token> were set, so the token wins over a stored login
and takes the same env-token path. It also
replaces any SENTRY_AUTH_TOKEN / SENTRY_TOKEN already in the environment,
because the flag is the more explicit choice. --access-token wins over
SENTRY_ACCESS_TOKEN. Like a plain env token, the alias is scoped to the
Sentry instance configured at startup (SENTRY_HOST/SENTRY_URL, or
--host/--url), else SaaS; an org token's own URL claim wins. A
.sentryclirc URL or the persisted default URL never scopes it, so the server
refuses to send it there (HostScopeError), even when you have a stored login
on that server.
Either one prints a single deprecation warning to stderr (stdout carries the MCP protocol), without the token:
Deprecation warning: --access-token is deprecated; set SENTRY_AUTH_TOKEN instead.
The flag value is redacted from the CLI's telemetry like --token.
When no credential is available and stdin is a TTY, the server starts the
interactive login before serving. MCP clients launch the server over pipes,
so in that case it exits with an error that names the login command for the
program that is running, such as npx -y @sentry/mcp-server auth login
(packages/cli/src/lib/app-identity.ts).
For self-hosted Sentry, set SENTRY_HOST/SENTRY_URL, the same as for every
other CLI command. They pick the stored account for that server (see
Accounts), scope SENTRY_AUTH_TOKEN to it, and point the
interactive login at it. A plain HTTP instance takes an http://
SENTRY_URL.
Older releases picked the instance with --host/--url, and plain HTTP with
--insecure-http. They still work, hidden from help, as an alias: the server
runs as if SENTRY_URL were set to that target (http:// with
--insecure-http), so the credential check, the env token's host scope, and
the interactive login all use it. Each prints a deprecation warning to
stderr.
A repo-local .sentryclirc URL is not a trust source. Unless --host/--url
is passed, a non-SaaS [defaults] url must match a server you are logged in
to, the same check every CLI command applies. With SENTRY_AUTH_TOKEN set, the
check uses that token, as serving does: the URL must match the server the token
is scoped to (its sntrys_ claim, or SENTRY_HOST/SENTRY_URL from the
environment the server started with, never the file). Otherwise the server
refuses to start (HostScopeError) instead of sending any token to that host.
An org auth token (sntrys_) passed through the deprecated alias is the
exception: it names the server it was issued for, so it is served when that
server matches the target and refused when it does not.
The credential store can hold several accounts. The server starts with one:
with SENTRY_HOST/SENTRY_URL set, a stored account on that server;
otherwise the active account (npx -y @sentry/mcp-server auth switch). Calls
that target no organization use that startup account, and another process
switching accounts does not change it.
With a stored login, each tool call uses the stored account that knows the
organization it targets (its organizationSlug, or the organization in a
Sentry URL argument), the same way CLI commands pick an account. No
auth switch or restart is needed. The server first lists the startup
account's organizations when no fresh list is cached, so it is kept only for
organizations it can reach. When no stored account is known to reach the
organization, the server lists the organizations of accounts without a
fresh cached list once, then routes; an organization no account reaches uses
the startup account. Only accounts on the server's target server are
candidates. One call never mixes accounts, and a 401 refreshes only the
account that made the call. find_organizations lists organizations from
every account, each once, and whoami lists every account's user.
Each account is pinned to the user it had when a call first used it. If an account is removed or another user logs in over it, calls routed to it fail until the server restarts.
Routing is off when the credential is a static token (SENTRY_AUTH_TOKEN,
--access-token, SENTRY_ACCESS_TOKEN): that token is the only account.
--organization-slug (or an <org>/ target) picks the account that knows the
organization once, at startup, and every call uses it. To use accounts on
different servers at once (say, sentry.io and a self-hosted server), configure
one MCP server per host via SENTRY_HOST.
Older releases had their own device code flow, bundled client ID, and token
cache (~/.sentry/mcp.json, SENTRY_MCP_AUTH_CACHE). Current releases do not
read that cache. Run npx -y @sentry/mcp-server auth login once, or set
SENTRY_AUTH_TOKEN. --access-token / SENTRY_ACCESS_TOKEN keep working but are
deprecated (see above). auth status, auth list,
auth switch, and auth logout work in the package as in the CLI.
| File | Purpose |
|---|---|
packages/cli/src/lib/mcp.ts |
Credential resolution, --access-token alias, refresh-on-401 |
packages/cli/src/commands/mcp.ts |
mcp command flags and help |
packages/cli/src/lib/mcp/server.ts |
Agent providers, telemetry, and stdio startup |
packages/cli/src/lib/mcp/account-router.ts |
Per-call routing between stored accounts |
packages/mcp-core/src/internal/tool-helpers/credential-routing.ts |
Applies ServerContext.credentialRouter to tool calls |
packages/cli/src/lib/db/auth.ts |
CLI token storage and refreshToken() |
packages/cli/src/lib/token-host.ts |
Host-scoping checks |
packages/mcp-core/src/transports/stdio.ts |
stdio transport and per-request auth context |