Files
nextcloud-mcp-server/keycloak
Chris Coutinho 3d4dfcbb35 fix: move token-exchange-nextcloud from default to optional scopes
The token-exchange-nextcloud scope was in both default and optional scopes
for the nextcloud-mcp-server client, causing all tokens to have aud: "nextcloud"
even when clients requested tokens for the MCP server itself.

## Problem

When external MCP clients (like Gemini CLI) requested tokens with
`resource=http://localhost:8002/mcp`, the tokens still had `aud: "nextcloud"`
because the token-exchange-nextcloud scope was automatically included as a
default scope. This caused authentication failures:

```
WARNING - Token rejected: wrong audience ['nextcloud'], expected nextcloud-mcp-server
ERROR - Received Nextcloud token in MCP context - client may be using wrong token
```

## Solution

Remove token-exchange-nextcloud from defaultClientScopes array. It remains in
optionalClientScopes for when the MCP server explicitly needs to request tokens
for Nextcloud API access.

### Before
```json
"defaultClientScopes": [
  "web-origins",
  "profile",
  "roles",
  "email",
  "token-exchange-nextcloud"  //  Auto-included
]
```

### After
```json
"defaultClientScopes": [
  "web-origins",
  "profile",
  "roles",
  "email"  //  Only OIDC basics
]
```

## Behavior

**External MCP Clients (Gemini CLI)**:
- Request: `resource=http://localhost:8002/mcp` (no token-exchange scope)
- Token audience: Determined by RFC 8707 resource parameter
- Result: `aud: "http://localhost:8002/mcp"` 

**MCP Server → Nextcloud APIs**:
- Request: `scope=token-exchange-nextcloud` (explicitly included)
- Token audience: Set by scope's audience mapper
- Result: `aud: "nextcloud"` 

## Related
- RFC 8707: Resource Indicators for OAuth 2.0
- RFC 9728: OAuth 2.0 Protected Resource Metadata
- Previous commit: Removed hardcoded audience-mcp-server mapper

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-04 05:35:07 +01:00
..