Skip to content

feat(mcp-server): Ship @sentry/mcp-server as a slim bundle that shares CLI auth - #1731

Open
sentry-junior[bot] wants to merge 12 commits into
mainfrom
ref/retire-mcp-server-package
Open

sentry-junior[bot] wants to merge 12 commits into
mainfrom
ref/retire-mcp-server-package

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

@sentry/mcp-server stays the recommended stdio install. Its server code moves into the CLI so it shares the CLI's auth, and the package becomes a slim, dependency-free bundle of that code (see the @sentry/mcp-server section below). The CLI exposes the same server as sentry mcp. This also locks in a one-way package graph, so MCP tools can later be built on the CLI's portable operations without a cycle.

What moved where

  • stdio transport: packages/mcp-server/src/transports/stdio.ts → packages/mcp-core/src/transports/stdio.ts, exported as @sentry/mcp-core/transports/stdio. It now uses @sentry/core tracing, so mcp-core takes no Node SDK dependency.
  • Server host (flag/env parsing, config validation, usage, agent provider and telemetry setup, the old runMcpServer): moved to packages/cli/src/lib/mcp/{args,config,usage,server}.ts. mcp-core stays free of CLI concepts. lib/mcp.ts still loads the host with a dynamic import, so normal CLI startup does not pay for mcp-core or Zod.
  • Standalone auth (device code flow, bundled client ID, ~/.sentry/mcp.json cache, auth subcommands): deleted. CLI auth replaces it.
  • Consumers: evals import @sentry/mcp-core/transports/stdio. The test client launches sentry mcp from CLI source. Smoke tests only target the hosted worker, so they needed no change. ensure-generated.mjs now sends generator output to stderr, so a first pnpm run cli mcp cannot write junk into the JSON-RPC stream.
  • Refresh after a 401: mcp-core copies the handler context per call, so a token returned from onUpstreamUnauthorized was dropped before. The refreshed token now reaches the context, and a regression test checks that later calls use it.
  • Install snippets and docs lead with npx @sentry/mcp-server@latest; the web install instructions are unchanged. User-facing docs mention the shared CLI login but do not steer installs to sentry mcp; the mcp-qa skill drives the server from CLI source. docs/operations/stdio-auth.md and docs/releases/stdio.md are rewritten package-first, and stdio-auth.md documents that each server process uses one account.

Parity

Old @sentry/mcp-server New @sentry/mcp-server (and sentry mcp)
--access-token / SENTRY_ACCESS_TOKEN Static token. The flag wins over the env var, and both win over the CLI session. It is never refreshed. An org token (sntrys_) issued for another host is refused with HostScopeError. Other CLI commands ignore SENTRY_ACCESS_TOKEN.
No token: device code flow plus ~/.sentry/mcp.json cache CLI session (sentry auth login, or SENTRY_AUTH_TOKEN/SENTRY_TOKEN), refreshed after an upstream 401. In a TTY it starts the CLI login. Over pipes it fails with an error naming the login command: npx -y @sentry/mcp-server auth login from the package, sentry auth login from sentry mcp. The old cache is not read.
--host / SENTRY_HOST, --url / SENTRY_URL Same flags. The env values come from the CLI's configured URL, which is translated into --host/--url. One difference: an http:// SENTRY_URL now maps to --host plus --insecure-http (the CLI's self-hosted behavior) instead of being rejected.
--insecure-http Same. It is still rejected with --url and for sentry.io hosts.
--mcp-url / MCP_URL, --sentry-dsn / SENTRY_DSN / DEFAULT_SENTRY_DSN Same
--skills / MCP_SKILLS, --all-skills, --disable-skills / MCP_DISABLE_SKILLS Same, including dropping seer from the defaults on self-hosted hosts
--agent-provider / EMBEDDED_AGENT_PROVIDER, --openai-base-url, --openai-model / OPENAI_MODEL, --anthropic-base-url, --anthropic-model / ANTHROPIC_MODEL, provider API keys Same, with the same provider mismatch and auto-detection warnings
--organization-slug, --project-slug, --experimental Same
--help / -h, --version / -v Same. --version prints sentry mcp <cli version> (sentry-mcp <package version> from @sentry/mcp-server).
Unknown flags or positionals Rejected, as before
SENTRY_CLIENT_ID, SENTRY_MCP_AUTH_CACHE Ignored, because the device flow is gone
sentry-mcp auth login|logout|status sentry-mcp auth login runs the CLI device flow with plain-text output and stores the CLI session. logout and status point to npx -y sentry auth ..., which reads the same session. sentry mcp auth points users at sentry auth.

Dependency direction guard

sentry → @sentry/mcp-core → @sentry/toolkit-core, and @sentry/mcp-cloudflare → @sentry/mcp-core. No edge runs the other way. pnpm run lint enforces this with two checks:

  • An oxlint no-restricted-imports override bans sentry, sentry/**, and relative CLI paths inside packages/mcp-core and packages/toolkit-core.
  • scripts/check-workspace-deps.mjs (lint:deps) reads every workspace package.json. It fails on any cycle, on mcp-core reaching sentry or mcp-cloudflare, and on toolkit-core reaching sentry or mcp-core.

The rule is documented in AGENTS.md and docs/architecture/overview.md#package-dependency-direction. Capabilities that only the CLI host has (SQLite cache, DSN detection from local files, file uploads) are injected into mcp-core through interfaces defined in mcp-core or toolkit-core. sentry mcp already works this way for the access token and refresh callback in ServerContext.

MCP registry

Unchanged. server.json and mcp-registry.yml keep the listing on @sentry/mcp-server, which keeps mcpName: io.github.getsentry/sentry-mcp.

@sentry/mcp-server bundle

@sentry/mcp-server stays the recommended, supported package. It now ships the CLI's server code bundled into one dependency-free file, instead of its own copy of the server. One implementation serves the package and sentry mcp, including self-hosted Sentry.

  • Entry and build: packages/cli/src/mcp-server.ts is the entry point. packages/cli/script/bundle-mcp-server.ts bundles it into packages/mcp-server/dist/sentry-mcp.cjs (about 3.6 MB, about 0.95 MB packed). The package has no runtime dependencies, and the sentry-mcp bin name is unchanged.
  • Shared code: sentry mcp and the bundle both call lib/mcp/run.ts (runMcpServer) and lib/project-context.ts (preloadProjectContext, moved out of cli.ts). lib/suppress-sqlite-warning.ts replaces the inline warning filter in bin.ts. startMcpServer reports whether a server is running, so runMcpServer closes the network dispatcher and schedules the force-exit backstop after --help, --version, or a setup error (and the standalone auth entry does the same), but never under a live server. --help/--version name sentry-mcp when the bundle defines SENTRY_MCP_SERVER_VERSION, and lib/login-command.ts makes auth hints (AuthError, refresh and device-flow failures) name npx -y @sentry/mcp-server auth login in the bundle. Hints that confirm a self-hosted host with --url still name npx -y sentry auth login --url, since the standalone auth login takes no flags.
  • Auth: sentry-mcp auth login (lib/mcp/auth.ts) runs the CLI's device flow. The bundle swaps formatters/markdown.ts for markdown-plain.ts, so login output is plain text and the markdown renderer and syntax highlighter stay out.
  • Left out: CLI commands, the markdown renderer, agent skills, shell completions, sixel/kitty images, the Ink UI, sentry init, and build/sourcemap/debug-file code. The SQLite WASM fallback is also left out, so the engine moves from >=22.13 to >=22.15 (native node:sqlite), and the bin exits early with a clear error on older Node.js.
  • Guards: the bundle script fails if any of those modules contributes code to the output, or if the file grows past 4.5 MB.
  • Tests and CI: packages/mcp-server/test/bundle.test.mjs runs the built file: initialize plus tools/list over stdio, no runtime dependencies in package.json, --version/--help, the auth subcommands, and the login hint when no credentials are available. merge-jobs.yml bundles, tests, and packs the package.

The old @sentry/mcp-server/transports/stdio export is gone (now @sentry/mcp-core/transports/stdio), and the standalone clean-consumer workflow (mcp-server-package.yml) is removed; the bundle test replaces it.

Release note: @sentry/mcp-server can publish from release/mcp branches through its Craft workspace as before. Do not run npm deprecate. Users on Node.js 22.13 or 22.14 need to upgrade Node.js.

mcp-core CJS output

Nothing builds or consumes mcp-core CJS anymore. #1732, now merged into this branch from main, switched packages/mcp-core/tsdown.config.ts to format: ["esm"]. mcp-core is "type": "module", and every exports entry maps only types and default (.js) with no require condition. The CLI's esbuild bundle (CJS output) resolves default and converts the ESM itself, and scripts/check-build-imports.ts now checks dist/server.js. This PR does not touch the build format.

Verification

  • pnpm run lint (includes lint:deps), CLI tsc --noEmit, ci:policy, docs:check, and check:generated pass.
  • CLI MCP and security tests pass, plus the new auth, plain-markdown, standalone usage, and teardown tests.
  • pnpm --filter @sentry/mcp-server run bundle builds 3555 KB; test:bundle passes 6/6.
  • A clean npm install of the packed tarball installs one package; sentry-mcp answers tools/list with 14 tools on sentry.io and 13 with --host=sentry.example.com (Seer is off on self-hosted). No SQLite warning reaches stderr.
  • Adding an agent-skills import to the entry point fails the bundle with the guard error.
  • The CLI bundle still builds, and sentry mcp answers tools/list.
Codemod used for stale package paths in contributor docs
sed -i 's#packages/mcp-server/src/#packages/mcp-core/src/#g' \
  docs/contributing/api-patterns.md docs/operations/{logging,monitoring,security}.md docs/testing/overview.md

via BYK.

--

View Session in Sentry

Move the stdio MCP host into the CLI so `sentry mcp` is the only local
server. The stdio transport moves to mcp-core; flag/env parsing, usage, and
server startup move to packages/cli/src/lib/mcp/. The standalone device-code
auth and token cache are deleted in favor of CLI auth.

`sentry mcp` keeps every standalone flag and env var, and accepts
`--access-token` / `SENTRY_ACCESS_TOKEN` as a static, never-refreshed token
that still goes through host scoping.

Lock the dependency direction (cli -> mcp-core -> toolkit-core) with an
oxlint import ban and a workspace manifest cycle check, move the MCP
registry entry to the `sentry` package, and reduce @sentry/mcp-server to a
deprecation shim for one last release.

Co-Authored-By: BYK <burak.kaya@sentry.io>
@vercel

vercel Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
sentry-local Error Error Oct 30, 2026 12:09am UTC

Request Review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread packages/cli/src/lib/mcp/args.ts
The doc example checker reads backticked sentry commands in the generated
configuration page and does not know about `sentry mcp` passthrough flags.

Co-Authored-By: BYK <burak.kaya@sentry.io>
The retired package fixed the SDK environment to "stdio" at build time.

Co-Authored-By: BYK <burak.kaya@sentry.io>
Comment thread .oxlintrc.json
Comment thread packages/cli/src/lib/mcp.ts
Comment thread packages/mcp-cloudflare/src/client/components/fragments/instructions/fx.tsx Outdated
sentry-junior Bot and others added 3 commits October 29, 2026 20:17
…nippet

Tool handlers read mcp-core's own copy of the server context, so updating
the host's context after a refresh had no effect. onUpstreamUnauthorized
can now return the new token, and mcp-core stores it where handlers read
it. The fx profile snippet also ran plain `npx sentry@latest`.

Co-Authored-By: BYK <burak.kaya@sentry.io>
…-package

Co-Authored-By: BYK <burak.kaya@sentry.io>
Oxlint replaces a rule's options per override, so the toolkit-core browser
override silently dropped the earlier CLI ban. Carry the ban there and test
the last matching override for each package.

Co-Authored-By: BYK <burak.kaya@sentry.io>
Comment thread packages/cli/src/lib/mcp/config.ts
@sentry-junior sentry-junior Bot changed the title ref(mcp): Retire @sentry/mcp-server in favor of sentry mcp ref(mcp): Move the stdio MCP server into sentry mcp Oct 29, 2026
sentry-junior Bot and others added 2 commits October 29, 2026 22:49
…-package

# Conflicts:
#	pnpm-lock.yaml

Co-Authored-By: BYK <burak.kaya@sentry.io>
Bundle the CLI's stdio MCP server into one dependency-free file instead of
forwarding to the sentry CLI. The package keeps its flags, env vars, and
self-hosted support, and adds a plain-text `sentry-mcp auth login`.

The bundle script keeps CLI-only code out (commands, markdown renderer,
agent skills, completions, terminal images, Ink UI, debug files) and drops
the SQLite WASM fallback, so the package requires Node.js 22.15+. It fails
the build if a CLI-only module reaches the output or the file exceeds 4.5 MB.

Co-Authored-By: BYK <burak.kaya@sentry.io>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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 982a007. Configure here.

Comment thread packages/cli/src/lib/mcp/run.ts
These invocations finish like any other drained command but skipped the
force-exit backstop and dispatcher close that runCli applies, so leftover
handles could keep the process alive on macOS. startMcpServer now reports
whether a server is running, and runMcpServer and the standalone auth entry
release resources whenever the invocation is finite.
@sentry-junior sentry-junior Bot changed the title ref(mcp): Move the stdio MCP server into sentry mcp feat(mcp): Run stdio MCP from sentry mcp and ship @sentry/mcp-server as its slim bundle Oct 29, 2026
sentry-junior Bot added a commit that referenced this pull request Oct 29, 2026
The stdio proxy to the hosted MCP (#1743) is closed in favor of bundling
the CLI's own server, which keeps one implementation and works with
self-hosted Sentry. Update the design decision, rollout step, proposal,
and task 11.6 to match #1731.

Co-Authored-By: BYK <burak.kaya@sentry.io>
Restore the web install instructions, the MCP registry manifest, and its
publish workflow to @sentry/mcp-server, and move mcpName back to that
package. Docs and READMEs recommend npx @sentry/mcp-server@latest and
mention sentry mcp as the same server.

Co-Authored-By: BYK <burak.kaya@sentry.io>
sentry-junior Bot added a commit that referenced this pull request Oct 29, 2026
#1731 now leaves server.json and the recommended stdio install on
@sentry/mcp-server, with sentry mcp as the same server for CLI users.

Co-Authored-By: BYK <burak.kaya@sentry.io>
Auth errors in the standalone bundle told users to run 'sentry auth login',
which needs the full CLI. A shared login-command constant now names
'npx -y @sentry/mcp-server auth login' when running as the bundle and
'sentry auth login' otherwise. Hints that confirm a self-hosted host with
--url still name the CLI, because the standalone auth login takes no flags.

Co-Authored-By: BYK <burak.kaya@sentry.io>
…unt per server

Co-Authored-By: BYK <burak.kaya@sentry.io>
@sentry-junior sentry-junior Bot changed the title feat(mcp): Run stdio MCP from sentry mcp and ship @sentry/mcp-server as its slim bundle feat(mcp-server): Ship @sentry/mcp-server as a slim bundle that shares CLI auth Oct 30, 2026

This branch had an error being deployed

1 failed and 1 active deployments
Preview — b83e10db Deployed Oct 30, 2026 by vercel[bot]
Actions — b83e10db Deployed Oct 30, 2026 by sentry-junior[bot] via eval #1414
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants