Skip to content

Story 2: OAuth2 for MCP Agents #7423

Description

@cstns

Description

Summary

Enable external AI agents (Claude Desktop, Cursor, Claude Code) to authenticate with FlowFuse through OAuth2 PKCE, building on the existing OAuth2 scaffolding. This evolves from manual PAT setup (phase 1, covered by #7411) to automated OAuth flows, and eventually to Claude plugin/connector directory submission.

Context

FlowFuse already has a working OAuth2 Authorization Code Grant with PKCE implementation (forge/routes/auth/oauth.js). It supports the ff-plugin client for the Node-RED editor, dynamic project/device clients, consent pages, token exchange, and refresh tokens. The infrastructure is sound. This story extends it for MCP agent clients without rearchitecting what exists.

The POC (PR #7414) added MCP-specific OAuth bits (hardcoded mcp-agent client, AccessRequestMCP.vue consent page, .well-known discovery endpoints). These should not be reused directly. Instead, this work builds around the existing OAuth scaffolding following the established patterns.

Requirements

Build on existing OAuth2 PKCE scaffolding

  • The existing implementation in forge/routes/auth/oauth.js already handles:
    • Authorization Code Grant with PKCE (S256)
    • /account/authorize and /account/token endpoints
    • Client validation (hardcoded + dynamic via AuthClient table)
    • Consent/authorization page workflow with approve/deny
    • Token exchange with refresh token support
    • 5-minute TTL on OAuth sessions, single-use authorization codes
  • This is the foundation. The MCP agent auth work extends it, it doesn't replace it.

MCP client registration

  • Register an MCP agent client, following the same pattern as the existing ff-plugin hardcoded client.
  • The client needs appropriate scope definitions for MCP platform access.
  • Redirect URI validation should support localhost (for local dev tools like Claude Code, Cursor) and, eventually, Anthropic's callback URLs (for Claude plugin).

Consent page

  • An MCP-specific consent page that clearly communicates what the agent will be able to do.
  • Should show the scope/permissions being granted in user-friendly terms.

Discovery endpoints (.well-known)

  • /.well-known/oauth-authorization-server (RFC 8414): Standard OAuth2 metadata. This is what enables clients to auto-discover the authorization server without manual configuration.
  • /.well-known/oauth-protected-resource (RFC 9728): Protected resource metadata pointing to the MCP endpoint.
  • These endpoints are the bridge between "user manually configures a token" and "user pastes their FlowFuse URL and the agent figures out the rest."
  • The POC prototyped these following the right RFCs. The implementation should follow the same specs.

Phased evolution

  • Phase 1 (covered by Add PAT (Personal Acces Tokens) scopes #7411): Manual PAT creation. User creates a scoped PAT, pastes it into their MCP client config. Works immediately, no OAuth needed.
  • Phase 2 (this story): OAuth2 PKCE with localhost redirect URIs. User's MCP client (Claude Desktop, Cursor, Claude Code) initiates the OAuth flow, browser opens, user approves, token is issued automatically. The user experience from dimitrieh's comment (Define requirements #7368): user enters their FlowFuse instance URL, OAuth kicks in, they authenticate, done.
  • Phase 3 (future): Claude plugin/connector directory submission. FlowFuse appears as a pre-built connector in Claude's directory. Requires accepting Anthropic's callback URLs instead of just localhost, and submitting for Anthropic's review. The .well-known endpoints and PKCE flow from phase 2 are the foundation. The delta is accepting Anthropic's redirect URIs and meeting their directory requirements. Not a rearchitecture, a natural extension.

Key consideration: Each phase should be built preparing for what's ahead (raised by dimitrieh on #7368). The OAuth2 work in phase 2 should be structured so that phase 3 (Claude plugin) is an incremental addition, not a rewrite.

What this story does NOT cover

  • PAT scopes (Add PAT (Personal Acces Tokens) scopes #7411), the prerequisite that provides the phase 1 auth mechanism
  • MCP endpoint implementation (Story 1)
  • Token scope-to-tool mapping (that's a PAT scopes concern, enforced at the MCP layer based on tool annotations)

References

  • Existing OAuth2 implementation: forge/routes/auth/oauth.js (the foundation to build on)
  • Existing client patterns: ff-plugin hardcoded client, AuthClient model for dynamic clients

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyA user-oriented description of a feature

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions