Repository navigation
feat(mcp-server): Ship @sentry/mcp-server as a slim bundle that shares CLI auth - #1731
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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>
…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>
…-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>
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.
Craft 3.5.0 ships the `mcp-registry` target (getsentry/craft#945), and getsentry/publish now grants `id-token: write`, so the target can use GitHub Actions OIDC. Add it to the `packages/cli` workspace after the npm targets, require Craft 3.5.0, and remove the Publish MCP Registry workflow it replaces.
Conflicts: - packages/mcp-core/src/server.ts: keep #1780's maxToolInputElements on the single SDK v2 McpServer this branch builds. - packages/mcp-core/src/server.test.ts: keep both imports, and run #1780's input-cap test once, since buildServer no longer takes sdkVersion. - packages/mcp-server/package.json: keep the bundle package. #1778's test:package consumer check typechecks the old library exports, which the bundle no longer ships, so drop it and its test/package files. - package.json, AGENTS.md: keep both sides.
`sentry mcp` and `@sentry/mcp-server` used the CLI's precedence, where a stored login wins over `SENTRY_AUTH_TOKEN` unless `SENTRY_FORCE_ENV_TOKEN=1` is set. With that flag gone from the client configs and `server.json`, a token the MCP client passed was silently replaced by any `sentry auth login` on the machine, so the server could run as a different account than the one configured. An MCP client passes the token to pick the account, so the server now runs an env token (`SENTRY_AUTH_TOKEN` or `SENTRY_TOKEN`) as forced, in a copy of the environment. Other commands keep preferring the stored login. mcp-test-client no longer needs to force its token, and the docs, help, and deprecation warning drop the flag for the server.
…ST/SENTRY_URL `sentry mcp` now picks the Sentry instance from SENTRY_HOST/SENTRY_URL, like every other command, with an http:// SENTRY_URL for plain HTTP. --host, --url, and --insecure-http still work, hidden from help, and print a deprecation warning on stderr. They now run as if SENTRY_URL were set to their target, before the credential check. Before, only the server's target used them: with no credential in a terminal, the fallback login ran against the CLI's default host (SaaS, or SENTRY_HOST/SENTRY_URL), so a self-hosted `--host` run could finish a SaaS login and then fail the host check. Now the login, an env token's host scope, and the target agree, and an unconfirmed self-hosted host is refused before any login starts. mcp-test-client passes its host as SENTRY_HOST only. Docs, help, and the generated skill reference drop the flags.
Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
`--sentry-dsn=` is documented as turning the server's telemetry off, but `initMcpTelemetry` treated the empty value like no DSN: it still called `Sentry.init` with `enabled` following the CLI's telemetry setting. No events were sent, since the DSN stayed empty, but the SDK and its instrumentation still started. An empty DSN now skips `init`, and only an unset DSN falls back to the CLI's DSN and telemetry opt-outs.
`sentry mcp` serves `SENTRY_AUTH_TOKEN` over a stored login, but its `.sentryclirc` URL check still resolved the stored login. With a login on another server, an env token scoped to the rc URL by `SENTRY_URL` failed with HostScopeError, though serving would have used it. The check now runs under the same forced env token. That copy of the environment keeps the env-token host snapshotted at startup instead of re-reading `SENTRY_URL`, which the `.sentryclirc` shim may have set by then: re-reading it would let the rc URL scope a token with no host claim, the case the check exists for. Org tokens are checked against their claim the same way. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Craft 3.7.0 bumps to the next development version after a release with `postReleaseBump`: it reruns the pre-release command with the next minor `-dev.0` version, then commits and pushes it. That is what `bump-version.ts --post` did with `npm version preminor --preid=dev`, so the CLI workspace uses `postReleaseBump: true` and the script drops `--post` with its git commit, pull, and push. `--pre` now also syncs the skill frontmatter versions, which only `--post` did before, so the dev bump keeps them in step with package.json. For the release version it writes what the skill generator would write from package.json. The logger workspace keeps no dev bump. Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4009bb8. Configure here.
| postReleaseCommand: bash -c 'cd packages/cli && node --experimental-strip-types script/bump-version.ts --post' | ||
| # After a release, Craft reruns preReleaseCommand with the next minor | ||
| # `-dev.0` version, then commits and pushes it. | ||
| postReleaseBump: true |
There was a problem hiding this comment.
Post-release bump uses missing Craft feature
High Severity
postReleaseCommand and the --post bump (next -dev version, mcp-server/plugin.json/skills, commit and push) were replaced with postReleaseBump: true and minVersion: "3.7.0". Released Craft is still 3.6.0 and has no postReleaseBump option, so craft prepare can fail the min-version check, and after publish main can stay on the released version with @sentry/mcp-server out of sync.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 4009bb8. Configure here.
There was a problem hiding this comment.
Not an issue: Craft 3.7.0 shipped on 2026-11-02 and is the latest release (3.7.0). It added postReleaseBump in getsentry/craft#950. Both release paths already run it: release.yml uses getsentry/craft@v3, which points at the 3.7.0 commit 055aa3c, and getsentry/publish uses getsentry/craft:latest, which is the 3.7.0 image. So the minVersion: "3.7.0" check passes, and the dev bump still updates @sentry/mcp-server, plugin.json and the skill frontmatter because Craft re-runs bump-version.ts --pre with the -dev.0 version.
`sentry mcp` forces `SENTRY_AUTH_TOKEN` over a stored login, because an MCP client sets it to pick the account. The `.sentryclirc` shim also copies a repo's `[auth] token` into `SENTRY_AUTH_TOKEN`, so a repository could replace the user's login for the MCP server. A token the shim injected is no longer forced: like every other command, the stored login wins over it. A token the client set is still forced. The rc URL check could not be passed with an rc token and URL pair before either: the env token's host is snapshotted before the shim runs, so it never comes from the file. Tests now cover that case too.
The Release workflow bumped the version in package.json itself, with `semver -i`. package.json holds the next `-dev` version, so a patch from `0.48.0-dev.0` gave `0.48.0` instead of `0.47.1`. Pass the bump type to `craft prepare` instead. Since Craft 3.6.0 (getsentry/craft#947) it bumps from the workspace's latest release tag (`cli@0.47.0` gives patch 0.47.1, minor 0.48.0, major 1.0.0), and before the first tag from the version in package.json (logger `1.0.0-dev.0` gives 1.0.0 for any bump). Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
| const targetEnv = withTargetEnv(env, flags, config); | ||
| const credentialEnv = deprecatedToken | ||
| ? deprecatedTokenEnv(targetEnv, deprecatedToken, config) | ||
| : preferEnvToken(targetEnv); |
There was a problem hiding this comment.
MCP env token can be re-scoped to a .sentryclirc host and leaked
credentialEnv from preferEnvToken() does not call inheritEnvTokenHost(), so a forced SENTRY_AUTH_TOKEN can be re-snapshotted against a post-rc SENTRY_URL and sent to that host. Add inheritEnvTokenHost(credentialEnv) on the non-deprecated path (as the startup check already does).
Evidence
- The comment above the rc gate states env tokens must keep the boot host snapshot so a
.sentryclircURL cannot scope them;checkEnvcorrectly callsinheritEnvTokenHost(checkEnv)beforeassertRcUrlTrusted. credentialEnvis built aspreferEnvToken(targetEnv)(or viawithTargetEnv) withoutinheritEnvTokenHost, andresolveMcpCredentialWithLogin/ refresh run underwithEnv(credentialEnv, …).getEnvTokenHost()keys snapshots by env object and auto-captures on miss, so the copy re-reads post-shimSENTRY_URL/SENTRY_HOSTfor non-sntrys_tokens.assertRcUrlTrustedcan still pass whenhasStoredAccountForHost(rcUrl)is true even if the forced env token’s boot host is SaaS, soresolveCliMcpCredential’sisHostTrusted(target, tokenHost)then sees matching evil hosts and attaches the env token.
Identified by Warden · security-review · HSR-F8U
There was a problem hiding this comment.
Fixed in #1801 (env token keeps its startup host, fatal errors exit non-zero on a closed stderr, startup pin requires the pinned user).


@sentry/mcp-serverstays 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-serversection below). The CLI exposes the same server assentry 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
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/coretracing, so mcp-core takes no Node SDK dependency.mcpis a real Stricli command (packages/cli/src/commands/mcp.ts) with its flags declared, so help is generated like every other command. Env merging and config validation live inpackages/cli/src/lib/mcp/{args,config}.ts, agent provider and telemetry setup inlib/mcp/server.ts. mcp-core stays free of CLI concepts. The command loadslib/mcp.ts, and that loads the server stack, only when it serves. The command module itself imports nothing from mcp-core (its help copies the skill names, and a test checks them againstALL_SKILLS), so docs generation andpnpm run clistill work without building mcp-core.~/.sentry/mcp.jsoncache,authsubcommands): deleted. CLI auth replaces it.@sentry/mcp-core/transports/stdio. The test client launchessentry mcpfrom CLI source. Smoke tests only target the hosted worker, so they needed no change.ensure-generated.mjsnow sends generator output to stderr, so a firstpnpm run cli mcpcannot write junk into the JSON-RPC stream.onUpstreamUnauthorizedwas dropped before. The refreshed token now reaches the context, and a regression test checks that later calls use it.npx @sentry/mcp-server@latest; the web install instructions are unchanged. User-facing docs mention the shared CLI login but do not steer installs tosentry mcp; themcp-qaskill drives the server from CLI source.docs/operations/stdio-auth.mdanddocs/releases/stdio.mdare rewritten package-first, andstdio-auth.mddocuments that each server process uses one account.Parity
@sentry/mcp-server@sentry/mcp-server(andsentry mcp)--access-token/SENTRY_ACCESS_TOKENSENTRY_AUTH_TOKEN=<token>andSENTRY_FORCE_ENV_TOKEN=1were set, through the same env-token path, so it wins over a stored login. It also replaces an existingSENTRY_AUTH_TOKEN/SENTRY_TOKEN, since the flag is the explicit choice. The flag wins over the env var. The token is sent to the--host/--urltarget as before; an org token (sntrys_) issued for another host is refused withHostScopeError. Prints one deprecation warning on stderr, without the token; the flag value is redacted from telemetry. Docs, help, andserver.jsonnow lead withSENTRY_AUTH_TOKEN(+SENTRY_FORCE_ENV_TOKEN=1, andSENTRY_HOST/SENTRY_URLfor self-hosted).~/.sentry/mcp.jsoncachesentry auth login, orSENTRY_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 loginfrom the package,sentry auth loginfromsentry mcp. The old cache is not read.--host/SENTRY_HOST,--url/SENTRY_URL--host/--url. One difference: anhttp://SENTRY_URLnow maps to--hostplus--insecure-http(the CLI's self-hosted behavior) instead of being rejected.--insecure-http--urland for sentry.io hosts.--mcp-url/MCP_URL,--sentry-dsn/SENTRY_DSN/DEFAULT_SENTRY_DSN--skills/MCP_SKILLS,--all-skills,--disable-skills/MCP_DISABLE_SKILLSseerfrom 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--organization-slug,--project-slug,--experimental--help/-h,--version/-vsentry-mcp --helplistsmcp,auth, andhelp;sentry-mcp mcp --helplists the flags and env vars. A lone-vstill prints the version; anywhere else-vis the CLI's--verbose. Changed: the output is the bare version (0.48.0), like the CLI, instead ofsentry-mcp 0.48.0.--flag=(for example--sentry-dsn=to turn off telemetry), values with a line break--flag valuefirst (splitInlineFlagValues).SENTRY_CLIENT_ID,SENTRY_MCP_AUTH_CACHEsentry-mcp auth login|logout|statusauthcommands:login(with all its flags, including--url),logout,status,list,switch,refresh,token,whoami. They use the CLI session. Account pickers take the account as an argument, since the Ink picker is not bundled.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 lintenforces this with two checks:no-restricted-importsoverride banssentry,sentry/**, and relative CLI paths insidepackages/mcp-coreandpackages/toolkit-core.scripts/check-workspace-deps.mjs(lint:deps) reads every workspacepackage.json. It fails on any cycle, on mcp-core reachingsentryor mcp-cloudflare, and on toolkit-core reachingsentryor mcp-core.The rule is documented in
AGENTS.mdanddocs/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 mcpalready works this way for the access token and refresh callback inServerContext.Release and MCP registry
Every CLI release now publishes
@sentry/mcp-serverat the CLI's version, so the next one goes from 0.42.0 to the CLI's next version (0.48.0). The privatemcp-*packages keep their own versions.packages/cli/script/bump-version.tssetspackages/mcp-server/package.jsonto the CLI version on--preand to the next-devversion on--post. The bundle script fails if the two versions differ.cli-build.ymlbundles, tests, and packs the package and uploads it asmcp-server-npm-package. Thepackages/cliCraft workspace publishes it through a second npm target and attaches it to thecli@<version>GitHub release.packages/mcp-serverCraft workspace, the Release workflow'smcpoption, and the packing steps inmerge-jobs.ymlare removed.mcp-registry.ymlnow runs on stablecli@releases and strips the prefix. A manual run with-f version=Xusescli@X, or the bare tags used up to 0.42.0.mcpName: io.github.getsentry/sentry-mcpis unchanged;server.json's environment variables now declareSENTRY_AUTH_TOKEN(required, secret) andSENTRY_FORCE_ENV_TOKEN(default1) instead ofSENTRY_ACCESS_TOKEN.@sentry/mcp-serverbundle@sentry/mcp-serverstays the recommended, supported package. It ships one dependency-free file built from the CLI's own runner, so the package andsentry mcprun the same code, including self-hosted Sentry.packages/cli/src/mcp-server.tsrunscli.ts'sstartCli()withmcp-server-app.ts, a route map of the CLI'smcp(the default command),auth, andhelp. The runner takes aCliEntrythat loads the application, sosentry(sentry-cli.ts) andsentry-mcpdiffer only in their route map.lib/application.tsholds the Stricli application setup that used to sit inapp.ts.packages/mcp-server/script/bundle.tsbundles the entry intopackages/mcp-server/dist/sentry-mcp.cjs.mcp:isMcpInvocation()findsmcpafter leading global flags, or no command at all wheremcpis the default. The runner then runs Stricli without the CLI's telemetry, recovery middleware, and update check (the server owns stdout and has its own telemetry). The command resolves when the client closes stdin, and only then does the runner close the dispatcher and arm the force-exit backstop.lib/app-identity.tsreplaceslogin-command.tsandusage.ts. Each entry registers its name, and hints (AuthError, refresh and device-flow failures, host-scope errors) and help examples use it:sentry auth login,sentry-mcp auth login, ornpx -y @sentry/mcp-server auth loginwhen npx launched the process (npm_command=execor an_npxpath). MCP telemetry keepsapp.server.distributionatsentry mcpor@sentry/mcp-server.--help,--version, andauth …do not load mcp-core's server, the provider factory, the MCP telemetry, or the stdio transport;commands/mcp.tsimportslib/mcp.tsonly when it serves, andlib/mcp.tsimportslib/mcp/server.tsonly after setup checks pass. A bare--version(or lone-v) returns before the application loads.--helpandauthstill load@sentry/node, because the CLI's command builder and error reporting import it, same assentry --help.261e371f, separate commit): stdio uses@modelcontextprotocol/serverand its stdio transport, like the Cloudflare worker.startStdio()returns aclosedpromise; v2's transport closes when stdin ends, which is what lets the command return.c0243b5athen removes SDK v1 from mcp-core:buildServer()always builds a v2McpServer, thesdkVersionoption is gone, and@modelcontextprotocol/sdkis only a dev dependency of mcp-core (its tests use the in-memory client). The Cloudflare worker keeps its own SDK dependency forStreamableHTTPClientTransport. Bothsentry mcpand the bundle serve 14 tools over v2 and exit 0 within ~13–16 ms of stdin closing.__SENTRY_CLI_SYNTAX_HIGHLIGHT__=false(perf(cli): Load syntax highlighting lazily and allow compiling it out #1765) and a new__SENTRY_CLI_INK_UI__=false(lib/select-prompt.ts) compile out highlight.js/parse5 and Ink;zod/v3resolves to a shared stub (packages/cli/script/lib/zod-v3-stub-plugin.ts) in both this bundle and the CLI's (script/bundle.ts,script/build.ts):@ai-sdk/provider-utilsand@mastra/schema-compatonly reach it for Zod 3 inputs, and nothing we bundle builds Zod 3 schemas. The stub keepsZodTypea class so Mastra'sinstanceofcheck is false, and throws a clear error if a Zod 3 path ever runs. A test bundles the real Mastra client and provider-utils, runs a workflow create/start, and converts Zod 4 and JSON schemas. With SDK v1 gone from mcp-core, the bundle no longer needs a v1 stub and fails if any@modelcontextprotocol/sdkmodule reaches it.pngjs; help falls back to block art), syntax highlighting, 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.13to>=22.15(nativenode:sqlite), and the bin exits early with a clear error on older Node.js.@modelcontextprotocol/sdkmodule) contributes code to the output, or if the file grows past 3.75 MiB (MAX_BUNDLE_BYTES, ~300 KB over the measured size; left as is, since removing SDK v1 saved only ~1 KB here, where it was already stubbed).0e227f71):help.tsimportedsixel.ts, which pulledkitty-image.ts,sixel-image.ts, the generated banner image,pngjs, andjpeg-jsinto this bundle throughhelp.help.tsnow takes aGraphicsBannerthroughsetGraphicsBanner(); the full CLI'sapp.tsregisters the sixel one, andmcp-server-app.tsdoesn't. The bundle check now rejects those modules andpngjs.jpeg-jsstays allowed, because mcp-core's snapshot and attachment tools use it (internal/blob-utils.ts). −45,219 B.test/script/help-graphics-bundle.test.tsbundleshelp.tsand fails against the old import.ed4eddf6, Warden):serveMcp()calledprocess.cwd()for the.sentryclirctrust gate added in this PR, so the server failed to start from a deleted worktree.mcpCommandnow passesthis.cwd(resolveCwd()with thePWDfallback).--versionguard (3392ea03, perf(cli): Give__completeits own light entry point #1762):test/script/cli-startup.test.tsnow also checks thatmcp-server.tsloads no@sentry/*module eagerly. The entry graph is 14 source modules and lazily loadsmcp-server-app.ts(197). Most of the--versioncost is parsing the 3.5 MB file (read + compile alone: 57 MB / 89 ms; bare Node 42 MB / 19 ms), so a separate version entry is a possible follow-up, not done here.packages/mcp-server/test/bundle.test.mjsruns the built file:initializeplustools/listover stdio with--sentry-dsn=(withSENTRY_AUTH_TOKEN, and with the deprecated--access-token, checking the warning is on stderr once and never echoes the token), exit on stdin close, no runtime dependencies, bare--versionand-v,--helplisting exactlymcp/auth/help,mcp --helpexamples namingsentry-mcp, the login hint with and without npx,auth status, and rejecting other CLI commands.cli-build.ymlbundles, tests, and packs the package next to the CLI's npm package.The old
@sentry/mcp-server/transports/stdioexport 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: do not run
npm deprecate. Users on Node.js 22.13 or 22.14 need to upgrade Node.js.Measurements (Node 22, this sandbox; startup rows are the median of 7 runs, idle RSS is 5 runs)
53fc92fe)9977bb0ca98cb249; 3,689,513 B at0a864625; 3,688,917 B after #1770; 3,643,698 B with the banner left out; 3,624,475 B after #1771)sentry-mcp --versionsentry-mcp --helpsentry-mcp auth status(logged out)initialize+tools/listAfter #1771 (
88c11b37, median of 9):--version85 MB / 129 ms,-v85 MB / 130 ms,--help158 MB / 341 ms,auth status164 MB / 505 ms, the same as the pre-banner-fix bundle within noise (85 / 126, 85 / 125, 158 / 331, 165 / 490).--help,auth status, and idle RSS in the table were measured at7a2f0a2a; the two later commits only add the-vfast path and move a string list, and the bundle grew 89 bytes.CLI
dist/index.cjs: 7,426,174 B beforec0243b5a→ 7,203,971 B without SDK v1 (−222 KB; ajv and most of zod-to-json-schema go with it) → 7,142,739 B with thezod/v3stub (−61 KB) → 7,143,333 B ata98cb249→ 7,021,265 B at0a864625(#1762 moves the__completepath into a separate 331,140 Bdist/complete.cjs) → 7,001,805 B plus a 259,731 Bcomplete.cjsafter #1771.The bundle ends up about the same size as before even with
550 KB of savings (Zod locales −264 KB, SDK v1 and Zod 3 −280 KB), because it now carries the CLI runner, the fullauthcommands, and generated help. Largest inputs:@sentry/api482 KB,@modelcontextprotocol/server291 KB (156 KB of it ajv),@sentry/server-utils242 KB,zod193 KB, mcp-core's OTel semantics 187 KB,@sentry/core162 KB.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.tstoformat: ["esm"]. mcp-core is"type": "module", and everyexportsentry maps onlytypesanddefault(.js) with norequirecondition. The CLI's esbuild bundle (CJS output) resolvesdefaultand converts the ESM itself, andscripts/check-build-imports.tsnow checksdist/server.js. This PR does not touch the build format.Verification
pnpm run tsc,pnpm run lint(includeslint:deps), and CLIci:policypass.pnpm run test: toolkit-core, mcp-core, mcp-cloudflare, mcp-test-client, docs-mcp, local, and cli-docs pass. CLI: 12,807 pass; the 6 failures are chmod-based tests (completionsEACCES/EPERM, read-only DB repair, upgrade lock permissions, unreadable DSN file, file-changes I/O) that fail in this sandbox's filesystem and do not touch this diff. The MCP, auth, app-identity, startup, help, and completion suites pass.pnpm --filter sentry run generate:docspasses withpackages/mcp-core/distremoved, which is thesentry-cli-docsCI condition.test/lib/mcp/args.test.tsparses with the command's real Stricli parameters (test/lib/mcp/parse-flags.ts);mcp-start.test.tsandmcp-auth.test.tsdriveserveMcp()andwithConfiguredTarget()through it;mcp-command.test.tscoversisMcpInvocation, the{mcp, auth, help}app, no CLI telemetry formcp, teardown only after the server returns, setup failures,--help, the help's skill list againstALL_SKILLS, and unknown flags;app-identity.test.tscovers names and npx hints.usage*.test.ts,mcp/auth.test.ts, andmcp-run.test.tsare deleted with their modules.pnpm --filter @sentry/mcp-server run bundle(withSENTRY_AUTH_TOKENunset) builds 3,689,513 B at0a864625(242,647 B under the 3.75 MiB limit);test:bundlepasses 13/13.node dist/bin.cjs mcpanswerstools/listwith 14 tools over SDK v2 and exits 0 when stdin closes. With--access-token, stdout carries only JSON-RPC frames and stderr has the one deprecation line, without the token. CLItest/e2e/bundle.test.ts+library.test.tspass 26/26.a98cb249:pnpm run lintpasses;tscpasses for cli, mcp-core, mcp-cloudflare, mcp-server-evals, and mcp-test-client; mcp-core (1,890), mcp-cloudflare (443), and mcp-test-client (82) tests pass. CLItest/lib test/commands test/types test/script: 12,816 pass, 11 fail, and all 11 fail the same way without this change (6 chmod-based tests, plus 5 login-hint wording tests inerrors,oauth, andauto-login-host-guardthat seenpx -y sentrybecause the sandbox runs vitest through npx).main(0a864625;5a72e8a3has the same tree):pnpm run lintandpnpm run tscpass. CLItest/script, completion, db, logger, telemetry, MCP, app-identity, and startup suites: 1,237 pass; the 3 failures are the sandbox-only chmod/read-only tests above (completionsEACCES/EPERM, read-only DB repair). Both bundles build withSENTRY_AUTH_TOKENunset:sentry-mcp.cjs3,689,513 B with no highlight.js in the output, CLIdist/index.cjs7,021,265 B plusdist/complete.cjs331,140 B. CLItest/e2e/bundle.test.ts+library.test.tspass 27/27, including perf(cli): Give__completeits own light entry point #1762's check that__completenever loadsindex.cjs.88c11b37):pnpm run lintandpnpm run tscpass. Help/sixel, MCP command/start/auth,lib/mcp/*, startup, completions, list-command, route-registry, schema, app-identity, and bundle-plugin suites: 258 pass; the 2 failures are the sandbox chmod tests incompletions(EACCES/EPERM;completions.tsand its test matchmain). WithSENTRY_AUTH_TOKENunset,sentry-mcp.cjsbuilds at 3,624,475 B (307 KB under the limit) andtest:bundlepasses 13/13; the CLI bundle builds (index.cjs7,001,805 B,index.mjs6,991,272 B,complete.cjs259,731 B). CLI e2ebundle,completion,auth, andtelemetry-exit: 27/28 in one parallel run, where the exit-timing test took 2.36 s against its 2 s limit; it passed twice on its own.--access-tokentests (mcp-start.test.ts): it serves the same token and refresh result asSENTRY_AUTH_TOKEN+SENTRY_FORCE_ENV_TOKEN=1, overrides a stored login before and after startup, overridesSENTRY_AUTH_TOKEN/SENTRY_TOKEN, leavesprocess.envuntouched, prints the hint once to stderr and nothing to stdout, and keeps the token out of the hint and ofMalformedAuthTokenError/HostScopeError. The existing self-hosted, org-token, and.sentryclirccases still pass.craft config --workspace packages/cliand the release checks above are unchanged from the earlier verification.Noticed, not changed:
serverInfo.versionininitializereports mcp-core's package version (0.42.0), as it did before this PR, not the CLI/package version.via @BYK.
--
View Session in Sentry