Files
Chris CoutinhoandClaude Opus 4.7 282c245da1 refactor(config)!: drop ENABLE_MULTI_USER_BASIC_AUTH env var, fail loud on legacy aliases
Same pattern as the ENABLE_LOGIN_FLOW removal in the previous commit:
the deployment mode (MCP_DEPLOYMENT_MODE) is the single source of truth
for selecting an auth flow. The ENABLE_MULTI_USER_BASIC_AUTH env-var
alias is redundant with `MCP_DEPLOYMENT_MODE=multi_user_basic`.

Unlike the ENABLE_LOGIN_FLOW removal — where silent removal was safe
because Login Flow v2 is the auto-detection default — silent removal
here would be a surprise: a user with only ENABLE_MULTI_USER_BASIC_AUTH=true
in their .env would auto-detect into LOGIN_FLOW after upgrade (wrong
runtime mode). Mitigation: detect_auth_mode now reads os.environ
directly for both legacy aliases and raises ValueError with a one-line
migration message if either is set. Applied retroactively to
ENABLE_LOGIN_FLOW as well — loud is better than silent.

- nextcloud_mcp_server/config.py:
  - Drop the dynaconf env-var alias entry for ENABLE_MULTI_USER_BASIC_AUTH.
  - Update the `enable_multi_user_basic_auth` field docstring to mark it
    as derived / not user-settable.
  - `_is_multi_user_mode()` (early-config helper, runs before Settings
    is built) switched to checking MCP_DEPLOYMENT_MODE directly. Now
    consistent with the canonical detection in detect_auth_mode.
- nextcloud_mcp_server/config_validators.py:
  - Drop the auto-detection branch (`if settings.enable_multi_user_basic_auth`).
    Selection of MULTI_USER_BASIC is now exclusively via the explicit
    MCP_DEPLOYMENT_MODE branch.
  - Add `enable_multi_user_basic_auth` to `_sync_derived_flags` alongside
    `enable_login_flow` — both flags are now derived from the resolved mode.
  - Drop `enable_multi_user_basic_auth` from
    `MODE_REQUIREMENTS[MULTI_USER_BASIC].required` and from the
    `forbidden` lists of SINGLE_USER_BASIC and LOGIN_FLOW (no longer
    user input → no meaningful forbidden check).
  - Add loud-deprecation `ValueError` block at the top of detect_auth_mode
    that errors with a clear migration message when ENABLE_MULTI_USER_BASIC_AUTH
    or ENABLE_LOGIN_FLOW is found in os.environ.
- tests/unit/test_config_validators.py:
  - Switch ~10 fixtures from `enable_multi_user_basic_auth=True` to
    `deployment_mode="multi_user_basic"` (mirrors `enable_login_flow`
    treatment from the previous commit).
  - Switch two `patch.dict(os.environ, {"ENABLE_MULTI_USER_BASIC_AUTH": "true"})`
    blocks to use MCP_DEPLOYMENT_MODE.
  - Rename `test_forbidden_multi_user_basic_auth` to
    `test_forbidden_multi_user_basic_when_credentials_present` — the
    scenario is now an explicit-mode + credentials conflict, not an
    env-var-flag conflict.
  - Add `test_legacy_enable_multi_user_basic_auth_env_var_errors` and
    `test_legacy_enable_login_flow_env_var_errors` to exercise the new
    loud-deprecation ValueError path.
- docker-compose.yml: mcp-multi-user-basic profile switched to
  `MCP_DEPLOYMENT_MODE=multi_user_basic`.
- env.sample: replaced `#ENABLE_MULTI_USER_BASIC_AUTH=true` example with
  `#MCP_DEPLOYMENT_MODE=multi_user_basic`.
- docs/authentication.md, configuration.md, troubleshooting.md,
  auth-flows.md, webhook-management-guide.md,
  configuration-migration-v2.md, ADR-025: replaced env-var examples
  with the canonical MCP_DEPLOYMENT_MODE form.
- docs/ADR-020: marked partly superseded by ADR-022.
- CLAUDE.md: Multi-User BasicAuth section updated to set
  MCP_DEPLOYMENT_MODE.
- nextcloud_mcp_server/vector/oauth_sync.py: module docstring updated.

BREAKING CHANGE: ENABLE_MULTI_USER_BASIC_AUTH is no longer read from
the environment, and setting it now raises a startup ValueError with
a migration message. Replace `ENABLE_MULTI_USER_BASIC_AUTH=true` with
`MCP_DEPLOYMENT_MODE=multi_user_basic`. The same loud-deprecation
check is also applied to the recently-removed ENABLE_LOGIN_FLOW —
replace with `MCP_DEPLOYMENT_MODE=login_flow` (or drop both;
`login_flow` is the auto-detect default when no other auth env vars
are set).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 20:06:16 +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
MCP_DEPLOYMENT_MODE=multi_user_basic

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)
MCP_DEPLOYMENT_MODE=multi_user_basic Multi-User (BasicAuth pass-through)
MCP_DEPLOYMENT_MODE=login_flow or no auth env vars set 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