modelcontextprotocol / modelcontextprotocol/kotlin-sdk

[Proposal] SEP-2351: Explicit RFC 8414 well-known URI suffix specification & client discovery (#810)

Open
#1,009 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Kotlin
Stars
1.5k
Forks
248
Avg merge
1d 20h
Merged PRs (30d)
23

Description

Proposal: SEP-2351 Explicit RFC 8414 Well-Known URI Suffix Specification & Client Discovery (#810)
Motivation & Context

Tracking implementation of SEP-2351 in kotlin-sdk for the 2026-07-28 MCP specification release (aligned with umbrella issue #842).

RFC 8414 (OAuth 2.0 Authorization Server Metadata) Section 3.1 requires application protocols that leverage OAuth authorization server metadata to explicitly designate which well-known URI suffix is used for discovery. Previously, the MCP specification left this requirement implicit, leading to ambiguities across SDK implementations regarding whether an application-specific suffix (e.g. /.well-known/mcp-authorization-server) might be introduced.

SEP-2351 resolves this:

  1. Formally specifies that MCP adheres strictly to the standard RFC 8414 Section 3.1 suffix: oauth-authorization-server (/.well-known/oauth-authorization-server).
  2. Confirms that MCP does not introduce any proprietary, custom well-known URI suffix.
  3. Aligns discovery behavior across all official MCP SDKs and OAuth-protected MCP servers.

This proposal outlines the implementation plan for RFC 8414 metadata resolution in kotlin-sdk across kotlin-sdk-core and kotlin-sdk-client.


Proposed Architecture & Component Design
1. Well-Known URI Constants (kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/)

In kotlin-sdk-core:
Define standardized discovery path constants:

public object McpAuthDiscovery {
    /**
     * Standard RFC 8414 Section 3.1 well-known URI suffix for OAuth authorization server metadata.
     */
    public const val RFC_8414_WELL_KNOWN_SUFFIX: String = "oauth-authorization-server"

    /**
     * Standard OpenID Connect Discovery suffix.
     */
    public const val OIDC_WELL_KNOWN_SUFFIX: String = "openid-configuration"

    /**
     * Standard well-known directory path prefix.
     */
    public const val WELL_KNOWN_PATH_PREFIX: String = "/.well-known/"
}
2. Authorization Server Metadata Discovery Helper (kotlin-sdk-client)

In kotlin-sdk-client (or auth utility module):
Implement an RFC 8414 metadata resolution algorithm with fallback:

public class McpOAuthMetadataResolver(
    private val httpClient: HttpClient
) {
    /**
     * Resolves RFC 8414 metadata for the specified issuer URL.
     *
     * In accordance with SEP-2351, probes `/.well-known/oauth-authorization-server` first,
     * falling back to `/.well-known/openid-configuration` if the RFC 8414 endpoint returns 404.
     */
    public suspend fun resolveMetadata(issuerUri: Url): OAuthAuthorizationServerMetadata {
        val rfc8414Url = buildWellKnownUrl(issuerUri, McpAuthDiscovery.RFC_8414_WELL_KNOWN_SUFFIX)
        
        val rfc8414Response = httpClient.get(rfc8414Url)
        if (rfc8414Response.status.isSuccess()) {
            return rfc8414Response.body<OAuthAuthorizationServerMetadata>()
        }

        // Fallback for IdPs advertising only OpenID Connect configuration
        val oidcUrl = buildWellKnownUrl(issuerUri, McpAuthDiscovery.OIDC_WELL_KNOWN_SUFFIX)
        val oidcResponse = httpClient.get(oidcUrl)
        if (oidcResponse.status.isSuccess()) {
            return oidcResponse.body<OAuthAuthorizationServerMetadata>()
        }

        throw McpAuthException(
            "Failed to discover authorization server metadata for issuer $issuerUri. " +
            "Probed RFC 8414 ($rfc8414Url) and OIDC ($oidcUrl)."
        )
    }

    private fun buildWellKnownUrl(baseUri: Url, suffix: String): Url {
        // Correct path insertion per RFC 8414 §3.1 (handling path components in base issuer URLs)
        val basePath = baseUri.encodedPath.trimEnd('/')
        val path = if (basePath.isEmpty()) {
            "${McpAuthDiscovery.WELL_KNOWN_PATH_PREFIX}$suffix"
        } else {
            "${McpAuthDiscovery.WELL_KNOWN_PATH_PREFIX}$suffix$basePath"
        }
        return URLBuilder(baseUri).apply { encodedPath = path }.build()
    }
}
3. RFC 8414 §3.1 Path Insertion Compliance

RFC 8414 specifies that for an authorization server with path components (e.g. https://auth.example.com/tenant1):

  • The well-known URI is formed by inserting /.well-known/oauth-authorization-server before the path component: https://auth.example.com/.well-known/oauth-authorization-server/tenant1.
  • The resolver must correctly handle both root issuers (https://auth.example.com) and path-scoped issuers (https://auth.example.com/oauth2/v1).
4. Testing & Verification Plan
  • Unit Tests:
    • Test URI construction for root issuer https://example.com -> https://example.com/.well-known/oauth-authorization-server.
    • Test URI construction for path-scoped issuer https://example.com/oauth/v2 -> https://example.com/.well-known/oauth-authorization-server/oauth/v2.
    • Mock HTTP responses verifying RFC 8414 metadata decoding and fallback to OpenID configuration.
  • Conformance Scenarios:
    • Validate against the OAuth authorization metadata discovery scenarios in modelcontextprotocol/conformance.

Next Steps

Upon maintainer review:

  1. Export discovery constants in kotlin-sdk-core.
  2. Integrate McpOAuthMetadataResolver in kotlin-sdk-client.
  3. Add unit test coverage for RFC 8414 §3.1 path resolution.

AI assistance disclosure: AI was used to discover this opportunity and draft the change or text. The submission was checked against the prepared artifact and recorded verification evidence.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the proposed discovery constants under kotlin-sdk-core/src/commonMain/kotlin/io/modelcontextprotocol/kotlin/sdk/ and the client or auth utility area in kotlin-sdk-client. Use the listed root and path-scoped URI cases, metadata decoding, and OIDC fallback as the verification plan. Done means the constants, resolver integration, and unit coverage for RFC 8414 path resolution are present, with conformance scenarios considered.

Written by the indexing model from the issue text.

Assessment

Tech stack
kotlin
Domain
api, authentication, backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.