Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

[v2] RFC 9728 PRM URLs and resource matching drop query components

Ouverte
#3,065 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
3/5
Temps estimé
1-2 jours
Accessibilité débutants
74/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
python
Domaine
authentication

Piste de recherche

Commencez par mcp.server.auth.routes.build_resource_metadata_url(), mcp.client.auth.utils.build_protected_resource_metadata_discovery_urls() et mcp.shared.auth_utils.check_resource_allowed(), puis suivez OAuthClientProvider._validate_resource_match(). Reproduisez les cas comportant des paramètres de requête présentés dans l’issue et ajoutez des tests d’auth ciblés ; le travail est terminé lorsque les URL de métadonnées préservent la requête et que des composants de requête différents ne correspondent plus.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

auth bug needs confirmation P2 v1 v2

What happened?

While testing the v2 auth/protected-resource-metadata path, I noticed query-bearing resource identifiers are treated as if the query is not part of the resource.

For a resource server URL like:

https://api.example.com/mcp?tenant=a

three SDK paths currently drop or ignore ?tenant=a:

  1. mcp.server.auth.routes.build_resource_metadata_url() returns:
https://api.example.com/.well-known/oauth-protected-resource/mcp
  1. mcp.client.auth.utils.build_protected_resource_metadata_discovery_urls(None, resource) also tries:
https://api.example.com/.well-known/oauth-protected-resource/mcp
https://api.example.com/.well-known/oauth-protected-resource
  1. mcp.shared.auth_utils.check_resource_allowed() treats different query components as matching, so the client accepts protected resource metadata for ?tenant=b when the server URL was ?tenant=a.

This is latent for path-only deployments, but it matters for query-routed or multi-tenant resource identifiers.

What did you expect?

RFC 9728 derives the protected-resource metadata URL by inserting /.well-known/oauth-protected-resource before the protected resource path and/or query. If the resource identifier includes a query component, the derived metadata URL and resource validation should not silently collapse it with a different query.

For https://api.example.com/mcp?tenant=a, I expected the path-specific metadata URL to be:

https://api.example.com/.well-known/oauth-protected-resource/mcp?tenant=a

And a PRM document whose resource is https://api.example.com/mcp?tenant=b should not validate for a client configured with https://api.example.com/mcp?tenant=a.

Code to reproduce

import anyio
from pydantic import AnyHttpUrl, AnyUrl

from mcp.client.auth import OAuthClientProvider
from mcp.client.auth.utils import build_protected_resource_metadata_discovery_urls
from mcp.server.auth.routes import build_resource_metadata_url
from mcp.shared.auth import OAuthClientMetadata, ProtectedResourceMetadata
from mcp.shared.auth_utils import check_resource_allowed
from tests.interaction.auth._harness import InMemoryTokenStorage


async def main() -> None:
    resource = "https://api.example.com/mcp?tenant=a"

    print(build_resource_metadata_url(AnyHttpUrl(resource)))
    print(build_protected_resource_metadata_discovery_urls(None, resource))
    print(check_resource_allowed(
        "https://api.example.com/mcp?tenant=a",
        "https://api.example.com/mcp?tenant=b",
    ))

    provider = OAuthClientProvider(
        server_url=resource,
        client_metadata=OAuthClientMetadata(
            client_name="probe",
            client_uri=AnyHttpUrl("https://example.com"),
            redirect_uris=[AnyUrl("http://localhost:3030/callback")],
        ),
        storage=InMemoryTokenStorage(),
    )
    prm = ProtectedResourceMetadata(
        resource=AnyHttpUrl("https://api.example.com/mcp?tenant=b"),
        authorization_servers=[AnyHttpUrl("https://auth.example.com")],
    )
    await provider._validate_resource_match(prm)
    print("accepted mismatched query")


anyio.run(main)

Current output:

https://api.example.com/.well-known/oauth-protected-resource/mcp
['https://api.example.com/.well-known/oauth-protected-resource/mcp', 'https://api.example.com/.well-known/oauth-protected-resource']
True
accepted mismatched query

SDK version

Current main branch, v2 development line.

Area

Auth

AI-assisted (Claude/Codex) for navigation and review; change authored and understood by me.

Langage dominant
Python
Étoiles
24.3k
Forks
4k
Merge moyen
1 j 19 min
PR mergées (30 j)
29

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de modelcontextprotocol/python-sdk

Toutes les issues de modelcontextprotocol/python-sdk

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.