-
Notifications
You must be signed in to change notification settings - Fork 20
Description
Summary
Add support for Nextcloud's Login Flow v2 to enable external applications to obtain app passwords through a user-friendly authorization flow, eliminating manual copy/paste of credentials.
Use Case
I'm developing a system with:
A Nextcloud app (frontend, OAuth confidential client)
A Python backend (non-ExApp, also OAuth confidential client)
The Python backend requires an app password for background sync operations (WebDAV, CalDAV, etc.). Currently, users must:
Navigate to Nextcloud → Settings → Security → Devices & Sessions
Manually generate an app password
Copy the password
Paste it into my app's settings page
Submit to the backend
This is error-prone and creates friction for end users.
Proposed Solution
Implement Login Flow v2 endpoints that allow MCP clients or external applications to:
Initiate a login flow - Backend calls POST /index.php/login/v2 and receives a poll endpoint + login URL
Redirect user to authorize - Frontend opens Nextcloud's authorization page
Poll for credentials - Backend polls until user completes authorization, receiving { server, loginName, appPassword }
API Flow
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ MCP Client / │ │ nextcloud-mcp │ │ Nextcloud │ │ External App │ │ -server │ │ Server │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ │ 1. Request auth URL │ │ │──────────────────────>│ │ │ │ 2. POST /login/v2 │ │ │──────────────────────>│ │ │<──────────────────────│ │ │ {poll, login URL} │ │<──────────────────────│ │ │ 3. Return login URL│ │ │ │ │ │ 4. User visits login URL ────────────────────>│ │ │ │ │ │ 5. Poll endpoint │ │ │──────────────────────>│ │ (User logs in and grants access) │ │ │<──────────────────────│ │ │ {appPassword, ...} │ │ │ │ │ 6. Auth complete │ │ │<──────────────────────│ │
Suggested Implementation
New MCP Tool: nc_auth_login_flow_initiate
@mcp.tool() async def nc_auth_login_flow_initiate( user_agent: str = "Nextcloud MCP Server" ) -> LoginFlowResponse: """ Initiate Nextcloud Login Flow v2 for obtaining an app password. Returns: - login_url: URL to open in browser for user authorization - poll_endpoint: Endpoint to poll for credentials - poll_token: Token for polling """ response = await httpx.post( f"{nextcloud_host}/index.php/login/v2", headers={"User-Agent": user_agent} ) data = response.json() return LoginFlowResponse( login_url=data["login"], poll_endpoint=data["poll"]["endpoint"], poll_token=data["poll"]["token"] )
New MCP Tool: nc_auth_login_flow_poll
@mcp.tool() async def nc_auth_login_flow_poll( poll_endpoint: str, poll_token: str ) -> LoginFlowCredentials | None: """ Poll for Login Flow v2 completion. Returns credentials if user has authorized, None if still pending. Raises error on timeout or rejection. """ response = await httpx.post( poll_endpoint, data={"token": poll_token} ) if response.status_code == 200: data = response.json() return LoginFlowCredentials( server=data["server"], login_name=data["loginName"], app_password=data["appPassword"] ) elif response.status_code == 404: return None # Still pending else: raise AuthorizationError("Login flow failed or was rejected")
Alternative: HTTP Endpoint (non-MCP)
For applications that need to integrate without MCP, expose REST endpoints:
POST /auth/login-flow/initiate → { "login_url": "...", "poll_endpoint": "...", "poll_token": "..." } POST /auth/login-flow/poll Body: { "poll_endpoint": "...", "poll_token": "..." } → { "server": "...", "login_name": "...", "app_password": "..." } | 202 Pending
Benefits
Better UX - One-click authorization instead of manual copy/paste
More secure - App password name is set via User-Agent, making it identifiable in Nextcloud's security settings
Standard approach - Uses Nextcloud's official client authentication mechanism
Complements OAuth - While OAuth is experimental and requires patches, Login Flow v2 works out-of-the-box with any Nextcloud instance
Relationship to Existing Auth
This would complement, not replace, the existing authentication modes:
ModeUse CaseStatusBasic AuthStatic credentials in env vars✅ Production-readyOAuth2/OIDCPer-user tokens, fine-grained scopes
References
Nextcloud Login Flow Documentation
Nextcloud OCS API - getapppassword
Related upstream issue: nextcloud/server#21178 - API Endpoint to set application specific password
Environment
nextcloud-mcp-server version: 0.48.6+
Nextcloud: Any version with Login Flow v2 support (NC 16+)
Willingness to Contribute
I'm happy to help implement this feature or provide additional context. Let me know if you'd like me to submit a PR.