* feat(cli,tui): normalize --catalog / --config with web; update --help (#1347) Bring the CLI and TUI in line with the web catalog vs read-only session model introduced in #1481/#1483, and close the outstanding --help item from #1347. Core (core/mcp/node/config.ts): - Add `catalogPath` to ServerConfigOptions (writable catalog slot). - `resolveServerSource()` picks the active source: `--catalog` (writable, seed-if-missing) wins over `--config` (read-only, error-if-missing). - Writable sources seed an empty `{"mcpServers":{}}` on first run (matches the web backend) instead of erroring; read-only `--config` still errors. - `serverSourceConflict()` shared conflict matrix (mirrors run-web): --catalog/--config mutually exclusive; neither combines with an ad-hoc target. - `readServerListFile()` public loader for runners (TUI) needing the raw map. - Rename `withDefaultConfigPath` → `withDefaultCatalogPath`; the no-flag default now fills the writable catalog slot, not --config. CLI / TUI: - Add `--catalog <path>` (+ MCP_CATALOG_PATH) and re-document `--config` as a read-only session in --help. - Enforce the shared conflict matrix before resolution. Full writable persistence/CRUD threading remains deferred to #1482 / #1432 (CLI/TUI are read consumers today; the split surfaces as seed- vs error-on-missing). Tests: core resolution matrix (source/conflict/seed/read-only), CLI catalog + conflict integration tests, TUI loadTuiServers unit tests. READMEs updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(launcher): add smoke:cli + smoke:tui e2e launcher smokes (#1347) The launcher smokes only checked `--help` for --cli/--tui; nothing exercised the launcher → CLI/TUI → core path on the built artifact (only smoke:web did, for web). Add two end-to-end smokes wired into validate:launcher between smoke:launcher and smoke:web: - smoke:cli (scripts/smoke-cli.mjs): runs `--cli` against the bundled stdio test server via a temp --catalog and asserts tools/list returns the tools, plus the #1347 resolution paths — default-catalog seed-on-missing, read-only --config error-without-seed, and the --catalog/--config conflict. - smoke:tui (scripts/smoke-tui.mjs): launches `--tui --catalog <temp>` and asserts the Ink app renders its first frame ("MCP Servers") within a timeout, then SIGTERMs it (shallow boot/render check). Both build test-servers/build on demand if missing. Docs updated (AGENTS.md validate description, launcher README). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor: address review on #1499 (comment accuracy, CLI/TUI flag parity) Review feedback from @claude on PR #1499 (all non-blocking): - Align CLI catalogPath resolution with the TUI: `options.catalog?.trim() || process.env.MCP_CATALOG_PATH` so an explicit empty `--catalog ""` falls back to MCP_CATALOG_PATH identically in both front-ends (CLI used `??`, which only guards undefined/null). - Clarify the `serverSourceConflict` comment: it mirrors only the source-selection portion of web's matrix and deliberately omits web's `--header` rejection, since CLI/TUI merge --header into per-server settings. - Note the deliberate --header broadcast semantics in loadTuiServers. - Share an EMPTY_CATALOG_CONTENT constant between seedEmptyCatalog and readServerListContent instead of two separate literals. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(cli): trim --config to match --catalog and the TUI (#1499 review) Cosmetic uniformity follow-up from the re-review: configPath now uses `options.config?.trim() || undefined`, matching the catalog slot above it and the TUI. Behavior is unchanged (resolveServerSource/serverSourceConflict already trim downstream). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
36b48e61a2
commit
73b651ff21
1 changed files with 962 additions and 81 deletions
|
|
@ -15,17 +15,36 @@ All configuration parsing, config-file loading, and server setup are handled by
|
|||
`mcp-inspector --web` chooses which server list the UI shows and whether it is
|
||||
editable (see [specification/v2_catalog_launch_config.md](../../specification/v2_catalog_launch_config.md)):
|
||||
|
||||
| Invocation | Server list | Editable in UI? |
|
||||
|------------|-------------|-----------------|
|
||||
| `mcp-inspector --web` | Default catalog `~/.mcp-inspector/mcp.json` | Yes |
|
||||
| `mcp-inspector --web --catalog <path>` (or `MCP_CATALOG_PATH=<path>`) | That file as the active catalog (created/seeded if missing) | Yes |
|
||||
| `mcp-inspector --web --config <path>` | That file as a **read-only session** — shown but never written, seeded, or migrated (safe for a foreign config) | No |
|
||||
| `mcp-inspector --web --server-url <url> --transport http --header "Name: Value"` (or a positional command) | One ad-hoc server held in memory, connectable with the given `--header`s | No |
|
||||
| Invocation | Server list | Editable in UI? |
|
||||
| ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- | --------------- |
|
||||
| `mcp-inspector --web` | Default catalog `~/.mcp-inspector/mcp.json` | Yes |
|
||||
| `mcp-inspector --web --catalog <path>` (or `MCP_CATALOG_PATH=<path>`) | That file as the active catalog (created/seeded if missing) | Yes |
|
||||
| `mcp-inspector --web --config <path>` | That file as a **read-only session** — shown but never written, seeded, or migrated (safe for a foreign config) | No |
|
||||
| `mcp-inspector --web --server-url <url> --transport http --header "Name: Value"` (or a positional command) | One ad-hoc server held in memory, connectable with the given `--header`s | No |
|
||||
|
||||
Rules: `--catalog` and `--config` are mutually exclusive; neither combines with
|
||||
an ad-hoc target or `--header`; `--header` requires an ad-hoc HTTP/SSE server
|
||||
and is applied to that connection (it is no longer a warn-only no-op).
|
||||
|
||||
## CLI and TUI server-list flags (`--cli` / `--tui`)
|
||||
|
||||
The CLI and TUI use the same `--catalog` / `--config` vocabulary as `--web`,
|
||||
resolved by the shared `core/mcp/node/config.ts` helpers:
|
||||
|
||||
| Invocation | Server list source |
|
||||
| ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------- |
|
||||
| `mcp-inspector --cli` / `--tui` (no source flag, no ad-hoc target) | Default writable catalog `~/.mcp-inspector/mcp.json` (created/seeded empty if missing) |
|
||||
| `--catalog <path>` (or `MCP_CATALOG_PATH=<path>`) | That file as a **writable catalog** — seeded empty if missing |
|
||||
| `--config <path>` | That file as a **read-only session** — served as-is, never written or seeded; **errors if absent** |
|
||||
| positional command / `--server-url <url>` | One ad-hoc server |
|
||||
|
||||
Rules (shared `serverSourceConflict`): `--catalog` and `--config` are mutually
|
||||
exclusive, and neither combines with an ad-hoc command/URL target. The CLI/TUI
|
||||
do not perform catalog CRUD yet — they are read consumers — so the
|
||||
writable/read-only split currently surfaces only as **seed-if-missing**
|
||||
(`--catalog`/default) vs **error-if-missing** (`--config`). Full writable
|
||||
persistence is tracked in #1482 / #1432.
|
||||
|
||||
### Production web build (`--web`, no `--dev`)
|
||||
|
||||
Prod `--web` serves static assets from `clients/web/dist/`, which only exists
|
||||
|
|
@ -42,6 +61,23 @@ end-to-end with `npm run smoke:web` (`scripts/smoke-web.mjs`): it starts
|
|||
`mcp-inspector --web` against the built `dist/` and asserts `GET /` returns the
|
||||
SPA (HTTP 200) with the injected `__INSPECTOR_API_TOKEN__`.
|
||||
|
||||
### CLI and TUI smokes
|
||||
|
||||
`validate:launcher` also runs end-to-end smokes for the other two modes through
|
||||
the built launcher artifact (beyond the `--help` checks in `smoke:launcher`):
|
||||
|
||||
- `npm run smoke:cli` (`scripts/smoke-cli.mjs`) — runs `mcp-inspector --cli`
|
||||
against the bundled stdio test server via a temp `--catalog` and asserts
|
||||
`tools/list` returns the server's tools, plus the `--catalog`/`--config`
|
||||
resolution paths (default-catalog seed-on-missing, read-only `--config`
|
||||
error-without-seed, `--catalog`/`--config` conflict).
|
||||
- `npm run smoke:tui` (`scripts/smoke-tui.mjs`) — launches
|
||||
`mcp-inspector --tui --catalog <temp>` and asserts the Ink app renders its
|
||||
first frame within a timeout, then shuts it down (a shallow boot/render
|
||||
check, not full interaction).
|
||||
|
||||
Both build `test-servers/build` on demand if it is missing.
|
||||
|
||||
## Publishing
|
||||
|
||||
The root `@modelcontextprotocol/inspector` package ships as one fat tarball: `npm run build` at the repo root builds all clients, then `prepack` runs before `npm publish`. Runtime dependencies are declared on the root `package.json`; client builds bundle `@inspector/core` and externalize npm packages resolved from the root install.
|
||||
|
|
|
|||
Loading…
Reference in a new issue