tiny-http-mcp-server 0.1.31 → 0.1.32
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/dist/composition.json +1 -1
- package/node_modules/mcp-oauth/README.md +8 -1
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +1 -0
- package/node_modules/mcp-oauth/dist/client/default-oauth-client-provider.js +21 -7
- package/node_modules/mcp-oauth/dist/client/scope.d.ts +2 -0
- package/node_modules/mcp-oauth/dist/client/scope.js +9 -0
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +4 -1
- package/node_modules/mcp-oauth/dist/client/types.d.ts +2 -0
- package/node_modules/tiny-mcp-client/dist/index.d.ts +2 -0
- package/node_modules/tiny-mcp-client/dist/index.js +33 -8
- package/package.json +1 -1
package/dist/composition.json
CHANGED
|
@@ -96,7 +96,14 @@ on 401 even when the server omits `error="invalid_token"`. Invalid provenance
|
|
|
96
96
|
fails without quoting token values.
|
|
97
97
|
|
|
98
98
|
Configure `client.metadata.scope` to request a precise scope set; broader
|
|
99
|
-
discovery metadata does not override it.
|
|
99
|
+
discovery metadata does not override it. Explicit scopes must match the cached
|
|
100
|
+
or imported grant's scope set; ordering, repeated spaces and duplicates are
|
|
101
|
+
normalized. An imported grant must declare its scope when a scope is configured.
|
|
102
|
+
Authorization records the requested set when the endpoint omits scope, and
|
|
103
|
+
refresh retains the previous granted set. Mismatched responses never activate
|
|
104
|
+
credentials; an unusable refresh response retains the pending refresh record.
|
|
105
|
+
Select a separate persistence namespace for another scope profile. No scope is
|
|
106
|
+
invented when the client does not configure one.
|
|
100
107
|
|
|
101
108
|
Imported `initialGrant.tokens` use `accessToken`, optional `refreshToken`,
|
|
102
109
|
`tokenType: "Bearer"`, `expiresAt` (Unix epoch milliseconds or `null` if unknown),
|
|
@@ -144,6 +144,7 @@ function isStoredOAuthSession(value) {
|
|
|
144
144
|
isNonBlankOwnString(value, "authorizationServer") &&
|
|
145
145
|
isStoredOAuthClient(getOwnEntry(value, "client")) &&
|
|
146
146
|
isStoredOAuthDiscovery(getOwnEntry(value, "discovery")) &&
|
|
147
|
+
(getOwnEntry(value, "requestedScope") === undefined || isNonBlankOwnString(value, "requestedScope")) &&
|
|
147
148
|
(getOwnEntry(value, "refreshState") === undefined ||
|
|
148
149
|
(getOwnEntry(value, "refreshState") === "pending" && getOwnEntry(value, "tokens") === undefined)) &&
|
|
149
150
|
isStoredOAuthTokensOrMissing(getOwnEntry(value, "tokens")));
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { normalizeOAuthScope } from "./scope.js";
|
|
1
2
|
import { isIP } from "node:net";
|
|
2
3
|
import { fetchMcpResponse } from "../http-fetch.js";
|
|
3
4
|
import { URL } from "node:url";
|
|
@@ -18,6 +19,8 @@ export function createOAuthClientProvider(options) {
|
|
|
18
19
|
export function createDefaultOAuthClientProvider(options) {
|
|
19
20
|
loopbackTarget(options.browser);
|
|
20
21
|
assertPersistenceNamespace(options.persistenceNamespace);
|
|
22
|
+
const clientMetadata = getClientMetadata(options.client);
|
|
23
|
+
const requestedScope = clientMetadata?.scope;
|
|
21
24
|
const sessionStore = options.sessionStore ?? createAuthStoreSessionStore(options.authStore, options.persistenceNamespace);
|
|
22
25
|
const clientStore = options.authStore === undefined ? null : createAuthStoreClientStore(options.authStore, options.persistenceNamespace);
|
|
23
26
|
const now = options.now ?? Date.now;
|
|
@@ -41,6 +44,8 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
41
44
|
if (initialGrant !== undefined && (initialGrant.tokens === undefined || initialGrant.client === null))
|
|
42
45
|
throw new Error("OAuth initial grant requires valid tokens and the original client ID");
|
|
43
46
|
if (initialGrant?.tokens !== undefined) {
|
|
47
|
+
if (requestedScope !== undefined && initialGrant.tokens.scope !== requestedScope)
|
|
48
|
+
throw new Error("OAuth initial grant does not match the requested OAuth scope");
|
|
44
49
|
try {
|
|
45
50
|
new Headers({ Authorization: `Bearer ${initialGrant.tokens.accessToken}` });
|
|
46
51
|
}
|
|
@@ -133,7 +138,8 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
133
138
|
initialGrant.tokens !== undefined && initialGrant.client !== null) {
|
|
134
139
|
assertSecureOAuthFlowEndpoints(discovery.authorizationServerMetadata);
|
|
135
140
|
session = { resource: canonicalResource, authorizationServer: discovery.authorizationServer,
|
|
136
|
-
client: initialGrant.client, tokens: initialGrant.tokens,
|
|
141
|
+
client: initialGrant.client, tokens: initialGrant.tokens,
|
|
142
|
+
...(requestedScope === undefined ? {} : { requestedScope }), discovery: toStoredDiscovery(discovery) };
|
|
137
143
|
await saveSession(canonicalResource, session);
|
|
138
144
|
initialGrantConsumed = true;
|
|
139
145
|
signal?.throwIfAborted();
|
|
@@ -146,6 +152,8 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
146
152
|
if (configured === null || configured.clientId !== session.client.clientId || configured.clientSecret !== session.client.clientSecret)
|
|
147
153
|
throw new Error("Stored session belongs to a different OAuth client; use separate persistence or explicitly reset it");
|
|
148
154
|
}
|
|
155
|
+
if (requestedScope !== undefined && session?.tokens !== undefined && normalizeOAuthScope(session.tokens.scope ?? session.requestedScope) !== requestedScope)
|
|
156
|
+
throw new Error("Stored session does not match the requested OAuth scope; authorize again or select separate persistence");
|
|
149
157
|
if (session?.refreshState === "pending") {
|
|
150
158
|
if (!allowInteractive || options.allowInteractive === false || sessionDiscovery === undefined)
|
|
151
159
|
throw new Error("OAuth refresh outcome is unknown; authorize again before using this resource");
|
|
@@ -226,10 +234,13 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
226
234
|
...session,
|
|
227
235
|
tokens: {
|
|
228
236
|
...refreshedTokens,
|
|
229
|
-
refreshToken: refreshedTokens.refreshToken ?? session.tokens.refreshToken
|
|
237
|
+
refreshToken: refreshedTokens.refreshToken ?? session.tokens.refreshToken,
|
|
238
|
+
scope: refreshedTokens.scope ?? session.tokens.scope
|
|
230
239
|
},
|
|
231
240
|
discovery: toStoredDiscovery(discovery)
|
|
232
241
|
};
|
|
242
|
+
if (requestedScope !== undefined && normalizeOAuthScope(updatedSession.tokens?.scope ?? session.requestedScope) !== requestedScope)
|
|
243
|
+
throw new Error("OAuth refresh response does not match the requested OAuth scope; authorize again");
|
|
233
244
|
await saveSession(resource, updatedSession);
|
|
234
245
|
return updatedSession;
|
|
235
246
|
}
|
|
@@ -257,6 +268,7 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
257
268
|
resource,
|
|
258
269
|
authorizationServer: discovery.authorizationServer,
|
|
259
270
|
client: resolvedClient.client,
|
|
271
|
+
...(requestedScope === undefined ? {} : { requestedScope }),
|
|
260
272
|
discovery: toStoredDiscovery(discovery)
|
|
261
273
|
};
|
|
262
274
|
await saveSession(resource, sessionWithoutTokens);
|
|
@@ -268,7 +280,7 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
268
280
|
clientId: resolvedClient.client.clientId,
|
|
269
281
|
redirectUri: loopback.redirectUri,
|
|
270
282
|
codeChallenge: challenge,
|
|
271
|
-
clientMetadata
|
|
283
|
+
clientMetadata
|
|
272
284
|
});
|
|
273
285
|
const code = await loopback.waitForCode(authorizationUrl);
|
|
274
286
|
const tokens = await exchangeAuthorizationCode({
|
|
@@ -282,6 +294,8 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
282
294
|
fetch, signal,
|
|
283
295
|
now
|
|
284
296
|
});
|
|
297
|
+
if (requestedScope !== undefined && tokens.scope !== undefined && normalizeOAuthScope(tokens.scope) !== requestedScope)
|
|
298
|
+
throw new Error("OAuth authorization response does not match the requested OAuth scope");
|
|
285
299
|
const session = {
|
|
286
300
|
...sessionWithoutTokens,
|
|
287
301
|
tokens
|
|
@@ -363,7 +377,7 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
363
377
|
};
|
|
364
378
|
}
|
|
365
379
|
}
|
|
366
|
-
const registrationBody = buildClientRegistrationBody(
|
|
380
|
+
const registrationBody = buildClientRegistrationBody(clientMetadata, redirectUri);
|
|
367
381
|
const deadline = AbortSignal.timeout(30_000);
|
|
368
382
|
const signal = parentSignal === undefined ? deadline : AbortSignal.any([parentSignal, deadline]);
|
|
369
383
|
const response = await fetchMcpResponse(fetch, registrationEndpoint, {
|
|
@@ -526,10 +540,10 @@ function normalizeStoredTokens(value) {
|
|
|
526
540
|
const tokenType = getOwnString(value, "tokenType");
|
|
527
541
|
const expiresAt = getOwnEntry(value, "expiresAt");
|
|
528
542
|
const refreshToken = getOwnEntry(value, "refreshToken");
|
|
529
|
-
const scope =
|
|
543
|
+
const scope = getOwnEntry(value, "scope");
|
|
530
544
|
const normalizedAccessToken = accessToken?.trim();
|
|
531
545
|
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : undefined;
|
|
532
|
-
const normalizedScope = scope
|
|
546
|
+
const normalizedScope = normalizeOAuthScope(scope);
|
|
533
547
|
if (accessToken === undefined ||
|
|
534
548
|
normalizedAccessToken === undefined ||
|
|
535
549
|
normalizedAccessToken.length === 0 ||
|
|
@@ -561,7 +575,7 @@ function getClientMetadata(client) {
|
|
|
561
575
|
}
|
|
562
576
|
return {
|
|
563
577
|
clientName: normalizeOptionalOAuthString(client.metadata.clientName),
|
|
564
|
-
scope:
|
|
578
|
+
scope: normalizeOAuthScope(client.metadata.scope),
|
|
565
579
|
softwareId: normalizeOptionalOAuthString(client.metadata.softwareId),
|
|
566
580
|
softwareVersion: normalizeOptionalOAuthString(client.metadata.softwareVersion)
|
|
567
581
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Compare OAuth scope sets without accepting controls or changing token case. */
|
|
2
|
+
export function normalizeOAuthScope(scope) {
|
|
3
|
+
if (scope === undefined)
|
|
4
|
+
return undefined;
|
|
5
|
+
if (typeof scope !== "string" || [...scope].some(char => char.charCodeAt(0) < 32 || char.charCodeAt(0) > 126 || char === '"' || char === "\\"))
|
|
6
|
+
throw new Error("Invalid OAuth scope syntax");
|
|
7
|
+
const normalized = [...new Set(scope.split(" ").filter(Boolean))].sort().join(" ");
|
|
8
|
+
return normalized || undefined;
|
|
9
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { canonicalizeResourceIndicator } from "../resource-indicator.js";
|
|
2
2
|
import { readBoundedResponseText } from "../http-response.js";
|
|
3
3
|
import { fetchMcpResponse } from "../http-fetch.js";
|
|
4
|
+
import { normalizeOAuthScope } from "./scope.js";
|
|
4
5
|
const MAX_JS_DATE_MS = 8_640_000_000_000_000;
|
|
5
6
|
export class OAuthError extends Error {
|
|
6
7
|
error;
|
|
@@ -117,7 +118,9 @@ async function requestTokens(input) {
|
|
|
117
118
|
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0
|
|
118
119
|
? refreshToken.trim()
|
|
119
120
|
: undefined;
|
|
120
|
-
const normalizedScope =
|
|
121
|
+
const normalizedScope = normalizeOAuthScope(scope);
|
|
122
|
+
if (scope !== undefined && normalizedScope === undefined)
|
|
123
|
+
throw new Error("Invalid OAuth scope syntax in token response");
|
|
121
124
|
return {
|
|
122
125
|
accessToken: normalizedAccessToken,
|
|
123
126
|
refreshToken: normalizedRefreshToken === undefined ? undefined : normalizedRefreshToken,
|
|
@@ -80,6 +80,8 @@ export interface StoredOAuthSession {
|
|
|
80
80
|
tokens?: StoredOAuthTokens;
|
|
81
81
|
/** A refresh was begun; its winning response may not have been persisted. */
|
|
82
82
|
refreshState?: "pending";
|
|
83
|
+
/** Canonical explicitly requested scope set when the server omits token scope. */
|
|
84
|
+
requestedScope?: string;
|
|
83
85
|
discovery: {
|
|
84
86
|
resourceMetadataUrl: string;
|
|
85
87
|
resourceMetadata: Record<string, unknown>;
|
|
@@ -183,6 +183,8 @@ interface StoredOAuthSession {
|
|
|
183
183
|
tokens?: StoredOAuthTokens;
|
|
184
184
|
/** A refresh was begun; its winning response may not have been persisted. */
|
|
185
185
|
refreshState?: "pending";
|
|
186
|
+
/** Canonical explicitly requested scope set when the server omits token scope. */
|
|
187
|
+
requestedScope?: string;
|
|
186
188
|
discovery: {
|
|
187
189
|
resourceMetadataUrl: string;
|
|
188
190
|
resourceMetadata: Record<string, unknown>;
|
|
@@ -4201,7 +4201,7 @@ function isStoredOAuthSession(value) {
|
|
|
4201
4201
|
if (!isObjectRecord(value)) {
|
|
4202
4202
|
return false;
|
|
4203
4203
|
}
|
|
4204
|
-
return isNonBlankOwnString(value, "resource") && isNonBlankOwnString(value, "authorizationServer") && isStoredOAuthClient(getOwnEntry3(value, "client")) && isStoredOAuthDiscovery(getOwnEntry3(value, "discovery")) && (getOwnEntry3(value, "refreshState") === void 0 || getOwnEntry3(value, "refreshState") === "pending" && getOwnEntry3(value, "tokens") === void 0) && isStoredOAuthTokensOrMissing(getOwnEntry3(value, "tokens"));
|
|
4204
|
+
return isNonBlankOwnString(value, "resource") && isNonBlankOwnString(value, "authorizationServer") && isStoredOAuthClient(getOwnEntry3(value, "client")) && isStoredOAuthDiscovery(getOwnEntry3(value, "discovery")) && (getOwnEntry3(value, "requestedScope") === void 0 || isNonBlankOwnString(value, "requestedScope")) && (getOwnEntry3(value, "refreshState") === void 0 || getOwnEntry3(value, "refreshState") === "pending" && getOwnEntry3(value, "tokens") === void 0) && isStoredOAuthTokensOrMissing(getOwnEntry3(value, "tokens"));
|
|
4205
4205
|
}
|
|
4206
4206
|
function isStoredOAuthClient(value) {
|
|
4207
4207
|
if (!isObjectRecord(value) || !isNonBlankOwnString(value, "clientId")) {
|
|
@@ -4242,6 +4242,16 @@ function isNonBlankOwnString(record2, key2) {
|
|
|
4242
4242
|
return value !== void 0 && value.trim().length > 0;
|
|
4243
4243
|
}
|
|
4244
4244
|
|
|
4245
|
+
// ../mcp-oauth/dist/client/scope.js
|
|
4246
|
+
function normalizeOAuthScope(scope) {
|
|
4247
|
+
if (scope === void 0)
|
|
4248
|
+
return void 0;
|
|
4249
|
+
if (typeof scope !== "string" || [...scope].some((char) => char.charCodeAt(0) < 32 || char.charCodeAt(0) > 126 || char === '"' || char === "\\"))
|
|
4250
|
+
throw new Error("Invalid OAuth scope syntax");
|
|
4251
|
+
const normalized = [...new Set(scope.split(" ").filter(Boolean))].sort().join(" ");
|
|
4252
|
+
return normalized || void 0;
|
|
4253
|
+
}
|
|
4254
|
+
|
|
4245
4255
|
// ../mcp-oauth/dist/client/default-oauth-client-provider.js
|
|
4246
4256
|
import { isIP } from "node:net";
|
|
4247
4257
|
|
|
@@ -4726,7 +4736,9 @@ async function requestTokens(input) {
|
|
|
4726
4736
|
const refreshToken = getOwnEntry5(payload, "refresh_token");
|
|
4727
4737
|
const scope = getOwnEntry5(payload, "scope");
|
|
4728
4738
|
const normalizedRefreshToken = typeof refreshToken === "string" && refreshToken.trim().length > 0 ? refreshToken.trim() : void 0;
|
|
4729
|
-
const normalizedScope =
|
|
4739
|
+
const normalizedScope = normalizeOAuthScope(scope);
|
|
4740
|
+
if (scope !== void 0 && normalizedScope === void 0)
|
|
4741
|
+
throw new Error("Invalid OAuth scope syntax in token response");
|
|
4730
4742
|
return {
|
|
4731
4743
|
accessToken: normalizedAccessToken,
|
|
4732
4744
|
refreshToken: normalizedRefreshToken === void 0 ? void 0 : normalizedRefreshToken,
|
|
@@ -4847,6 +4859,8 @@ function createOAuthClientProvider(options) {
|
|
|
4847
4859
|
function createDefaultOAuthClientProvider(options) {
|
|
4848
4860
|
loopbackTarget(options.browser);
|
|
4849
4861
|
assertPersistenceNamespace(options.persistenceNamespace);
|
|
4862
|
+
const clientMetadata = getClientMetadata(options.client);
|
|
4863
|
+
const requestedScope = clientMetadata?.scope;
|
|
4850
4864
|
const sessionStore = options.sessionStore ?? createAuthStoreSessionStore(options.authStore, options.persistenceNamespace);
|
|
4851
4865
|
const clientStore = options.authStore === void 0 ? null : createAuthStoreClientStore(options.authStore, options.persistenceNamespace);
|
|
4852
4866
|
const now = options.now ?? Date.now;
|
|
@@ -4869,6 +4883,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4869
4883
|
if (initialGrant !== void 0 && (initialGrant.tokens === void 0 || initialGrant.client === null))
|
|
4870
4884
|
throw new Error("OAuth initial grant requires valid tokens and the original client ID");
|
|
4871
4885
|
if (initialGrant?.tokens !== void 0) {
|
|
4886
|
+
if (requestedScope !== void 0 && initialGrant.tokens.scope !== requestedScope)
|
|
4887
|
+
throw new Error("OAuth initial grant does not match the requested OAuth scope");
|
|
4872
4888
|
try {
|
|
4873
4889
|
new Headers({ Authorization: `Bearer ${initialGrant.tokens.accessToken}` });
|
|
4874
4890
|
} catch {
|
|
@@ -4956,6 +4972,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4956
4972
|
authorizationServer: discovery.authorizationServer,
|
|
4957
4973
|
client: initialGrant.client,
|
|
4958
4974
|
tokens: initialGrant.tokens,
|
|
4975
|
+
...requestedScope === void 0 ? {} : { requestedScope },
|
|
4959
4976
|
discovery: toStoredDiscovery(discovery)
|
|
4960
4977
|
};
|
|
4961
4978
|
await saveSession(canonicalResource, session);
|
|
@@ -4970,6 +4987,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
4970
4987
|
if (configured === null || configured.clientId !== session.client.clientId || configured.clientSecret !== session.client.clientSecret)
|
|
4971
4988
|
throw new Error("Stored session belongs to a different OAuth client; use separate persistence or explicitly reset it");
|
|
4972
4989
|
}
|
|
4990
|
+
if (requestedScope !== void 0 && session?.tokens !== void 0 && normalizeOAuthScope(session.tokens.scope ?? session.requestedScope) !== requestedScope)
|
|
4991
|
+
throw new Error("Stored session does not match the requested OAuth scope; authorize again or select separate persistence");
|
|
4973
4992
|
if (session?.refreshState === "pending") {
|
|
4974
4993
|
if (!allowInteractive || options.allowInteractive === false || sessionDiscovery === void 0)
|
|
4975
4994
|
throw new Error("OAuth refresh outcome is unknown; authorize again before using this resource");
|
|
@@ -5046,10 +5065,13 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5046
5065
|
...session,
|
|
5047
5066
|
tokens: {
|
|
5048
5067
|
...refreshedTokens,
|
|
5049
|
-
refreshToken: refreshedTokens.refreshToken ?? session.tokens.refreshToken
|
|
5068
|
+
refreshToken: refreshedTokens.refreshToken ?? session.tokens.refreshToken,
|
|
5069
|
+
scope: refreshedTokens.scope ?? session.tokens.scope
|
|
5050
5070
|
},
|
|
5051
5071
|
discovery: toStoredDiscovery(discovery)
|
|
5052
5072
|
};
|
|
5073
|
+
if (requestedScope !== void 0 && normalizeOAuthScope(updatedSession.tokens?.scope ?? session.requestedScope) !== requestedScope)
|
|
5074
|
+
throw new Error("OAuth refresh response does not match the requested OAuth scope; authorize again");
|
|
5053
5075
|
await saveSession(resource, updatedSession);
|
|
5054
5076
|
return updatedSession;
|
|
5055
5077
|
}
|
|
@@ -5077,6 +5099,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5077
5099
|
resource,
|
|
5078
5100
|
authorizationServer: discovery.authorizationServer,
|
|
5079
5101
|
client: resolvedClient.client,
|
|
5102
|
+
...requestedScope === void 0 ? {} : { requestedScope },
|
|
5080
5103
|
discovery: toStoredDiscovery(discovery)
|
|
5081
5104
|
};
|
|
5082
5105
|
await saveSession(resource, sessionWithoutTokens);
|
|
@@ -5088,7 +5111,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5088
5111
|
clientId: resolvedClient.client.clientId,
|
|
5089
5112
|
redirectUri: loopback.redirectUri,
|
|
5090
5113
|
codeChallenge: challenge,
|
|
5091
|
-
clientMetadata
|
|
5114
|
+
clientMetadata
|
|
5092
5115
|
});
|
|
5093
5116
|
const code = await loopback.waitForCode(authorizationUrl);
|
|
5094
5117
|
const tokens = await exchangeAuthorizationCode({
|
|
@@ -5103,6 +5126,8 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5103
5126
|
signal,
|
|
5104
5127
|
now
|
|
5105
5128
|
});
|
|
5129
|
+
if (requestedScope !== void 0 && tokens.scope !== void 0 && normalizeOAuthScope(tokens.scope) !== requestedScope)
|
|
5130
|
+
throw new Error("OAuth authorization response does not match the requested OAuth scope");
|
|
5106
5131
|
const session = {
|
|
5107
5132
|
...sessionWithoutTokens,
|
|
5108
5133
|
tokens
|
|
@@ -5180,7 +5205,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5180
5205
|
};
|
|
5181
5206
|
}
|
|
5182
5207
|
}
|
|
5183
|
-
const registrationBody = buildClientRegistrationBody(
|
|
5208
|
+
const registrationBody = buildClientRegistrationBody(clientMetadata, redirectUri);
|
|
5184
5209
|
const deadline = AbortSignal.timeout(3e4);
|
|
5185
5210
|
const signal = parentSignal === void 0 ? deadline : AbortSignal.any([parentSignal, deadline]);
|
|
5186
5211
|
const response = await fetchMcpResponse(fetch2, registrationEndpoint, {
|
|
@@ -5335,10 +5360,10 @@ function normalizeStoredTokens(value) {
|
|
|
5335
5360
|
const tokenType = getOwnString2(value, "tokenType");
|
|
5336
5361
|
const expiresAt = getOwnEntry6(value, "expiresAt");
|
|
5337
5362
|
const refreshToken = getOwnEntry6(value, "refreshToken");
|
|
5338
|
-
const scope =
|
|
5363
|
+
const scope = getOwnEntry6(value, "scope");
|
|
5339
5364
|
const normalizedAccessToken = accessToken?.trim();
|
|
5340
5365
|
const normalizedRefreshToken = typeof refreshToken === "string" ? refreshToken.trim() : void 0;
|
|
5341
|
-
const normalizedScope = scope
|
|
5366
|
+
const normalizedScope = normalizeOAuthScope(scope);
|
|
5342
5367
|
if (accessToken === void 0 || normalizedAccessToken === void 0 || normalizedAccessToken.length === 0 || tokenType !== "Bearer" || !(expiresAt === null || typeof expiresAt === "number" && Number.isSafeInteger(expiresAt) && expiresAt <= MAX_JS_DATE_MS3 && Number.isFinite(new Date(expiresAt).getTime())) || refreshToken !== void 0 && (typeof refreshToken !== "string" || normalizedRefreshToken === void 0 || normalizedRefreshToken.length === 0)) {
|
|
5343
5368
|
return void 0;
|
|
5344
5369
|
}
|
|
@@ -5356,7 +5381,7 @@ function getClientMetadata(client) {
|
|
|
5356
5381
|
}
|
|
5357
5382
|
return {
|
|
5358
5383
|
clientName: normalizeOptionalOAuthString(client.metadata.clientName),
|
|
5359
|
-
scope:
|
|
5384
|
+
scope: normalizeOAuthScope(client.metadata.scope),
|
|
5360
5385
|
softwareId: normalizeOptionalOAuthString(client.metadata.softwareId),
|
|
5361
5386
|
softwareVersion: normalizeOptionalOAuthString(client.metadata.softwareVersion)
|
|
5362
5387
|
};
|