The token-exchange-nextcloud scope was being inherited by DCR clients
and requested by external MCP clients (like Gemini CLI), causing all
tokens to have aud: "nextcloud" even when targeting the MCP server.
## Problem
When external clients registered via DCR, they inherited all optional
scopes from the realm defaults, including token-exchange-nextcloud. When
these clients requested tokens, they would include this scope, which added
aud: "nextcloud" via the scope's protocol mapper.
This caused authentication failures for MCP server access:
```
'aud': 'nextcloud'
WARNING - Token rejected: wrong audience ['nextcloud'], expected nextcloud-mcp-server
```
## Root Cause
Client scopes with protocol mappers are applied whenever that scope is
requested, regardless of which client requests it. The token-exchange-nextcloud
scope was designed for the MCP server's own token requests to Nextcloud APIs,
but external clients were also requesting it.
## Solution
Move the audience mapper from the token-exchange-nextcloud scope to a
direct protocol mapper on the nextcloud-mcp-server client itself.
### Changes
1. **Remove token-exchange-nextcloud from nextcloud-mcp-server optional scopes**
- External DCR clients won't inherit this scope
- Prevents external clients from requesting it
2. **Add nextcloud-audience protocol mapper directly to nextcloud-mcp-server**
- Hardcode aud: "nextcloud" for this client only
- Only tokens issued TO nextcloud-mcp-server will have this audience
- External MCP clients won't be affected
## Behavior After Fix
**Gemini CLI (DCR client) → MCP Server**:
- Client doesn't have token-exchange-nextcloud scope
- Token audience: Based on RFC 8707 resource parameter (if provided)
- Result: No hardcoded audience ✅
**MCP Server (nextcloud-mcp-server) → Nextcloud APIs**:
- Client has nextcloud-audience protocol mapper
- Token audience: Always "nextcloud" (hardcoded)
- Result: aud: "nextcloud" for Nextcloud API access ✅
## Related
- RFC 8707: Resource Indicators for OAuth 2.0
- Keycloak client scopes vs. client protocol mappers
- DCR client scope inheritance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>