@ai-sdk/mcp 1.0.42 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +134 -0
- package/dist/index.js +20 -10
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +20 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/tool/mcp-http-transport.ts +25 -10
package/package.json
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
extractResourceMetadataUrl,
|
|
17
17
|
UnauthorizedError,
|
|
18
18
|
auth,
|
|
19
|
+
type AuthResult,
|
|
19
20
|
type OAuthClientProvider,
|
|
20
21
|
} from './oauth';
|
|
21
22
|
import { LATEST_PROTOCOL_VERSION } from './types';
|
|
@@ -37,6 +38,7 @@ export class HttpMCPTransport implements MCPTransport {
|
|
|
37
38
|
private inboundSseConnection?: { close: () => void };
|
|
38
39
|
private redirectMode: RequestRedirect;
|
|
39
40
|
private fetchFn: FetchFunction;
|
|
41
|
+
private authPromise?: Promise<AuthResult>;
|
|
40
42
|
|
|
41
43
|
// Inbound SSE resumption and reconnection state
|
|
42
44
|
private lastInboundEventId?: string;
|
|
@@ -100,6 +102,27 @@ export class HttpMCPTransport implements MCPTransport {
|
|
|
100
102
|
);
|
|
101
103
|
}
|
|
102
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Runs a single OAuth recovery flow for concurrent 401 responses.
|
|
107
|
+
*/
|
|
108
|
+
private authorizeOnce(resourceMetadataUrl?: URL): Promise<AuthResult> {
|
|
109
|
+
if (!this.authProvider) {
|
|
110
|
+
return Promise.resolve('REDIRECT');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!this.authPromise) {
|
|
114
|
+
this.authPromise = auth(this.authProvider, {
|
|
115
|
+
serverUrl: this.url,
|
|
116
|
+
resourceMetadataUrl,
|
|
117
|
+
fetchFn: this.fetchFn,
|
|
118
|
+
}).finally(() => {
|
|
119
|
+
this.authPromise = undefined;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return this.authPromise;
|
|
124
|
+
}
|
|
125
|
+
|
|
103
126
|
async start(): Promise<void> {
|
|
104
127
|
if (this.abortController) {
|
|
105
128
|
throw new MCPClientError({
|
|
@@ -160,11 +183,7 @@ export class HttpMCPTransport implements MCPTransport {
|
|
|
160
183
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
161
184
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
162
185
|
try {
|
|
163
|
-
const result = await
|
|
164
|
-
serverUrl: this.url,
|
|
165
|
-
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
166
|
-
fetchFn: this.fetchFn,
|
|
167
|
-
});
|
|
186
|
+
const result = await this.authorizeOnce(this.resourceMetadataUrl);
|
|
168
187
|
if (result !== 'AUTHORIZED') {
|
|
169
188
|
const error = new UnauthorizedError();
|
|
170
189
|
throw error;
|
|
@@ -340,11 +359,7 @@ export class HttpMCPTransport implements MCPTransport {
|
|
|
340
359
|
if (response.status === 401 && this.authProvider && !triedAuth) {
|
|
341
360
|
this.resourceMetadataUrl = extractResourceMetadataUrl(response);
|
|
342
361
|
try {
|
|
343
|
-
const result = await
|
|
344
|
-
serverUrl: this.url,
|
|
345
|
-
resourceMetadataUrl: this.resourceMetadataUrl,
|
|
346
|
-
fetchFn: this.fetchFn,
|
|
347
|
-
});
|
|
362
|
+
const result = await this.authorizeOnce(this.resourceMetadataUrl);
|
|
348
363
|
if (result !== 'AUTHORIZED') {
|
|
349
364
|
const error = new UnauthorizedError();
|
|
350
365
|
this.onerror?.(error);
|