Skip to content

feat(cli): Generate command-catalog.json from the route tree - #1919

Open
sentry-junior[bot] wants to merge 6 commits into
feat/command-access-metadatafrom
feat/command-catalog
Open

sentry-junior[bot] wants to merge 6 commits into
feat/command-access-metadatafrom
feat/command-catalog

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Stacks on #1916 (#1880). The base is its branch; retarget to main once it merges.

The CLI build now writes each command's MCP metadata to JSON, so both MCP servers read the same generated data and list the same commands with the same schemas (cli-first-mcp task 1.3). Following #1914, runtime reads generated per-command data instead of computing it: neither sentry mcp nor the hosted server on Workers builds schemas from the route tree at runtime.

generate:command-catalog, which runs in generate:docs (build, typecheck, test:unit), writes packages/mcp-core/src/command-catalog.json from src/lib/command-catalog.ts. That module builds on buildCommandInfo and publicTargetPaths from lib/introspect.ts; only the generator and the test use it. mcp-core exports the result, with its types, as @sentry/mcp-core/command-catalog. The built module has no imports, so mcp-cloudflare can import it without pulling in the CLI, and mcp-core still never imports the CLI.

Shape: { commands: [...] }, sorted by path. Each entry has path, brief, permission, exposure, parameters (JSON Schema 2020-12), completions (completion kinds of positionals and flags), localPathFlags, examples, outputFields, and apiOperations (from command-api.json).

  • parameters has two properties. positional is an array (prefixItems for tuples, items for variadics). flags is keyed by CLI flag name, which is the shape the SDK's invoke(path, flags, positional) takes. Flat names wouldn't work because positional placeholders collide with flag names (for example org view and trial list both have an org positional and an --org flag). Hidden flags are left out. Only Stricli enum flags become enum. The values of a choice parser are suggestions, since the parser accepts other values (--cursor takes a raw cursor), so they go in examples. Number typing follows the SDK generator.
  • fullDescription is left out. It repeats the examples and the JSON fields section, and including it added about 150 KB.

Hidden commands are left out. No MCP server lists or runs them. Leaving them in the hosted bundle would only invite someone to expose them by mistake. stdio-only commands stay in, with their exposure, so a test can compare both servers' lists from one source. Hosted filters to exposed. That leaves 115 commands: 81 exposed and 34 stdio-only.

The file is committed (about 474 KB pretty-printed, 289 KB minified; toolDefinitions.json is 374 KB) and excluded from oxfmt. check:command-catalog in ci:policy fails when it is stale. The git diff --exit-code step after the CLI project's tests catches it as well, because the tests regenerate the file. test/lib/command-catalog.test.ts checks three things: the committed file equals the catalog of the current tree; each non-hidden command from extractAllRoutes has an entry with matching brief, permission, exposure, examples, output fields, local-path flags, API operations, flags, and positionals; and the JSON Schema of a fixture command.

Open for the execute tools (#1890): the stdio server and the SDK may want camelCase parameter names instead of CLI flag names. The catalog also keeps injected flags such as json and fields, so the executor decides which ones to strip.

outputFields comes from #1923's generated field data: introspection reads each command's __jsonFields, so the catalog has no derivation of its own.

Closes #1881

via @BYK.

--

View Session in Sentry

sentry-junior Bot and others added 2 commits November 3, 2026 22:29
The hosted MCP cannot load the CLI's route tree, so `generate:command-catalog`
writes the agent-facing metadata of every command whose exposure is not
`hidden` to `packages/mcp-core/src/command-catalog.json`: path, brief,
permission class, exposure, parameters as JSON Schema, completion kinds,
local-path flags, examples, output fields, and API operations. mcp-core
exports it as `@sentry/mcp-core/command-catalog`, so mcp-cloudflare can
import it without the CLI.

The file is committed. `generate:docs` regenerates it, and
`check:command-catalog` in `ci:policy` fails when it is stale. A test checks
it against `lib/introspect.ts` for the full tree.

Closes #1881

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
…to feat/command-catalog

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

vercel Bot commented Nov 3, 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 Nov 4, 2026 9:50am UTC

Request Review

@github-actions github-actions Bot added the risk: medium PR risk score: medium label Nov 3, 2026
The repository quality job lints before building mcp-core, so its types
resolve to error types there. Drop the unions with them and give the
test's sorts a compare function.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
sentry-junior Bot and others added 2 commits November 3, 2026 22:53
…to feat/command-catalog

# Conflicts:
#	packages/cli/package.json

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
Both servers read command-catalog.json instead of building schemas at
runtime (#1914), so the comments no longer tie the catalog to the hosted
server alone.

Co-Authored-By: BYK <126780+BYK@users.noreply.github.com>
# Conflicts:
#	packages/cli/package.json

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

This branch had an error being deployed

1 failed deployment
Preview — 3ba73e69 Deployed Nov 4, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: medium PR risk score: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generate command-catalog.json from the CLI route tree

1 participant