Repository navigation
Conversation
…socket path (#2823) `connections/list` and `servers/show` with no name read a `daemon_unreachable` error as "nothing is connected". When the daemon socket path is over the platform's sun_path limit the daemon can never bind, so that read was wrong: the list printed `Connections (0)` and exited 0, and MRU inference said there was no most-recently-used connection, while `connect` refused with the real cause. Both now run the same `assertSocketPathWithinLimit()` check that `ensureDaemon()` runs before treating an unreachable daemon as empty, so they fail with connect's error and exit code. Neither starts the daemon or creates its directory, and an absent daemon on a valid path still reports an empty list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
) The image's HEALTHCHECK always built an http:// URL, so with both INSPECTOR_TLS_KEY_PATH and INSPECTOR_TLS_CERT_PATH set the probe failed every time and a correctly running TLS container was reported unhealthy forever. The probe now follows the server's TLS rule (both paths set, a blank value counting as unset) and uses https without verifying the certificate, since it only reaches the container's own listener where a self-signed or private-CA certificate is the normal case. It uses node:http/https rather than fetch because fetch has no per-request way to skip verification without undici, which the copied script cannot resolve. It also probes the unauthenticated /healthz route (#2438) instead of /, which read and token-injected index.html on every probe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
saveResultToFile resolves its target with node:path resolve(cwd, path), so on Windows the mocked writeFile receives D:\d\a.json while the test asserted POSIX literals. Build the expected paths the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…2826) Tools, Resources and Prompts rows now render with wrap="truncate-end", so a long name no longer wraps into extra rows that the item-counting scroll window cannot see. The window is also re-clamped every render, so a terminal resize cannot leave the selected row outside it. The Tools detail header wraps its [Enter to Test] hint onto its own line when it does not fit beside the full tool name, instead of overlapping it, and a row's schema-portability marker sits outside the truncated text. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…eases (#2822) engines.node goes from >=22.19.0 to ^22.23.4 || ^24.22.1 || >=26.12.1, the patched release on each supported line, so npm warns (EBADENGINE) on an unpatched runtime. A per-line range is what keeps an unpatched 24.x or 26.x from satisfying it. Every doc that states the floor is updated. The code comments that reasoned from the 22.19 floor were re-read rather than replaced: - NODE_USE_ENV_PROXY was "unsupported at our floor"; it was added in 22.21.0, so it exists at 22.23.4. It is still no substitute: opt-in at process start and Stability 1.1. The comments now say that. - The short-GCM-tag note said only Node 22 accepts a truncated tag. The floor now spans 22 and 24, and 24 only runtime-deprecates it (DEP0182); Node 26 is where it is end-of-life. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Lockfile-only: ^2.0.0 already admits 2.0.4. Upstream calls it a patch of example and dependency changes with no library API change; its exports map and dependency set are identical to 2.0.3, so the bundler externals need no change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
The four-edit vitest bump: the exact pins on vitest and @vitest/coverage-v8 (root) and @vitest/browser-playwright (web), plus web's vitest overrides entry. Clears GHSA-qxg6-89mg-rqv8 and GHSA-xp26-3454-mjgp, and the @storybook/addon-vitest finding that was only inherited from vitest. ip-address (transitive, via server-legacy -> express-rate-limit ^10.2.0) is an in-range npm update, so no overrides entry. fast-uri was already fixed at 3.1.9 by #2820. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
happy-dom 21 turns iframe page loading off by default. The web unit project already stopped child-frame navigation, but with loading off every sandbox iframe now logs a NotSupportedError and gets no contentWindow. Turning enableIframePageLoading back on restores the previous behavior; the navigation flag still stops the frame before it fetches anything. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
, #2843) The loopback listener used by the CLI, TUI and mcpdo accepted the first request to its callback path whatever its `state`, so any local process or web page able to hit the fixed port could end an in-progress sign-in with a forged `?error=` and choose the message the runner reported. - `OAuthCallbackServer.start()` takes `expectedState` (a promise, since the listener is bound before the authorize URL exists). A callback whose `state` does not match -- success or error response -- gets a short 400 and the listener keeps waiting; one that arrives before the state is known is held until it is, or answered 503 if the listener stops first. - `runRunnerInteractiveOAuth` hands over the state from the authorize URL (the step-up URL before navigating, or the one `authenticate()` returns). - Authorization-server error text is labeled as such ("The authorization server said: ...") in both the page and the runner's error. - #2843: the non-GET, unparseable-URL and wrong-path branches (and the new mismatch, 409 and 503 answers) no longer send the "OAuth complete" page. - Responses send `Connection: close`, so `stop()` is not held open by an idle kept-alive socket. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Closing or reloading a connected web tab dropped /api/mcp/events and sent nothing else, so the backend RemoteSession and its spawned stdio child lived until the Inspector exited, queueing every later server message without bound. - Backend: arm a detach grace timer (default 60s, `sessionDetachGraceMs`) whenever a session has no events consumer — after connect and when its stream drops. A reattach (the OAuth redirect's attachToSession) cancels it; otherwise the transport is closed and the session dropped. A stream that was already replaced no longer clears the live consumer. - Cap RemoteSession's event queue at 1000, dropping the oldest and telling the next consumer how many went. - Web: on pagehide (not bfcache, not an OAuth redirect that will reattach to this session) send a keepalive fetch to /api/mcp/disconnect. Not sendBeacon: it cannot carry the x-mcp-remote-auth header every /api route requires. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
… split success latency, report dropped rate slots (#2834, #2835, #2836, #2837) - CLI: SIGINT/SIGTERM abort the run instead of the process; the partial summary prints with stoppedEarly.reason "interrupted", then exit 130. A second signal exits at once. Load flag refusals use load_flag_conflict. - Engine: circuit breaker after 50 consecutive thrown calls (or 1s of only thrown calls), reported as stoppedEarly consecutive_errors; mcpdo names a dropped connection connection_lost. - latencyMs is success-only, errorLatencyMs times failures, okThroughput added, --load-max-p99 judges successes; isError text is tallied in toolErrorMessages. - --load-rate runs report plannedStarts/droppedSlots/achievedRate and warn on stderr under 90% of target; a duration-bound run is measured to the end of its window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
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>
… text (#2847) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…tener Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…l in tests (#2847) The runner told our own exchange failures from redirect errors by the `error` string, which a redirect can set to anything (callback_error included). The listener now reports `source: "redirect" | "callback"` and the runner labels every redirect error. The integration tests waited 20ms for a request to reach the listener; they now wait on the http server's own "request" event. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…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>
…p, breaker only while starts remain, uncapped planned slots, exact shortfall check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…request (#2847) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…r the stop, whichever is first Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
…e figures count only calls made Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
Rollup smoke, round 1 (
|
| PR | Check | Result |
|---|---|---|
| #2848 | TLS web launch: the probe exits 0. Plain HTTP launch: the probe exits 0. HTTP probe against the TLS server: exits 1 | ✅ |
| #2849 | Over-long MCP_INSPECTOR_DAEMON_DIR: connections/list and servers/show both exit 1 with the socket-path error, and the dir is not created. Short dir: empty list, exit 0 |
✅ |
| #2850 | Real pty at 60×18: rows stay one line and truncate, the selected last tool stays visible, [Enter to Test] drops below the name |
✅ |
| #2852 | vitest 4.1.12, happy-dom 21.0.4, ext-apps 2.0.4, ip-address 10.7.5, fast-uri 3.1.9. engines is ^22.23.4 || ^24.22.1 || >=26.12.1. npm audit reports 0 in root and web |
✅ |
| #2853 | Playwright, connect then close tab: stdio children go 1 → 0 within 1s. Connect then reload: 1 → 0 within 1s (re-run after #2856 merged) | ✅ |
| #2854 | Wrong path gets 404 and POST gets 405, both with a "not the OAuth callback" page. Forged ?error= with no state, and wrong state, both get 400 "ignored" while the CLI keeps waiting. The genuine approval completes and the CLI prints tools/list |
✅ |
| #2856 | Weak-token warning ✅. Sandbox HEAD 200, ?x=1 200, rebind Host 403 ✅. /apixyz gets the SPA, /api/nope gets 401 ✅. No googleapis refs ✅. Seed uses os.tmpdir() ✅. The TUI ad-hoc server is named node, tools are A→Z, and "Test Tool:" appears once ✅ |
✅ |
| #2855 | #2835 breaker trips about 1.9s after the server dies, with stoppedEarly.consecutive_errors ✅. #2836 toolErrorMessages counts rate limited ×50, latencyMs is null, --load-max-p99 exits 10 ✅. #2837: 500 planned, 407 dropped, 18.6/s, warning printed; a 1/s run reports 1.0/s over 5000 ms ✅. load_flag_conflict ✅. #2834 ❌: a real SIGINT/SIGTERM exits 130 with no partial summary. when-exit re-raises the signal and the handler takes it for a second Ctrl+C |
❌, sent back to #2855 |
…ts as the second Ctrl+C (#2834) when-exit (via atomically) re-raises SIGINT/SIGTERM with process.kill after its cleanups, so the CLI's listener saw two signals for one press and exited 130 before the partial summary was written. A repeat of the same signal within 500ms of the first is now treated as that re-raise. Adds a spawn test that delivers real signals to the built CLI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Signed-off-by: cliffhall <cliff@futurescale.com>
|
Closing unmerged, as planned. This rollup did its job: all eight v2.14.0 PRs (#2852, #2853, #2854, #2855, #2856, #2848, #2849, #2850) merged together on |
Refs #2847, #2843, #2834, #2835, #2836, #2837, #2826, #2810, #2825, #2824, #2823, #2827, #2822, #2814, #2813, #2811
Integration proof only — this PR will be closed, not merged. It merges the eight v2.14.0 PRs together on top of
v2/mainto show they apply without conflicts and work together. Each one is then merged individually./healthzmcpdo connections/listandservers/showreport an over-limit socket pathstate; its non-callback pages no longer say sign-in finished--load: interrupt summary, circuit breaker, success-only latency, rate shortfallSmoke results on this branch are posted as a comment.
🤖 Generated with Claude Code