Skip to content

Latest commit

 

History

History
541 lines (402 loc) · 15.9 KB

File metadata and controls

541 lines (402 loc) · 15.9 KB

OAuth Setup Guide

This guide walks you through setting up OAuth2/OIDC authentication for the Nextcloud MCP server in production.

Quick Start? If you want a 5-minute setup for development, see OAuth Quick Start.

Table of Contents

Prerequisites

Before beginning, ensure you have:

  • Nextcloud instance with administrator access
  • Nextcloud version 28 or later
  • SSH/CLI access to Nextcloud server (for occ commands)
  • Python 3.11+ installed on MCP server host
  • MCP server installed (see Installation Guide)

Architecture Overview

The OAuth implementation uses the following components:

MCP Client ←→ MCP Server (Resource Server) ←→ Nextcloud (Authorization Server + APIs)
            OAuth Flow                       Bearer Token Auth

Key Roles:

  • MCP Server: OAuth Resource Server (validates tokens, provides MCP tools)
  • Nextcloud oidc app: OAuth Authorization Server (issues tokens)
  • Nextcloud user_oidc app: Token validation middleware

For detailed architecture, see OAuth Architecture.

Step 1: Install Nextcloud Apps

OAuth authentication requires two Nextcloud apps to work together.

Required Apps

1. oidc - OIDC Identity Provider

Purpose: Makes Nextcloud an OAuth2/OIDC authorization server

Installation:

  1. Open Nextcloud as administrator
  2. Navigate to AppsSecurity
  3. Find "OIDC" (full name: "OIDC Identity Provider")
  4. Click Enable or Download and enable

Provides:

  • OAuth2 authorization endpoint
  • Token endpoint
  • User info endpoint
  • JWKS endpoint
  • Dynamic client registration endpoint (optional)

2. user_oidc - OpenID Connect User Backend

Purpose: Authenticates users and validates Bearer tokens

Installation:

  1. In AppsSecurity
  2. Find "OpenID Connect user backend" (app ID: user_oidc)
  3. Click Enable or Download and enable

Provides:

  • Bearer token validation against OIDC provider
  • User authentication via OIDC
  • Session management for authenticated users

Important

Upstream Patch Required: The user_oidc app needs a patch for Bearer token support with app-specific APIs (Notes, Calendar, etc.). The patch is pending upstream review.

Status: See Upstream Status for current PR status and workarounds.

Impact: OCS APIs work without patch, but app-specific APIs require the patch.

Verify Installation

# Check both apps are installed and enabled
php occ app:list | grep -E "oidc|user_oidc"

# Expected output:
#  - oidc: enabled
#  - user_oidc: enabled

Step 2: Configure OIDC Apps

Configure oidc App (Identity Provider)

Option A: Dynamic Client Registration (Development)

Best for: Development, testing, auto-registration

  1. Navigate to SettingsOIDC (Administration settings)
  2. Enable "Allow dynamic client registration"
  3. (Optional) Configure client expiration:
    # Default: 3600 seconds (1 hour)
    php occ config:app:set oidc expire_time --value "86400"  # 24 hours

Option B: Pre-configured Clients (Production)

Best for: Production, long-running deployments

Skip the dynamic registration setting. You'll manually register clients via CLI in Step 3.

Configure user_oidc App (Token Validation)

Required: Enable Bearer token validation:

# SSH into Nextcloud server
php occ config:system:set user_oidc oidc_provider_bearer_validation --value=true --type=boolean

This tells user_oidc to validate Bearer tokens against Nextcloud's OIDC Identity Provider.

Verify OIDC Discovery

Test that OIDC discovery endpoint is accessible:

curl https://your.nextcloud.instance.com/.well-known/openid-configuration | jq

Expected response:

{
  "issuer": "https://your.nextcloud.instance.com",
  "authorization_endpoint": "https://your.nextcloud.instance.com/apps/oidc/authorize",
  "token_endpoint": "https://your.nextcloud.instance.com/apps/oidc/token",
  "userinfo_endpoint": "https://your.nextcloud.instance.com/apps/oidc/userinfo",
  "jwks_uri": "https://your.nextcloud.instance.com/apps/oidc/jwks",
  "registration_endpoint": "https://your.nextcloud.instance.com/apps/oidc/register",
  ...
}

PKCE Support

The MCP server requires PKCE (Proof Key for Code Exchange) with S256 code challenge method.

Validation: The MCP server automatically validates PKCE support at startup by checking the discovery response for code_challenge_methods_supported.

Note: If PKCE is not advertised in discovery metadata, the server logs a warning but continues (PKCE still works, it's just not advertised). See Upstream Status for tracking.

Step 3: Choose Deployment Mode

You have two options for managing OAuth clients:

Mode A: Automatic Registration (Dynamic Client Registration)

Best for: Development, testing, quick deployments

How it works:

  • MCP server automatically registers an OAuth client on first startup
  • Uses Nextcloud's dynamic client registration endpoint
  • Saves credentials to SQLite database
  • Reuses stored credentials on subsequent restarts
  • Re-registers automatically if credentials expire

Pros:

  • Zero configuration required
  • Quick setup
  • Automatic credential management

Cons:

  • Clients expire (default: 1 hour, configurable)
  • Must have dynamic client registration enabled on Nextcloud

Configuration: Skip to Step 4 with minimal config.


Mode B: Pre-configured Client (Production)

Best for: Production, long-running deployments, stable environments

How it works:

  • You manually register an OAuth client via Nextcloud CLI
  • Provide client credentials to MCP server via environment variables
  • Credentials don't expire

Pros:

  • Credentials don't expire
  • Stable for production
  • More control over client configuration
  • Better for audit trails

Cons:

  • Requires manual setup
  • Needs SSH/CLI access to Nextcloud server

Setup: Register a client via CLI:

# SSH into Nextcloud server
php occ oidc:create \
  --name="Nextcloud MCP Server" \
  --type=confidential \
  --redirect-uri="http://localhost:8000/oauth/callback"

# Example output:
# Client ID: abc123xyz789
# Client Secret: secret456def012

# Save these credentials for Step 4

Important: Adjust --redirect-uri to match your MCP server URL:

  • Local: http://localhost:8000/oauth/callback
  • Remote: http://your-server:8000/oauth/callback
  • Custom port: http://your-server:PORT/oauth/callback

The redirect URI must be:

{NEXTCLOUD_MCP_SERVER_URL}/oauth/callback

Step 4: Configure MCP Server

Create or update your .env file with OAuth configuration.

For Mode A (Automatic Registration)

# Copy sample if needed
cp env.sample .env

# Edit .env
cat > .env << 'EOF'
# Nextcloud Instance
NEXTCLOUD_HOST=https://your.nextcloud.instance.com

# Leave EMPTY for OAuth mode (do not set USERNAME/PASSWORD)
NEXTCLOUD_USERNAME=
NEXTCLOUD_PASSWORD=

# Optional: MCP server URL (for OAuth callbacks)
NEXTCLOUD_MCP_SERVER_URL=http://localhost:8000
EOF

For Mode B (Pre-configured Client)

# Copy sample if needed
cp env.sample .env

# Edit .env
cat > .env << 'EOF'
# Nextcloud Instance
NEXTCLOUD_HOST=https://your.nextcloud.instance.com

# OAuth Client Credentials (from Step 3)
NEXTCLOUD_OIDC_CLIENT_ID=abc123xyz789
NEXTCLOUD_OIDC_CLIENT_SECRET=secret456def012

# MCP server URL (must match redirect URI)
NEXTCLOUD_MCP_SERVER_URL=http://localhost:8000

# Leave EMPTY for OAuth mode
NEXTCLOUD_USERNAME=
NEXTCLOUD_PASSWORD=
EOF

Environment Variables Reference

Variable Required Default Description
NEXTCLOUD_HOST ✅ Yes - Full URL of Nextcloud instance
NEXTCLOUD_OIDC_CLIENT_ID ⚠️ Mode B only - OAuth client ID
NEXTCLOUD_OIDC_CLIENT_SECRET ⚠️ Mode B only - OAuth client secret
NEXTCLOUD_MCP_SERVER_URL ⚠️ Optional http://localhost:8000 MCP server URL for callbacks
NEXTCLOUD_USERNAME ❌ Must be empty - Leave empty for OAuth
NEXTCLOUD_PASSWORD ❌ Must be empty - Leave empty for OAuth

See Configuration Guide for all options.

Step 5: Start and Verify

Load Environment Variables

# Load from .env file
export $(grep -v '^#' .env | xargs)

# Verify key variables are set
echo "NEXTCLOUD_HOST: $NEXTCLOUD_HOST"
echo "NEXTCLOUD_MCP_SERVER_URL: $NEXTCLOUD_MCP_SERVER_URL"

Start MCP Server

# Start with OAuth mode
uv run nextcloud-mcp-server --oauth

# Or with custom options
uv run nextcloud-mcp-server --oauth --port 8000 --log-level info

Verify Startup

Look for these success messages:

For Mode A (Auto-registration):

INFO     OAuth mode detected (NEXTCLOUD_USERNAME/PASSWORD not set)
INFO     Configuring MCP server for OAuth mode
INFO     Performing OIDC discovery: https://your.nextcloud.instance.com/.well-known/openid-configuration
✓ PKCE support validated: ['S256']
INFO     OIDC discovery successful
INFO     Attempting dynamic client registration...
INFO     Dynamic client registration successful
INFO     OAuth client ready: <client-id>...
INFO     Saved OAuth client credentials to SQLite database
INFO     OAuth initialization complete
INFO     MCP server ready at http://127.0.0.1:8000

For Mode B (Pre-configured):

INFO     OAuth mode detected (NEXTCLOUD_USERNAME/PASSWORD not set)
INFO     Configuring MCP server for OAuth mode
INFO     Performing OIDC discovery: https://your.nextcloud.instance.com/.well-known/openid-configuration
✓ PKCE support validated: ['S256']
INFO     OIDC discovery successful
INFO     Using pre-configured OAuth client: abc123xyz789
INFO     OAuth initialization complete
INFO     MCP server ready at http://127.0.0.1:8000

Common Startup Issues

Issue Solution
"OAuth mode requires NEXTCLOUD_HOST" Set NEXTCLOUD_HOST in .env
"OIDC discovery failed" Verify Nextcloud URL and network connectivity
"Dynamic registration failed" Enable dynamic registration in OIDC app settings
"PKCE validation failed" See Upstream Status

See OAuth Troubleshooting for detailed solutions.

Testing Authentication

Test with MCP Inspector

The MCP Inspector provides a web UI for testing:

# In a new terminal
uv run mcp dev

# Opens browser at http://localhost:6272

In the MCP Inspector UI:

  1. Enter server URL: http://localhost:8000/mcp
  2. Click Connect
  3. Complete OAuth flow in browser popup:
    • Login to Nextcloud
    • Authorize MCP server access
    • Redirected back to MCP Inspector
  4. Test tools:
    • Try nc_notes_create_note
    • Try nc_notes_search_notes
    • Try nc_calendar_list_events

Test from Command Line

# Get an OAuth token (you'll need to implement client flow or extract from browser)
TOKEN="your_access_token_here"

# Test OCS API (should work)
curl -H "Authorization: Bearer $TOKEN" \
  "$NEXTCLOUD_HOST/ocs/v2.php/cloud/capabilities?format=json" \
  -H "OCS-APIRequest: true"

# Test Notes API (requires upstream patch)
curl -H "Authorization: Bearer $TOKEN" \
  "$NEXTCLOUD_HOST/apps/notes/api/v1/notes"

Verify Token Validation

Check MCP server logs for token validation:

# Start server with debug logging
uv run nextcloud-mcp-server --oauth --log-level debug

# Look for:
# DEBUG    Token validation via userinfo endpoint
# DEBUG    Token validated successfully for user: username

Production Recommendations

Security Best Practices

  1. Use Pre-configured Clients (Mode B)

    • More stable
    • Better audit trails
    • No expiration issues
  2. Secure Credential Storage

    # Set restrictive permissions on environment file
    chmod 600 .env
    # Database permissions are handled automatically
  3. Use HTTPS for MCP Server

    • Especially important for remote access
    • Use reverse proxy (nginx, Apache) with SSL
  4. Restrict Redirect URIs

    • Only register necessary redirect URIs
    • Use specific URLs (not wildcards)

Deployment Considerations

  1. MCP Server URL

    • Must be accessible to OAuth clients
    • Must match redirect URI registered with Nextcloud
    • For Docker: expose port and use correct host
  2. Network Configuration

    • MCP server must reach Nextcloud (OIDC endpoints)
    • OAuth clients must reach MCP server (callbacks)
    • OAuth clients must reach Nextcloud (authorization flow)
  3. Process Management

    • Use systemd, supervisord, or Docker for MCP server
    • Ensure automatic restart on failure
    • Monitor logs for OAuth errors

Example Production Configs

Docker Compose

version: '3'
services:
  nextcloud-mcp:
    image: ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
    ports:
      - "127.0.0.1:8000:8000"
    environment:
      NEXTCLOUD_HOST: https://your.nextcloud.instance.com
      NEXTCLOUD_OIDC_CLIENT_ID: ${NEXTCLOUD_OIDC_CLIENT_ID}
      NEXTCLOUD_OIDC_CLIENT_SECRET: ${NEXTCLOUD_OIDC_CLIENT_SECRET}
      NEXTCLOUD_MCP_SERVER_URL: http://your-server:8000
    volumes:
      - ./data:/app/data  # For SQLite database persistence
    command: ["--oauth", "--transport", "streamable-http"]
    restart: unless-stopped

Systemd Service

[Unit]
Description=Nextcloud MCP Server (OAuth)
After=network.target

[Service]
Type=simple
User=mcp
WorkingDirectory=/opt/nextcloud-mcp-server
Environment="NEXTCLOUD_HOST=https://your.nextcloud.instance.com"
Environment="NEXTCLOUD_OIDC_CLIENT_ID=abc123xyz789"
Environment="NEXTCLOUD_OIDC_CLIENT_SECRET=secret456def012"
Environment="NEXTCLOUD_MCP_SERVER_URL=http://your-server:8000"
ExecStart=/opt/nextcloud-mcp-server/.venv/bin/nextcloud-mcp-server --oauth
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Monitoring and Maintenance

  1. Log Monitoring

    # Watch for OAuth errors
    tail -f /var/log/nextcloud-mcp/server.log | grep -i "oauth\|token"
  2. Token Expiration (Mode A only)

    • Monitor for "Stored client has expired" messages
    • Consider increasing expiration or switching to Mode B
  3. Upstream Patches

Troubleshooting

For OAuth-specific issues, see OAuth Troubleshooting.

Common issues:

Next Steps

See Also