* 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>
* feat(web): build dist on demand for prod --web + end-to-end CI smoke (#1486)
Prod `mcp-inspector --web` serves static assets from clients/web/dist,
which only exists after a build. In a fresh checkout it was absent and the
prod path served a broken page (ENOENT on index.html); the launcher smoke
test only covered --help, so this path was unverified in CI.
- ensure-web-build.ts: build dist on demand (vite build via build:client)
when missing, or exit with an actionable error if the build can't run.
- run-web.ts: invoke ensureWebBuild before startHonoServer in the prod path
(--dev runs Vite directly and skips it).
- scripts/smoke-web.mjs + smoke:web: start --web against built dist and
assert GET / returns 200 with the injected __INSPECTOR_API_TOKEN__.
Wired into validate:launcher and a new CI step.
- Docs: launcher README + AGENTS.md.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(web): surface spawn error in build-on-demand; clarify smoke comment
Address PR #1497 review:
- runViteBuild now logs result.error.message (e.g. ENOENT when npm isn't on
PATH) before returning a null status, so the spawn-failure cause surfaces
instead of only the generic actionable error. The build seam gains a `log`
param; added a test covering the ENOENT path.
- Reword scripts/smoke-web.mjs header so it no longer implies the readiness
wait covers a cold build-on-demand vite build (it's sized for a pre-built
dist, which validate/CI guarantee).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ports the CLI, TUI, and launcher from v1.5 into v2 behind a single
`mcp-inspector` entrypoint (launcher → web/cli/tui). Includes the
`mcp-inspector --web --dev` launcher fix (Vite alias resolution + prod-server
double-start), the root `postinstall` install cascade with simplified CI, and
spec/AGENTS docs (no-workspaces rationale, Development setup).
Closes#1246.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Added update-version.js script to automate version bumps across all packages
- Added check-version-consistency.js script to verify version consistency
- Integrated version check into CI workflow
- Scripts check package.json versions AND package-lock.json sync
- Added npm scripts: `npm run update-version` and `npm run check-version`
- Added documentation in scripts/README.md
This ensures version consistency across the monorepo and prevents
accidental version mismatches or outdated lock files.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>