| Filename | Latest commit message | Latest commit date |
|---|---|---|
* chore: close a batch of quality-gate & tidy gaps (#1785 #1787 #1789 #1790 #1767) Bundles five small, related tidy/gate items into one PR: - #1785: delete the dead src/types/navigation.ts InspectorTab (0 importers; duplicated/drifted from utils/inspectorTabs InspectorTabId). src/types/ now holds only ambient .d.ts stubs. - #1787: add src/hooks/** to the web coverage `include` (it was silently outside the ≥90 gate) and add tests for the two untested hooks, useServerJsonImport and useImportClientConfig, bringing every hook to ≥90 on lines/statements/functions/branches. - #1789: widen clients/{cli,tui,launcher} format/format:check to their top-level configs; add root format:shared / format:check:shared covering test-servers/src/**, vitest.shared.mts, and the repo-root eslint.config.js. - #1790: pin prettier to an exact version (3.8.4, dropping the ^3.8.1 caret) in all five package.json files so the format gate's verdict can't shift with an in-range patch bump; lockfiles synced. - #1767: its root-file format+lint gap is closed here (format:shared + a new lint:shared via a second files block in the root eslint.config.js; web/server/ was already gated in #1788). Its larger cli/tui __tests__ typecheck piece (76 type errors) is split out to #1791. Prettier-normalized the newly-covered files (pure formatting). No runtime behavior change. `npm run ci` green. Closes #1785 Closes #1787 Closes #1789 Closes #1790 Closes #1767 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * chore: address PR #1792 review findings - #1789 gap: widen clients/web format to include .storybook and clients/ launcher format to include scripts/; reformat the 3 .storybook files (were non-conforming under the pinned prettier 3.8.4). Audited all 885 tracked source files — now fully prettier-clean. - Export VALIDATE_DEBOUNCE_MS / COLLAPSE_DELAY_MS / HIGHLIGHT_DURATION_MS from useServerJsonImport and use them in the test instead of hardcoded 300/1000/250 (so a tuned constant can't silently desync the test). - Assert the symmetric renameErrors["alpha"] alongside ["beta"] so a one-directional collision-check regression fails. - Comment the blank-rename test as exercising a UI-unreachable defensive branch (canImport gates submit). - Un-stale the two specification/v2_ux_interfaces_plan.md references to the now-removed navigation.ts InspectorTab. npm run ci green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * docs: sync AGENTS.md format-surface description with the widened globs (#1792 review r2) 1ce3b64 added .storybook to clients/web's format glob and scripts/ to clients/launcher's, but AGENTS.md:222 still described the pre-fix scope. Bring it in line and note the non-recursive top-level glob is why nested dirs are named explicitly. Docs only. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * chore: handle PR #1792 round-3 follow-ups in-place (format-coverage guard, uniform globs, theme gate) Rather than defer these to tickets, fold them into this PR: - Obs 2: widen every client + root format glob to a uniform *.{ts,tsx,mts,cts,js,jsx,mjs,cjs} so a future .mts/.cjs/.tsx top-level file can't silently slip the gate. - Obs 1: add scripts/verify-format-coverage.mjs (wired into `validate`) — it parses the format:check globs out of every package.json, enumerates all tracked source files, and fails listing any not covered by a glob. The durable, standing version of #1789's one-shot audit; negative-tested. - Obs 3: bring src/theme/** under the coverage gate (21/23 files were already ≥90 transitively; add Paper.test.tsx for the one laggard, Paper.ts). src/App.tsx (~4.5k lines, ~42% branches) is converted from a silent omission into an explicit, documented exclusion (comment on the coverage `include` + AGENTS.md) — gating it is a dedicated effort, not a whitelist tweak. npm run ci green (the new guard reports 885/885 tracked source files gated). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * chore: address PR #1792 round-4 findings (guard hardening, docs, exclusion list) - Harden verify-format-coverage: only harvest format:check globs from scripts transitively reachable from `validate` (via npm run refs), so an unwired/renamed format:check no longer counts as coverage. Negative-tested — renaming clients/web format:check to an unreferenced name now fails the guard (627 files flagged) instead of passing. - Name src/main.tsx and src/index.ts (browser + bin bootstraps) alongside src/App.tsx in the coverage-include comment and AGENTS.md, so the documented exclusion list is complete rather than claiming App.tsx is the only one. - Doc sync: document verify:format-coverage (AGENTS.md + README script table + scripts/ layout line), fix the `validate` ordering (verify:format- coverage now runs before validate:core) in AGENTS.md and README, and update the quoted globs to the uniform *.{ts,tsx,mts,cts,js,jsx,mjs,cjs} / test-servers *.{ts,tsx,mts,cts}. npm run ci green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 * chore: address PR #1792 round-5 findings (airtight guard + doc/config sync) - verify-format-coverage: assert the root `validate` chain invokes each client's `validate` (cd <dir> && npm run validate), closing the last reachability edge — a client dropped from the root chain now fails the guard even though its own globs still exist. Negative-tested. - eslint.config.js: widen the shared `files` block to test-servers/src/**/*.{ts,tsx,mts,cts} to match the widened lint:shared glob, so a future .mts/.cts there is lint-gated, not just prettier-gated. - AGENTS.md: scope the "uniform extension set" claim to client globs (core stays {ts,tsx}, shared {ts,tsx,mts,cts}), with verify:format-coverage as the backstop — removing the self-contradiction with the line below. npm run ci green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XNdjEPKLG637X8YmhDiEk5 --------- 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)
The TUI supports OAuth for SSE and Streamable HTTP servers. Per-server OAuth fields in mcp.json (static client id/secret, scopes, enterprise-managed flag) are applied automatically when loaded from --catalog or --config. Install-wide settings (CIMD, enterprise IdP) come from ~/.mcp-inspector/storage/client.json — the same file the web Client Settings dialog writes. You can point at a different file with --client-config or MCP_CLIENT_CONFIG_PATH.
OAuth callback URL
The TUI starts a small loopback HTTP server to receive the authorization redirect after you sign in in the browser. Defaults:
| Surface | Default callback |
|---|---|
| Web | http://localhost:6274/oauth/callback (main app server) |
| TUI | http://127.0.0.1:6276/oauth/callback (dedicated runner port; avoids colliding with web on 6274) |
Why a fixed default port? Enterprise-managed auth (EMA), CIMD, and many static OAuth apps require pre-registered redirect URIs. A predictable default (http://127.0.0.1:6276/oauth/callback) lets you register once on the IdP and reuse it across TUI sessions. Dynamic registration (DCR) can use ephemeral ports instead — see below.
Trade-off: only one TUI OAuth flow at a time can listen on the default port. A second instance starting OAuth while another is in progress may fail with EADDRINUSE. Override the listener with --callback-url or MCP_OAUTH_CALLBACK_URL (e.g. a different fixed port per instance, or http://127.0.0.1:0/oauth/callback when the authorization server accepts dynamically registered redirect URIs).
OAuth redirect URIs must match exactly what you register on the authorization server — localhost and 127.0.0.1 are different URIs. Register the TUI default on your OAuth app / IdP when using pre-registered (static), CIMD, or enterprise-managed clients. Override the listener with --callback-url or MCP_OAUTH_CALLBACK_URL; use http://127.0.0.1:0/oauth/callback for an OS-assigned ephemeral port when the authorization server registers redirect URIs dynamically (DCR).
Flags
| Option | Env | Description |
|---|---|---|
--client-config <path> |
MCP_CLIENT_CONFIG_PATH |
Install-level client config (default: ~/.mcp-inspector/storage/client.json). |
--client-id <id> |
— | OAuth client ID (static client); overrides client.json. |
--client-secret <secret> |
— | OAuth client secret (confidential clients); overrides client.json. |
--client-metadata-url <url> |
— | Client ID Metadata Document URL (CIMD); overrides client.json. |
--callback-url <url> |
MCP_OAUTH_CALLBACK_URL |
OAuth redirect/callback listener (default: http://127.0.0.1:6276/oauth/callback). |
Authenticating in the TUI
- Select an HTTP/SSE server and press C to connect.
- If authorization is required, the TUI starts OAuth automatically (browser opens for sign-in).
- After the callback completes, connect finishes without a second C.
- Use the Auth tab to inspect OAuth state (same fields as web Connection Info) or Clear OAuth state (disconnects when connected).
See also EMA / enterprise-managed auth and OAuth smoke testing for staging servers and verification steps.
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.
- Protocol: View JSON-RPC request/response/notification history (matches the web Protocol monitor).
- Network: View HTTP fetch traffic for SSE / Streamable HTTP servers (matches the web Network monitor).
- Console: View stdio stderr from the connected server process (matches the web Console monitor).
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.
