The docs claimed scopes are mcp:-prefixed (mcp:notes.read, mcp:notes.write) and that the notes.* pair "covers all Nextcloud apps". Both are false. Per @require_scopes decorators across nextcloud_mcp_server/server/, scopes are unprefixed and per-app: notes.read/write, talk.read/write, files.read/write, calendar.read/write, contacts.read/write, deck.read/write, news.read, tables.read/write, cookbook.read/write, todo.read/write, collectives.read/write, sharing.write, semantic.read, plus standard OIDC scopes. Changes: - login-flow-v2.md: replace the false 2-row "covers all apps" scope table with the real per-app reference (links to scope_authorization.discover_all_scopes() as authoritative source); strip mcp: prefix from intro paragraph, sequence diagrams, @require_scopes example, WWW-Authenticate header example. Also fix sticky-session keying advice per reviewer: route on user identity (sub claim) rather than the raw bearer token, since tokens rotate on refresh. - auth-flows.md: clarify "Astrolabe (hosted UI) → MCP" matrix column header; strip mcp: from sequence diagram and key characteristics bullet; correct "issued by MCP server" to "issued by configured IdP" on the Login Flow v2 token. - authentication.md: strip mcp: from the high-level diagram and scope-enforcement prose; cross-link to the scope reference. - configuration.md: add NEXTCLOUD_OIDC_CLIENT_ID, NEXTCLOUD_OIDC_CLIENT_SECRET, and OIDC_DISCOVERY_URL to the Login Flow v2 vars table — these were undocumented in the table after the round-2 multi-IdP fix. - running.md: drop deprecated `version: '3.8'` from compose snippets (Compose v2 ignores it and emits warnings). - testing-oidc-consent.md: fix sample authorize URL and consent description to use real scope names instead of mcp:-prefixed ones (the manual test as written would have failed with invalid_scope). - CLAUDE.md: replace dead links to deleted oauth-architecture.md, oauth-setup.md, and audience-validation-setup.md with login-flow-v2.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
13 KiB
Running the Server
This guide covers different ways to start and run the Nextcloud MCP server.
Prerequisites
Before running the server:
- Install the server - See Installation Guide
- Configure environment - See Configuration Guide
- Set up authentication - See Authentication (multi-user deployments: see Login Flow v2)
Quick Start
Start the server using Docker:
# OAuth mode (--oauth, recommended for multi-user; required by Login Flow v2)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# BasicAuth mode (single-user or multi-user pass-through)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
Note: Under
--oauththe MCP server is an OIDC relying party of a configurable IdP (Nextcloud's built-in OIDC by default; Keycloak, AWS Cognito, etc. viaOIDC_DISCOVERY_URL) and exposes an OAuth facade for MCP clients. Bearer tokens are validated against the IdP's JWKS. The MCP server does not forward client OAuth tokens to Nextcloud — Nextcloud is always reached via per-user app passwords (Login Flow v2) or Basic Auth credentials.
The server will start on http://127.0.0.1:8000 by default.
Running with Docker
Basic Docker Run
OAuth Mode (--oauth, recommended for multi-user)
The --oauth flag turns on the OAuth/OIDC layer. In this mode the MCP server is an OIDC relying party of a configurable IdP — Nextcloud's built-in OIDC by default, or any OIDC-compliant provider (Keycloak, AWS Cognito, Auth0, etc.) selected via OIDC_DISCOVERY_URL. The MCP server validates Bearer tokens against that IdP's JWKS and exposes an OAuth facade for MCP clients. Login Flow v2 is layered on top to acquire and store per-user Nextcloud app passwords for the data leg.
The MCP server registers itself with the IdP in one of two ways:
- Static client (preferred) — set
NEXTCLOUD_OIDC_CLIENT_IDandNEXTCLOUD_OIDC_CLIENT_SECRETin.env(matching a client you registered in your IdP — Nextcloud admin → OIDC, Keycloak realm → Clients, etc.). These env-var names predate multi-IdP support; they hold generic OIDC client credentials. - Dynamic Client Registration (fallback) — if the static creds aren't set and the IdP advertises a
registration_endpoint, the server self-registers via RFC 7591.
# OAuth with static (pre-registered) client — preferred
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
-e NEXTCLOUD_OIDC_CLIENT_ID=abc123 \
-e NEXTCLOUD_OIDC_CLIENT_SECRET=xyz789 \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# OAuth with auto-registration (DCR) — used when static creds are absent
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# OAuth on a custom port
docker run -p 127.0.0.1:8080:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# OAuth with specific apps only
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--enable-app notes --enable-app calendar
BasicAuth Mode
# BasicAuth (requires NEXTCLOUD_USERNAME/PASSWORD in .env)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
# BasicAuth with specific apps
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest \
--enable-app notes --enable-app webdav
Docker with Persistent Token Storage
# Mount volume for persistent OAuth token storage
docker run -p 127.0.0.1:8000:8000 --env-file .env \
-v $(pwd)/data:/app/data \
--rm ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
Docker Compose
Create docker-compose.yml:
services:
mcp:
image: ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
command: --oauth --enable-app notes --enable-app calendar
ports:
- "127.0.0.1:8000:8000"
env_file:
- .env
volumes:
- ./data:/app/data # Persistent token storage
restart: unless-stopped
Start the service:
# Start in foreground
docker-compose up
# Start in background
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the service
docker-compose down
Server Options
Host and Port
# Bind to all interfaces (accessible from network)
docker run -p 0.0.0.0:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# Bind to localhost only (default, more secure)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# Use a different port (map host port 8080 to container port 8000)
docker run -p 127.0.0.1:8080:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
Security Note: Binding to 0.0.0.0 exposes the server to your network. Only use this if you understand the security implications.
Transport Protocols
The server supports multiple MCP transport protocols:
# Streamable HTTP (default, recommended)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--transport streamable-http
# SSE - Server-Sent Events (deprecated)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--transport sse
# HTTP
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--transport http
Warning
SSE transport is deprecated and will be removed in a future version of the MCP spec. Please migrate to
streamable-http.
Logging
# Set log level (critical, error, warning, info, debug, trace)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--log-level debug
# Production: use warning or error
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--log-level warning
Selective App Enablement
By default, all supported Nextcloud apps are enabled. You can enable specific apps only:
# Available apps: notes, tables, webdav, calendar, contacts, cookbook, deck
# Enable all apps (default)
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth
# Enable only Notes
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--enable-app notes
# Enable multiple apps
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--enable-app notes --enable-app calendar --enable-app contacts
# Enable only WebDAV for file operations
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--enable-app webdav
Use cases:
- Reduce memory usage and startup time
- Limit functionality for security/organizational reasons
- Test specific app integrations
- Run lightweight instances with only needed features
Development Mode
Running for Development
For active development with auto-reload, mount your source code as a volume:
# Development mode with source code mounted
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
-v $(pwd):/app \
-v $(pwd)/data:/app/data \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--log-level debug
For local development without Docker:
# Load environment variables
export $(grep -v '^#' .env | xargs)
# Run the server with auto-reload
uv run nextcloud-mcp-server run --oauth --log-level debug
CLI Subcommands
The nextcloud-mcp-server CLI has two main subcommands:
-
run- Start the MCP server (default command in Docker)uv run nextcloud-mcp-server run --oauth --host 0.0.0.0 --port 8000 -
db- Database migration management (Alembic)# Show current migration revision uv run nextcloud-mcp-server db current # Upgrade to latest migration uv run nextcloud-mcp-server db upgrade # Show migration history uv run nextcloud-mcp-server db history # Create new migration (developers only) uv run nextcloud-mcp-server db migrate "description of changes"
Database Migrations
Token storage uses Alembic for schema management:
- Automatic migrations: Database is upgraded automatically on server startup
- Backward compatibility: Pre-Alembic databases are automatically stamped with the initial revision
- Migration files: Located in
alembic/versions/ - For developers: When changing the schema:
- Create a migration:
uv run nextcloud-mcp-server db migrate "add new column" - Edit the generated file in
alembic/versions/to add SQL statements - Test upgrade:
uv run nextcloud-mcp-server db upgrade - Test downgrade:
uv run nextcloud-mcp-server db downgrade
- Create a migration:
See Database Migrations Guide for detailed information.
Connecting to the Server
Using MCP Inspector
MCP Inspector is a browser-based tool for testing MCP servers:
- Start your MCP server using Docker (see above)
- Start MCP Inspector:
npx @modelcontextprotocol/inspector - In the browser:
- Enter server URL:
http://localhost:8000 - Complete OAuth flow (if using OAuth)
- Explore tools and resources
- Enter server URL:
Using MCP Clients
MCP clients (like Claude Desktop, LLM IDEs) can connect to your server:
- Configure the client with your server URL
- Complete OAuth authentication (if enabled)
- Start interacting with Nextcloud through the LLM
Verifying Server Status
Check Server Health
# Test if server is responding
curl http://localhost:8000/health
# Expected response: HTTP 200 OK
Check OAuth Configuration
Look for these log messages on startup:
OAuth mode:
INFO OAuth mode detected (NEXTCLOUD_USERNAME/PASSWORD not set)
INFO Configuring MCP server for OAuth mode
INFO OIDC discovery successful
INFO OAuth client ready: <client-id>...
INFO OAuth initialization complete
BasicAuth mode:
INFO BasicAuth mode detected (NEXTCLOUD_USERNAME/PASSWORD set)
INFO Initializing Nextcloud client with BasicAuth
Process Management
Running as a Background Service
Use Docker Compose with restart: unless-stopped (see Docker Compose section above).
Monitoring Logs
# Docker (find container name first)
docker ps
docker logs -f <container-name>
# Docker Compose
docker-compose logs -f mcp
Performance Tuning
Production Settings
For production deployments, use Docker Compose with the recommended settings:
services:
mcp:
image: ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
command: --oauth --log-level warning --transport streamable-http
ports:
- "127.0.0.1:8000:8000"
env_file:
- .env
volumes:
- ./data:/app/data
restart: unless-stopped
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
Scaling with Multiple Replicas
For higher load, use Docker Swarm or Kubernetes. See the Helm chart for Kubernetes deployments.
Troubleshooting
Server won't start
Check logs for errors:
# View container logs
docker logs <container-name>
# Or run with debug logging
docker run -p 127.0.0.1:8000:8000 --env-file .env --rm \
ghcr.io/cbcoutinho/nextcloud-mcp-server:latest --oauth \
--log-level debug
Common issues:
- Environment variables not loaded - Check your
.envfile - Port already in use - Use a different host port (e.g.,
-p 127.0.0.1:8080:8000) - OAuth configuration errors - See Troubleshooting
Can't connect to server
- Verify server is running:
curl http://localhost:8000/health - Check firewall settings
- Verify host binding (use
0.0.0.0to allow network access) - Check OAuth authentication if enabled
OAuth authentication fails
See Troubleshooting OAuth for detailed OAuth troubleshooting.
See Also
- Configuration Guide - Environment variables
- Authentication - Authentication modes
- Login Flow v2 - Recommended multi-user setup
- Troubleshooting - Common issues and solutions
- Installation - Installing the server