Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions docs/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,14 @@ Revoke the client's grant in your Usable account settings, then remove the store
credentials from the client (see the client's own credential management). Revocation is
immediate for new requests; already-issued access tokens remain valid until they expire.

## Known deviation
## Both metadata URLs work

The path-suffixed protected-resource URL from RFC 9728 §3.1,
`https://usable.dev/.well-known/oauth-protected-resource/api/mcp`, currently returns the
site's HTML rather than JSON or a 404. Clients that construct that URL by convention instead
of following the `resource_metadata` parameter in the `WWW-Authenticate` header will fail
discovery.
Either discovery strategy reaches the same document. Reading the `resource_metadata`
parameter out of the `WWW-Authenticate` challenge gives
`https://usable.dev/.well-known/oauth-protected-resource`; constructing the URL by the
RFC 9728 §3.1 rule — inserting `/.well-known/oauth-protected-resource` between host and
resource path — gives `https://usable.dev/.well-known/oauth-protected-resource/api/mcp`.
Both return the same JSON.

Clients that follow the header — which is what the specification requires — work correctly.
This is recorded in `docs/supported-clients.md` and has been reported upstream.
The path-suffixed URL previously served the site's HTML, which broke discovery for clients
that prefer the RFC construction over the challenge header. Fixed server-side on 2026-08-07.
11 changes: 6 additions & 5 deletions docs/supported-clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,13 @@ Untested. Needs verification of plugin loading, skill discovery, and OAuth handl

## Known ecosystem deviations

**Path-suffixed protected resource metadata returns HTML.**
`https://usable.dev/.well-known/oauth-protected-resource/api/mcp` serves the site's HTML
rather than JSON or a 404. Clients that build that URL by convention — appending the resource
**Path-suffixed protected resource metadata returned HTML. Fixed 2026-08-07.**
`https://usable.dev/.well-known/oauth-protected-resource/api/mcp` used to serve the site's
HTML rather than JSON, so clients that build that URL by convention — appending the resource
path, per RFC 9728 §3.1 — instead of reading the `resource_metadata` parameter from the
`WWW-Authenticate` header will fail discovery. Clients that follow the header succeed.
Reported upstream; tracked for a server-side fix.
`WWW-Authenticate` header failed discovery. Both URLs now return the same JSON document, and
unmatched paths under `.well-known` return a JSON `404` rather than the app shell. No client
workaround is needed.

**`plain` PKCE is advertised.** The authorization server lists both `S256` and `plain` in
`code_challenge_methods_supported`. Clients must use `S256`.
Expand Down
7 changes: 4 additions & 3 deletions docs/troubleshooting.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ Then:

```bash
curl -sS https://usable.dev/.well-known/oauth-protected-resource
curl -sS https://usable.dev/.well-known/oauth-protected-resource/api/mcp
curl -sS https://usable.dev/.well-known/oauth-authorization-server
```

Both must return JSON. If they do and your client still fails, the client is likely building
the path-suffixed metadata URL by convention instead of reading the `resource_metadata`
parameter — see the known deviation in `supported-clients.md`.
All three must return JSON, and the first two must return the same document — a client is
free to reach the metadata either by reading `resource_metadata` from the challenge header or
by constructing the path-suffixed URL per RFC 9728 §3.1.

**Browser never opens.** Headless or remote environments cannot complete the interactive
flow. Do not work around this by adding a static credential to `mcp.json`. See the headless
Expand Down