Skip to content

.well-known Discovery Endpoints for MCP OAuth #7431

@cstns

Description

@cstns

Summary

Add .well-known discovery endpoints that let MCP clients auto-discover the OAuth authorization server and protected resource metadata without manual configuration. This is what bridges the gap between "paste a PAT" and "paste your FlowFuse URL and authenticate."

Prerequisites

Requirements

/.well-known/oauth-authorization-server (RFC 8414)

  • Returns JSON metadata describing the OAuth2 authorization server
  • Must include: issuer, authorization_endpoint, token_endpoint, response_types_supported, code_challenge_methods_supported, grant_types_supported
  • Values derived from app.config.base_url so they're correct for both local dev and production/self-hosted
  • No auth required (public endpoint)

/.well-known/oauth-protected-resource (RFC 9728)

  • Returns JSON metadata describing the MCP endpoint as a protected resource
  • Must include: resource (the MCP endpoint URL), authorization_servers (pointing to the authorization server metadata URL)
  • No auth required (public endpoint)

Route placement

  • Register in forge/routes/wellKnown.js (new file) or similar, outside the EE routes since discovery should work regardless of license tier
  • Mounted at the root level so .well-known paths resolve correctly

Tests

  • Both endpoints return valid JSON with the required fields
  • URLs are correctly derived from app.config.base_url
  • Endpoints are publicly accessible (no auth required)
  • Response content types are application/json

Aside on EE gating: These endpoints are placed outside EE routes so that discovery works regardless of license tier. If .well-known were EE-gated, non-EE instances would 404 on discovery and MCP clients would fail with a confusing error instead of a clean "not available." The actual MCP endpoint and OAuth flow remain EE-gated. Might be worth reconsidering if there's a reason to hide discovery entirely on non-EE instances.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions