docs(auth): clarify that resource_server_url must include the transport path#2662
Conversation
…rt path The `resource_server_url` setting must equal the full public URL of the MCP endpoint, including the transport path, so that the value advertised in RFC 9728 Protected Resource Metadata matches the URL the client used to reach the server. RFC 9728 §3.3 requires strict equality. Update the `AuthSettings.resource_server_url` docstring to spell this out, fix the `examples/snippets/servers/oauth_server.py` snippet so it ends in `/mcp`, and select `/mcp` or `/sse` in the `simple-auth` example based on the chosen transport instead of hardcoding `/mcp` regardless of the `--transport=sse` flag. Refs modelcontextprotocol#1264
The README code snippet at L1024-1028 is run through ruff via pytest_examples. On Windows the ruff subprocess pipe defaults to cp1252 and fails to decode the \xc2\xa7 byte sequence, breaking the 10 Windows CI jobs with 'stream did not contain valid UTF-8'. Linux and macOS pipes default to UTF-8 so they passed. Replace \xc2\xa7 with the word 'section' across the four files I introduced it in. Pre-existing \xc2\xa7 references elsewhere in the tree are unaffected.
|
Pushed d54b216 to fix the 10 Windows CI failures. Root cause was the Replaced |
Issue #1264 keeps surfacing because RFC 9728 §3.3 requires strict equality between the client's resource identifier and the
resourcevalue advertised in protected resource metadata, but the public surface ofAuthSettings.resource_server_urldoes not say this. PR #1407 established the contract thatresource_server_urlmust be the full endpoint URL including the transport path, and thesimple-authexample was updated, but the matchingexamples/snippets/servers/oauth_server.pysnippet (which is rendered intoREADME.v2.mdbyscripts/update_readme_snippets.py) still passeshttp://localhost:3001with no path, theAuthSettings.resource_server_urldescription still says only "URL of the MCP server", andsimple-auth/server.pyhardcodes/mcpeven when the user passes--transport=sse.This change updates the
AuthSettings.resource_server_urlfield description to spell out the contract, including the requirement that the URL include the transport path and the reference to RFC 9728 §3.3. Theoauth_server.pysnippet is changed tohttp://localhost:3001/mcpwith a comment explaining why, andREADME.v2.mdis regenerated so the embedded snippet matches. Insimple-auth/server.py, the override that builtserver_urlpicks/sseor/mcpbased on the--transportflag so the SSE path no longer produces an RFC 9728 mismatch.Per the closing comment on #2189, the maintainer asked for a docs and example fix here rather than auto-appending
streamable_http_path, becausestreamable_http_pathis an internal Starlette route and not always the public URL (for example when the app is mounted at/apiwithstreamable_http_path="/", or behind a reverse proxy). Verified withuv run --frozen ruff check,uv run --frozen pyright,uv run --frozen pytest tests/server/auth/ tests/server/mcpserver/(388 passed), anduv run --frozen python scripts/update_readme_snippets.py --check.Refs #1264