Files
mcp-nextcloud/docs/authentication.md
T
Chris CoutinhoandClaude Opus 4.7 0c6b766e7e docs: fix scope naming and round-3 reviewer feedback
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>
2026-04-30 03:05:33 +02:00

4.5 KiB

Authentication

The Nextcloud MCP server authenticates to Nextcloud using app-specific passwords (HTTP Basic Auth). It supports three deployment modes that differ in how those credentials are sourced.

Mode Comparison

Mode How credentials are obtained Best for
Single-User (BasicAuth) App password in environment variables Personal use, development, single-tenant deployments
Multi-User (BasicAuth pass-through) MCP client sends credentials in HTTP Authorization header Internal multi-user setups where users manage their own Nextcloud credentials
Multi-User (Login Flow v2) Per-user app password obtained via Nextcloud's Login Flow v2, stored encrypted Hosted deployments, OAuth-based MCP clients (claude.ai, Astrolabe Cloud), production multi-user

OAuth-direct-to-Nextcloud is no longer supported. It required upstream patches to user_oidc that were never merged. Login Flow v2 replaces it for multi-user deployments and works with stock Nextcloud 16+. See ADR-022 for the rationale.

Single-User (BasicAuth)

One set of credentials is configured in the environment and shared by all MCP clients. All Nextcloud requests are made as the same user.

Configuration

NEXTCLOUD_HOST=https://your.nextcloud.example.com
NEXTCLOUD_USERNAME=your_username
NEXTCLOUD_PASSWORD=your_app_password

Generate the app password in Nextcloud under Settings → Security → Devices & sessions. Don't use your login password.

Trade-offs

  • Simplest setup; no persistent state
  • All MCP tools available (no scope enforcement — trusted environment)
  • No per-user identity; all actions appear from the same account in Nextcloud
  • Not suitable for shared deployments

See Configuration for the full environment variable reference.

Multi-User (BasicAuth Pass-Through)

Each MCP client sends its own credentials in an HTTP Authorization: Basic header. The server creates a per-request Nextcloud client from those credentials and never persists them.

Configuration

NEXTCLOUD_HOST=https://your.nextcloud.example.com
ENABLE_MULTI_USER_BASIC_AUTH=true

NEXTCLOUD_USERNAME and NEXTCLOUD_PASSWORD must NOT be set in this mode.

Trade-offs

  • Stateless — no token storage required
  • Each user's actions are properly attributed in Nextcloud audit logs
  • Clients must handle Nextcloud credentials directly (credential exposure risk)
  • Not compatible with OAuth-based MCP clients (claude.ai, Astrolabe Cloud) without a credential bridge

Multi-User (Login Flow v2)

The recommended mode for hosted and OAuth-based deployments. MCP clients authenticate to the MCP server via OAuth; the MCP server obtains a per-user app password from Nextcloud (via Login Flow v2) and uses HTTP Basic Auth to talk to Nextcloud APIs.

MCP Client ──(OAuth, per-app scopes)──> MCP Server ──(Basic Auth, app password)──> Nextcloud

The MCP server enforces per-app scopes (notes.read, talk.write, files.read, etc. — see Login Flow v2 → Scope Reference) at the application layer (defense-in-depth, since Nextcloud app passwords have no native scope support).

See Login Flow v2 for full setup, architecture, scope reference, and troubleshooting.

Mode Detection

The server detects the active mode from environment variables at startup:

Env vars present Detected mode
NEXTCLOUD_USERNAME + NEXTCLOUD_PASSWORD Single-User (BasicAuth)
ENABLE_MULTI_USER_BASIC_AUTH=true (no creds) Multi-User (BasicAuth pass-through)
ENABLE_LOGIN_FLOW=true (no creds) Multi-User (Login Flow v2)

You can also force a mode via CLI flag:

# Force Login Flow v2 / OAuth identity layer
uv run nextcloud-mcp-server --oauth

# Force BasicAuth
uv run nextcloud-mcp-server --no-oauth

See Also