Skip to content

fix: nine small defects from the v2.13 review (#2827) - #2856

Merged
cliffhall merged 2 commits into
v2/mainfrom
v2/fix/2827-v213-review-small-defects
Oct 29, 2026
Merged

cliffhall merged 2 commits into
v2/mainfrom
v2/fix/2827-v213-review-small-defects

Conversation

@cliffhall

Copy link
Copy Markdown
Member

Closes #2827

All nine items from the v2.13 review, one commit each concern, no new dependencies.

# Change Where
1 Fonts are self-hosted. The Fredoka / Roboto Mono variable woff2 subsets Google served are committed under clients/web/src/theme/fonts/ with a fonts.css of matching @font-face rules (split by unicode-range), imported by main.tsx and the Storybook preview. The fonts.googleapis.com links are gone from index.html and .storybook/main.ts. Vite bundles and hashes the files. Licenses: OFL 1.1 (Fredoka), Apache 2.0 (Roboto Mono); both allow redistribution. A test pins "no http(s):// in index.html" and "every url() in fonts.css is a local file that exists". clients/web/index.html, src/theme/fonts/*
2 Sandbox listener: answers HEAD like GET minus the body (Content-Length included), matches /sandbox / /sandbox/ ignoring a query string, and applies the main server's Host allow-list (createHostAllowList from host-allow-list.ts: loopback names, IP literals, bind host, ALLOWED_ORIGINS hosts, MCP_INSPECTOR_ALLOWED_HOSTS, plus the host of MCP_SANDBOX_FULL_ADDRESS). A refused Host gets the same 403 text as the main server. Applies in prod and --dev. server/sandbox-controller.ts (+ allowedHosts passed from server.ts and vite-hono-plugin.ts)
3 SPA fallback excludes only /api and /api/… (isApiPath), so /apixyz gets the SPA. That is the only change in server.ts besides threading allowedHosts to the sandbox. server/server.ts
4 One ad-hoc naming rule. I kept the web rule (URL host, else command basename, else server) and moved it to adHocServerName in core/mcp/serverList.ts. The shared loadServerEntries (CLI, TUI, mcpdo) now uses it too, so node server.js is node everywhere. Why this one: default doesn't tell you which server it is. Behavior change: CLI, TUI and mcpdo no longer key an ad-hoc server as default. Selection is unaffected, since an ad-hoc launch has one entry and no --server. core/mcp/serverList.ts, core/mcp/node/servers.ts, server/run-web.ts
5 Seed temp dir. serverList.ts is browser-consumed, so it can't import node:os. DEFAULT_SEED_CONFIG is now defaultSeedConfig(tempDir), and the only caller that writes a seed (the Node backend's first-launch branch) passes os.tmpdir(). core/mcp/serverList.ts, core/mcp/remote/node/server.ts (3 lines)
6 Every screen has an <h1>. InspectorView renders <VisuallyHidden component="h1">MCP Inspector: <tab></VisuallyHidden> first in the header. Design note: an h1 alone would have broken axe heading-order on every connected screen, because their panel headings start at h3/h4 and h1→h4 skips. So the connected screens' panel headings move to h2 and their sections to h3, through PanelHeading / SubHeading Title.withProps constants that keep the old visual size (size: "h4" / "h5"). Nothing looks different. The Servers panel title also moves h3→h2, because that screen shows while connected too, when the header has no h2. Modal-hosted panels (ConnectionInfoContent, SamplingRequestPanel, ImportServerJsonPanel) are unchanged: they already sit under the modal's h2. InspectorView.tsx + ~20 components/groups/*
7 One list order: alphabetical. The web sidebar has sorted tools since #2782 (a user asked for it: 20–30 unordered tools are hard to scan), and server tools/list order isn't something servers promise. So the TUI now sorts too. The collator moved to core/mcp/toolOrder.ts, and web toolUtils re-exports it. Each surface sorts by the label its row shows: web rows show title ?? name, TUI rows show name (same as the web's excluded-tool rows). The two orders are identical for tools without a title. Prompts and resources were unsorted in both clients and stay that way. core/mcp/toolOrder.ts, clients/tui/src/App.tsx
8 TUI nits. ink-form prints form.title in its own header and the modal prints it again, so the form now gets an untitled copy (untitledForm). I applied it to the prompt and resource-template modals too, since they had the same duplication (Get Prompt: / Read Resource:). The roots: cleanRoots(...) comment now describes the #2432 roots editor (session-only, never writes mcp.json). clients/tui/src/utils/formHeader.ts, the three *TestModal.tsx, App.tsx
9 Weak token warning. A custom MCP_INSPECTOR_API_TOKEN (or the legacy MCP_PROXY_AUTH_TOKEN) shorter than 32 characters prints a startup warning. It is still accepted. The generated token is 64 hex characters, so only an operator-chosen one can trigger it. server/web-server-config.ts

Docs: docs/mcp-server-configuration.md (seed path, ad-hoc naming), docs/environment-variables.md (warning), clients/web/README.md (sandbox Host check), clients/launcher/README.md (seed).

Verification

  • npm run local:gate green.
  • An axe scan of the prod build, connected to a composable test server (tools, resources, templates, prompts, an MCP App), ran page-has-heading-one, heading-order, region and landmark-one-main on Servers, Tools (incl. an executed result), Apps, Prompts and Resources (incl. a read resource), plus Protocol and Network in the monitor. 0 violations. Before the heading shift, the same scan showed heading-order failing on every connected tab once the h1 was in.

Screenshots

Web Tools tab on the prod build. Fredoka and Roboto Mono render from the bundled files, with no request to Google. The h1 is visually hidden, so the look is unchanged:

web tools

TUI tool form, before (title twice) and after. These are ANSI-stripped Ink frames rendered to PNG, so terminal colors are dropped:

tui before
tui after

🤖 Generated with Claude Code

1. Self-host the Fredoka and Roboto Mono woff2 files (clients/web/src/theme/fonts)
   instead of loading them from fonts.googleapis.com at runtime, in the app and
   in Storybook.
2. The sandbox listener answers HEAD, ignores a query string on /sandbox, and
   applies the main server's Host allow-list (plus the host of
   MCP_SANDBOX_FULL_ADDRESS).
3. The prod SPA fallback excludes only /api and /api/..., so /apixyz gets the SPA.
4. One ad-hoc server naming rule (adHocServerName in core/mcp/serverList.ts):
   URL host or command basename, used by web and by the shared CLI/TUI/mcpdo
   resolution, which used to call it "default".
5. The default seed scopes filesystem-server-default to os.tmpdir(), passed in
   by the Node backend (defaultSeedConfig(tempDir)) since serverList.ts is
   browser-consumed.
6. Every web screen has a visually hidden h1; connected-screen panel headings
   move to h2/h3 (visual sizes unchanged) so axe heading-order stays clean.
7. The TUI lists tools alphabetically, as the web sidebar does since #2782,
   via a shared core/mcp/toolOrder.ts.
8. TUI test modals no longer print their title twice; the roots-editor comment
   in App.tsx reflects #2432.
9. A custom MCP_INSPECTOR_API_TOKEN shorter than 32 characters prints a startup
   warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
@cliffhall cliffhall added the v2 Issues and PRs for v2 label Oct 29, 2026
@cliffhall cliffhall linked an issue Oct 29, 2026 that may be closed by this pull request
2 tasks done
@cliffhall
cliffhall requested a balanced review from Copilot October 29, 2026 04:32

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved issues include missing font redistribution license materials, a heading-order violation in maximized apps with messages, and tool selection and scroll resets on unrelated server updates.

3 open issues
What changed in this PR

Addresses nine defects from #2827 across the web client, TUI, and shared MCP configuration, without adding dependencies.

Changes:

  • Self-hosts web fonts, improves heading structure, and removes duplicate TUI form titles.
  • Hardens sandbox request handling, corrects SPA routing, and warns about short custom tokens.
  • Unifies ad-hoc server naming and tool sorting, uses platform-specific seed paths, and updates tests and documentation.
File Description
docs/​mcp-server-configuration.md Documents platform-specific seed paths.
docs/​environment-variables.md Documents short-token warnings.
core/​mcp/​toolOrder.ts Adds shared tool comparators.
core/​mcp/​serverList.ts Centralizes ad-hoc naming and parameterizes seed paths.
core/​mcp/​remote/​node/​server.ts Seeds catalogs using os.tmpdir().
core/​mcp/​node/​servers.ts Applies shared ad-hoc naming.
clients/​web/​src/​utils/​toolUtils.ts Re-exports shared tool comparators.
clients/​web/​src/​theme/​fonts/​fonts.test.ts Checks local font references.
clients/​web/​src/​theme/​fonts/​fonts.css Defines self-hosted font faces.
clients/​web/​src/​test/​integration/​server/​web-server-config.test.ts Tests custom-token warnings.
clients/​web/​src/​test/​integration/​server/​server-token-injection.test.ts Tests non-API SPA fallback.
clients/​web/​src/​test/​integration/​server/​sandbox-controller.test.ts Tests HEAD, query strings, and Host filtering.
clients/​web/​src/​test/​integration/​mcp/​remote/​servers-route.test.ts Updates seed-route expectations.
clients/​web/​src/​test/​core/​react/​useServers.test.tsx Updates seed-key assertions.
clients/​web/​src/​test/​core/​mcp/​toolOrder.test.ts Tests shared sorting behavior.
clients/​web/​src/​test/​core/​mcp/​serverList.test.ts Tests naming and platform seed paths.
clients/​web/​src/​test/​core/​mcp/​node/​servers.test.ts Updates ad-hoc server expectations.
clients/​web/​src/​main.tsx Loads bundled fonts.
clients/​web/​src/​components/​views/​InspectorView/​InspectorView.tsx Adds a screen-specific hidden h1.
clients/​web/​src/​components/​views/​InspectorView/​InspectorView.test.tsx Tests page headings.
clients/​web/​src/​components/​screens/​ServerListScreen/​ServerListScreen.tsx Makes the panel title h2.
clients/​web/​src/​components/​screens/​ConsoleScreen/​ConsoleScreen.tsx Makes console headings h2.
clients/​web/​src/​components/​screens/​AppsScreen/​AppsScreen.tsx Makes app messages a subsection heading.
clients/​web/​src/​components/​groups/​ToolResultPanel/​ToolResultPanel.tsx Adjusts result heading hierarchy.
clients/​web/​src/​components/​groups/​ToolResultPanel/​ToolCallErrorPanel.tsx Makes the error panel heading h2.
clients/​web/​src/​components/​groups/​ToolControls/​ToolControls.tsx Makes the tools heading h2.
clients/​web/​src/​components/​groups/​TaskListPanel/​TaskListPanel.tsx Adjusts task heading hierarchy.
clients/​web/​src/​components/​groups/​TaskControls/​TaskControls.tsx Adjusts task control headings.
clients/​web/​src/​components/​groups/​StructuredOutputPanel/​StructuredOutputPanel.tsx Makes structured output a subsection heading.
clients/​web/​src/​components/​groups/​ResourceTemplatePanel/​ResourceTemplatePanel.tsx Makes the template heading h2.
clients/​web/​src/​components/​groups/​ResourcePreviewPanel/​ResourcePreviewPanel.tsx Makes the preview heading h2.
clients/​web/​src/​components/​groups/​ResourceControls/​ResourceControls.tsx Makes the resources heading h2.
clients/​web/​src/​components/​groups/​ProtocolListPanel/​ProtocolListPanel.tsx Adjusts protocol heading hierarchy.
clients/​web/​src/​components/​groups/​ProtocolControls/​ProtocolControls.tsx Adjusts protocol control headings.
clients/​web/​src/​components/​groups/​PromptMessagesDisplay/​PromptMessagesDisplay.tsx Makes the messages heading h2.
clients/​web/​src/​components/​groups/​PromptControls/​PromptControls.tsx Makes the prompts heading h2.
clients/​web/​src/​components/​groups/​PromptArgumentsForm/​PromptArgumentsForm.tsx Makes the arguments heading h2.
clients/​web/​src/​components/​groups/​NetworkStreamPanel/​NetworkStreamPanel.tsx Makes the network panel heading h2.
clients/​web/​src/​components/​groups/​NetworkControls/​NetworkControls.tsx Adjusts network control headings.
clients/​web/​src/​components/​groups/​MessageDirectionFilter/​MessageDirectionFilter.tsx Makes the filter heading h3.
clients/​web/​src/​components/​groups/​LogStreamPanel/​LogStreamPanel.tsx Makes the log stream heading h2.
clients/​web/​src/​components/​groups/​LogControls/​LogControls.tsx Adjusts logging control headings.
clients/​web/​src/​components/​groups/​AppControls/​AppControls.tsx Makes the apps heading h2.
clients/​web/​server/​web-server-config.ts Warns about short custom tokens.
clients/​web/​server/​vite-hono-plugin.ts Passes allowed hosts to the dev sandbox.
clients/​web/​server/​server.ts Corrects SPA routing and passes sandbox hosts.
clients/​web/​server/​sandbox-controller.ts Adds Host filtering, HEAD, and query support.
clients/​web/​server/​run-web.ts Uses shared ad-hoc naming.
clients/​web/​README.md Documents sandbox Host checks.
clients/​web/​index.html Removes Google Fonts links.
clients/​web/​.storybook/​preview.tsx Loads bundled fonts in Storybook.
clients/​web/​.storybook/​main.ts Removes external font injection.
clients/​tui/​src/​utils/​formHeader.ts Adds an untitled form-copy helper.
clients/​tui/​src/​components/​ToolTestModal.tsx Removes the duplicate form title.
clients/​tui/​src/​components/​ResourceTestModal.tsx Removes the duplicate form title.
clients/​tui/​src/​components/​PromptTestModal.tsx Removes the duplicate form title.
clients/​tui/​src/​App.tsx Sorts tools and corrects the roots-editor comment.
clients/​tui/​__tests__/​tui-servers.test.ts Updates ad-hoc naming expectations.
clients/​tui/​__tests__/​formHeader.test.ts Tests title removal without mutation.
clients/​tui/​__tests__/​App.test.tsx Tests alphabetical tool display.
clients/​launcher/​README.md Documents platform-specific seed paths.

Review effort: Balanced

Comment thread clients/tui/src/App.tsx Outdated
Comment thread clients/web/src/components/screens/AppsScreen/AppsScreen.tsx Outdated
Comment thread clients/web/src/theme/fonts/fonts.css Outdated
Comment on lines +10 to +12
* - Fredoka (wght 300–700) — SIL Open Font License 1.1
* - Roboto Mono (wght 100–700, normal + italic) — Apache License 2.0
* Both licenses permit redistribution. To refresh them, request the same css2

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 6f63891: the full upstream texts from google/fonts (ofl/fredoka/OFL.txt, ofl/robotomono/OFL.txt) are now in clients/web/public/fonts/, copyright notices included. Vite copies that folder verbatim to dist/fonts/, so the licenses ship in every build and in the npm tarball (clients/web/dist is in files). I also corrected the header: Roboto Mono is OFL 1.1 too, not Apache. A test pins that both files exist and carry their notice.

…led font licenses (#2827)

- TUI: memoize the sorted tools on the store snapshot so an unrelated update
  (a stderr line) no longer resets the Tools selection; regression test.
- Web: the Apps 'Messages from app' heading is an h2, valid with the sidebar
  hidden while maximized; test.
- Ship the full upstream OFL 1.1 texts for Fredoka and Roboto Mono in
  public/fonts (copied to dist/fonts, so they are in the tarball); test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
@cliffhall

Copy link
Copy Markdown
Member Author

Copilot round 1, all three findings fixed in 6f63891 (replies are in each thread):

  • TUI tool selection reset on unrelated updates: sorted tools are memoized on the store snapshot. Regression test added.
  • Heading-order gap with the app maximized: "Messages from app" is now an h2. Test added.
  • Font licenses: the full OFL 1.1 texts are bundled in public/fonts, which ships as dist/fonts. Test added.

local:gate is green. Requesting round 2.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues require changes to the Inspector web, TUI, and shared-core updates.

1 open issue
2 resolved since last review

Review effort: Balanced

@cliffhall

Copy link
Copy Markdown
Member Author

Copilot review loop closed. Round 2 recommends approval, with no inline comments, nothing in the headline and nothing suppressed. The font-license item it still lists as "open" is the round-1 thread, which is fixed in 6f63891 and answered in place; the thread just has not been resolved. clients/web/dist/fonts/ holds both OFL texts after a build. Exit: first clean round.

@cliffhall
cliffhall merged commit 0d61bd0 into v2/main Oct 29, 2026
11 checks passed
@cliffhall
cliffhall deleted the v2/fix/2827-v213-review-small-defects branch October 29, 2026 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Issues and PRs for v2

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Small defects in web, TUI and default catalog (tracking list from a v2.13 review)

2 participants