Skip to main content
Glama
oauth-troubleshooting.md16.7 kB
# OAuth Troubleshooting This guide covers OAuth-specific issues and solutions for the Nextcloud MCP server. For general troubleshooting, see [Troubleshooting Guide](troubleshooting.md). ## Quick Diagnosis Start here to identify your issue: | Symptom | Likely Cause | Quick Fix Link | |---------|--------------|----------------| | "OAuth mode requires NEXTCLOUD_HOST" | Missing environment variable | [Missing NEXTCLOUD_HOST](#missing-nextcloud_host) | | "OAuth mode requires client credentials OR dynamic registration" | OIDC apps not configured | [Missing OIDC Apps](#missing-or-misconfigured-oidc-apps) | | "PKCE support validation failed" | OIDC app doesn't advertise PKCE | [PKCE Not Advertised](#pkce-not-advertised) | | "Stored client has expired" | Dynamic client expired | [Client Expired](#client-expired) | | Only seeing Notes tools (7 instead of 90+) | Limited OAuth scopes granted | [Limited Scopes](#limited-scopes---only-seeing-notes-tools) | | HTTP 401 for Notes API | Bearer token patch missing | [Bearer Token Auth Fails](#bearer-token-authentication-fails) | | "OIDC discovery failed" | Network or configuration issue | [Discovery Failed](#oidc-discovery-failed) | | "Database error" on OAuth client storage | Database permissions issue | [Database Permission Error](#database-permission-error) | ## Configuration Issues ### Missing NEXTCLOUD_HOST **Error Message**: ``` OAuth mode requires NEXTCLOUD_HOST environment variable ``` **Cause**: The `NEXTCLOUD_HOST` environment variable is not set or empty. **Solution**: 1. Add to your `.env` file: ```bash NEXTCLOUD_HOST=https://your.nextcloud.instance.com ``` 2. Reload environment variables: ```bash export $(grep -v '^#' .env | xargs) ``` 3. Verify it's set: ```bash echo $NEXTCLOUD_HOST # Should output: https://your.nextcloud.instance.com ``` --- ### Missing or Misconfigured OIDC Apps **Error Message**: ``` OAuth mode requires either client credentials OR dynamic client registration ``` **Cause**: The required Nextcloud OIDC apps are either: - Not installed - Not enabled - Missing configuration **Solution**: **Step 1**: Verify both apps are installed: ```bash # Check installed apps php occ app:list | grep -E "oidc|user_oidc" # Should show: # - oidc: enabled # - user_oidc: enabled ``` If not installed: 1. Open Nextcloud as administrator 2. Navigate to **Apps** → **Security** 3. Install **"OIDC"** (OIDC Identity Provider) 4. Install **"OpenID Connect user backend"** (user_oidc) 5. Enable both apps **Step 2**: Enable dynamic client registration: 1. Go to **Settings** → **OIDC** (Administration) 2. Enable **"Allow dynamic client registration"** **Step 3**: Configure Bearer token validation: ```bash php occ config:system:set user_oidc oidc_provider_bearer_validation --value=true --type=boolean ``` **Step 4**: Verify discovery endpoint: ```bash curl https://your.nextcloud.instance.com/.well-known/openid-configuration | jq '.registration_endpoint' # Should output: # "https://your.nextcloud.instance.com/apps/oidc/register" ``` **Alternative**: Use pre-configured client credentials: ```bash # Register client via CLI php occ oidc:create \ --name="Nextcloud MCP Server" \ --type=confidential \ --redirect-uri="http://localhost:8000/oauth/callback" # Add to .env echo "NEXTCLOUD_OIDC_CLIENT_ID=<client-id>" >> .env echo "NEXTCLOUD_OIDC_CLIENT_SECRET=<client-secret>" >> .env ``` --- ### Client Expired **Error Message**: ``` Stored client has expired ``` **Cause**: Dynamically registered OAuth clients expire (default: 1 hour). **Solution**: **Option 1: Restart the Server** (Automatic re-registration) ```bash uv run nextcloud-mcp-server --oauth # Server automatically re-registers if credentials expired ``` **Option 2: Use Pre-configured Credentials** (Recommended for production) ```bash # Register permanent client via Nextcloud CLI php occ oidc:create \ --name="Nextcloud MCP Server" \ --type=confidential \ --redirect-uri="http://localhost:8000/oauth/callback" # Add to .env NEXTCLOUD_OIDC_CLIENT_ID=<from-output> NEXTCLOUD_OIDC_CLIENT_SECRET=<from-output> ``` Pre-configured clients don't expire. **Option 3: Increase Expiration Time** ```bash # Via Nextcloud CLI (default: 3600 seconds = 1 hour) php occ config:app:set oidc expire_time --value "86400" # 24 hours ``` --- ### Database Permission Error **Error Message**: ``` Permission denied when accessing SQLite database Database is locked ``` **Cause**: The server cannot access the SQLite database file. **Solution**: ```bash # Check database directory permissions ls -la /app/data/ # Ensure directory is writable chmod 755 /app/data # Check if database file exists and has correct permissions ls -la /app/data/tokens.db chmod 644 /app/data/tokens.db # If running in Docker, ensure volume is mounted correctly docker compose logs mcp-oauth | grep -i "database\|sqlite" ``` **For Docker deployments**: Ensure the data directory is properly mounted as a volume: ```yaml volumes: - ./data:/app/data # Persistent storage for SQLite database ``` --- ## Discovery and Connection Issues ### OIDC Discovery Failed **Error Message**: ``` OIDC discovery failed Cannot reach OIDC discovery endpoint ``` **Cause**: The server cannot reach the Nextcloud OIDC discovery endpoint. **Solution**: **Step 1**: Verify Nextcloud URL is correct: ```bash echo $NEXTCLOUD_HOST # Should be full URL: https://your.nextcloud.instance.com ``` **Step 2**: Test discovery endpoint manually: ```bash curl https://your.nextcloud.instance.com/.well-known/openid-configuration # Should return JSON with OIDC configuration # { # "issuer": "https://your.nextcloud.instance.com", # "authorization_endpoint": "https://your.nextcloud.instance.com/apps/oidc/authorize", # ... # } ``` **Step 3**: Check network connectivity: ```bash # Test basic connectivity ping your.nextcloud.instance.com # Test HTTPS curl -I https://your.nextcloud.instance.com ``` **Step 4**: Verify both OIDC apps are enabled: ```bash php occ app:list | grep -E "oidc|user_oidc" ``` **Step 5**: Check firewall rules (if using Docker): ```bash # Check if MCP server can reach Nextcloud docker exec nextcloud-mcp-server curl https://your.nextcloud.instance.com/.well-known/openid-configuration ``` --- ## Authentication Issues ### Bearer Token Authentication Fails **Error Message**: ``` HTTP 401 Unauthorized when calling Nextcloud APIs ``` **Symptoms**: - OCS APIs work (`/ocs/v2.php/cloud/capabilities`) - App APIs fail (`/apps/notes/api/`, `/apps/calendar/`, etc.) **Cause**: The `user_oidc` app's CORS middleware interferes with Bearer token authentication for non-OCS endpoints. **Solution**: Apply the Bearer token patch to `user_oidc` app. See [Upstream Status](oauth-upstream-status.md#1-bearer-token-support-for-non-ocs-endpoints) for details. **Quick Patch**: ```bash # SSH into Nextcloud server cd /path/to/nextcloud/apps/user_oidc # Edit lib/User/Backend.php # Add this line before each return statement in getCurrentUserId() method: $this->session->set('app_api', true); # Lines to modify: ~243, ~310, ~315, ~337 ``` **Test the fix**: ```bash # Get an OAuth token (from MCP client or test) TOKEN="your_access_token" # Test Notes API curl -H "Authorization: Bearer $TOKEN" \ https://your.nextcloud.instance.com/apps/notes/api/v1/notes # Should return notes JSON (not 401) ``` --- ### PKCE Not Advertised **Error Message**: ``` ERROR: OIDC CONFIGURATION ERROR - Missing PKCE Support Advertisement ⚠️ MCP clients (like Claude Code) WILL REJECT this provider! ``` **Cause**: The OIDC discovery endpoint doesn't include `code_challenge_methods_supported` field. **Impact**: - Some MCP clients may refuse to connect - Standards compliance issue (RFC 8414) - **Functionality still works** (PKCE is accepted, just not advertised) **Solution**: **Short-term**: The MCP server logs a warning but continues. OAuth flow still works. **Long-term**: Update the `oidc` app to advertise PKCE support. See [Upstream Status](oauth-upstream-status.md#2-pkce-support-advertisement-in-discovery) for tracking. **Verify**: ```bash curl https://your.nextcloud.instance.com/.well-known/openid-configuration | jq '.code_challenge_methods_supported' # Should return: # ["S256", "plain"] # If null, PKCE isn't advertised (but still works) ``` --- ## Runtime Issues ### MCP Client Can't Authenticate **Symptoms**: - Client connects but OAuth flow fails - Authorization redirects don't work - Token exchange fails **Diagnosis**: **Step 1**: Verify OAuth is configured correctly: ```bash uv run nextcloud-mcp-server --oauth --log-level debug ``` Look for: ``` INFO OAuth initialization complete INFO MCP server ready at http://127.0.0.1:8000 ``` **Step 2**: Check OIDC discovery: ```bash curl https://your.nextcloud.instance.com/.well-known/openid-configuration ``` **Step 3**: Verify MCP server URL matches client expectations: ```bash echo $NEXTCLOUD_MCP_SERVER_URL # Should match the URL clients use to connect # Default: http://localhost:8000 ``` If MCP server is on a different host/port, update: ```bash NEXTCLOUD_MCP_SERVER_URL=http://actual-host:actual-port ``` **Step 4**: Check redirect URI configuration: For pre-configured clients, ensure redirect URI matches: ```bash # Client redirect URI should be: http://your-mcp-server-url/oauth/callback # Example for local server: http://localhost:8000/oauth/callback ``` --- ### Tools Return 401 Errors **Symptoms**: - OAuth flow completes successfully - Token is valid - MCP tools return 401 errors **Cause**: Bearer token not working with Nextcloud APIs. **Solution**: See [Bearer Token Authentication Fails](#bearer-token-authentication-fails) above. --- ### Limited Scopes - Only Seeing Notes Tools **Symptoms**: - MCP client (e.g., Claude Code) successfully connects via OAuth - Only Notes tools are available (7 tools instead of 90+) - Token scopes show only `mcp:notes:read` and `mcp:notes:write` **Cause**: During the OAuth consent flow, the user only granted access to Notes scopes, or the client only requested those scopes. **Diagnosis**: Check what scopes the client has been granted: ```bash # View registered clients and their allowed scopes php occ oidc:list | jq '.[] | select(.name | contains("Claude Code")) | {name, allowed_scopes}' ``` Look for the client's `allowed_scopes` field. If it's empty or only contains notes scopes, that's the issue. **Solution**: **Option 1: Delete Client and Reconnect** (Recommended for MCP clients) ```bash # Find the client ID php occ oidc:list | jq '.[] | select(.name | contains("Claude Code")) | {name, client_id}' # Delete the client php occ oidc:delete <client_id> # Reconnect from Claude Code # This will trigger a new OAuth flow where you can grant all scopes ``` When reconnecting, you'll see a consent screen listing all available scopes. Make sure to approve all the scopes you want the client to access. **Option 2: Update Client Scopes via CLI** ```bash # Update allowed scopes for an existing client php occ oidc:update <client_id> \ --allowed-scopes "openid profile email mcp:notes:read mcp:notes:write mcp:calendar:read mcp:calendar:write mcp:contacts:read mcp:contacts:write mcp:cookbook:read mcp:cookbook:write mcp:deck:read mcp:deck:write mcp:tables:read mcp:tables:write mcp:files:read mcp:files:write mcp:sharing:read mcp:sharing:write" # User will need to reconnect to get new token with updated scopes ``` **Verify Available Scopes**: Check what scopes the MCP server advertises: ```bash curl http://localhost:8001/.well-known/oauth-protected-resource | jq '.scopes_supported' # Should show all 16 scope categories: # - openid # - mcp:notes:read, mcp:notes:write # - mcp:calendar:read, mcp:calendar:write # - mcp:contacts:read, mcp:contacts:write # - mcp:cookbook:read, mcp:cookbook:write # - mcp:deck:read, mcp:deck:write # - mcp:tables:read, mcp:tables:write # - mcp:files:read, mcp:files:write # - mcp:sharing:read, mcp:sharing:write ``` **Understanding Scope Filtering**: The MCP server dynamically filters tools based on the scopes in your access token: - Check server logs for: `✂️ JWT scope filtering: X/90 tools available for scopes: {...}` - This shows how many tools are visible vs total available - Each tool requires specific scopes (read and/or write) **Available Scope Categories**: | Scope Prefix | Nextcloud App | Read Operations | Write Operations | |--------------|---------------|-----------------|------------------| | `mcp:notes:*` | Notes | Get, search, list | Create, update, delete, append | | `mcp:calendar:*` | Calendar (CalDAV) | Get events, todos, calendars | Create/update/delete events, todos | | `mcp:contacts:*` | Contacts (CardDAV) | Get contacts, address books | Create/update/delete contacts | | `mcp:cookbook:*` | Cookbook | Get recipes, search | Create/update recipes | | `mcp:deck:*` | Deck | Get boards, cards | Create/update boards, cards | | `mcp:tables:*` | Tables | Get rows, tables | Create/update/delete rows | | `mcp:files:*` | Files (WebDAV) | List, read files | Upload, delete, move files | | `mcp:sharing:*` | Sharing | Get shares | Create/update shares | --- ## Switching Authentication Modes ### From BasicAuth to OAuth ```bash # 1. Remove or comment out USERNAME/PASSWORD in .env sed -i 's/^NEXTCLOUD_USERNAME/#NEXTCLOUD_USERNAME/' .env sed -i 's/^NEXTCLOUD_PASSWORD/#NEXTCLOUD_PASSWORD/' .env # 2. Ensure NEXTCLOUD_HOST is set grep NEXTCLOUD_HOST .env # 3. Restart server with OAuth export $(grep -v '^#' .env | xargs) uv run nextcloud-mcp-server --oauth ``` ### From OAuth to BasicAuth ```bash # 1. Add USERNAME/PASSWORD to .env echo "NEXTCLOUD_USERNAME=your-username" >> .env echo "NEXTCLOUD_PASSWORD=your-password" >> .env # 2. Restart server (BasicAuth auto-detected) export $(grep -v '^#' .env | xargs) uv run nextcloud-mcp-server --no-oauth ``` --- ## Advanced Debugging ### Enable Debug Logging ```bash uv run nextcloud-mcp-server --oauth --log-level debug ``` Look for: - OIDC discovery details - Client registration attempts - Token validation logs - API request/response details ### Test Discovery Endpoint ```bash # Full discovery response curl https://your.nextcloud.instance.com/.well-known/openid-configuration | jq # Check specific fields curl https://your.nextcloud.instance.com/.well-known/openid-configuration | jq '{ issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, registration_endpoint, code_challenge_methods_supported }' ``` ### Test Token Validation ```bash # Get userinfo with token curl -H "Authorization: Bearer $TOKEN" \ https://your.nextcloud.instance.com/apps/oidc/userinfo # Should return user info: # { # "sub": "username", # "preferred_username": "username", # "name": "Display Name", # ... # } ``` ### Test Nextcloud API Access ```bash # Test OCS API (should work) curl -H "Authorization: Bearer $TOKEN" \ "$NEXTCLOUD_HOST/ocs/v2.php/cloud/capabilities?format=json" \ -H "OCS-APIRequest: true" # Test app API (requires patch) curl -H "Authorization: Bearer $TOKEN" \ "$NEXTCLOUD_HOST/apps/notes/api/v1/notes" ``` --- ## Getting Help If you continue to experience issues: ### 1. Collect Diagnostic Information ```bash # Server version uv run nextcloud-mcp-server --version # Python version python3 --version # Server logs with debug uv run nextcloud-mcp-server --oauth --log-level debug 2>&1 | tee mcp-server.log # OIDC discovery curl https://your.nextcloud.instance.com/.well-known/openid-configuration > oidc-discovery.json # Nextcloud version # Check in Nextcloud admin panel or: php occ -V ``` ### 2. Check Documentation - [OAuth Architecture](oauth-architecture.md) - How OAuth works - [OAuth Setup Guide](oauth-setup.md) - Configuration steps - [Upstream Status](oauth-upstream-status.md) - Required patches - [Configuration](configuration.md) - Environment variables ### 3. Open an Issue If problems persist, [open an issue](https://github.com/cbcoutinho/nextcloud-mcp-server/issues) with: - **Error messages** (full text) - **Server logs** (with `--log-level debug`) - **OIDC discovery response** (from curl command above) - **Nextcloud version** - **OIDC app versions** (`oidc` and `user_oidc`) - **Steps to reproduce** - **Environment details** (OS, Python version, Docker vs local) --- ## See Also - [OAuth Quick Start](quickstart-oauth.md) - Get started quickly - [OAuth Setup Guide](oauth-setup.md) - Detailed configuration - [OAuth Architecture](oauth-architecture.md) - Technical details - [Upstream Status](oauth-upstream-status.md) - Required patches - [General Troubleshooting](troubleshooting.md) - Non-OAuth issues

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/No-Smoke/nextcloud-mcp-comprehensive'

If you have feedback or need assistance with the MCP directory API, please join our Discord server