feat(auth): advertise offline_access in discovered OAuth scopes
discover_all_scopes() builds the scopes_supported lists exposed at /.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server. It previously emitted only the base OIDC scopes plus tool-derived @require_scopes, so offline_access was never advertised and discovery-driven MCP clients had no way to know they could request a refresh token. Add offline_access unconditionally. The AS proxy already forwards client-requested scopes upstream to Nextcloud, which issues a refresh token when the MCP server's OIDC client is permitted the scope. This only changes what is advertised; it is not added to ALL_SUPPORTED_SCOPES (the app-level permission set), since offline_access is an OIDC behavior rather than a Nextcloud resource permission. Add a regression test asserting offline_access is always present in discover_all_scopes() output. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
fcbf6e1486
commit
c30a795a1f
@@ -523,11 +523,12 @@ def discover_all_scopes(mcp) -> list[str]:
|
||||
pass
|
||||
|
||||
scopes = discover_all_scopes(mcp)
|
||||
# Returns: ["notes.read", "notes.write", "openid", "profile", "email"]
|
||||
# Returns: ["notes.read", "notes.write", "offline_access", "openid", ...]
|
||||
```
|
||||
|
||||
Note:
|
||||
- Base OIDC scopes (openid, profile, email) are always included
|
||||
- offline_access is always included so clients can request a refresh token
|
||||
- Scopes are deduplicated and sorted alphabetically
|
||||
- Only scopes from decorated tools are included
|
||||
- Must be called after tools are registered
|
||||
@@ -535,6 +536,13 @@ def discover_all_scopes(mcp) -> list[str]:
|
||||
# Start with base OIDC scopes that are always required
|
||||
all_scopes = {"openid", "profile", "email"}
|
||||
|
||||
# Advertise offline_access so discovery-driven MCP clients can request a
|
||||
# refresh token. The AS proxy forwards it upstream to Nextcloud, which
|
||||
# issues a refresh token when the MCP server's OIDC client is permitted the
|
||||
# scope. Optional for clients (unlike the base OIDC scopes) and never tied
|
||||
# to a tool, so it is added here rather than discovered from @require_scopes.
|
||||
all_scopes.add("offline_access")
|
||||
|
||||
# Get all registered tools
|
||||
try:
|
||||
tools = mcp._tool_manager.list_tools()
|
||||
|
||||
Reference in New Issue
Block a user