Skip to content

AthorizationManager discover_metadata stopped working for paths with suffix in 0.13 release #632

@glicht

Description

@glicht

Describe the bug
After upgrading to 0.13 (also tested with 0.14) metadata discovery stopped working for urls with a suffix.

Example url: https://auditlogs.mcp.cloudflare.com/mcp

It seems that the discovery stopped checking <base_domain>/.well-known/oauth-authorization-server.

To Reproduce
Steps to reproduce the behavior:

Use following example program:

use anyhow::{Context, Result};
use rmcp::transport::AuthorizationManager;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

#[tokio::main]
async fn main() -> Result<()> {
    tracing_subscriber::registry()
        .with(tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "debug".into()))
        .with(tracing_subscriber::fmt::layer())
        .init();

    let url = std::env::args().nth(1).context("Usage: metadata_discovery <url>")?;
    tracing::info!("Discovering metadata for URL: {}", url);

    let metadata = AuthorizationManager::new(&url).await?.discover_metadata().await?;
    tracing::info!("Discovered metadata: {:#?}", metadata);

    Ok(())
}

Run with the following url for example: https://auditlogs.mcp.cloudflare.com/mcp

Output with rmcp 0.14 (fails):

2026-01-28T08:55:19.269795Z  INFO metadata_discovery: Discovering metadata for URL: https://auditlogs.mcp.cloudflare.com/mcp
2026-01-28T08:55:19.290356Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/.well-known/oauth-authorization-server/mcp", query: None, fragment: None }
2026-01-28T08:55:19.290959Z DEBUG reqwest::connect: starting new connection: https://auditlogs.mcp.cloudflare.com/
2026-01-28T08:55:19.293894Z DEBUG hyper_util::client::legacy::connect::http: connecting to 104.18.24.159:443
2026-01-28T08:55:19.307814Z DEBUG hyper_util::client::legacy::connect::http: connected to 104.18.24.159:443
2026-01-28T08:55:19.349196Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.349290Z DEBUG rmcp::transport::auth: discovery returned non-200: 404 Not Found
2026-01-28T08:55:19.349310Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/.well-known/openid-configuration/mcp", query: None, fragment: None }
2026-01-28T08:55:19.349391Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.362191Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.362247Z DEBUG rmcp::transport::auth: discovery returned non-200: 404 Not Found
2026-01-28T08:55:19.362265Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/mcp/.well-known/openid-configuration", query: None, fragment: None }
2026-01-28T08:55:19.362328Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.375701Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.375771Z DEBUG rmcp::transport::auth: discovery returned non-200: 401 Unauthorized
2026-01-28T08:55:19.375853Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.389409Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.389570Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.402893Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.402948Z DEBUG rmcp::transport::auth: resource metadata probe returned unexpected status: 404 Not Found
2026-01-28T08:55:19.403023Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.420695Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.420827Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.442677Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:55:19.442733Z DEBUG rmcp::transport::auth: resource metadata probe returned unexpected status: 404 Not Found
Error: No authorization support detected

Output with rmcp 0.12 (succeeds):

026-01-28T08:51:27.253029Z  INFO metadata_discovery: Discovering metadata for URL: https://auditlogs.mcp.cloudflare.com/mcp
2026-01-28T08:51:27.270586Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/.well-known/oauth-authorization-server/mcp", query: None, fragment: None }
2026-01-28T08:51:27.271189Z DEBUG reqwest::connect: starting new connection: https://auditlogs.mcp.cloudflare.com/
2026-01-28T08:51:27.273854Z DEBUG hyper_util::client::legacy::connect::http: connecting to 104.18.24.159:443
2026-01-28T08:51:27.285834Z DEBUG hyper_util::client::legacy::connect::http: connected to 104.18.24.159:443
2026-01-28T08:51:27.330962Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:51:27.331111Z DEBUG rmcp::transport::auth: discovery returned non-200: 404 Not Found
2026-01-28T08:51:27.331149Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/mcp/.well-known/oauth-authorization-server", query: None, fragment: None }
2026-01-28T08:51:27.331244Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:51:27.350701Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:51:27.350792Z DEBUG rmcp::transport::auth: discovery returned non-200: 401 Unauthorized
2026-01-28T08:51:27.350825Z DEBUG rmcp::transport::auth: discovery url: Url { scheme: "https", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("auditlogs.mcp.cloudflare.com")), port: None, path: "/.well-known/oauth-authorization-server", query: None, fragment: None }
2026-01-28T08:51:27.350921Z DEBUG hyper_util::client::legacy::pool: reuse idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:51:27.364915Z DEBUG hyper_util::client::legacy::pool: pooling idle connection for ("https", auditlogs.mcp.cloudflare.com)
2026-01-28T08:51:27.365310Z  INFO metadata_discovery: Discovered metadata: AuthorizationMetadata {
    authorization_endpoint: "https://auditlogs.mcp.cloudflare.com/oauth/authorize",
    token_endpoint: "https://auditlogs.mcp.cloudflare.com/token",
    registration_endpoint: Some(
        "https://auditlogs.mcp.cloudflare.com/register",
    ),
    issuer: Some(
        "https://auditlogs.mcp.cloudflare.com",
    ),
    jwks_uri: None,
    scopes_supported: None,
    response_types_supported: Some(
        [
            "code",
        ],
    ),
    additional_fields: {
        "token_endpoint_auth_methods_supported": Array [
            String("client_secret_basic"),
            String("client_secret_post"),
            String("none"),
        ],
        "response_modes_supported": Array [
            String("query"),
        ],
        "grant_types_supported": Array [
            String("authorization_code"),
            String("refresh_token"),
        ],
        "revocation_endpoint": String("https://auditlogs.mcp.cloudflare.com/token"),
        "code_challenge_methods_supported": Array [
            String("plain"),
            String("S256"),
        ],
    },
}

Expected behavior
Keep working as expected in 0.12

Logs
See reproduce steps.

Additional context
Seems related to this PR: #598

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