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 64 commits into
mainfrom
ref/retire-mcp-server-package
Open

sentry-junior[bot] wants to merge 64 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

Base: #1763 (Zod English locale), #1764 (lazy server stack), #1765 (lazy syntax highlighting), #1762 (light __complete entry) and #1766 (route registry) are now on main and merged into this branch with merge commits (cc2ae2e7; 0a864625 for #1762; 5a72e8a3 for #1766, which leaves the tree unchanged because this branch already carried #1766; b7a34abd for #1770 and 23a92f9e for #1771). With #1766, help.ts, completions.ts, list-command.ts, and schema read routes from lib/route-registry.ts, and buildCliApplication() calls setRoutes() for both app.ts and mcp-server-app.ts; those files and the REQUIRE_ALIAS_FILTER (no list-command) match main, so no interim workaround is left. With #1762, shell completion runs from the bin entry points, so CliEntry only carries loadApp; the branch's own completion hook is gone. #1764 only touched packages/mcp-server/src/index.ts, which this PR deletes; its lazy-loading idea lives in the unified entry here. This PR's own changes are 261e371f (MCP SDK v2), ffeaf9ba (unified entry), 7a2f0a2a (stdio-auth docs), 69e65252 (lone -v), 9977bb0c (no mcp-core import in the command tree), c0243b5a (MCP SDK v1 removed from mcp-core), 07b8d4c8 (zod/v3 stub in both bundles), ccdd87ab (--access-token redacted from telemetry), a98cb249 (--access-token as a deprecated alias), 0e227f71 (help's kitty/sixel banner out of the bundle), ed4eddf6 (start the server when its cwd was deleted), 3392ea03 (startup guard for the bundle's --version entry), and 88c11b37 (bundle size note).

@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: mcp is 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 in packages/cli/src/lib/mcp/{args,config}.ts, agent provider and telemetry setup in lib/mcp/server.ts. mcp-core stays free of CLI concepts. The command loads lib/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 against ALL_SKILLS), so docs generation and pnpm run cli still work without building mcp-core.
  • 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 Deprecated alias. Runs as if SENTRY_AUTH_TOKEN=<token> and SENTRY_FORCE_ENV_TOKEN=1 were set, through the same env-token path, so it wins over a stored login. It also replaces an existing SENTRY_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/--url target as before; an org token (sntrys_) issued for another host is refused with HostScopeError. Prints one deprecation warning on stderr, without the token; the flag value is redacted from telemetry. Docs, help, and server.json now lead with SENTRY_AUTH_TOKEN (+ SENTRY_FORCE_ENV_TOKEN=1, and SENTRY_HOST/SENTRY_URL for self-hosted).
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 Stricli's generated help. sentry-mcp --help lists mcp, auth, and help; sentry-mcp mcp --help lists the flags and env vars. A lone -v still prints the version; anywhere else -v is the CLI's --verbose. Changed: the output is the bare version (0.48.0), like the CLI, instead of sentry-mcp 0.48.0.
--flag= (for example --sentry-dsn= to turn off telemetry), values with a line break Same. Stricli does not read these joined forms, so the runner splits them into --flag value first (splitInlineFlagValues).
Unknown flags or positionals Rejected by Stricli (exit 252)
SENTRY_CLIENT_ID, SENTRY_MCP_AUTH_CACHE Ignored, because the device flow is gone
sentry-mcp auth login|logout|status The CLI's real auth commands: 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 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.

Release and MCP registry

Every CLI release now publishes @sentry/mcp-server at the CLI's version, so the next one goes from 0.42.0 to the CLI's next version (0.48.0). The private mcp-* packages keep their own versions.

  • packages/cli/script/bump-version.ts sets packages/mcp-server/package.json to the CLI version on --pre and to the next -dev version on --post. The bundle script fails if the two versions differ.
  • cli-build.yml bundles, tests, and packs the package and uploads it as mcp-server-npm-package. The packages/cli Craft workspace publishes it through a second npm target and attaches it to the cli@<version> GitHub release.
  • The separate packages/mcp-server Craft workspace, the Release workflow's mcp option, and the packing steps in merge-jobs.yml are removed.
  • mcp-registry.yml now runs on stable cli@ releases and strips the prefix. A manual run with -f version=X uses cli@X, or the bare tags used up to 0.42.0. mcpName: io.github.getsentry/sentry-mcp is unchanged; server.json's environment variables now declare SENTRY_AUTH_TOKEN (required, secret) and SENTRY_FORCE_ENV_TOKEN (default 1) instead of SENTRY_ACCESS_TOKEN.

@sentry/mcp-server bundle

@sentry/mcp-server stays the recommended, supported package. It ships one dependency-free file built from the CLI's own runner, so the package and sentry mcp run the same code, including self-hosted Sentry.

  • Entry: packages/cli/src/mcp-server.ts runs cli.ts's startCli() with mcp-server-app.ts, a route map of the CLI's mcp (the default command), auth, and help. The runner takes a CliEntry that loads the application, so sentry (sentry-cli.ts) and sentry-mcp differ only in their route map. lib/application.ts holds the Stricli application setup that used to sit in app.ts. packages/mcp-server/script/bundle.ts bundles the entry into packages/mcp-server/dist/sentry-mcp.cjs.
  • Running mcp: isMcpInvocation() finds mcp after leading global flags, or no command at all where mcp is 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.
  • Names: lib/app-identity.ts replaces login-command.ts and usage.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, or npx -y @sentry/mcp-server auth login when npx launched the process (npm_command=exec or an _npx path). MCP telemetry keeps app.server.distribution at sentry mcp or @sentry/mcp-server.
  • Lazy loading (from perf(mcp): Load the server stack only when the stdio server starts #1764): --help, --version, and auth … do not load mcp-core's server, the provider factory, the MCP telemetry, or the stdio transport; commands/mcp.ts imports lib/mcp.ts only when it serves, and lib/mcp.ts imports lib/mcp/server.ts only after setup checks pass. A bare --version (or lone -v) returns before the application loads. --help and auth still load @sentry/node, because the CLI's command builder and error reporting import it, same as sentry --help.
  • MCP SDK v2 (261e371f, separate commit): stdio uses @modelcontextprotocol/server and its stdio transport, like the Cloudflare worker. startStdio() returns a closed promise; v2's transport closes when stdin ends, which is what lets the command return. c0243b5a then removes SDK v1 from mcp-core: buildServer() always builds a v2 McpServer, the sdkVersion option is gone, and @modelcontextprotocol/sdk is only a dev dependency of mcp-core (its tests use the in-memory client). The Cloudflare worker keeps its own SDK dependency for StreamableHTTPClientTransport. Both sentry mcp and the bundle serve 14 tools over v2 and exit 0 within ~13–16 ms of stdin closing.
  • Size work: perf(cli): Bundle only Zod's English locale #1763's Zod English-locale plugin; __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/v3 resolves 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-utils and @mastra/schema-compat only reach it for Zod 3 inputs, and nothing we bundle builds Zod 3 schemas. The stub keeps ZodType a class so Mastra's instanceof check 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/sdk module reaches it.
  • Left out: the other CLI commands, agent skills, shell completions, the sixel dashboard and help's kitty/sixel image banner (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.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 (or any @modelcontextprotocol/sdk module) 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).
  • Help banner (0e227f71): help.ts imported sixel.ts, which pulled kitty-image.ts, sixel-image.ts, the generated banner image, pngjs, and jpeg-js into this bundle through help. help.ts now takes a GraphicsBanner through setGraphicsBanner(); the full CLI's app.ts registers the sixel one, and mcp-server-app.ts doesn't. The bundle check now rejects those modules and pngjs. jpeg-js stays allowed, because mcp-core's snapshot and attachment tools use it (internal/blob-utils.ts). −45,219 B. test/script/help-graphics-bundle.test.ts bundles help.ts and fails against the old import.
  • Deleted cwd (ed4eddf6, Warden): serveMcp() called process.cwd() for the .sentryclirc trust gate added in this PR, so the server failed to start from a deleted worktree. mcpCommand now passes this.cwd (resolveCwd() with the PWD fallback).
  • --version guard (3392ea03, perf(cli): Give __complete its own light entry point #1762): test/script/cli-startup.test.ts now also checks that mcp-server.ts loads no @sentry/* module eagerly. The entry graph is 14 source modules and lazily loads mcp-server-app.ts (197). Most of the --version cost 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.
  • Tests and CI: packages/mcp-server/test/bundle.test.mjs runs the built file: initialize plus tools/list over stdio with --sentry-dsn= (with SENTRY_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 --version and -v, --help listing exactly mcp/auth/help, mcp --help examples naming sentry-mcp, the login hint with and without npx, auth status, and rejecting other CLI commands. cli-build.yml bundles, tests, and packs the package next to the CLI's npm 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: 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)

Before restack (53fc92fe) 9977bb0c
Bundle 3,663,084 B 3,690,124 B (3,689,429 B at a98cb249; 3,689,513 B at 0a864625; 3,688,917 B after #1770; 3,643,698 B with the banner left out; 3,624,475 B after #1771)
sentry-mcp --version 137 MB / ~335 ms (sibling scratch) 86 MB / 133–138 ms
sentry-mcp --help – 153 MB / 352 ms
sentry-mcp auth status (logged out) – 158 MB / 444 ms
Idle server after initialize + tools/list – 152–153 MB RSS

After #1771 (88c11b37, median of 9): --version 85 MB / 129 ms, -v 85 MB / 130 ms, --help 158 MB / 341 ms, auth status 164 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 at 7a2f0a2a; the two later commits only add the -v fast path and move a string list, and the bundle grew 89 bytes.

CLI dist/index.cjs: 7,426,174 B before c0243b5a → 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 the zod/v3 stub (−61 KB) → 7,143,333 B at a98cb249 → 7,021,265 B at 0a864625 (#1762 moves the __complete path into a separate 331,140 B dist/complete.cjs) → 7,001,805 B plus a 259,731 B complete.cjs after #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 full auth commands, and generated help. Largest inputs: @sentry/api 482 KB, @modelcontextprotocol/server 291 KB (156 KB of it ajv), @sentry/server-utils 242 KB, zod 193 KB, mcp-core's OTel semantics 187 KB, @sentry/core 162 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.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 tsc, pnpm run lint (includes lint:deps), and CLI ci:policy pass.
  • 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 (completions EACCES/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:docs passes with packages/mcp-core/dist removed, which is the sentry-cli-docs CI condition.
  • New or rewritten tests: test/lib/mcp/args.test.ts parses with the command's real Stricli parameters (test/lib/mcp/parse-flags.ts); mcp-start.test.ts and mcp-auth.test.ts drive serveMcp() and withConfiguredTarget() through it; mcp-command.test.ts covers isMcpInvocation, the {mcp, auth, help} app, no CLI telemetry for mcp, teardown only after the server returns, setup failures, --help, the help's skill list against ALL_SKILLS, and unknown flags; app-identity.test.ts covers names and npx hints. usage*.test.ts, mcp/auth.test.ts, and mcp-run.test.ts are deleted with their modules.
  • pnpm --filter @sentry/mcp-server run bundle (with SENTRY_AUTH_TOKEN unset) builds 3,689,513 B at 0a864625 (242,647 B under the 3.75 MiB limit); test:bundle passes 13/13.
  • The CLI bundle builds; node dist/bin.cjs mcp answers tools/list with 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. CLI test/e2e/bundle.test.ts + library.test.ts pass 26/26.
  • At a98cb249: pnpm run lint passes; tsc passes 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. CLI test/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 in errors, oauth, and auto-login-host-guard that see npx -y sentry because the sandbox runs vitest through npx).
  • After merging main (0a864625; 5a72e8a3 has the same tree): pnpm run lint and pnpm run tsc pass. CLI test/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 (completions EACCES/EPERM, read-only DB repair). Both bundles build with SENTRY_AUTH_TOKEN unset: sentry-mcp.cjs 3,689,513 B with no highlight.js in the output, CLI dist/index.cjs 7,021,265 B plus dist/complete.cjs 331,140 B. CLI test/e2e/bundle.test.ts + library.test.ts pass 27/27, including perf(cli): Give __complete its own light entry point #1762's check that __complete never loads index.cjs.
  • After merging fix(cli): Repair DB schema when telemetry is off #1770 and perf(cli): Replace consola with a small in-house logger #1771 (88c11b37): pnpm run lint and pnpm run tsc pass. 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 in completions (EACCES/EPERM; completions.ts and its test match main). With SENTRY_AUTH_TOKEN unset, sentry-mcp.cjs builds at 3,624,475 B (307 KB under the limit) and test:bundle passes 13/13; the CLI bundle builds (index.cjs 7,001,805 B, index.mjs 6,991,272 B, complete.cjs 259,731 B). CLI e2e bundle, completion, auth, and telemetry-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-token tests (mcp-start.test.ts): it serves the same token and refresh result as SENTRY_AUTH_TOKEN + SENTRY_FORCE_ENV_TOKEN=1, overrides a stored login before and after startup, overrides SENTRY_AUTH_TOKEN/SENTRY_TOKEN, leaves process.env untouched, prints the hint once to stderr and nothing to stdout, and keeps the token out of the hint and of MalformedAuthTokenError/HostScopeError. The existing self-hosted, org-token, and .sentryclirc cases still pass.
  • craft config --workspace packages/cli and the release checks above are unchanged from the earlier verification.

Noticed, not changed: serverInfo.version in initialize reports 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

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.

1 Skipped Deployment
Project Deployment Actions Updated
sentry-local Skipped Skipped Nov 1, 2026 7:03pm 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 Resolved
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 Resolved
Comment thread packages/cli/src/lib/mcp.ts Resolved
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 Resolved
@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.

Stale Bugbot comment from a previous run.

Comment thread packages/cli/src/lib/mcp/run.ts Resolved
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 and others added 3 commits October 31, 2026 15:25
Adds `mcp-server.ts` to #1762's startup guard. The entry's eager graph is
14 source modules with no `@sentry/*` SDK import, so `--version` and a lone
`-v` return before `@sentry/node` or OpenTelemetry load; the guard keeps it
that way.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Brings in #1771 (in-house logger replacing consola). The one conflict is
`preloadProjectContext`, which this branch moved to `lib/project-context.ts`;
#1771's comment update is applied there.

@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.

sentry-junior Bot and others added 2 commits November 1, 2026 00:14
Brings in #1774 (agents 0.32.0, MCP SDK 1.32.2). pnpm-lock.yaml conflicted
and was regenerated with pnpm install; mcp-core keeps
@modelcontextprotocol/sdk as a dev dependency only.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
markdown-plain.ts stood in for markdown.ts when the standalone
@sentry/mcp-server bundle only ran the login flow. Since the bundle runs
the CLI's full auth and help commands (ffeaf9b), their formatters need
renderMarkdown, renderTextTable, colorTag, and escapeMarkdownInline, so
nothing aliases the stub anymore.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>

@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/cli.ts Resolved
The runner now hands the whole argv to Stricli, and `mcp` declares no
--json or --fields (it has no output config), so `sentry --json mcp`
and `sentry-mcp --json` failed to parse. The old interceptor dropped
leading global flags. Drop leading --json, --no-json, and --fields
before the command on the MCP path. Flags after `mcp` still belong to
the server, and the rest of the CLI is unchanged.
`Sentry.init` calls `process.cwd()`, which throws ENOENT (uv_cwd) when
the server starts in a deleted directory, so `sentry mcp` and
`sentry-mcp` crashed before serving. ed4eddf fixed only the
`.sentryclirc` trust check on that path.

Check the working directory before `Sentry.init`. When it is gone, log
at debug level and serve without telemetry. Add a unit test that makes
`process.cwd()` throw and a bundle test that serves MCP from a deleted
directory.
The tool prediction scorer spread `process.env` into the server it
starts, so an inherited deprecated `SENTRY_ACCESS_TOKEN` replaced the
mock `SENTRY_AUTH_TOKEN`. When that token was scoped to another host,
the server refused the sentry.io target and tool discovery failed. Drop
`SENTRY_ACCESS_TOKEN` from the child environment.

The scorer also ran `pnpm exec sentry-mcp`, which no longer resolves
from the evals package since it stopped depending on
`@sentry/mcp-server`. Run `sentry mcp` from the workspace CLI source,
as mcp-test-client does.
Comment thread packages/cli/src/lib/mcp/server.ts Resolved
Comment thread docs/architecture/overview.md Resolved
Comment thread docs/operations/embedded-agents.md Resolved
Comment thread docs/releases/stdio.md Resolved
Brings in #1773 (@sentry/logger) and #1759 (flag completion kinds).

Conflicts:
- .craft.yml, merge-jobs.yml, release.yml: keep main's logger release
  workspace, branch, packaging, and product; keep the removal of the
  separate mcp release (the CLI release publishes @sentry/mcp-server).
- packages/cli/package.json: depend on @sentry/logger and
  @sentry/mcp-core, not the retired @sentry/mcp-server workspace.
- pnpm-lock.yaml: regenerated with pnpm install.

Follow-ups for the merged tree:
- `sentry mcp` string flags parse with parseText, as #1759's lint rule
  requires.
- completion-target.ts now imports commands/local/loopback.ts, so allow
  that leaf module in the mcp-server bundle's CLI-only input check.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
A leftover handle, such as a second Sentry client's runtime metrics
interval, would keep the stdio process alive after the client
disconnects. Give the bundle smoke test's stdio helper an exit timeout,
and add a case that serves with telemetry on through an explicit DSN.

The tests with a fresh config dir now pass only SENTRY_AUTH_TOKEN: with
no stored login, the env token needs no SENTRY_FORCE_ENV_TOKEN.
`getAuthConfig()` falls back to `SENTRY_AUTH_TOKEN` when no login is
stored, so the force flag only matters to use the env token over an
existing login. Remove it from the example MCP client configs and
commands, and from the registry manifest, and say when to add it.

The eval scorer now gives `sentry mcp` an empty `SENTRY_CONFIG_DIR`
instead of forcing the mock token, so a developer's stored login is
never read.

The deprecated `--access-token` alias keeps forcing its token, as
`@sentry/mcp-server` always did, and so does mcp-test-client for an
explicit `--access-token`.
…lags

`sentry mcp` and `@sentry/mcp-server` now scope calls with `--org` and
`--project`, the flags every other CLI command takes, instead of
`--organization-slug` and `--project-slug`. The command owns both flags,
so they reach the server instead of being mapped onto
SENTRY_ORG/SENTRY_PROJECT like on other commands.

The old names still work, hidden from help, and print a deprecation
warning on stderr. Passing a new flag and its alias with different
values is an error. `--access-token`'s help now points at
SENTRY_AUTH_TOKEN alone.
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.

@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 server.json Resolved
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.

@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.ts Resolved
…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>

@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 b1dc826. Configure here.

Comment thread packages/cli/src/lib/mcp/server.ts Resolved
`--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.

This branch was successfully deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants