| Filename | Latest commit message | Latest commit date |
|---|---|---|
* refactor(launcher): self-contained validate; split smokes into top-level step (#1504) Previously `validate:launcher` built cli/tui/web and ran the cross-client smokes, so the launcher's "validation" depended on every other client being built — and the launcher had no lint/format/coverage of its own. - clients/launcher: add a web-style `validate` (format:check && lint && build && test:coverage) with a Node-only eslint flat config, prettier, and a per-file coverage gate (parse-launcher-argv.ts covered; src/index.ts excluded as binary bootstrap). 100% on the gated file. - Root `validate:launcher` now just delegates: `cd clients/launcher && npm run validate` — no dependency on the other clients. - New top-level `smoke` step (smoke:launcher + smoke:cli + smoke:tui + smoke:web) with NO build commands; `validate` runs it last. Each client's own validation builds its bundle first, so nothing builds twice (cli/tui via test:coverage, launcher via its validate; smoke:web builds dist on demand). - clients/tui test:coverage now builds the TUI bundle (mirroring cli) so the build-free smoke has it available. - CI: replace the standalone cli/tui/launcher build step with a "Validate launcher" step. Docs updated (AGENTS.md, launcher README). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(cli,tui,root): every client self-validates; smoke separate from validate Extends the launcher self-validate work to the CLI and TUI, and makes the top-level `validate` nothing but the per-client validations — smokes are now a separate top-level target. - clients/cli, clients/tui: add a web-style `validate` with a Node flat eslint config + prettier. CLI lint/format pass as-is. TUI registers eslint-plugin-react-hooks for the classic rules only (rules-of-hooks + exhaustive-deps, which the source already references); the stricter react-hooks@7 rules are not enforced on the interim component surface (#1501). - Avoid double builds: - CLI's e2e spawns the built binary, so its `test:coverage` builds first; `validate` folds that in (`format:check && lint && test:coverage`, no separate `build`). - TUI tests don't spawn a bundle, so `validate` keeps an explicit `build` (for the smoke) and `test:coverage` is pure. - Root: `validate` = validate:web && validate:cli && validate:tui && validate:launcher (each delegates to the client's own validate). `smoke` is no longer part of `validate` — it's a separate top-level target run after a build/validate, with no build commands of its own. - CI: per-client "Validate X" steps + a single "Run cross-client smokes" (npm run smoke). Docs updated (AGENTS.md, cli/tui READMEs). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(root): drop redundant test aggregator scripts Now that every client self-validates and the top-level `validate` chains the per-client validations, the root `test` / `test:web` / `test:cli` / `test:tui` / `test:coverage` aggregators are redundant — run `npm run validate` (all) or `cd clients/<name> && npm run validate` (one). `test:storybook` stays (it's the one check not part of validate). CI was already using each client's own scripts, so it's unaffected. Docs updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(web): silence happy-dom infra noise in unit runs Passing unit runs printed dozens of alarming-but-expected lines that made green runs look broken — all from happy-dom performing real I/O with no server behind it: - `<iframe src="/sandbox.html">` (MCP Apps sandbox) made happy-dom fetch and later unload that URL, emitting ~40 `DOMException [NetworkError/ AbortError]` + `AsyncTaskManager destroyed` lines. Disable child-frame navigation in the unit project (the tests only assert on the iframe element/attributes, not its document), removing the noise with no coverage loss. - App-level renders read `GET /api/config` via useSandboxUrl / useServerListWritable, 404-ing ~76x. Add a benign default `fetch` (empty 200) in the unit setup; tests that exercise fetch still override it. Negative tests that assert on errors already suppress their own console output (e.g. jsonUtils/schemaUtils); CLI, TUI, and the web integration suite were already clean. Unit suite is now noise-free; 2424 web tests pass and the coverage gate is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(scripts): make validate fast (test), split coverage into its own target Each client's `validate` now runs `test` instead of `test:coverage`, so the everyday pre-push check skips v8 instrumentation (and, for web, the slower integration project). The per-file coverage gate moves to a dedicated top-level `coverage` script: coverage = coverage:web && coverage:cli && coverage:tui && coverage:launcher coverage:<name> = cd clients/<name> && npm run test:coverage `validate` still builds each client's bundle (cli via its test `pretest`, the others via an explicit `build`), so `npm run validate && npm run smoke` works unchanged. CI now runs `validate` (fast checks + builds), then `coverage` (the gate), then `smoke` — collapsing the old per-client steps. Docs updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: drop the coverage gate from CI; keep web integration as its own step CI no longer runs `npm run coverage` — the per-file coverage gate is now a local/manual check (`npm run coverage` before pushing). To avoid silently dropping the web integration suite (it only ran via test:coverage, and `validate` runs the unit project only), CI gains a standalone `clients/web` `test:integration` step that exercises the real stdio/HTTP/OAuth/storage paths without coverage instrumentation. CI is now: validate (fast) → web integration → smoke → storybook. Docs updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(smoke): give smoke:launcher its own script like the others smoke:launcher was the odd one out — an inline chain of three `node clients/launcher/build/index.js ... --help` commands while smoke:cli / smoke:tui / smoke:web each run a `scripts/smoke-*.mjs`. Extract it to `scripts/smoke-launcher.mjs`, which runs the same `--help` / `--cli --help` / `--tui --help` dispatch checks but now also asserts each prints that mode's usage banner (proving the launcher resolved the right client build) and verifies the required builds exist up front with a clear error. Prints a `smoke:launcher OK — ...` summary in the same style as the rest. Docs updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: reorder package.json scripts for readability Move frequently-run scripts toward the top and rarely-run-by-hand ones (pretest hooks, lint/format internals, etc.) toward the end, consistently across the root and client manifests. Pure reordering — no script names or values changed, and no other manifest content is touched. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: drop references to removed root inspector / test:storybook scripts The reordering dropped the root `inspector` and `test:storybook` aggregators (intentional — `inspector` is redundant with `web`, and storybook is run from clients/web in CI). Update AGENTS.md so it no longer points at `npm run inspector`, and run `test:storybook` from `clients/web/`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: address PR #1505 review (format glob gap, fetch-baseline comment) - TUI format/format:check now also cover the client-root source files (index.ts, tui.tsx, dev.ts) that live outside src/ — `eslint .` already lints them, so they were linted but not format-checked. (cli/launcher have no source outside src/; their root .ts are single-quoted configs intentionally left out of prettier, matching web.) - Reword the setup.ts default-fetch comment: it overstated auto-restore (the unit project sets no restoreMocks/unstubGlobals), and now also flags that the permissive 200 default means a test asserting on a fetch FAILURE must install its own rejecting stub. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: remove redundant root install:clients script `install:clients` ran the same `node scripts/install-clients.mjs` as `postinstall`, which fires automatically on `npm install` — so the manual alias was redundant. Drop it and the doc references (AGENTS.md, spec). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(ci): skip smoke:tui in CI (Ink needs a real TTY) This PR made CI run the full `npm run smoke`, which surfaced that smoke:tui fails in headless CI: the Ink TUI throws "Raw mode is not supported" on mount (no TTY) and exits before rendering its first frame. The old CI never ran smoke:tui, so this was latent. smoke-tui.mjs now self-skips when `process.env.CI` is set — the boot/ render check is inherently local-only (a TUI needs a terminal). The TUI is still built and unit-tested in CI; `npm run smoke` stays the single command everywhere (full locally, tui-skipped in CI). Verified `CI=true npm run smoke` is green (launcher/cli OK, tui SKIPPED, web OK). Docs + CI comment updated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
| .. | ||
| __tests__ | ||
| src | ||
| dev.ts | ||
| eslint.config.js | ||
| index.ts | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| test-config.json | ||
| tsconfig.json | ||
| tsup.config.ts | ||
| tui.tsx | ||
| vitest.config.ts | ||
MCP Inspector TUI Client
The Terminal User Interface (TUI) client brings the interactive exploration capabilities of the Web Client directly to your terminal. It is built using Ink to provide a rich, React-like component experience in a command-line environment.
Running the TUI
You can run the TUI client via npx:
npx @modelcontextprotocol/inspector --tui node build/index.js
With Configuration Files
The TUI can load all servers from an MCP catalog/config file. With no source
flag it uses the default writable catalog ~/.mcp-inspector/mcp.json (seeded
empty if missing):
npx @modelcontextprotocol/inspector --tui --catalog mcp.json # writable catalog (seeded if missing)
npx @modelcontextprotocol/inspector --tui --config mcp.json # read-only session (errors if absent)
(It does not use --server; all servers in the file are available in the TUI.)
Options
MCP server (which server(s) to connect to)
Options that specify the MCP server(s) (catalog/config file, ad-hoc command/URL, env vars, headers) are shared by the Web, CLI, and TUI and are documented in MCP server configuration: --catalog (writable catalog, seeded if missing; default ~/.mcp-inspector/mcp.json or MCP_CATALOG_PATH), --config (read-only session, errors if absent), -e, --cwd, --header, --transport, --server-url, and the positional [target...]. --catalog and --config are mutually exclusive, and neither combines with an ad-hoc target.
TUI-specific (OAuth for HTTP servers)
When connecting to SSE or Streamable HTTP servers that use OAuth, you can pass:
| Option | Description |
|---|---|
--client-id <id> |
OAuth client ID (static client). |
--client-secret <secret> |
OAuth client secret (confidential clients). |
--client-metadata-url <url> |
OAuth Client ID Metadata Document URL (CIMD). |
--callback-url <url> |
OAuth redirect/callback listener URL (default: http://127.0.0.1:0/oauth/callback). |
Features
The TUI provides terminal-native tabs and panes for interacting with your MCP server:
- Resources: Browse and read resources exposed by the server.
- Prompts: List and test prompts.
- Tools: View available tools and execute them with form-like inputs.
- History: View the request and response history of your interactions.
- Console: View the direct stdout/stderr and diagnostic logging of the connected server.
Navigation
- Use the Arrow Keys (Left/Right) or Tab to switch between the main tabs (Resources, Tools, Prompts, etc.).
- Use the Arrow Keys (Up/Down) to scroll through lists of items.
- Press Enter to select an item, execute a tool, or fetch a resource.
- Press Escape or
Ctrl+Cto exit the application.
Development
Like the other clients, the TUI self-validates from its own folder:
npm run validate # format:check && lint && build && test:coverage
npm test # run all tests
npm run test:coverage # run tests under the per-file coverage gate
The repo-root validate:tui just delegates here. eslint.config.js registers
react-hooks for the classic rules only (rules-of-hooks + exhaustive-deps); the
stricter react-hooks@7 rules are not enforced on the interim component surface
(#1501).
Tests live in __tests__/. The coverage gate currently covers the TUI's
non-React logic (server resolution, logger, tab metadata, and the utils/
form/URL helpers); the Ink components and App.tsx are an interim exclusion in
vitest.config.ts pending a renderer-based follow-up.
