docs: state the exemption's canonicalization contract, and fix the smoke recipe's cwd

Copilot review round 2.

The exemption compares the WHATWG-canonicalized `URL.hostname`, so it covers
alternate spellings of three loopback *addresses* rather than three input
strings: `127.1`, `2130706433`, `0x7f.0.0.1`, `[0:0:0:0:0:0:0:1]` and a
root-anchored `127.0.0.1.` all pass. The behavior is right — the security
argument is about the address the request reaches, and all of these are the
loopback interface — but the comment described it as a literal-input match,
which it is not. It now states the contract, and six regression cases pin the
aliases alongside the existing near-miss cases.

This is also still an exact match for the SDK: `assertSecureTokenEndpoint` tests
`url.hostname` against the same three values after the same `new URL`
canonicalization, so an alias accepted here is one the SDK accepts too.

Separately, the smoke guide's fixture recipe left the shell in `clients/web`
after the build line, so the repo-root-relative paths on the next line resolved
under `clients/web` and the copy-pasted setup failed before the server started.
The build now runs in a subshell, and the block notes that the server announces
its URL on stderr and walks past a taken port.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GfHQ8vMm5NBgzbUJ6UwxmB
Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
cliffhall 2026-09-11 03:12:07 -04:00
commit a21fd0c161

View file

@ -513,10 +513,14 @@ Same MCP URL (`stytch-as-demo.val.run/mcp` or `mcp.stytch.dev/mcp`), leave CIMD
For offline CIMD regression — or a **strict** fail-with-CIMD-off / succeed-with-CIMD-on pair without Stytch’s DCR fallback — use the shipped `oauth-cimd-http.json` fixture, which sets `supportCIMD: true` and **`supportDCR: false`** and hosts the client metadata document itself at `/client-metadata.json`.
```bash
cd clients/web && npm run test-servers:build
# The build script lives in clients/web; both paths below are repo-root-relative,
# so come back up before starting the server.
(cd clients/web && npm run test-servers:build)
node test-servers/build/server-composable.js --config test-servers/configs/oauth-cimd-http.json
```
The server announces its URL on **stderr**, and walks to the next free port on `EADDRINUSE` — read the announced URL rather than assuming 8092.
Since [#2305](https://github.com/modelcontextprotocol/inspector/issues/2305) a loopback `http://` metadata URL is a **valid persisted `client.json` setting and a valid entry in the settings form**, not a test-only affordance — `getCimdClientMetadataUrlError` exempts `localhost`, `127.0.0.1` and `[::1]`, the same three literals the SDK exempts for token endpoints. So point `clientMetadataUrl` straight at the URL the fixture announced (`http://127.0.0.1:8092/client-metadata.json` on its configured port) with no HTTPS listener. Before that change the exemption existed only in `ensureCimdClientRegistration`, for an already-stored `client_id`, and driving this by hand needed a self-signed HTTPS listener plus `NODE_TLS_REJECT_UNAUTHORIZED=0`.
With CIMD off in Client Settings, connect + authenticate should **fail**; with CIMD on and that local metadata URL, it should **succeed**. `docs/test-servers.md` has the full walkthrough, including the `redirect_uris` port trap.