* 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>
51 lines
3.4 KiB
Markdown
51 lines
3.4 KiB
Markdown
# MCP Inspector Launcher
|
||
|
||
The launcher is the package that provides the global `mcp-inspector` binary (e.g. when users run `npx @modelcontextprotocol/inspector`). It is not a separate user-facing app—it is the single entrypoint that selects and runs one of the clients (web, CLI, or TUI).
|
||
|
||
## Responsibility
|
||
|
||
- Parse mode from a leading prefix of `--web` (default), `--cli`, or `--tui` immediately after the script name.
|
||
- Forward all following arguments unchanged (including tokens that look like mode flags).
|
||
- Dynamically import that app’s runner from `clients/{web,cli,tui}/build/index.js` (relative to the launcher build output) and call it **in-process** (no `spawn()`).
|
||
|
||
All configuration parsing, config-file loading, and server setup are handled by the app runners and by **core**; the launcher does not interpret config or env vars.
|
||
|
||
## Web server-list flags (`--web`)
|
||
|
||
`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 |
|
||
|
||
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).
|
||
|
||
### Production web build (`--web`, no `--dev`)
|
||
|
||
Prod `--web` serves static assets from `clients/web/dist/`, which only exists
|
||
after a build. In the published package `dist/` always ships. In a fresh dev
|
||
checkout it is absent, so the runner **builds it on demand** the first time you
|
||
launch (`vite build` via `npm run build:client`, run in `clients/web`) instead
|
||
of serving a broken page (#1486). If that build can't run — e.g. dev
|
||
dependencies are missing — the launcher exits with an actionable error telling
|
||
you to run `npm run build` (from `clients/web`) or relaunch with `--dev` to use
|
||
the Vite dev server. `--dev` never needs `dist/`; it runs Vite directly.
|
||
|
||
CI and `npm run validate` (via `validate:launcher`) exercise this prod path
|
||
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__`.
|
||
|
||
## 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.
|
||
|
||
## Architecture
|
||
|
||
For how the launcher fits with the shared config processor and app runners, see the [Launcher and config consolidation](../../docs/launcher-config-consolidation-plan.md) document in the repo root `docs/` folder.
|