Skip to content

Commit c277b48

Browse files
Merge branch 'main' into fweinberger/abort-handlers-on-close
2 parents 3b88756 + e563e63 commit c277b48

File tree

24 files changed

+1330
-318
lines changed

24 files changed

+1330
-318
lines changed

.changeset/tame-camels-greet.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@modelcontextprotocol/client': patch
3+
---
4+
5+
Don't swallow fetch `TypeError` as CORS in non-browser environments. Network errors
6+
(DNS resolution failure, connection refused, invalid URL) in Node.js and Cloudflare
7+
Workers now propagate from OAuth discovery instead of being silently misattributed
8+
to CORS and returning `undefined`. This surfaces the real error to callers rather
9+
than masking it as "metadata not found."
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
'@modelcontextprotocol/client': minor
3+
---
4+
5+
Add `AuthProvider` for composable bearer-token auth; transports adapt `OAuthClientProvider` automatically
6+
7+
- New `AuthProvider` interface: `{ token(): Promise<string | undefined>; onUnauthorized?(ctx): Promise<void> }`. Transports call `token()` before every request and `onUnauthorized()` on 401 (then retry once).
8+
- Transport `authProvider` option now accepts `AuthProvider | OAuthClientProvider`. OAuth providers are adapted internally via `adaptOAuthProvider()` — no changes needed to existing `OAuthClientProvider` implementations.
9+
- For simple bearer tokens (API keys, gateway-managed tokens, service accounts): `{ authProvider: { token: async () => myKey } }` — one-line object literal, no class.
10+
- New `adaptOAuthProvider(provider)` export for explicit adaptation.
11+
- New `handleOAuthUnauthorized(provider, ctx)` helper — the standard OAuth `onUnauthorized` behavior.
12+
- New `isOAuthClientProvider()` type guard.
13+
- New `UnauthorizedContext` type.
14+
- Exported previously-internal auth helpers for building custom flows: `applyBasicAuth`, `applyPostAuth`, `applyPublicAuth`, `executeTokenRequest`.
15+
16+
Transports are simplified internally — ~50 lines of inline OAuth orchestration (auth() calls, WWW-Authenticate parsing, circuit-breaker state) moved into the adapter's `onUnauthorized()` implementation. `OAuthClientProvider` itself is unchanged.

.github/workflows/claude.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ on:
1414
jobs:
1515
claude:
1616
if: |
17-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && !startsWith(github.event.comment.body, '@claude review')) ||
1818
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
1919
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
2020
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))

docs/client.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ A client connects to a server, discovers what it offers — tools, resources, pr
1313
The examples below use these imports. Adjust based on which features and transport you need:
1414

1515
```ts source="../examples/client/src/clientGuide.examples.ts#imports"
16-
import type { Prompt, Resource, Tool } from '@modelcontextprotocol/client';
16+
import type { AuthProvider, Prompt, Resource, Tool } from '@modelcontextprotocol/client';
1717
import {
1818
applyMiddlewares,
1919
Client,
@@ -113,7 +113,19 @@ console.log(systemPrompt);
113113

114114
## Authentication
115115

116-
MCP servers can require OAuth 2.0 authentication before accepting client connections (see [Authorization](https://modelcontextprotocol.io/specification/latest/basic/authorization) in the MCP specification). Pass an `authProvider` to {@linkcode @modelcontextprotocol/client!client/streamableHttp.StreamableHTTPClientTransport | StreamableHTTPClientTransport} to enable this — the SDK provides built-in providers for common machine-to-machine flows, or you can implement the full {@linkcode @modelcontextprotocol/client!client/auth.OAuthClientProvider | OAuthClientProvider} interface for user-facing OAuth.
116+
MCP servers can require authentication before accepting client connections (see [Authorization](https://modelcontextprotocol.io/specification/latest/basic/authorization) in the MCP specification). Pass an {@linkcode @modelcontextprotocol/client!client/auth.AuthProvider | AuthProvider} to {@linkcode @modelcontextprotocol/client!client/streamableHttp.StreamableHTTPClientTransport | StreamableHTTPClientTransport}. The transport calls `token()` before every request and `onUnauthorized()` (if provided) on 401, then retries once.
117+
118+
### Bearer tokens
119+
120+
For servers that accept bearer tokens managed outside the SDK — API keys, tokens from a gateway or proxy, service-account credentials — implement only `token()`. With no `onUnauthorized()`, a 401 throws {@linkcode @modelcontextprotocol/client!client/auth.UnauthorizedError | UnauthorizedError} immediately:
121+
122+
```ts source="../examples/client/src/clientGuide.examples.ts#auth_tokenProvider"
123+
const authProvider: AuthProvider = { token: async () => getStoredToken() };
124+
125+
const transport = new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'), { authProvider });
126+
```
127+
128+
See [`simpleTokenProvider.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/client/src/simpleTokenProvider.ts) for a complete runnable example.
117129

118130
### Client credentials
119131

0 commit comments

Comments
 (0)