@lovable.dev/mcp-js 0.20.1-rc.0 → 0.20.1
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/{base-RSqYamjy.d.ts → base-CFy5vZ5Z.d.ts} +7 -2
- package/dist/chunk-6QFZYYUV.js +11 -0
- package/dist/{chunk-RT2I26ZN.js → chunk-H7W77K6V.js} +6 -2
- package/dist/{chunk-ID3YWZBR.js → chunk-IUWLXNFW.js} +6 -2
- package/dist/{chunk-E7CPOJN6.js → chunk-M35C7Y3M.js} +18 -74
- package/dist/{chunk-YAXKWTJK.js → chunk-PTPLMKOV.js} +1 -1
- package/dist/{chunk-A2GUTEAK.js → chunk-VOMKN2HP.js} +1 -1
- package/dist/{chunk-OMEL6F6I.js → chunk-VW7B32WL.js} +1 -1
- package/dist/cli/extract-manifest.cjs +1 -1
- package/dist/cli/extract-manifest.js +3 -3
- package/dist/protocols/mcp/index.cjs +27 -75
- package/dist/protocols/mcp/index.d.cts +1 -1
- package/dist/protocols/mcp/index.d.ts +1 -1
- package/dist/protocols/mcp/index.js +4 -3
- package/dist/protocols/oauth-metadata.cjs +15 -56
- package/dist/protocols/oauth-metadata.js +3 -3
- package/dist/protocols/rest/index.cjs +27 -75
- package/dist/protocols/rest/index.d.cts +1 -1
- package/dist/protocols/rest/index.d.ts +1 -1
- package/dist/protocols/rest/index.js +5 -4
- package/dist/stacks/supabase/index.cjs +30 -76
- package/dist/stacks/supabase/index.js +7 -6
- package/dist/stacks/supabase/vite.cjs +1 -1
- package/dist/stacks/supabase/vite.js +1 -1
- package/dist/stacks/tanstack/index.cjs +30 -76
- package/dist/stacks/tanstack/index.js +7 -6
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_config_error"
|
|
1
|
+
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_config_error";
|
|
2
2
|
/** One recorded MCP call. Carries no arguments or response payloads — only the
|
|
3
|
-
* tool name, the JSON-RPC method, the result class, timing, and byte sizes.
|
|
3
|
+
* tool name, the JSON-RPC method, the result class, timing, and byte sizes.
|
|
4
|
+
* `errorText` is the sole exception: it is logged locally for debugging and
|
|
5
|
+
* deliberately never included in the OTLP payload (see `emit` / `buildLogsPayload`). */
|
|
4
6
|
interface InvocationRecord {
|
|
5
7
|
/** Tool name for `tools/call`; `null` for list/initialize, transport faults, and auth-config failures. */
|
|
6
8
|
tool: string | null;
|
|
@@ -10,6 +12,9 @@ interface InvocationRecord {
|
|
|
10
12
|
durationMs: number;
|
|
11
13
|
reqBytes?: number;
|
|
12
14
|
resBytes?: number;
|
|
15
|
+
/** The `tool_error` message (text content of an `isError` result). Local log
|
|
16
|
+
* only — never sent to the collector, so it stays on-box for the operator. */
|
|
17
|
+
errorText?: string;
|
|
13
18
|
}
|
|
14
19
|
/** A per-request telemetry recorder. `emit` logs the invocation and sends it as a
|
|
15
20
|
* single OTLP POST, awaited so it lands before the request ends. */
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/core/content.ts
|
|
2
|
+
function extractTextContent(content) {
|
|
3
|
+
if (!content)
|
|
4
|
+
return void 0;
|
|
5
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
6
|
+
return text.length > 0 ? text : void 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
extractTextContent
|
|
11
|
+
};
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractTextContent
|
|
3
|
+
} from "./chunk-6QFZYYUV.js";
|
|
1
4
|
import {
|
|
2
5
|
ToolContext
|
|
3
6
|
} from "./chunk-MA5H6PSF.js";
|
|
@@ -10,7 +13,7 @@ import {
|
|
|
10
13
|
methodNotAllowed,
|
|
11
14
|
nowMs,
|
|
12
15
|
withCors
|
|
13
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-M35C7Y3M.js";
|
|
14
17
|
|
|
15
18
|
// src/protocols/rest/invoke-tool.ts
|
|
16
19
|
import { getParseErrorMessage, objectFromShape, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
@@ -113,7 +116,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
113
116
|
tool: tool.name,
|
|
114
117
|
method: "tools/call",
|
|
115
118
|
outcome: result.isError ? "tool_error" : "ok",
|
|
116
|
-
durationMs: nowMs() - start
|
|
119
|
+
durationMs: nowMs() - start,
|
|
120
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
117
121
|
});
|
|
118
122
|
return Response.json({
|
|
119
123
|
content: result.content ?? [],
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
extractTextContent
|
|
3
|
+
} from "./chunk-6QFZYYUV.js";
|
|
1
4
|
import {
|
|
2
5
|
ToolContext
|
|
3
6
|
} from "./chunk-MA5H6PSF.js";
|
|
@@ -7,7 +10,7 @@ import {
|
|
|
7
10
|
createRequestAuthorizer,
|
|
8
11
|
nowMs,
|
|
9
12
|
withCors
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-M35C7Y3M.js";
|
|
11
14
|
import {
|
|
12
15
|
describeError,
|
|
13
16
|
log
|
|
@@ -45,7 +48,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
45
48
|
tool: tool.name,
|
|
46
49
|
method: "tools/call",
|
|
47
50
|
outcome: result.isError ? "tool_error" : "ok",
|
|
48
|
-
durationMs: nowMs() - start
|
|
51
|
+
durationMs: nowMs() - start,
|
|
52
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
49
53
|
});
|
|
50
54
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
51
55
|
};
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./chunk-6DXGZZA4.js";
|
|
14
14
|
import {
|
|
15
15
|
version
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-VW7B32WL.js";
|
|
17
17
|
|
|
18
18
|
// src/core/http.ts
|
|
19
19
|
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
@@ -156,7 +156,8 @@ var BaseMetricRecorder = class {
|
|
|
156
156
|
method: ev.method,
|
|
157
157
|
outcome: ev.outcome,
|
|
158
158
|
durationMs: ev.durationMs,
|
|
159
|
-
stack: this.stack
|
|
159
|
+
stack: this.stack,
|
|
160
|
+
...ev.errorText !== void 0 && { errorText: ev.errorText }
|
|
160
161
|
});
|
|
161
162
|
if (!this.config.enabled)
|
|
162
163
|
return;
|
|
@@ -289,18 +290,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
289
290
|
this.name = "OAuthConfigurationError";
|
|
290
291
|
}
|
|
291
292
|
};
|
|
292
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
293
|
-
constructor(message) {
|
|
294
|
-
super(message);
|
|
295
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
296
|
-
}
|
|
297
|
-
};
|
|
298
|
-
var MetadataUnreachableError = class extends Error {
|
|
299
|
-
constructor(message) {
|
|
300
|
-
super(message);
|
|
301
|
-
this.name = "MetadataUnreachableError";
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
293
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
305
294
|
function issuerPath(url) {
|
|
306
295
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -325,37 +314,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
325
314
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
326
315
|
}
|
|
327
316
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
|
|
317
|
+
const errors = [];
|
|
318
|
+
for (const url of metadataUrls) {
|
|
319
|
+
try {
|
|
320
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
321
|
+
} catch (err) {
|
|
331
322
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
332
|
-
|
|
333
|
-
}
|
|
334
|
-
);
|
|
335
|
-
try {
|
|
336
|
-
const metadata = await Promise.any(attempts);
|
|
337
|
-
controller.abort();
|
|
338
|
-
return metadata;
|
|
339
|
-
} catch (aggregate) {
|
|
340
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
341
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
342
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
343
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
344
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
345
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
323
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
324
|
+
}
|
|
346
325
|
}
|
|
326
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
327
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
347
328
|
}
|
|
348
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer
|
|
329
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
349
330
|
log.debug("oauth.discovery.fetch", { url });
|
|
350
|
-
|
|
351
|
-
try {
|
|
352
|
-
response = await fetch(url, {
|
|
353
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
354
|
-
redirect: "manual"
|
|
355
|
-
});
|
|
356
|
-
} catch (err) {
|
|
357
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
358
|
-
}
|
|
331
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
359
332
|
if (!response.ok) {
|
|
360
333
|
throw new Error(String(response.status));
|
|
361
334
|
}
|
|
@@ -378,21 +351,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
378
351
|
try {
|
|
379
352
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
380
353
|
} catch (err) {
|
|
381
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
382
|
-
if (err instanceof MetadataUnreachableError) {
|
|
383
|
-
log.error("oauth.discovery.unreachable", {
|
|
384
|
-
issuer,
|
|
385
|
-
...describeError(err),
|
|
386
|
-
outcome: "503 authorization server unreachable"
|
|
387
|
-
});
|
|
388
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
389
|
-
}
|
|
390
354
|
log.error("oauth.discovery.config_error", {
|
|
391
355
|
issuer,
|
|
392
356
|
...describeError(err),
|
|
393
357
|
outcome: "500 oauth configuration error"
|
|
394
358
|
});
|
|
395
|
-
throw new OAuthConfigurationError(
|
|
359
|
+
throw new OAuthConfigurationError(
|
|
360
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
361
|
+
);
|
|
396
362
|
}
|
|
397
363
|
}
|
|
398
364
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -458,14 +424,8 @@ function tokenHeaderFields(token) {
|
|
|
458
424
|
}
|
|
459
425
|
}
|
|
460
426
|
async function fetchVerificationKeySet(jwksUri) {
|
|
461
|
-
let response;
|
|
462
|
-
try {
|
|
463
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
464
|
-
} catch (err) {
|
|
465
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
466
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
467
|
-
}
|
|
468
427
|
try {
|
|
428
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
469
429
|
if (!response.ok)
|
|
470
430
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
471
431
|
const json = await response.json();
|
|
@@ -606,12 +566,6 @@ function oauthConfigurationErrorResponse() {
|
|
|
606
566
|
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
607
567
|
});
|
|
608
568
|
}
|
|
609
|
-
function oauthUpstreamUnreachableResponse() {
|
|
610
|
-
return new Response(JSON.stringify({ error: "authorization server unreachable" }), {
|
|
611
|
-
status: 503,
|
|
612
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store", "Retry-After": "30" }
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
569
|
function parseBearerToken(request) {
|
|
616
570
|
const header = request.headers.get("Authorization");
|
|
617
571
|
if (!header)
|
|
@@ -684,16 +638,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
684
638
|
assertRequiredScopes(runtime.auth, auth);
|
|
685
639
|
return { ok: true, auth };
|
|
686
640
|
} catch (err) {
|
|
687
|
-
if (err instanceof OAuthUpstreamUnreachableError) {
|
|
688
|
-
log.error("auth.upstream_unreachable", { ...describeError(err), outcome: "503" });
|
|
689
|
-
await recorder?.emit({
|
|
690
|
-
tool: null,
|
|
691
|
-
method: "authorize",
|
|
692
|
-
outcome: "auth_upstream_unreachable",
|
|
693
|
-
durationMs: nowMs() - startedAt
|
|
694
|
-
});
|
|
695
|
-
return { ok: false, response: oauthUpstreamUnreachableResponse() };
|
|
696
|
-
}
|
|
697
641
|
if (err instanceof OAuthConfigurationError) {
|
|
698
642
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
699
643
|
await recorder?.emit({
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
buildMcpListing
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-PTPLMKOV.js";
|
|
5
|
+
import "../chunk-M35C7Y3M.js";
|
|
6
6
|
import "../chunk-H37EB22A.js";
|
|
7
7
|
import "../chunk-6DXGZZA4.js";
|
|
8
8
|
import {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "../chunk-Y3ZFPEQH.js";
|
|
11
11
|
import {
|
|
12
12
|
version
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-VW7B32WL.js";
|
|
14
14
|
|
|
15
15
|
// src/manifest/io.ts
|
|
16
16
|
import { randomUUID } from "crypto";
|
|
@@ -153,18 +153,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
153
153
|
this.name = "OAuthConfigurationError";
|
|
154
154
|
}
|
|
155
155
|
};
|
|
156
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
157
|
-
constructor(message) {
|
|
158
|
-
super(message);
|
|
159
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
var MetadataUnreachableError = class extends Error {
|
|
163
|
-
constructor(message) {
|
|
164
|
-
super(message);
|
|
165
|
-
this.name = "MetadataUnreachableError";
|
|
166
|
-
}
|
|
167
|
-
};
|
|
168
156
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
169
157
|
function issuerPath(url) {
|
|
170
158
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -189,37 +177,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
189
177
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
190
178
|
}
|
|
191
179
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
|
|
180
|
+
const errors = [];
|
|
181
|
+
for (const url of metadataUrls) {
|
|
182
|
+
try {
|
|
183
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
184
|
+
} catch (err) {
|
|
195
185
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
try {
|
|
200
|
-
const metadata = await Promise.any(attempts);
|
|
201
|
-
controller.abort();
|
|
202
|
-
return metadata;
|
|
203
|
-
} catch (aggregate) {
|
|
204
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
205
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
206
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
207
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
208
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
209
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer, signal) {
|
|
213
|
-
log.debug("oauth.discovery.fetch", { url });
|
|
214
|
-
let response;
|
|
215
|
-
try {
|
|
216
|
-
response = await fetch(url, {
|
|
217
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
218
|
-
redirect: "manual"
|
|
219
|
-
});
|
|
220
|
-
} catch (err) {
|
|
221
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
186
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
187
|
+
}
|
|
222
188
|
}
|
|
189
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
190
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
191
|
+
}
|
|
192
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
193
|
+
log.debug("oauth.discovery.fetch", { url });
|
|
194
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
223
195
|
if (!response.ok) {
|
|
224
196
|
throw new Error(String(response.status));
|
|
225
197
|
}
|
|
@@ -242,21 +214,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
242
214
|
try {
|
|
243
215
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
244
216
|
} catch (err) {
|
|
245
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
246
|
-
if (err instanceof MetadataUnreachableError) {
|
|
247
|
-
log.error("oauth.discovery.unreachable", {
|
|
248
|
-
issuer,
|
|
249
|
-
...describeError(err),
|
|
250
|
-
outcome: "503 authorization server unreachable"
|
|
251
|
-
});
|
|
252
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
253
|
-
}
|
|
254
217
|
log.error("oauth.discovery.config_error", {
|
|
255
218
|
issuer,
|
|
256
219
|
...describeError(err),
|
|
257
220
|
outcome: "500 oauth configuration error"
|
|
258
221
|
});
|
|
259
|
-
throw new OAuthConfigurationError(
|
|
222
|
+
throw new OAuthConfigurationError(
|
|
223
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
224
|
+
);
|
|
260
225
|
}
|
|
261
226
|
}
|
|
262
227
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -349,14 +314,8 @@ function tokenHeaderFields(token) {
|
|
|
349
314
|
}
|
|
350
315
|
}
|
|
351
316
|
async function fetchVerificationKeySet(jwksUri) {
|
|
352
|
-
let response;
|
|
353
|
-
try {
|
|
354
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
355
|
-
} catch (err) {
|
|
356
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
357
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
358
|
-
}
|
|
359
317
|
try {
|
|
318
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
360
319
|
if (!response.ok)
|
|
361
320
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
362
321
|
const json = await response.json();
|
|
@@ -497,12 +456,6 @@ function oauthConfigurationErrorResponse() {
|
|
|
497
456
|
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
498
457
|
});
|
|
499
458
|
}
|
|
500
|
-
function oauthUpstreamUnreachableResponse() {
|
|
501
|
-
return new Response(JSON.stringify({ error: "authorization server unreachable" }), {
|
|
502
|
-
status: 503,
|
|
503
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store", "Retry-After": "30" }
|
|
504
|
-
});
|
|
505
|
-
}
|
|
506
459
|
function parseBearerToken(request) {
|
|
507
460
|
const header = request.headers.get("Authorization");
|
|
508
461
|
if (!header)
|
|
@@ -567,16 +520,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
567
520
|
assertRequiredScopes(runtime.auth, auth);
|
|
568
521
|
return { ok: true, auth };
|
|
569
522
|
} catch (err) {
|
|
570
|
-
if (err instanceof OAuthUpstreamUnreachableError) {
|
|
571
|
-
log.error("auth.upstream_unreachable", { ...describeError(err), outcome: "503" });
|
|
572
|
-
await recorder?.emit({
|
|
573
|
-
tool: null,
|
|
574
|
-
method: "authorize",
|
|
575
|
-
outcome: "auth_upstream_unreachable",
|
|
576
|
-
durationMs: nowMs() - startedAt
|
|
577
|
-
});
|
|
578
|
-
return { ok: false, response: oauthUpstreamUnreachableResponse() };
|
|
579
|
-
}
|
|
580
523
|
if (err instanceof OAuthConfigurationError) {
|
|
581
524
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
582
525
|
await recorder?.emit({
|
|
@@ -661,6 +604,14 @@ var ToolContext = class {
|
|
|
661
604
|
}
|
|
662
605
|
};
|
|
663
606
|
|
|
607
|
+
// src/core/content.ts
|
|
608
|
+
function extractTextContent(content) {
|
|
609
|
+
if (!content)
|
|
610
|
+
return void 0;
|
|
611
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
612
|
+
return text.length > 0 ? text : void 0;
|
|
613
|
+
}
|
|
614
|
+
|
|
664
615
|
// src/core/cors.ts
|
|
665
616
|
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
666
617
|
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
@@ -711,7 +662,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
711
662
|
tool: tool.name,
|
|
712
663
|
method: "tools/call",
|
|
713
664
|
outcome: result.isError ? "tool_error" : "ok",
|
|
714
|
-
durationMs: nowMs() - start
|
|
665
|
+
durationMs: nowMs() - start,
|
|
666
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
715
667
|
});
|
|
716
668
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
717
669
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-CPkhCRxc.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CFy5vZ5Z.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-CPkhCRxc.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CFy5vZ5Z.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpProtocolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-IUWLXNFW.js";
|
|
4
|
+
import "../../chunk-6QFZYYUV.js";
|
|
4
5
|
import "../../chunk-MA5H6PSF.js";
|
|
5
|
-
import "../../chunk-
|
|
6
|
+
import "../../chunk-M35C7Y3M.js";
|
|
6
7
|
import "../../chunk-H37EB22A.js";
|
|
7
8
|
import "../../chunk-6DXGZZA4.js";
|
|
8
|
-
import "../../chunk-
|
|
9
|
+
import "../../chunk-VW7B32WL.js";
|
|
9
10
|
export {
|
|
10
11
|
createMcpProtocolHandler
|
|
11
12
|
};
|
|
@@ -148,18 +148,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
148
148
|
this.name = "OAuthConfigurationError";
|
|
149
149
|
}
|
|
150
150
|
};
|
|
151
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
152
|
-
constructor(message) {
|
|
153
|
-
super(message);
|
|
154
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
var MetadataUnreachableError = class extends Error {
|
|
158
|
-
constructor(message) {
|
|
159
|
-
super(message);
|
|
160
|
-
this.name = "MetadataUnreachableError";
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
151
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
164
152
|
function issuerPath(url) {
|
|
165
153
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -184,37 +172,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
184
172
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
185
173
|
}
|
|
186
174
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
187
|
-
const
|
|
188
|
-
const
|
|
189
|
-
|
|
175
|
+
const errors = [];
|
|
176
|
+
for (const url of metadataUrls) {
|
|
177
|
+
try {
|
|
178
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
179
|
+
} catch (err) {
|
|
190
180
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
191
|
-
|
|
192
|
-
}
|
|
193
|
-
);
|
|
194
|
-
try {
|
|
195
|
-
const metadata = await Promise.any(attempts);
|
|
196
|
-
controller.abort();
|
|
197
|
-
return metadata;
|
|
198
|
-
} catch (aggregate) {
|
|
199
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
200
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
201
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
202
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
203
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
204
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
181
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
182
|
+
}
|
|
205
183
|
}
|
|
184
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
185
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
206
186
|
}
|
|
207
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer
|
|
187
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
208
188
|
log.debug("oauth.discovery.fetch", { url });
|
|
209
|
-
|
|
210
|
-
try {
|
|
211
|
-
response = await fetch(url, {
|
|
212
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
213
|
-
redirect: "manual"
|
|
214
|
-
});
|
|
215
|
-
} catch (err) {
|
|
216
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
217
|
-
}
|
|
189
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
218
190
|
if (!response.ok) {
|
|
219
191
|
throw new Error(String(response.status));
|
|
220
192
|
}
|
|
@@ -237,21 +209,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
237
209
|
try {
|
|
238
210
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
239
211
|
} catch (err) {
|
|
240
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
241
|
-
if (err instanceof MetadataUnreachableError) {
|
|
242
|
-
log.error("oauth.discovery.unreachable", {
|
|
243
|
-
issuer,
|
|
244
|
-
...describeError(err),
|
|
245
|
-
outcome: "503 authorization server unreachable"
|
|
246
|
-
});
|
|
247
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
248
|
-
}
|
|
249
212
|
log.error("oauth.discovery.config_error", {
|
|
250
213
|
issuer,
|
|
251
214
|
...describeError(err),
|
|
252
215
|
outcome: "500 oauth configuration error"
|
|
253
216
|
});
|
|
254
|
-
throw new OAuthConfigurationError(
|
|
217
|
+
throw new OAuthConfigurationError(
|
|
218
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
219
|
+
);
|
|
255
220
|
}
|
|
256
221
|
}
|
|
257
222
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -341,14 +306,8 @@ function tokenHeaderFields(token) {
|
|
|
341
306
|
}
|
|
342
307
|
}
|
|
343
308
|
async function fetchVerificationKeySet(jwksUri) {
|
|
344
|
-
let response;
|
|
345
|
-
try {
|
|
346
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
347
|
-
} catch (err) {
|
|
348
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
349
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
350
|
-
}
|
|
351
309
|
try {
|
|
310
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
352
311
|
if (!response.ok)
|
|
353
312
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
354
313
|
const json = await response.json();
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createOAuthProtectedResourceMetadataHandler
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-VOMKN2HP.js";
|
|
4
|
+
import "../chunk-M35C7Y3M.js";
|
|
5
5
|
import "../chunk-H37EB22A.js";
|
|
6
6
|
import "../chunk-6DXGZZA4.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-VW7B32WL.js";
|
|
8
8
|
export {
|
|
9
9
|
createOAuthProtectedResourceMetadataHandler
|
|
10
10
|
};
|
|
@@ -163,18 +163,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
163
163
|
this.name = "OAuthConfigurationError";
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
167
|
-
constructor(message) {
|
|
168
|
-
super(message);
|
|
169
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
var MetadataUnreachableError = class extends Error {
|
|
173
|
-
constructor(message) {
|
|
174
|
-
super(message);
|
|
175
|
-
this.name = "MetadataUnreachableError";
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
166
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
179
167
|
function issuerPath(url) {
|
|
180
168
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -199,37 +187,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
199
187
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
200
188
|
}
|
|
201
189
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
|
|
190
|
+
const errors = [];
|
|
191
|
+
for (const url of metadataUrls) {
|
|
192
|
+
try {
|
|
193
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
194
|
+
} catch (err) {
|
|
205
195
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
206
|
-
|
|
207
|
-
}
|
|
208
|
-
);
|
|
209
|
-
try {
|
|
210
|
-
const metadata = await Promise.any(attempts);
|
|
211
|
-
controller.abort();
|
|
212
|
-
return metadata;
|
|
213
|
-
} catch (aggregate) {
|
|
214
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
215
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
216
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
217
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
218
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
219
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer, signal) {
|
|
223
|
-
log.debug("oauth.discovery.fetch", { url });
|
|
224
|
-
let response;
|
|
225
|
-
try {
|
|
226
|
-
response = await fetch(url, {
|
|
227
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
228
|
-
redirect: "manual"
|
|
229
|
-
});
|
|
230
|
-
} catch (err) {
|
|
231
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
196
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
197
|
+
}
|
|
232
198
|
}
|
|
199
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
200
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
201
|
+
}
|
|
202
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
203
|
+
log.debug("oauth.discovery.fetch", { url });
|
|
204
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
233
205
|
if (!response.ok) {
|
|
234
206
|
throw new Error(String(response.status));
|
|
235
207
|
}
|
|
@@ -252,21 +224,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
252
224
|
try {
|
|
253
225
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
254
226
|
} catch (err) {
|
|
255
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
256
|
-
if (err instanceof MetadataUnreachableError) {
|
|
257
|
-
log.error("oauth.discovery.unreachable", {
|
|
258
|
-
issuer,
|
|
259
|
-
...describeError(err),
|
|
260
|
-
outcome: "503 authorization server unreachable"
|
|
261
|
-
});
|
|
262
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
263
|
-
}
|
|
264
227
|
log.error("oauth.discovery.config_error", {
|
|
265
228
|
issuer,
|
|
266
229
|
...describeError(err),
|
|
267
230
|
outcome: "500 oauth configuration error"
|
|
268
231
|
});
|
|
269
|
-
throw new OAuthConfigurationError(
|
|
232
|
+
throw new OAuthConfigurationError(
|
|
233
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
234
|
+
);
|
|
270
235
|
}
|
|
271
236
|
}
|
|
272
237
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -359,14 +324,8 @@ function tokenHeaderFields(token) {
|
|
|
359
324
|
}
|
|
360
325
|
}
|
|
361
326
|
async function fetchVerificationKeySet(jwksUri) {
|
|
362
|
-
let response;
|
|
363
|
-
try {
|
|
364
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
365
|
-
} catch (err) {
|
|
366
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
367
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
368
|
-
}
|
|
369
327
|
try {
|
|
328
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
370
329
|
if (!response.ok)
|
|
371
330
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
372
331
|
const json = await response.json();
|
|
@@ -507,12 +466,6 @@ function oauthConfigurationErrorResponse() {
|
|
|
507
466
|
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
508
467
|
});
|
|
509
468
|
}
|
|
510
|
-
function oauthUpstreamUnreachableResponse() {
|
|
511
|
-
return new Response(JSON.stringify({ error: "authorization server unreachable" }), {
|
|
512
|
-
status: 503,
|
|
513
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store", "Retry-After": "30" }
|
|
514
|
-
});
|
|
515
|
-
}
|
|
516
469
|
function parseBearerToken(request) {
|
|
517
470
|
const header = request.headers.get("Authorization");
|
|
518
471
|
if (!header)
|
|
@@ -585,16 +538,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
585
538
|
assertRequiredScopes(runtime.auth, auth);
|
|
586
539
|
return { ok: true, auth };
|
|
587
540
|
} catch (err) {
|
|
588
|
-
if (err instanceof OAuthUpstreamUnreachableError) {
|
|
589
|
-
log.error("auth.upstream_unreachable", { ...describeError(err), outcome: "503" });
|
|
590
|
-
await recorder?.emit({
|
|
591
|
-
tool: null,
|
|
592
|
-
method: "authorize",
|
|
593
|
-
outcome: "auth_upstream_unreachable",
|
|
594
|
-
durationMs: nowMs() - startedAt
|
|
595
|
-
});
|
|
596
|
-
return { ok: false, response: oauthUpstreamUnreachableResponse() };
|
|
597
|
-
}
|
|
598
541
|
if (err instanceof OAuthConfigurationError) {
|
|
599
542
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
600
543
|
await recorder?.emit({
|
|
@@ -744,6 +687,14 @@ var ToolContext = class {
|
|
|
744
687
|
}
|
|
745
688
|
};
|
|
746
689
|
|
|
690
|
+
// src/core/content.ts
|
|
691
|
+
function extractTextContent(content) {
|
|
692
|
+
if (!content)
|
|
693
|
+
return void 0;
|
|
694
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
695
|
+
return text.length > 0 ? text : void 0;
|
|
696
|
+
}
|
|
697
|
+
|
|
747
698
|
// src/protocols/rest/invoke-tool.ts
|
|
748
699
|
var MAX_REFLECTED_TOOL_NAME = 256;
|
|
749
700
|
function safeReflectName(name) {
|
|
@@ -844,7 +795,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
844
795
|
tool: tool.name,
|
|
845
796
|
method: "tools/call",
|
|
846
797
|
outcome: result.isError ? "tool_error" : "ok",
|
|
847
|
-
durationMs: nowMs() - start
|
|
798
|
+
durationMs: nowMs() - start,
|
|
799
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
848
800
|
});
|
|
849
801
|
return Response.json({
|
|
850
802
|
content: result.content ?? [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-CPkhCRxc.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CFy5vZ5Z.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-CPkhCRxc.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CFy5vZ5Z.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createInvokeToolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-H7W77K6V.js";
|
|
4
4
|
import {
|
|
5
5
|
createListToolsHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-PTPLMKOV.js";
|
|
7
|
+
import "../../chunk-6QFZYYUV.js";
|
|
7
8
|
import "../../chunk-MA5H6PSF.js";
|
|
8
|
-
import "../../chunk-
|
|
9
|
+
import "../../chunk-M35C7Y3M.js";
|
|
9
10
|
import "../../chunk-H37EB22A.js";
|
|
10
11
|
import "../../chunk-6DXGZZA4.js";
|
|
11
|
-
import "../../chunk-
|
|
12
|
+
import "../../chunk-VW7B32WL.js";
|
|
12
13
|
export {
|
|
13
14
|
createInvokeToolHandler,
|
|
14
15
|
createListToolsHandler
|
|
@@ -174,7 +174,7 @@ function describeError(err) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// package.json
|
|
177
|
-
var version = "0.20.1
|
|
177
|
+
var version = "0.20.1";
|
|
178
178
|
|
|
179
179
|
// src/metrics/otlp.ts
|
|
180
180
|
var SCOPE_NAME = "@lovable.dev/mcp-js";
|
|
@@ -281,7 +281,8 @@ var BaseMetricRecorder = class {
|
|
|
281
281
|
method: ev.method,
|
|
282
282
|
outcome: ev.outcome,
|
|
283
283
|
durationMs: ev.durationMs,
|
|
284
|
-
stack: this.stack
|
|
284
|
+
stack: this.stack,
|
|
285
|
+
...ev.errorText !== void 0 && { errorText: ev.errorText }
|
|
285
286
|
});
|
|
286
287
|
if (!this.config.enabled)
|
|
287
288
|
return;
|
|
@@ -445,18 +446,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
445
446
|
this.name = "OAuthConfigurationError";
|
|
446
447
|
}
|
|
447
448
|
};
|
|
448
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
449
|
-
constructor(message) {
|
|
450
|
-
super(message);
|
|
451
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
452
|
-
}
|
|
453
|
-
};
|
|
454
|
-
var MetadataUnreachableError = class extends Error {
|
|
455
|
-
constructor(message) {
|
|
456
|
-
super(message);
|
|
457
|
-
this.name = "MetadataUnreachableError";
|
|
458
|
-
}
|
|
459
|
-
};
|
|
460
449
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
461
450
|
function issuerPath(url) {
|
|
462
451
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -481,37 +470,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
481
470
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
482
471
|
}
|
|
483
472
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
484
|
-
const
|
|
485
|
-
const
|
|
486
|
-
|
|
473
|
+
const errors = [];
|
|
474
|
+
for (const url of metadataUrls) {
|
|
475
|
+
try {
|
|
476
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
477
|
+
} catch (err) {
|
|
487
478
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
488
|
-
|
|
489
|
-
}
|
|
490
|
-
);
|
|
491
|
-
try {
|
|
492
|
-
const metadata = await Promise.any(attempts);
|
|
493
|
-
controller.abort();
|
|
494
|
-
return metadata;
|
|
495
|
-
} catch (aggregate) {
|
|
496
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
497
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
498
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
499
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
500
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
501
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
479
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
480
|
+
}
|
|
502
481
|
}
|
|
482
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
483
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
503
484
|
}
|
|
504
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer
|
|
485
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
505
486
|
log.debug("oauth.discovery.fetch", { url });
|
|
506
|
-
|
|
507
|
-
try {
|
|
508
|
-
response = await fetch(url, {
|
|
509
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
510
|
-
redirect: "manual"
|
|
511
|
-
});
|
|
512
|
-
} catch (err) {
|
|
513
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
514
|
-
}
|
|
487
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
515
488
|
if (!response.ok) {
|
|
516
489
|
throw new Error(String(response.status));
|
|
517
490
|
}
|
|
@@ -534,21 +507,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
534
507
|
try {
|
|
535
508
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
536
509
|
} catch (err) {
|
|
537
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
538
|
-
if (err instanceof MetadataUnreachableError) {
|
|
539
|
-
log.error("oauth.discovery.unreachable", {
|
|
540
|
-
issuer,
|
|
541
|
-
...describeError(err),
|
|
542
|
-
outcome: "503 authorization server unreachable"
|
|
543
|
-
});
|
|
544
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
545
|
-
}
|
|
546
510
|
log.error("oauth.discovery.config_error", {
|
|
547
511
|
issuer,
|
|
548
512
|
...describeError(err),
|
|
549
513
|
outcome: "500 oauth configuration error"
|
|
550
514
|
});
|
|
551
|
-
throw new OAuthConfigurationError(
|
|
515
|
+
throw new OAuthConfigurationError(
|
|
516
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
517
|
+
);
|
|
552
518
|
}
|
|
553
519
|
}
|
|
554
520
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -614,14 +580,8 @@ function tokenHeaderFields(token) {
|
|
|
614
580
|
}
|
|
615
581
|
}
|
|
616
582
|
async function fetchVerificationKeySet(jwksUri) {
|
|
617
|
-
let response;
|
|
618
|
-
try {
|
|
619
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
620
|
-
} catch (err) {
|
|
621
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
622
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
623
|
-
}
|
|
624
583
|
try {
|
|
584
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
625
585
|
if (!response.ok)
|
|
626
586
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
627
587
|
const json = await response.json();
|
|
@@ -762,12 +722,6 @@ function oauthConfigurationErrorResponse() {
|
|
|
762
722
|
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
763
723
|
});
|
|
764
724
|
}
|
|
765
|
-
function oauthUpstreamUnreachableResponse() {
|
|
766
|
-
return new Response(JSON.stringify({ error: "authorization server unreachable" }), {
|
|
767
|
-
status: 503,
|
|
768
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store", "Retry-After": "30" }
|
|
769
|
-
});
|
|
770
|
-
}
|
|
771
725
|
function parseBearerToken(request) {
|
|
772
726
|
const header = request.headers.get("Authorization");
|
|
773
727
|
if (!header)
|
|
@@ -840,16 +794,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
840
794
|
assertRequiredScopes(runtime.auth, auth);
|
|
841
795
|
return { ok: true, auth };
|
|
842
796
|
} catch (err) {
|
|
843
|
-
if (err instanceof OAuthUpstreamUnreachableError) {
|
|
844
|
-
log.error("auth.upstream_unreachable", { ...describeError(err), outcome: "503" });
|
|
845
|
-
await recorder?.emit({
|
|
846
|
-
tool: null,
|
|
847
|
-
method: "authorize",
|
|
848
|
-
outcome: "auth_upstream_unreachable",
|
|
849
|
-
durationMs: nowMs() - startedAt
|
|
850
|
-
});
|
|
851
|
-
return { ok: false, response: oauthUpstreamUnreachableResponse() };
|
|
852
|
-
}
|
|
853
797
|
if (err instanceof OAuthConfigurationError) {
|
|
854
798
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
855
799
|
await recorder?.emit({
|
|
@@ -934,6 +878,14 @@ var ToolContext = class {
|
|
|
934
878
|
}
|
|
935
879
|
};
|
|
936
880
|
|
|
881
|
+
// src/core/content.ts
|
|
882
|
+
function extractTextContent(content) {
|
|
883
|
+
if (!content)
|
|
884
|
+
return void 0;
|
|
885
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
886
|
+
return text.length > 0 ? text : void 0;
|
|
887
|
+
}
|
|
888
|
+
|
|
937
889
|
// src/core/cors.ts
|
|
938
890
|
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
939
891
|
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
@@ -984,7 +936,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
984
936
|
tool: tool.name,
|
|
985
937
|
method: "tools/call",
|
|
986
938
|
outcome: result.isError ? "tool_error" : "ok",
|
|
987
|
-
durationMs: nowMs() - start
|
|
939
|
+
durationMs: nowMs() - start,
|
|
940
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
988
941
|
});
|
|
989
942
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
990
943
|
};
|
|
@@ -1240,7 +1193,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1240
1193
|
tool: tool.name,
|
|
1241
1194
|
method: "tools/call",
|
|
1242
1195
|
outcome: result.isError ? "tool_error" : "ok",
|
|
1243
|
-
durationMs: nowMs() - start
|
|
1196
|
+
durationMs: nowMs() - start,
|
|
1197
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
1244
1198
|
});
|
|
1245
1199
|
return Response.json({
|
|
1246
1200
|
content: result.content ?? [],
|
|
@@ -3,21 +3,22 @@ import {
|
|
|
3
3
|
} from "../../chunk-UQK5UO6C.js";
|
|
4
4
|
import {
|
|
5
5
|
createMcpProtocolHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-IUWLXNFW.js";
|
|
7
7
|
import {
|
|
8
8
|
createOAuthProtectedResourceMetadataHandler
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-VOMKN2HP.js";
|
|
10
10
|
import {
|
|
11
11
|
createInvokeToolHandler
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-H7W77K6V.js";
|
|
13
13
|
import {
|
|
14
14
|
createListToolsHandler
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-PTPLMKOV.js";
|
|
16
|
+
import "../../chunk-6QFZYYUV.js";
|
|
16
17
|
import "../../chunk-MA5H6PSF.js";
|
|
17
18
|
import {
|
|
18
19
|
assertResourcePathShape,
|
|
19
20
|
createRecorderForRuntime
|
|
20
|
-
} from "../../chunk-
|
|
21
|
+
} from "../../chunk-M35C7Y3M.js";
|
|
21
22
|
import {
|
|
22
23
|
trimTrailingSlash
|
|
23
24
|
} from "../../chunk-H37EB22A.js";
|
|
@@ -28,7 +29,7 @@ import {
|
|
|
28
29
|
FUNCTIONS_MOUNT_PREFIX,
|
|
29
30
|
assertFunctionName
|
|
30
31
|
} from "../../chunk-XQWJN6DC.js";
|
|
31
|
-
import "../../chunk-
|
|
32
|
+
import "../../chunk-VW7B32WL.js";
|
|
32
33
|
|
|
33
34
|
// src/stacks/supabase/handler.ts
|
|
34
35
|
function deriveResourcePath(options) {
|
|
@@ -129,7 +129,7 @@ function describeError(err) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// package.json
|
|
132
|
-
var version = "0.20.1
|
|
132
|
+
var version = "0.20.1";
|
|
133
133
|
|
|
134
134
|
// src/metrics/otlp.ts
|
|
135
135
|
var SCOPE_NAME = "@lovable.dev/mcp-js";
|
|
@@ -236,7 +236,8 @@ var BaseMetricRecorder = class {
|
|
|
236
236
|
method: ev.method,
|
|
237
237
|
outcome: ev.outcome,
|
|
238
238
|
durationMs: ev.durationMs,
|
|
239
|
-
stack: this.stack
|
|
239
|
+
stack: this.stack,
|
|
240
|
+
...ev.errorText !== void 0 && { errorText: ev.errorText }
|
|
240
241
|
});
|
|
241
242
|
if (!this.config.enabled)
|
|
242
243
|
return;
|
|
@@ -421,18 +422,6 @@ var OAuthConfigurationError = class extends Error {
|
|
|
421
422
|
this.name = "OAuthConfigurationError";
|
|
422
423
|
}
|
|
423
424
|
};
|
|
424
|
-
var OAuthUpstreamUnreachableError = class extends Error {
|
|
425
|
-
constructor(message) {
|
|
426
|
-
super(message);
|
|
427
|
-
this.name = "OAuthUpstreamUnreachableError";
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
var MetadataUnreachableError = class extends Error {
|
|
431
|
-
constructor(message) {
|
|
432
|
-
super(message);
|
|
433
|
-
this.name = "MetadataUnreachableError";
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
425
|
var METADATA_FETCH_TIMEOUT_MS = 5e3;
|
|
437
426
|
function issuerPath(url) {
|
|
438
427
|
const path = trimTrailingSlash(url.pathname);
|
|
@@ -457,37 +446,21 @@ function oauthMetadataUrlsForIssuer(issuer) {
|
|
|
457
446
|
return [...pathInsertedOAuthMetadataUrls(url, path), `${normalizedIssuer}/.well-known/openid-configuration`];
|
|
458
447
|
}
|
|
459
448
|
async function fetchFirstValidOAuthServerMetadata(metadataUrls, expectedIssuer) {
|
|
460
|
-
const
|
|
461
|
-
const
|
|
462
|
-
|
|
449
|
+
const errors = [];
|
|
450
|
+
for (const url of metadataUrls) {
|
|
451
|
+
try {
|
|
452
|
+
return await fetchOAuthServerMetadata(url, expectedIssuer);
|
|
453
|
+
} catch (err) {
|
|
463
454
|
log.debug("oauth.discovery.attempt_failed", { url, ...describeError(err) });
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
try {
|
|
468
|
-
const metadata = await Promise.any(attempts);
|
|
469
|
-
controller.abort();
|
|
470
|
-
return metadata;
|
|
471
|
-
} catch (aggregate) {
|
|
472
|
-
const causes = aggregate instanceof AggregateError ? aggregate.errors : [aggregate];
|
|
473
|
-
const unreachable = causes.some((c) => c instanceof MetadataUnreachableError);
|
|
474
|
-
const detail = causes.map((c) => c instanceof Error ? c.message : String(c)).join("; ");
|
|
475
|
-
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors: detail, unreachable });
|
|
476
|
-
const message = `failed to discover OAuth server metadata (${detail})`;
|
|
477
|
-
throw unreachable ? new MetadataUnreachableError(message) : new Error(message);
|
|
455
|
+
errors.push(`${url}: ${err instanceof Error ? err.message : String(err)}`);
|
|
456
|
+
}
|
|
478
457
|
}
|
|
458
|
+
log.error("oauth.discovery.exhausted", { expectedIssuer, urlsTried: metadataUrls, errors });
|
|
459
|
+
throw new Error(`failed to discover OAuth server metadata (${errors.join("; ")})`);
|
|
479
460
|
}
|
|
480
|
-
async function fetchOAuthServerMetadata(url, expectedIssuer
|
|
461
|
+
async function fetchOAuthServerMetadata(url, expectedIssuer) {
|
|
481
462
|
log.debug("oauth.discovery.fetch", { url });
|
|
482
|
-
|
|
483
|
-
try {
|
|
484
|
-
response = await fetch(url, {
|
|
485
|
-
signal: AbortSignal.any([signal, AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS)]),
|
|
486
|
-
redirect: "manual"
|
|
487
|
-
});
|
|
488
|
-
} catch (err) {
|
|
489
|
-
throw new MetadataUnreachableError(err instanceof Error ? err.message : String(err));
|
|
490
|
-
}
|
|
463
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(METADATA_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
491
464
|
if (!response.ok) {
|
|
492
465
|
throw new Error(String(response.status));
|
|
493
466
|
}
|
|
@@ -510,21 +483,14 @@ async function fetchIssuerOAuthServerMetadata(issuer) {
|
|
|
510
483
|
try {
|
|
511
484
|
return await fetchFirstValidOAuthServerMetadata(oauthMetadataUrlsForIssuer(issuer), issuer);
|
|
512
485
|
} catch (err) {
|
|
513
|
-
const message = `OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`;
|
|
514
|
-
if (err instanceof MetadataUnreachableError) {
|
|
515
|
-
log.error("oauth.discovery.unreachable", {
|
|
516
|
-
issuer,
|
|
517
|
-
...describeError(err),
|
|
518
|
-
outcome: "503 authorization server unreachable"
|
|
519
|
-
});
|
|
520
|
-
throw new OAuthUpstreamUnreachableError(message);
|
|
521
|
-
}
|
|
522
486
|
log.error("oauth.discovery.config_error", {
|
|
523
487
|
issuer,
|
|
524
488
|
...describeError(err),
|
|
525
489
|
outcome: "500 oauth configuration error"
|
|
526
490
|
});
|
|
527
|
-
throw new OAuthConfigurationError(
|
|
491
|
+
throw new OAuthConfigurationError(
|
|
492
|
+
`OAuth issuer discovery failed: ${err instanceof Error ? err.message : String(err)}`
|
|
493
|
+
);
|
|
528
494
|
}
|
|
529
495
|
}
|
|
530
496
|
function createOAuthDiscoveryResolver(auth) {
|
|
@@ -617,14 +583,8 @@ function tokenHeaderFields(token) {
|
|
|
617
583
|
}
|
|
618
584
|
}
|
|
619
585
|
async function fetchVerificationKeySet(jwksUri) {
|
|
620
|
-
let response;
|
|
621
|
-
try {
|
|
622
|
-
response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
623
|
-
} catch (err) {
|
|
624
|
-
log.error("oauth.jwks.unreachable", { ...describeError(err), outcome: "503 authorization server unreachable" });
|
|
625
|
-
throw new OAuthUpstreamUnreachableError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
626
|
-
}
|
|
627
586
|
try {
|
|
587
|
+
const response = await fetch(jwksUri, { signal: AbortSignal.timeout(JWKS_FETCH_TIMEOUT_MS), redirect: "manual" });
|
|
628
588
|
if (!response.ok)
|
|
629
589
|
throw new Error(`JWKS endpoint returned ${response.status}`);
|
|
630
590
|
const json = await response.json();
|
|
@@ -765,12 +725,6 @@ function oauthConfigurationErrorResponse() {
|
|
|
765
725
|
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
766
726
|
});
|
|
767
727
|
}
|
|
768
|
-
function oauthUpstreamUnreachableResponse() {
|
|
769
|
-
return new Response(JSON.stringify({ error: "authorization server unreachable" }), {
|
|
770
|
-
status: 503,
|
|
771
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store", "Retry-After": "30" }
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
728
|
function parseBearerToken(request) {
|
|
775
729
|
const header = request.headers.get("Authorization");
|
|
776
730
|
if (!header)
|
|
@@ -843,16 +797,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
843
797
|
assertRequiredScopes(runtime.auth, auth);
|
|
844
798
|
return { ok: true, auth };
|
|
845
799
|
} catch (err) {
|
|
846
|
-
if (err instanceof OAuthUpstreamUnreachableError) {
|
|
847
|
-
log.error("auth.upstream_unreachable", { ...describeError(err), outcome: "503" });
|
|
848
|
-
await recorder?.emit({
|
|
849
|
-
tool: null,
|
|
850
|
-
method: "authorize",
|
|
851
|
-
outcome: "auth_upstream_unreachable",
|
|
852
|
-
durationMs: nowMs() - startedAt
|
|
853
|
-
});
|
|
854
|
-
return { ok: false, response: oauthUpstreamUnreachableResponse() };
|
|
855
|
-
}
|
|
856
800
|
if (err instanceof OAuthConfigurationError) {
|
|
857
801
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
858
802
|
await recorder?.emit({
|
|
@@ -937,6 +881,14 @@ var ToolContext = class {
|
|
|
937
881
|
}
|
|
938
882
|
};
|
|
939
883
|
|
|
884
|
+
// src/core/content.ts
|
|
885
|
+
function extractTextContent(content) {
|
|
886
|
+
if (!content)
|
|
887
|
+
return void 0;
|
|
888
|
+
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
889
|
+
return text.length > 0 ? text : void 0;
|
|
890
|
+
}
|
|
891
|
+
|
|
940
892
|
// src/core/cors.ts
|
|
941
893
|
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
942
894
|
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
@@ -987,7 +939,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
987
939
|
tool: tool.name,
|
|
988
940
|
method: "tools/call",
|
|
989
941
|
outcome: result.isError ? "tool_error" : "ok",
|
|
990
|
-
durationMs: nowMs() - start
|
|
942
|
+
durationMs: nowMs() - start,
|
|
943
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
991
944
|
});
|
|
992
945
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
993
946
|
};
|
|
@@ -1243,7 +1196,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1243
1196
|
tool: tool.name,
|
|
1244
1197
|
method: "tools/call",
|
|
1245
1198
|
outcome: result.isError ? "tool_error" : "ok",
|
|
1246
|
-
durationMs: nowMs() - start
|
|
1199
|
+
durationMs: nowMs() - start,
|
|
1200
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
1247
1201
|
});
|
|
1248
1202
|
return Response.json({
|
|
1249
1203
|
content: result.content ?? [],
|
|
@@ -3,23 +3,24 @@ import {
|
|
|
3
3
|
} from "../../chunk-UQK5UO6C.js";
|
|
4
4
|
import {
|
|
5
5
|
createMcpProtocolHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-IUWLXNFW.js";
|
|
7
7
|
import {
|
|
8
8
|
createOAuthProtectedResourceMetadataHandler
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-VOMKN2HP.js";
|
|
10
10
|
import {
|
|
11
11
|
createInvokeToolHandler
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-H7W77K6V.js";
|
|
13
13
|
import {
|
|
14
14
|
createListToolsHandler
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-PTPLMKOV.js";
|
|
16
|
+
import "../../chunk-6QFZYYUV.js";
|
|
16
17
|
import "../../chunk-MA5H6PSF.js";
|
|
17
18
|
import {
|
|
18
19
|
createRecorderForRuntime
|
|
19
|
-
} from "../../chunk-
|
|
20
|
+
} from "../../chunk-M35C7Y3M.js";
|
|
20
21
|
import "../../chunk-H37EB22A.js";
|
|
21
22
|
import "../../chunk-6DXGZZA4.js";
|
|
22
|
-
import "../../chunk-
|
|
23
|
+
import "../../chunk-VW7B32WL.js";
|
|
23
24
|
|
|
24
25
|
// src/stacks/tanstack/handlers.ts
|
|
25
26
|
var STACK = "tanstack";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovable.dev/mcp-js",
|
|
3
|
-
"version": "0.20.1
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "Author MCP servers for Lovable apps. Declare tools with defineTool, register them in defineMcp, and a framework adapter (TanStack or Supabase Edge Functions) emits the route(s) at build time.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|