Commit graph

2,607 commits

Author SHA1 Message Date
Bob Dickinson
479e757315 Merge remote-tracking branch 'origin/v2/main' into feat/mid-session-auth 2026-07-02 16:38:33 -07:00
Bob Dickinson
562bdd00f1 All of the mid-session and step-up auth work 2026-07-02 16:35:31 -07:00
cliffhall
d68202a88b docs(spec): add V2 Auth landing page and canonicalize spec top menus (closes #1605)
Add a specification/v2_auth.md landing page summarizing the four auth specs
(EMA / XAA, Hardening, Mid-session, Smoke testing) with a section submenu,
mirroring the V2 UX index pattern.

Add a V2 Auth link (after V2 UX) and a V2 New Spec Impact link to every spec
page's top menu so the top-level nav is uniform, and restructure the four
v2_auth_*.md pages onto the shared two-tier menu (top menu + auth submenu).

Docs only.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-02 17:20:06 -04:00
cliffhall
859911d5ad revert(rollup): remove CONTRIBUTORS docs (#1537/#1517) from Wave-1 rollup — tracked separately, not Wave 1 2026-07-02 13:03:41 -04:00
Cliff Hall
c2bc6a6a63
Merge pull request #1603 from modelcontextprotocol/1550-ci-coverage-gate
ci: enforce the ≥90% per-file coverage gate in CI
2026-07-02 12:49:20 -04:00
Cliff Hall
747148fac3
Merge pull request #1597 from modelcontextprotocol/v2/1596-test-stability
test(web): eliminate timeout flakiness in the web test suite
2026-07-02 12:46:53 -04:00
cliffhall
fa274fae06 chore: retarget #1597 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:46:47 -04:00
Cliff Hall
7d4caf8081
Merge pull request #1537 from modelcontextprotocol/chore/1517-contributors-md
docs: add CONTRIBUTORS.md issues-only policy (#1517)
2026-07-02 12:46:31 -04:00
cliffhall
9f0e4d88e2 chore: retarget #1537 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:46:25 -04:00
Cliff Hall
7e1496a338
Merge pull request #1592 from modelcontextprotocol/v2/1548-web-remote-oauth-storage
Web: migrate auth store to shared /store API (RemoteOAuthStorage parity with TUI/CLI)
2026-07-02 12:46:16 -04:00
cliffhall
ca00935d1e chore: retarget #1592 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:46:11 -04:00
Cliff Hall
8b8e46ffee
Merge pull request #1591 from modelcontextprotocol/v2/1559-hostcontext-utils
feat(web): extract hostContext utilities for the Apps host
2026-07-02 12:45:50 -04:00
cliffhall
1fdf03e2ec chore: retarget #1591 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:45:46 -04:00
Cliff Hall
42fb853038
Merge pull request #1590 from modelcontextprotocol/v2/1563-node-proxy
feat(core): honor HTTPS_PROXY/HTTP_PROXY/NO_PROXY in the Node transport
2026-07-02 12:45:30 -04:00
cliffhall
30dc370ddf chore: retarget #1590 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:45:23 -04:00
Cliff Hall
d307639354
Merge pull request #1589 from modelcontextprotocol/v2/1562-oauth-state-hardening
auth hardening: generateOAuthState requires WebCrypto; OAuth callback rejects unparseable state
2026-07-02 12:45:04 -04:00
cliffhall
56ca566296 chore: retarget #1589 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:44:58 -04:00
Cliff Hall
3de93b9beb
Merge pull request #1588 from modelcontextprotocol/v2/1558-sandbox-csp
feat(web): add sandbox CSP builder library (closes #1558)
2026-07-02 12:44:43 -04:00
cliffhall
060b64af1d chore: retarget #1588 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:44:37 -04:00
Cliff Hall
b96fd6eb0d
Merge pull request #1587 from modelcontextprotocol/v2/1557-mcp-app-demo
feat(test-servers): mcp_app_demo preset + _meta on tool/resource defs
2026-07-02 12:44:17 -04:00
cliffhall
3b4c958426 chore: retarget #1587 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:44:12 -04:00
Cliff Hall
53cca10323
Merge pull request #1586 from modelcontextprotocol/v2/1560-downloadfile
feat(web): downloadFile.ts enhancements (downloadBlob, fileNameFromUri, isHttpUrl)
2026-07-02 12:43:52 -04:00
cliffhall
949bc3b514 chore: retarget #1586 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:43:48 -04:00
Cliff Hall
98dff8b0d3
Merge pull request #1585 from modelcontextprotocol/v2/1561-redact-headers
feat(core): redact sensitive headers in the fetch log
2026-07-02 12:43:29 -04:00
cliffhall
ff9269c417 chore: retarget #1585 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:43:24 -04:00
Cliff Hall
72ae119d09
Merge pull request #1584 from modelcontextprotocol/v2/1556-core-appinfo
feat(core): add AppInfo + extractAppInfo() to core/mcp/apps.ts
2026-07-02 12:43:04 -04:00
cliffhall
985ef32de0 chore: retarget #1584 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:42:59 -04:00
Cliff Hall
0fe9c4e4d9
Merge pull request #1583 from modelcontextprotocol/v2/1564-cli-exit-codes
feat(cli): exit-code map + structured JSON error envelopes
2026-07-02 12:42:49 -04:00
cliffhall
436257b17f chore: retarget #1583 onto 1579-wave-1 rollup (empty commit enables base change; tree unchanged) 2026-07-02 12:42:26 -04:00
cliffhall
61ca22003f ci: enforce the ≥90% per-file coverage gate in CI (closes #1550)
Add a CI step that runs `npm run coverage` so a PR that drops any file
below 90% on lines/statements/functions/branches fails the job. Remove
the now-redundant standalone `Run web integration tests` step, since
web's `test:coverage` already runs `--project=unit --project=integration
--coverage`, and update AGENTS.md to reflect that CI now enforces the gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-02 11:59:32 -04:00
cliffhall
e19d11070a merge: #1599 gate src/lib coverage (#1594) 2026-07-01 22:48:03 -04:00
cliffhall
4b180d919a merge: #1598 redact bodies+URL query (#1593) 2026-07-01 22:48:00 -04:00
cliffhall
775b98a019 docs(core): clarify redaction scope + add nested request-body test
Address round-1 review feedback on fetchTracking redaction:
- Cross-reference REDACTED_VALUE / REDACTED_HEADER_VALUE so a reader
  understands why two identical "[REDACTED]" constants coexist.
- Document that redactBody deliberately scopes to form-encoded + JSON
  (multipart/binary bodies pass through; OAuth never uses multipart).
- Add a tracker-path test asserting a nested sensitive key in a JSON
  request body is redacted in the recorded copy while the live outbound
  body stays byte-identical.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 22:34:40 -04:00
cliffhall
1fd1313c96 test(web): gate src/lib/** under the coverage include globs (closes #1594)
Broaden the web vitest `coverage.include` from the single-file
`src/lib/sandbox-csp.{ts,tsx}` entry to `src/lib/**/*.{ts,tsx}` so the
per-file >=90 four-dimension gate applies to every library module under
`src/lib`, not just sandbox-csp.

- Add unit tests for the previously-ungated `environmentFactory.ts`
  (createWebEnvironment) and `types/customHeaders.ts` value helpers,
  bringing both to 100% on all four dimensions.
- Annotate downloadFile.ts's provably-dead `?? ""` fallback (String.split
  always returns a non-empty array so .pop() is never undefined) with a
  justified `v8 ignore`, closing its last uncovered branch (92.3 -> 100).

All five src/lib files now report 100/100/100/100.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 22:23:43 -04:00
cliffhall
524bf2d543 feat(core): redact sensitive body + URL-query fields in fetch log (closes #1593)
Extends the header redaction from #1585. Before a fetch entry reaches any
sink, mask known-sensitive credentials in the request/response bodies and
the URL query string, in addition to headers:

- redactBody(): form-urlencoded + JSON bodies, recursive over nested
  objects/arrays, best-effort (never throws), values-only.
- redactUrlQuery(): masks sensitive query params, preserves path,
  non-sensitive params, and any fragment.
- Sensitive fields: client_secret, code, refresh_token, access_token,
  id_token, code_verifier, client_assertion, assertion, password, token
  (case-insensitive), reusing the [REDACTED] sentinel.

Applied to the request success + error entries and the async response-body
callback. Live outbound requests are byte-identical — only the logged copy
is redacted.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 22:20:42 -04:00
cliffhall
b2ff34a901 merge: chore/1517-contributors-md (#1537) 2026-07-01 22:06:17 -04:00
cliffhall
c6b5af3b81 merge: v2/1596-test-stability (#1597) 2026-07-01 22:05:57 -04:00
cliffhall
e425602295 merge: v2/1548-web-remote-oauth-storage (#1592)
# Conflicts:
#	clients/web/src/test/core/auth/utils.test.ts
2026-07-01 22:05:52 -04:00
cliffhall
cc37a755ae merge: v2/1562-oauth-state-hardening (#1589) 2026-07-01 22:04:22 -04:00
cliffhall
52cd90bd50 merge: v2/1560-downloadfile (#1586) 2026-07-01 22:04:18 -04:00
cliffhall
3f22299b14 merge: v2/1559-hostcontext-utils (#1591) 2026-07-01 22:04:18 -04:00
cliffhall
e55867cd45 merge: v2/1558-sandbox-csp (#1588) 2026-07-01 22:04:12 -04:00
cliffhall
9257c849b9 merge: v2/1557-mcp-app-demo (#1587) 2026-07-01 22:04:07 -04:00
cliffhall
4c5036e032 merge: v2/1564-cli-exit-codes (#1583) 2026-07-01 22:04:01 -04:00
cliffhall
4e3cd591a4 merge: v2/1563-node-proxy (#1590) 2026-07-01 22:03:55 -04:00
cliffhall
2d1a99ab37 merge: v2/1561-redact-headers (#1585) 2026-07-01 22:03:51 -04:00
cliffhall
8bc32c85d7 merge: v2/1556-core-appinfo (#1584) 2026-07-01 22:03:46 -04:00
cliffhall
dd7812063c test(web): make the debounce-cancellation test load-bearing (review round 1)
The "cancels a pending debounce timer when the input is re-focused" test
passed trivially after the delay:null change: synchronous typing meant the
assertion ran at t≈0, before the 300ms debounce could ever fire, so it
passed whether or not handleFocus's clearTimeout worked.

Rewrote it with fake timers so the debounce window elapses deterministically
(advance the clock by 400ms directly). The interaction is driven with
fireEvent rather than userEvent because userEvent's async internals deadlock
under vitest fake timers with the Mantine/happy-dom stack. Verified
load-bearing: removing the clearTimeout in handleFocus makes it fail
(expected 1 to be 0), and it passes once restored.

Also tightened the sibling-context comment (with delay:null the sibling is
reliably "es"); the tolerant /^es?$/ regex is left as-is.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 21:22:04 -04:00
cliffhall
4bad110942 test(web): eliminate timeout flakiness in the web test suite (closes #1596)
Root-cause and deterministically fix the recurring 5s-timeout flakes that
surfaced under v8-instrumented, concurrent load. All fixes are test-only; no
product source changed. No test was skipped or disabled, and the per-file
coverage gate (>=90 on all four dims) still holds.

Common root cause across the modal/form/screen suites: userEvent.setup()
schedules a real setTimeout between keystrokes. Under CPU contention those
yields balloon, so multi-field interactions blew past the 5s per-test
timeout. Fix: userEvent.setup({ delay: null }) removes the per-keystroke
real-timer dependence (typing dispatches synchronously), making the suites
load-independent.

Per file:
- ServerConfigModal / ServerImportConfigModal / ServerImportJsonModal /
  ResourcesScreen / InspectorView: userEvent.setup({ delay: null }).
- PromptArgumentsForm (completions): replaced wall-clock sleeps sized just
  past the 300ms completion debounce (await setTimeout(400)) — which race
  the debounce timer under load — with awaited conditions (findBy/waitFor)
  on the real rendered outcome, plus delay:null. Negative assertions now
  lean on the component's synchronous state/timer teardown instead of a
  timed window, so they are deterministic regardless of machine speed.
- inspectorClient integration "tracks stderr logs": the child's stderr is
  piped out-of-band from the tool's JSON-RPC response, so reading the log
  synchronously after callTool raced the stderr chunk. Wrapped the assertion
  in vi.waitFor so it polls until the line lands.

Verified: web validate + 6x test:coverage (4 sequential + 2 concurrent
under load) + standalone test:integration, all green (229 files / 3237
tests per coverage run; 799 integration tests), zero intermittent failures.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S3fTN8H3R8YV4yUGvZjYnX
2026-07-01 21:11:11 -04:00
cliffhall
3df4f0e7e2 Merge remote-tracking branch 'origin/v2/main' into merge-1537 2026-07-01 20:57:34 -04:00