chore(release): merge v2/main into main for v2.8.0 - #2456
Merged
Merged
Conversation
!!process.env.DANGEROUSLY_OMIT_AUTH read every non-empty string as on, so =false silently disabled the bearer gate. Reuse the DANGEROUSLY_BIND_ALL_INTERFACES parser (exported as isEnvFlagEnabled) so both safety flags fail closed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…stream (#2317) A new suppressNotificationStream server setting answers the Streamable HTTP transport's standalone GET with a local 405, which the SDK already treats as 'no standalone stream', so traffic stays POST-only. It persists omit-when-off, is validated by the web backend, reaches createTransportNode on the web, CLI and TUI paths, and is exposed as a checkbox in Server Settings > Options for streamable-http servers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
A Zod schema instance reused by two fields is emitted once under $defs and referenced by a bare $ref with no type, so the web form rendered the second field as a JSON editor and dropped a plain string typed into it. Inline local refs once in core and use it in the web form schema, core argument conversion and the TUI tool form. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
The 2026-07-28 Streamable HTTP transport requires Mcp-Method on every POSTed message, notifications included, but the SDK derives the standard headers for requests only. Closing a subscriptions/listen stream — which every modern resource unsubscribe does — POSTs a notifications/cancelled without it, and a strict server refuses it with 400. Wrap the Streamable HTTP fetch so a single JSON-RPC notification carrying a modern protocol-version _meta claim gains Mcp-Method and MCP-Protocol-Version, mirroring the SDK's own request rule. Legacy and unclaimed messages pass through untouched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…uth-false fix(web): only DANGEROUSLY_OMIT_AUTH=true/1 disables /api auth
…endencies (#2391 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…round (#2392 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Neither the non-OK probe's release nor the substituted original's is awaited any more, so a body cancel that never settles can no longer stall discovery or keep the caller's abort from reaching it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…etached-body-release Signed-off-by: cliffhall <cliff@futurescale.com>
…me-header fix: stamp Mcp-Method on modern-era notification POSTs
…expansion (#2391 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…etached-body-release fix: detach the OIDC compat's normal-path body releases
…he legacy era (#2394 review) The transport shares its fetch with OAuth metadata discovery, so matching every headerless GET would have answered discovery with a synthetic 405. Match only a GET to the MCP endpoint asking for text/event-stream without Last-Event-ID. Docs, type comments and the form now say the stream exists only on the legacy era; the checkbox is hidden for a server pinned to modern. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…eep enumNames (#2391 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…ess-get-stream Signed-off-by: cliffhall <cliff@futurescale.com> # Conflicts: # core/mcp/node/transport.ts
…e-ref-widgets fix: resolve local $refs before choosing form widgets (#2321)
…ess-get-stream feat: per-server setting to suppress the standalone GET notification stream
…2286) Keep the rule at warning severity (it never fails --strict's exit 6), but reword its message to acknowledge that providers recommend the array form for nullable fields, and name the concrete consumer class it is unportable to instead of an unevidenced 'several MCP clients'. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…t's contract (#2395 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
….json (#2396 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…view) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…#2396 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…on (#2396 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…on (#2396 review) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…-union-caveat fix(core): reframe the type-union lint as a portability trade
…nly-config-interop
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
chore: add the project LICENSE and point every manifest at it
…del (#2447) Read the file-store passphrase from a file named by MCP_INSPECTOR_SECRET_KEY_FILE, so Docker and Compose secrets can supply it without putting it in the environment. Both variables set, or a key file that is missing, unreadable or empty, is a key problem: the store refuses to read or write rather than falling back to plaintext, and reports it as "File (unreadable)" with the reason. docker.md gains a warning that mounting the volume turns on plaintext file storage unless a key is supplied, with KEY_FILE examples for docker run and Compose; secret-storage.md gains a threat model for the file store. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
review) A set-but-empty key-file variable is a template that failed to expand, not a request for plaintext; also strip a lone trailing CR, and assert both key variables in the caveat and footer tooltip tests. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
#2447) A [!WARNING] after the selection table in secret-storage.md, and in the README and environment-variables.md, for Linux without libsecret, headless/SSH and Termux, where secrets land in a plaintext file without the user asking. The fallback and caveat warnings on stderr now end with a link to the guide. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…#2448 review) Source comments name MCP_INSPECTOR_SECRET_KEY_FILE and the per-write salt; the 'both set' conflict is qualified to a non-blank MCP_INSPECTOR_SECRET_KEY; the Docker example creates the key file 0600 under ~/.config (not in the project directory) and explains the uid 1000 ownership it needs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
Reading secrets.json as the passphrase and then overwriting it with ciphertext would change the key under the file on the next start. Checked by path and by inode, before reading. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…ity-advisory-skill docs: add the security-advisory skill, and reconcile the two rules it contradicts
gh project item-list truncates silently past --limit, and board #28 now holds more than the 500 the lookups asked for, so existing cards read as missing. Issue cards are now looked up from the issue's projectItems, which is independent of board size. Draft-card lookups and whole-board dumps (GHSA lookup, snapshot, recovery, triage sweep and audit) use --limit 2000 and assert .items|length == .totalCount, failing closed on a truncated listing or a failed gh call. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…t-storage-guide feat: MCP_INSPECTOR_SECRET_KEY_FILE, and document secret storage for every runtime
…#2452 review) Clear ITEM_ID before the GHSA lookup so a failed listing cannot leave an earlier id in place; guard item-edit and item-delete on a non-empty id, and split the issue-side lookup from the Status edit so the delete recipe does not inherit it; end every dump guard with false so an incomplete dump returns non-zero; widen projectItems to first:100. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…2452 review) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
A deleted dump still let the redirect create an empty lost-ids.json, so the re-apply loop ran zero times and exited 0. lost-ids.json is now written only inside the completeness check, and step 3 refuses to run without it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…iew) The snapshot is the only record of what the orphaned cards held, and an incomplete one is now deleted, so step 1 drops lost-ids.json when the snapshot report cannot run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…lookup-limits docs(skills): stop board lookups from trusting item-list --limit
npm audit --audit-level=high reports 0 vulnerabilities across the root and all four client installs, so no audit fixes precede the bump. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
…-2-8-0 chore: bump version to 2.8.0 (release step 1)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: cliffhall <cliff@futurescale.com>
5 tasks
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Private advisory summaries are exposed to broader project-board access, and required release verification evidence is still missing.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 3
Open (4)
What changed in this PR
Merges the complete v2.8.0 development tree into the release branch.
Changes:
- Adds schema-reference handling and Streamable HTTP compatibility controls.
- Hardens authentication and encrypted secret storage.
- Updates licensing, documentation, automation skills, and test coverage.
| File | Description |
|---|---|
package.json |
Bumps v2.8.0 and updates licensing. |
package-lock.json |
Synchronizes release metadata. |
LICENSE |
Adds transitional licensing terms. |
README.md |
Adds security, licensing, and roadmap guidance. |
AGENTS.md |
Updates repository and advisory rules. |
scripts/lib/claude-cli.mjs |
Generalizes CLI spawning and probing. |
scripts/lib/claude-cli.test.mjs |
Tests generic CLI helpers. |
scripts/skill-eval.mjs |
Adds Copilot skill evaluation. |
scripts/skill-eval.test.mjs |
Tests Copilot evaluation behavior. |
docs/secret-storage.md |
Documents secret-store selection and security. |
docs/docker.md |
Expands container secret guidance. |
docs/environment-variables.md |
Documents hardened flags and key files. |
docs/mcp-server-configuration.md |
Documents new transport setting and interoperability. |
docs/publishing.md |
Links secret-storage guidance. |
docs/skill-authoring.md |
Documents Copilot skill measurements. |
docs/v1-to-v2-migration.md |
Notes stricter auth flag parsing. |
docs/inspector-roadmap-2026-h2.md |
Adds the six-month roadmap. |
core/json/localRefs.ts |
Implements bounded local-reference inlining. |
core/json/jsonUtils.ts |
Resolves references before coercion. |
core/json/schemaLint.ts |
Clarifies union portability warnings. |
core/mcp/types.ts |
Adds notification-stream suppression settings. |
core/mcp/serverList.ts |
Persists the new transport setting. |
core/mcp/remote/node/server.ts |
Validates and normalizes the setting. |
core/mcp/node/transport.ts |
Installs HTTP fetch wrappers. |
core/mcp/node/suppressNotificationStreamFetch.ts |
Suppresses standalone legacy SSE streams. |
core/mcp/node/notificationHeadersFetch.ts |
Stamps modern notification headers. |
core/auth/secret-storage-info.ts |
Mentions both encryption-key mechanisms. |
core/auth/oidcDiscoveryCompat.ts |
Prevents stalled response cancellation. |
core/auth/node/secret-store.ts |
Documents key-file support. |
core/auth/node/secret-store-selection.ts |
Adds secret-storage guidance links. |
core/auth/node/file-secret-store.ts |
Adds fail-closed key-file loading. |
clients/web/src/utils/jsonUtils.ts |
Resolves references for web forms. |
clients/web/server/web-server-config.ts |
Parses omit-auth safely. |
clients/web/server/resolve-bind-host.ts |
Shares strict environment-flag parsing. |
clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.tsx |
Connects stream suppression to settings. |
clients/web/src/components/groups/ServerSettingsModal/ServerSettingsModal.test.tsx |
Tests modal persistence behavior. |
clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.tsx |
Adds the suppression checkbox. |
clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.test.tsx |
Tests checkbox behavior and visibility. |
clients/web/src/components/groups/ServerSettingsForm/ServerSettingsForm.stories.tsx |
Updates interactive stories. |
clients/web/src/components/groups/SchemaForm/SchemaForm.test.tsx |
Tests referenced form properties. |
clients/web/src/components/elements/SecretStorageFooter/SecretStorageFooter.tsx |
Updates encryption advice. |
clients/web/src/components/elements/SecretStorageFooter/SecretStorageFooter.test.tsx |
Tests key-file advice. |
clients/web/src/test/core/localRefs.test.ts |
Covers reference resolution and bounds. |
clients/web/src/test/core/jsonUtils.test.ts |
Tests referenced-value coercion. |
clients/web/src/test/core/schemaLint.test.ts |
Tests revised portability warnings. |
clients/web/src/test/core/mcp/serverList.test.ts |
Tests suppression-setting round trips. |
clients/web/src/test/core/mcp/node/suppressNotificationStreamFetch.test.ts |
Tests request classification. |
clients/web/src/test/core/mcp/node/notificationHeadersFetch.test.ts |
Tests notification header stamping. |
clients/web/src/test/core/auth/secret-storage-info.test.ts |
Tests encryption guidance. |
clients/web/src/test/core/auth/oidcDiscoveryCompat.test.ts |
Tests non-settling cancellation. |
clients/web/src/test/integration/server/web-server-config.test.ts |
Tests strict auth opt-in values. |
clients/web/src/test/integration/mcp/suppress-notification-stream.test.ts |
Exercises suppression through the SDK. |
clients/web/src/test/integration/mcp/remote/server-extra-coverage.test.ts |
Tests remote setting validation. |
clients/web/src/test/integration/mcp/inspectorClient-subscriptions-era.test.ts |
Verifies modern notification headers. |
clients/web/src/test/integration/auth/node/secret-store-selection.test.ts |
Tests guidance warnings. |
clients/web/src/test/integration/auth/node/file-secret-store.test.ts |
Tests key-file failure modes. |
clients/web/package.json |
Updates web licensing metadata. |
clients/web/package-lock.json |
Synchronizes web licensing metadata. |
clients/tui/src/components/ToolTestModal.tsx |
Resolves references for TUI forms. |
clients/tui/__tests__/ToolTestModal.test.tsx |
Tests referenced union validation. |
clients/tui/package.json |
Updates TUI licensing metadata. |
clients/tui/package-lock.json |
Synchronizes TUI licensing metadata. |
clients/cli/package.json |
Updates CLI licensing metadata. |
clients/cli/package-lock.json |
Synchronizes CLI licensing metadata. |
clients/launcher/package.json |
Updates launcher licensing metadata. |
clients/launcher/package-lock.json |
Synchronizes launcher licensing metadata. |
.claude/skills/testing/SKILL.md |
Strengthens test-server handoff guidance. |
.claude/skills/security-advisory/SKILL.md |
Adds the private-advisory procedure. |
.claude/skills/security-advisory/evals/evals.json |
Adds advisory-skill trigger cases. |
.claude/skills/issue-triage/SKILL.md |
Hardens board audits and advisory handling. |
.claude/skills/issue-create/SKILL.md |
Documents the advisory exception. |
.claude/skills/board-ops/SKILL.md |
Hardens project-card lookup procedures. |
Files not reviewed (4)
- clients/cli/package-lock.json: Generated file
- clients/launcher/package-lock.json: Generated file
- clients/tui/package-lock.json: Generated file
- clients/web/package-lock.json: Generated file
Closed
3 tasks
Member
Author
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Closes #2455
Milestone merge of
v2/mainintomainfor the v2.8.0 release — step 2 of thereleaseskill.This is a pure merge
No commits of its own — the merge commit and nothing else:
The merged tree is byte-identical to
origin/v2/main, with no conflicts. Version on the tree: 2.8.0 (bumped onv2/mainfirst in #2453 / PR #2454, per #2010).Milestone payload
v2.8.0 is complete: 14 contributions closed, plus the bump. Fifteen PRs landed on
v2/mainsince 2.7.0 (#2390–#2396, #2398, #2401, #2402, #2444, #2448, #2449, #2452, #2454), one per milestone issue plus the bump. The only issue still open is this merge (#2455).Verification
npm run local:gate(dedicated worktree, fullnpm install)node --test)npm run pack:verify(its own step; not a gate stage)All 14 of 14 milestone issues were driven from the production build (built launcher, served web
dist, CLI and TUI bundles) against real test servers. Highlights:Mcp-Method(control: 400 without the header), Subscribe → Unsubscribe in the web client sentnotifications/cancelledwithmcp-method=notifications/cancelled, and none was refused.initialize · initialized · GET · tools/list, and the suppressed connect sentinitialize · initialized · tools/list. The setting persisted to the catalog and is hidden for modern-pinned servers.$refrender as text inputs in the web client and the TUI, and both send"since":"2026-09-01","until":"2026-09-23"as strings.DANGEROUSLY_OMIT_AUTH=false/FALSE/0/no/""→ 401 without a token; onlytrue/1(trimmed, any case) omit auth.cancel()that never settles: the fix resolves in 10ms and honors an abort in 103ms, while the pre-fix file fromorigin/mainhangs on both.skills:evalsuite through Copilot: 71/71 first-move cases at 100% (including all six for the newsecurity-advisoryskill) and 2/2 hand-offs. Thetest-servershand-offs atRUNS=5: listing 100%, pagination 60%, matching what Make the testing → test-servers hand-off fire under Copilot on the pagination prompt #2402 recorded.Full ledger, one row per issue with the output observed: https://claude.ai/artifact/YLGV4sYUwwRwusNNgPZPFF
After merge
Tag
origin/mainwith the bare2.8.0(novprefix) and publish the GitHub Release, which firespublishandpublish-github-container-registry.🤖 Generated with Claude Code