Skip to content

Run the command surface on the hosted MCP through the CLI SDK #1899

Open

Description

@sentry-junior

Part of #1357. Plan: cli-first-mcp tasks 6.4 and 6.5 (design, tasks). Depends on #1882, #1897, #1898, #1890.

Scope

  • In mcp-cloudflare's Hono app, create one SDK instance per request with the OAuth grant's token and the session constraints, persistence off.
  • Serve search_sentry and the execute tools from command-catalog.json, next to the catalog, listing only commands the hosted build can run.

Done when

Spike findings (#1882)

The SDK bundles and runs on workerd; 10 core command calls pass cold and warm after small fixes. Needed here:

  • Compatibility date 2026-01-28 or later. Every date up to 2026-01-01 fails (pngjs calls util.inherits on a stream class older polyfills lack). Check the rest of the hosted worker on the new date.
  • A hosted entry point whose route loaders cover only exposed commands. ROUTE_LOADERS imports every command today, which pulls in the Ink sidecar (lib/init/ui/ink-ui.ts, with { type: "file" }) that wrangler can't bundle, and roughly half the bundle is code hosted never runs (highlight.js, the sentry mcp server stack, init's AI libraries, @sentry/node).
  • Build fixes: define import.meta.url (11 modules call createRequire(import.meta.url) at load), and add a createRequire banner for CommonJS deps ("Dynamic require of util").
  • Size: 6,971 KiB raw / 1,989 KiB gzip minified (hosted today: 5,092 / 975). Limit is 64 MiB uncompressed. Startup CPU ~65 ms; first call in a fresh isolate 155–215 ms, warm 6–28 ms.
  • trace view makes one request per span (853 on a large fixture): under the subrequest limit, but slow. Worth a batched path before hosted serves it.
  • Commands that fall back to DSN detection need org and project from the session constraints.

via @BYK.

--

View Session in Sentry

Activity

  1. added
    enhancementNew feature or request
    MCPSentry MCP tools, transports, and documentation
    on Nov 3, 2026
  2. linear-code commented on Nov 3, 2026

    @linear-code
  3. sentry-junior commented on Nov 3, 2026

    @sentry-junior
    ContributorAuthor

    #1918 (merged, 77edf6b) changes how the hosted entry point should be built. The workerd spike (#1882) planned a hosted variant of the generated route-loaders.ts. That generator is gone. src/command-manifest.ts (COMMAND_MANIFEST) now holds an import() loader for every top-level route, and sdk-app.ts loads only the routes a call runs.

    The hosted bundle still can't use sdk-app.ts as it is:

    • app-for-args.ts imports COMMAND_MANIFEST, whose loaders are literal import()s. Bundlers follow those, so the bundle still includes init (and its Ink sidecar, which wrangler can't bundle), wasm-split, sourcemap, debug-files and the rest. Filtering the manifest at runtime doesn't shrink the bundle.
    • loadSdkApp falls back to import("./app.js") for help, schema, cli and unknown names, which pulls in the whole tree.

    Proposed approach:

    1. A checked-in hosted manifest: the subset of COMMAND_MANIFEST whose top-level route has at least one exposed command in command-catalog.json (feat(cli): Generate command-catalog.json from the route tree #1919). A test keeps the two in sync, the same way command-manifest.test.ts checks app.ts.
    2. Let loadSdkApp/createSentrySDK take a manifest, with no full-app fallback. On hosted, a name outside the manifest is refused instead of loading app.js.
    3. Exposure stays per command (feat(cli): Add a permission class and an MCP exposure to every command #1916). Granularity is per top-level route, because a group's index imports all its subcommands. Mixed groups (release, replay, event, react-native) still bundle their stdio-only subcommands, and the executor refuses them. Check that those modules have no load-time Node-only work.

    The module-level loaded cache in sdk-app.ts holds only route code, so sharing it across requests looks safe. It still belongs on #1898's audit list.

  4. sentry-junior commented on Nov 3, 2026

    @sentry-junior
    ContributorAuthor

    Correction to my previous comment, checked against the #1919 catalog. react-native isn't a mixed group: every subcommand in it is stdio-only. Only four groups are mixed:

    group stdio-only subcommands
    auth list, status
    event send
    release propose-version, set-commits
    replay download

    That's 6 subcommands, about 1.6k lines. None of them does Node-only work when it loads. They import lib/db, lib/git, node:fs/promises and @sentry/core, which the bundle needs for other commands anyway. Twelve top-level routes are entirely stdio-only and drop out of the hosted manifest: build, cli, code-mappings, dart-symbol-map, debug-files, info, init, proguard, react-native, snapshots, sourcemap and wasm-split.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    MCPSentry MCP tools, transports, and documentationenhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions