[v2] OAuth discovery validates any /.well-known/openid-configuration document as OIDC, rejecting conforming RFC 8414 metadata
Mantenedores costumam responder em até 1 dia
Avaliação
- Dificuldade
- 4/5
- Tempo estimado
- 3-5 dias
- Facilidade para iniciantes
- 58/100
- Tipo de issue
- Bug
- Clareza
- Razoavelmente clara
- Status de atividade
- Ativa
- Stack de tecnologia
- typescript
- Domínio
- authentication, security
Direção de pesquisa
Comece com discoverAuthorizationServerMetadata() e os schemas relacionados em client/dist/index.mjs e, em seguida, execute a reprodução fornecida de fetchFn usando o documento RFC 8414. Rastreie as falhas dos candidatos e a seleção de schemas e verifique se um documento de metadados OAuth em conformidade em /.well-known/openid-configuration é aceito ou se a descoberta continua com outro candidato, mantendo intacta a validação do issuer.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
What happened?
discoverAuthorizationServerMetadata() picks its validation schema from which well-known filename resolved, not from the document that came back. Every openid-configuration candidate is typed "oidc", so anything served there is validated against OpenIdProviderDiscoveryMetadataSchema:
// client/dist/index.mjs (2.0.0)
const parsed = type === "oauth"
? OAuthMetadataSchema.parse(await response.json())
: OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());
That schema requires jwks_uri, subject_types_supported and id_token_signing_alg_values_supported — three fields OpenID Connect Discovery 1.0 requires and RFC 8414 does not. So a plain OAuth 2.0 authorization server (no ID tokens, no JWKS, no sub) that publishes RFC 8414 metadata at /.well-known/openid-configuration is rejected:
[
{"expected":"string","code":"invalid_type","path":["jwks_uri"],"message":"Invalid input: expected string, received undefined"},
{"expected":"array","code":"invalid_type","path":["subject_types_supported"],"message":"Invalid input: expected array, received undefined"},
{"expected":"array","code":"invalid_type","path":["id_token_signing_alg_values_supported"],"message":"Invalid input: expected array, received undefined"}
]
Two things make this fatal rather than cosmetic:
- RFC 8414 §5 explicitly permits that filename for general OAuth metadata. The server is conforming; the client is not.
- The parse throws instead of continuing the candidate loop. Every other failure in that loop (
continueon 4xx/502,continueon a CORS failure) falls through to the next candidate. A schema failure abortsdiscoverAuthorizationServerMetadata()entirely, so no later candidate is tried and the whole connection fails.
Reported downstream at modelcontextprotocol/inspector#2172 against a real server (https://misc.poodll.com/mod/minilesson/mcp.php, a plain OAuth 2.0 AS whose resource lives under a path). Reproduced independently against @modelcontextprotocol/[email protected] with an injected fetchFn, and again against a local test server that serves RFC 8414 metadata only at /.well-known/openid-configuration.
Two smaller things noticed in the same code path, mentioned here rather than as separate issues since a fix will likely touch both:
OpenIdProviderDiscoveryMetadataSchemais az.object(...), not az.looseObject(...)likeOAuthMetadataSchema. So a successful OIDC parse strips RFC 8414 fields that are not in the OIDC shape —revocation_endpointandintrospection_endpointamong them — from the returned metadata.- The doc comment on
discoverAuthorizationServerMetadatasays it "attempts RFC 8414 OAuth metadata discovery first / if OAuth discovery fails, falls back to OpenID Connect Discovery", which is what the URL ordering does but not what the schema selection does.
What did you expect?
A document should be validated by what it is, not by the filename it was found under. Concretely, either:
- try
OAuthMetadataSchemaand fall back toOpenIdProviderDiscoveryMetadataSchema(or vice versa) regardless of the candidate'stype—OAuthMetadataSchemais a loose object, so it accepts a full OIDC document without dropping any of its fields; or - treat a schema failure like the other per-candidate failures and
continueto the next candidate rather than throwing out of the whole function.
Either way, issuer validation (RFC 8414 §3.3 / OIDC Discovery §4.3) should stay exactly as it is.
Code to reproduce
import { discoverAuthorizationServerMetadata } from '@modelcontextprotocol/client';
// A plain OAuth 2.0 AS: RFC 8414 metadata, served only at the OIDC well-known path.
const METADATA = {
issuer: 'https://as.example.com',
authorization_endpoint: 'https://as.example.com/oauth/authorize',
token_endpoint: 'https://as.example.com/oauth/token',
response_types_supported: ['code'],
grant_types_supported: ['authorization_code', 'refresh_token'],
code_challenge_methods_supported: ['S256'],
};
const fetchFn: typeof fetch = async input => {
const url = String(input);
if (url === 'https://as.example.com/.well-known/openid-configuration') {
return new Response(JSON.stringify(METADATA), {
status: 200,
headers: { 'content-type': 'application/json' },
});
}
return new Response('not found', { status: 404 });
};
// Throws a ZodError for jwks_uri / subject_types_supported /
// id_token_signing_alg_values_supported. Expected: the RFC 8414 document.
await discoverAuthorizationServerMetadata('https://as.example.com', { fetchFn });
SDK version
@modelcontextprotocol/[email protected] (with @modelcontextprotocol/[email protected])
- Linguagem predominante
- TypeScript
- Estrelas
- 13.7k
- Forks
- 2.3k
- Merge médio
- 1d 12h
- PRs com merge (30d)
- 44
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de modelcontextprotocol/typescript-sdk
-
[v2] createMcpHandler legacy fallback misses an abort that happens before it subscribesTalvez já em andamento @mariano-aguero assumiu há 2 dias. Abertav2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
modelcontextprotocol/typescript-sdk#3136 ·
Mantenedores costumam responder em até 1 dia
-
[v2] requireBearerAuth: drop error="invalid_token" when no credentials were sent and resource_metadata is set (RFC 6750 §3.1)Talvez já em andamento @Anandumv assumiu há 1 dia. Abertav2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
modelcontextprotocol/typescript-sdk#3124 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
The `maxToolInputElements` refusal lacks the `Input validation error:` prefix that the schema refusal carriesTalvez já em andamento @barry166 assumiu há 5 dias. Abertav1 v2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
modelcontextprotocol/typescript-sdk#3111 · 3 comentários ·
Mantenedores costumam responder em até 1 dia
-
server: registeredResource.update and registeredResourceTemplate.update desync title and metadata.title when updating metadata aloneTalvez já em andamento Um pull request vinculado a esta issue está aberto ou já foi mesclado. Abertav1 v2
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
modelcontextprotocol/typescript-sdk#3103 · 5 comentários ·
Mantenedores costumam responder em até 1 dia
-
[v1.x] Protocol.request keeps its abort listener after the request resolved, so a later abort sends notifications/cancelled for an answered request (1.30.0)Talvez já em andamento Um pull request vinculado a esta issue está aberto ou já foi mesclado. Abertav1
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 76/100
modelcontextprotocol/typescript-sdk#3090 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de modelcontextprotocol/typescript-sdk
Issues semelhantes
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:other issue-rating: 🦞 diamond lobster maturity:stable no-stale P1
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
openclaw/openclaw#190772 · 1 comentário · 1 reação ·
Mantenedores costumam responder em até 1 dia
-
2026-11 good first issue gsoc-2027 project: virtual tests
Dificuldade 2/5 Meio dia Facilidade para iniciantes 82/100
alphaonelabs/website#1150 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 70/100
flisk-sh/run-my-agents#61 ·
-
Dificuldade 2/5 3-5 dias Facilidade para iniciantes 62/100
career-ops-hq/career-ops#6399 · 1 comentário ·
Mantenedores costumam responder em até 1 dia
-
agents ai-agents area: cli claude-code difficulty: easy dx enhancement examples good first issue growth hacktoberfest help wanted island: Agent Isle island: Recipe Archipelago rank: 7 kyu tech: typescript
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 62/100
tdk-landscape/tdk-cli-core#3126 ·