tiny-http-mcp-server 0.1.44 → 0.1.46
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/default-oauth-client-provider.js +1 -0
- package/node_modules/mcp-oauth/dist/client/token-endpoint.js +12 -8
- package/node_modules/tiny-mcp-client/dist/index.js +13 -8
- package/package.json +1 -1
package/dist/composition.json
CHANGED
|
@@ -33,7 +33,7 @@ const verifier = createJwksTokenVerifier({
|
|
|
33
33
|
- `normalizeOAuthScope(value)`: validate scope syntax and normalize its case-sensitive set.
|
|
34
34
|
- `canonicalizeResourceIndicator(value)`: resource indicator canonicalization.
|
|
35
35
|
- `createJwksTokenVerifier(options)`: JWKS-backed access-token verifier for MCP servers.
|
|
36
|
-
- `OAuthError`:
|
|
36
|
+
- `OAuthError`: OAuth HTTP error type with status, retryability and known-outcome fields.
|
|
37
37
|
|
|
38
38
|
## Configuration
|
|
39
39
|
|
|
@@ -244,3 +244,10 @@ cannot disable this policy.
|
|
|
244
244
|
|
|
245
245
|
This package exposes no direct environment variables. When `authStore` is used,
|
|
246
246
|
`auth-store` honors its own backend environment variables.
|
|
247
|
+
|
|
248
|
+
Malformed OAuth HTTP errors retain their numeric HTTP status without echoing
|
|
249
|
+
response bodies. Raw/incomplete client-error responses (including registration
|
|
250
|
+
HTTP 403) are nonretryable `invalid_response` errors; authorization fails without
|
|
251
|
+
waiting for consent that never started. Raw server errors remain transient.
|
|
252
|
+
`outcomeKnown: false` still withholds an uncertain rotating refresh family: a
|
|
253
|
+
nonretryable HTTP status alone does not prove a refresh token was unconsumed.
|
|
@@ -459,6 +459,7 @@ export function createDefaultOAuthClientProvider(options) {
|
|
|
459
459
|
const response = await fetchMcpResponse(fetch, registrationEndpoint, {
|
|
460
460
|
method: "POST",
|
|
461
461
|
headers: {
|
|
462
|
+
Accept: "application/json",
|
|
462
463
|
"Content-Type": "application/json"
|
|
463
464
|
},
|
|
464
465
|
body: JSON.stringify(registrationBody),
|
|
@@ -16,13 +16,15 @@ export class OAuthError extends Error {
|
|
|
16
16
|
/** True only when a complete OAuth error response establishes rejection. */
|
|
17
17
|
outcomeKnown;
|
|
18
18
|
constructor(shape, status, outcomeKnown = true) {
|
|
19
|
-
|
|
19
|
+
const description = Object.hasOwn(shape, "error_description") ? shape.error_description : undefined;
|
|
20
|
+
const uri = Object.hasOwn(shape, "error_uri") ? shape.error_uri : undefined;
|
|
21
|
+
super(description ?? (outcomeKnown ? shape.error : `OAuth HTTP response did not contain a valid error (HTTP ${status})`));
|
|
20
22
|
this.name = "OAuthError";
|
|
21
23
|
this.error = shape.error;
|
|
22
|
-
this.errorDescription =
|
|
23
|
-
this.errorUri =
|
|
24
|
-
this.error_description =
|
|
25
|
-
this.error_uri =
|
|
24
|
+
this.errorDescription = description;
|
|
25
|
+
this.errorUri = uri;
|
|
26
|
+
this.error_description = description;
|
|
27
|
+
this.error_uri = uri;
|
|
26
28
|
this.status = status;
|
|
27
29
|
this.retryable = isRetryableOAuthError(this);
|
|
28
30
|
this.terminal = !this.retryable;
|
|
@@ -77,7 +79,7 @@ async function requestTokens(input) {
|
|
|
77
79
|
if (method !== "none" && (input.clientSecret === undefined || input.clientSecret.trim() === ""))
|
|
78
80
|
throw new Error("OAuth token endpoint authentication requires a client secret");
|
|
79
81
|
const body = new URLSearchParams(input.params);
|
|
80
|
-
const headers = new Headers({ "Content-Type": "application/x-www-form-urlencoded" });
|
|
82
|
+
const headers = new Headers({ Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded" });
|
|
81
83
|
if (method === "client_secret_basic") {
|
|
82
84
|
const encoded = new URLSearchParams({ credential: input.clientId }).toString().slice("credential=".length);
|
|
83
85
|
const encodedSecret = new URLSearchParams({ credential: input.clientSecret }).toString().slice("credential=".length);
|
|
@@ -164,7 +166,9 @@ export async function readOAuthJsonObjectResponse(response, signal) {
|
|
|
164
166
|
const record = payload;
|
|
165
167
|
if (!response.ok) {
|
|
166
168
|
const error = getOwnEntry(record, "error");
|
|
167
|
-
|
|
169
|
+
if (typeof error !== "string" || error.trim() === "")
|
|
170
|
+
throw fallbackError;
|
|
171
|
+
throw new OAuthError(readOAuthError(record), response.status);
|
|
168
172
|
}
|
|
169
173
|
return record;
|
|
170
174
|
}
|
|
@@ -182,7 +186,7 @@ function getOwnEntry(record, key) {
|
|
|
182
186
|
return Object.prototype.hasOwnProperty.call(record, key) ? record[key] : undefined;
|
|
183
187
|
}
|
|
184
188
|
function createFallbackOAuthError(status) {
|
|
185
|
-
const error = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
189
|
+
const error = status === 503 ? "temporarily_unavailable" : status >= 500 ? "server_error" : "invalid_response";
|
|
186
190
|
return new OAuthError({ error }, status, false);
|
|
187
191
|
}
|
|
188
192
|
function normalizeBearerTokenType(value) {
|
|
@@ -5014,13 +5014,15 @@ var OAuthError = class extends Error {
|
|
|
5014
5014
|
/** True only when a complete OAuth error response establishes rejection. */
|
|
5015
5015
|
outcomeKnown;
|
|
5016
5016
|
constructor(shape, status, outcomeKnown = true) {
|
|
5017
|
-
|
|
5017
|
+
const description = Object.hasOwn(shape, "error_description") ? shape.error_description : void 0;
|
|
5018
|
+
const uri = Object.hasOwn(shape, "error_uri") ? shape.error_uri : void 0;
|
|
5019
|
+
super(description ?? (outcomeKnown ? shape.error : `OAuth HTTP response did not contain a valid error (HTTP ${status})`));
|
|
5018
5020
|
this.name = "OAuthError";
|
|
5019
5021
|
this.error = shape.error;
|
|
5020
|
-
this.errorDescription =
|
|
5021
|
-
this.errorUri =
|
|
5022
|
-
this.error_description =
|
|
5023
|
-
this.error_uri =
|
|
5022
|
+
this.errorDescription = description;
|
|
5023
|
+
this.errorUri = uri;
|
|
5024
|
+
this.error_description = description;
|
|
5025
|
+
this.error_uri = uri;
|
|
5024
5026
|
this.status = status;
|
|
5025
5027
|
this.retryable = isRetryableOAuthError(this);
|
|
5026
5028
|
this.terminal = !this.retryable;
|
|
@@ -5071,7 +5073,7 @@ async function requestTokens(input) {
|
|
|
5071
5073
|
if (method !== "none" && (input.clientSecret === void 0 || input.clientSecret.trim() === ""))
|
|
5072
5074
|
throw new Error("OAuth token endpoint authentication requires a client secret");
|
|
5073
5075
|
const body = new URLSearchParams(input.params);
|
|
5074
|
-
const headers = new Headers({ "Content-Type": "application/x-www-form-urlencoded" });
|
|
5076
|
+
const headers = new Headers({ Accept: "application/json", "Content-Type": "application/x-www-form-urlencoded" });
|
|
5075
5077
|
if (method === "client_secret_basic") {
|
|
5076
5078
|
const encoded = new URLSearchParams({ credential: input.clientId }).toString().slice("credential=".length);
|
|
5077
5079
|
const encodedSecret = new URLSearchParams({ credential: input.clientSecret }).toString().slice("credential=".length);
|
|
@@ -5149,7 +5151,9 @@ async function readOAuthJsonObjectResponse(response, signal) {
|
|
|
5149
5151
|
const record2 = payload;
|
|
5150
5152
|
if (!response.ok) {
|
|
5151
5153
|
const error = getOwnEntry5(record2, "error");
|
|
5152
|
-
|
|
5154
|
+
if (typeof error !== "string" || error.trim() === "")
|
|
5155
|
+
throw fallbackError;
|
|
5156
|
+
throw new OAuthError(readOAuthError(record2), response.status);
|
|
5153
5157
|
}
|
|
5154
5158
|
return record2;
|
|
5155
5159
|
}
|
|
@@ -5167,7 +5171,7 @@ function getOwnEntry5(record2, key2) {
|
|
|
5167
5171
|
return Object.prototype.hasOwnProperty.call(record2, key2) ? record2[key2] : void 0;
|
|
5168
5172
|
}
|
|
5169
5173
|
function createFallbackOAuthError(status) {
|
|
5170
|
-
const error = status === 503 ? "temporarily_unavailable" : "server_error";
|
|
5174
|
+
const error = status === 503 ? "temporarily_unavailable" : status >= 500 ? "server_error" : "invalid_response";
|
|
5171
5175
|
return new OAuthError({ error }, status, false);
|
|
5172
5176
|
}
|
|
5173
5177
|
function normalizeBearerTokenType(value) {
|
|
@@ -5656,6 +5660,7 @@ function createDefaultOAuthClientProvider(options) {
|
|
|
5656
5660
|
const response = await fetchMcpResponse(fetch2, registrationEndpoint, {
|
|
5657
5661
|
method: "POST",
|
|
5658
5662
|
headers: {
|
|
5663
|
+
Accept: "application/json",
|
|
5659
5664
|
"Content-Type": "application/json"
|
|
5660
5665
|
},
|
|
5661
5666
|
body: JSON.stringify(registrationBody),
|