Skip to content

Select the advertised authorization server by the stored issuer - #680

Merged
koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:select_the_advertised_authorization_server_by_the_stored_issuer
Nov 13, 2026
Merged

koic merged 1 commit into
modelcontextprotocol:mainfrom
koic:select_the_advertised_authorization_server_by_the_stored_issuer

Conversation

@koic

@koic koic commented Nov 11, 2026

Copy link
Copy Markdown
Member

Motivation and Context

Protected resource metadata may list several authorization servers, and the flow always took the first. With issuer: on ClientCredentialsProvider and CrossAppAccessProvider that could not work: a resource listing the configured server second was refused as a different authorization server, although its metadata named the right one. A registered client fared the same: its stored client information records the server that issued the registration, and it was registered again at the first entry instead.

The flow now prefers the entry naming the issuer recorded in the provider's client information, with the single trailing slash tolerance the issuer checks apply, and falls back to the first entry when nothing is recorded or listed; the checks that follow still decide, so a configured issuer the resource does not list is refused as before. The Python SDK's client credentials provider selects the advertised server the same way for its configured issuer.

How Has This Been Tested?

test/mcp/client/oauth/flow_test.rb: a resource listing the configured issuer second runs both machine-to-machine grants and the refresh at that server, a trailing slash difference still matches, an issuer the resource does not list is refused, a provider without an issuer keeps the first entry, and a registered client keeps its authorization server; before the change the tests that expect the second entry fail by picking the first.

Breaking Changes

None.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

## Motivation and Context

Protected resource metadata may list several authorization servers, and the flow always took the first.
With `issuer:` on `ClientCredentialsProvider` and `CrossAppAccessProvider` that could not work:
a resource listing the configured server second was refused as a different authorization server,
although its metadata named the right one. A registered client fared the same: its stored client information records
the server that issued the registration, and it was registered again at the first entry instead.

The flow now prefers the entry naming the issuer recorded in the provider's client information, with
the single trailing slash tolerance the issuer checks apply, and falls back to the first entry when nothing
is recorded or listed; the checks that follow still decide, so a configured issuer the resource does not
list is refused as before. The Python SDK's client credentials provider selects the advertised server
the same way for its configured issuer.

## How Has This Been Tested?

test/mcp/client/oauth/flow_test.rb: a resource listing the configured issuer second runs both
machine-to-machine grants and the refresh at that server, a trailing slash difference still matches,
an issuer the resource does not list is refused, a provider without an issuer keeps the first entry,
and a registered client keeps its authorization server; before the change the tests that expect
the second entry fail by picking the first.

## Breaking Changes

None.
@koic
koic merged commit d9a19c1 into modelcontextprotocol:main Nov 13, 2026
13 checks passed
@koic
koic deleted the select_the_advertised_authorization_server_by_the_stored_issuer branch November 13, 2026 03:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants