@lovable.dev/mcp-js 0.5.1 → 0.6.0
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/{chunk-DDF63QWG.js → chunk-K2T4WTKX.js} +15 -21
- package/dist/{chunk-GLG5RZGE.js → chunk-NJ5WBRYI.js} +10 -3
- package/dist/{chunk-VD6CS7Y6.js → chunk-SYI32IRK.js} +18 -6
- package/dist/{chunk-XEDRJFAR.js → chunk-ZKKLOL2C.js} +23 -1
- package/dist/protocols/mcp/index.cjs +26 -1
- package/dist/protocols/mcp/index.js +2 -2
- package/dist/protocols/oauth-metadata.cjs +28 -16
- package/dist/protocols/oauth-metadata.js +2 -2
- package/dist/protocols/rest/index.cjs +34 -4
- package/dist/protocols/rest/index.js +2 -2
- package/dist/stacks/tanstack/index.cjs +51 -24
- package/dist/stacks/tanstack/index.js +4 -4
- package/package.json +1 -1
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
JSON_HEADERS,
|
|
3
|
+
corsPreflightResponse,
|
|
3
4
|
getOAuthRuntime,
|
|
4
5
|
headResponse,
|
|
5
6
|
methodNotAllowed,
|
|
6
7
|
oauthConfigurationErrorResponse,
|
|
7
|
-
resolveProtectedResource
|
|
8
|
-
|
|
8
|
+
resolveProtectedResource,
|
|
9
|
+
withCors
|
|
10
|
+
} from "./chunk-ZKKLOL2C.js";
|
|
9
11
|
|
|
10
12
|
// src/protocols/oauth-metadata.ts
|
|
11
|
-
var CORS_ORIGIN = { "Access-Control-Allow-Origin": "*" };
|
|
12
|
-
function withCors(response) {
|
|
13
|
-
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
14
|
-
return response;
|
|
15
|
-
}
|
|
16
13
|
function notFound() {
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
return withCors(
|
|
15
|
+
new Response(JSON.stringify({ error: "not found" }), {
|
|
16
|
+
status: 404,
|
|
17
|
+
// `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
|
|
18
|
+
// then served past a later deploy that enables OAuth and starts returning 200.
|
|
19
|
+
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
20
|
+
})
|
|
21
|
+
);
|
|
23
22
|
}
|
|
24
23
|
async function buildProtectedResourceMetadata(mcp, auth, request, options, discovery) {
|
|
25
24
|
const issuer = await discovery.resolveIssuer();
|
|
@@ -44,17 +43,12 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
44
43
|
return async (request) => {
|
|
45
44
|
if (runtime.kind !== "configured" || runtime.auth.protectedResourceMetadataUrl !== void 0)
|
|
46
45
|
return notFound();
|
|
47
|
-
if (request.method === "OPTIONS")
|
|
48
|
-
return
|
|
49
|
-
status: 204,
|
|
50
|
-
headers: { ...CORS_ORIGIN, "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS" }
|
|
51
|
-
});
|
|
52
|
-
}
|
|
46
|
+
if (request.method === "OPTIONS")
|
|
47
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
53
48
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
54
49
|
return withCors(methodNotAllowed("GET, HEAD, OPTIONS"));
|
|
55
50
|
const headers = {
|
|
56
51
|
...JSON_HEADERS,
|
|
57
|
-
...CORS_ORIGIN,
|
|
58
52
|
"Cache-Control": "public, max-age=300",
|
|
59
53
|
Vary: "Host"
|
|
60
54
|
};
|
|
@@ -66,7 +60,7 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
66
60
|
runtime.options,
|
|
67
61
|
runtime.discovery
|
|
68
62
|
);
|
|
69
|
-
const response = Response.json(metadata, { headers });
|
|
63
|
+
const response = withCors(Response.json(metadata, { headers }));
|
|
70
64
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
71
65
|
} catch {
|
|
72
66
|
const response = withCors(oauthConfigurationErrorResponse());
|
|
@@ -2,8 +2,10 @@ import {
|
|
|
2
2
|
ToolContext
|
|
3
3
|
} from "./chunk-MA5H6PSF.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
corsPreflightResponse,
|
|
6
|
+
createRequestAuthorizer,
|
|
7
|
+
withCors
|
|
8
|
+
} from "./chunk-ZKKLOL2C.js";
|
|
7
9
|
|
|
8
10
|
// src/protocols/mcp/protocol.ts
|
|
9
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -25,7 +27,7 @@ function adaptToolToSdkCallback(tool, auth) {
|
|
|
25
27
|
}
|
|
26
28
|
function createMcpProtocolHandler(mcp, options = {}) {
|
|
27
29
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
28
|
-
|
|
30
|
+
const handle = async (request) => {
|
|
29
31
|
const authResult = await authorizer.authorize(request);
|
|
30
32
|
if (!authResult.ok)
|
|
31
33
|
return authResult.response;
|
|
@@ -59,6 +61,11 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
59
61
|
);
|
|
60
62
|
}
|
|
61
63
|
};
|
|
64
|
+
return async (request) => {
|
|
65
|
+
if (request.method === "OPTIONS")
|
|
66
|
+
return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
|
|
67
|
+
return withCors(await handle(request));
|
|
68
|
+
};
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
export {
|
|
@@ -4,10 +4,12 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
JSON_HEADERS,
|
|
6
6
|
assertRestResourceBinding,
|
|
7
|
+
corsPreflightResponse,
|
|
7
8
|
createRequestAuthorizer,
|
|
8
9
|
headResponse,
|
|
9
|
-
methodNotAllowed
|
|
10
|
-
|
|
10
|
+
methodNotAllowed,
|
|
11
|
+
withCors
|
|
12
|
+
} from "./chunk-ZKKLOL2C.js";
|
|
11
13
|
|
|
12
14
|
// src/protocols/rest/list-tools.ts
|
|
13
15
|
import { objectFromShape } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
@@ -24,12 +26,12 @@ function shapeToJsonSchema(shape) {
|
|
|
24
26
|
function createListToolsHandler(mcp, options = {}) {
|
|
25
27
|
assertRestResourceBinding(mcp, options);
|
|
26
28
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
27
|
-
|
|
29
|
+
const handle = async (request) => {
|
|
28
30
|
const authResult = await authorizer.authorize(request);
|
|
29
31
|
if (!authResult.ok)
|
|
30
32
|
return authResult.response;
|
|
31
33
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
32
|
-
return methodNotAllowed("GET, HEAD");
|
|
34
|
+
return methodNotAllowed("GET, HEAD, OPTIONS");
|
|
33
35
|
const body = {
|
|
34
36
|
server: { name: mcp.name, version: mcp.version, title: mcp.title },
|
|
35
37
|
tools: mcp.tools.map((tool) => ({
|
|
@@ -44,6 +46,11 @@ function createListToolsHandler(mcp, options = {}) {
|
|
|
44
46
|
const response = Response.json(body);
|
|
45
47
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
46
48
|
};
|
|
49
|
+
return async (request) => {
|
|
50
|
+
if (request.method === "OPTIONS")
|
|
51
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
52
|
+
return withCors(await handle(request));
|
|
53
|
+
};
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
// src/protocols/rest/invoke-tool.ts
|
|
@@ -63,12 +70,12 @@ function isEmptyArgs(value) {
|
|
|
63
70
|
function createInvokeToolHandler(mcp, options = {}) {
|
|
64
71
|
assertRestResourceBinding(mcp, options);
|
|
65
72
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
66
|
-
|
|
73
|
+
const handle = async (request, toolName) => {
|
|
67
74
|
const authResult = await authorizer.authorize(request);
|
|
68
75
|
if (!authResult.ok)
|
|
69
76
|
return authResult.response;
|
|
70
77
|
if (request.method !== "POST")
|
|
71
|
-
return methodNotAllowed("POST");
|
|
78
|
+
return methodNotAllowed("POST, OPTIONS");
|
|
72
79
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
73
80
|
if (!tool) {
|
|
74
81
|
return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
|
|
@@ -136,6 +143,11 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
136
143
|
isError: result.isError
|
|
137
144
|
});
|
|
138
145
|
};
|
|
146
|
+
return async (request, toolName) => {
|
|
147
|
+
if (request.method === "OPTIONS")
|
|
148
|
+
return corsPreflightResponse("POST, OPTIONS");
|
|
149
|
+
return withCors(await handle(request, toolName));
|
|
150
|
+
};
|
|
139
151
|
}
|
|
140
152
|
|
|
141
153
|
export {
|
|
@@ -359,6 +359,26 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
359
359
|
};
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
+
// src/core/cors.ts
|
|
363
|
+
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
364
|
+
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
365
|
+
function withCors(response) {
|
|
366
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
367
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
368
|
+
return response;
|
|
369
|
+
}
|
|
370
|
+
function corsPreflightResponse(allowMethods) {
|
|
371
|
+
return new Response(null, {
|
|
372
|
+
status: 204,
|
|
373
|
+
headers: {
|
|
374
|
+
"Access-Control-Allow-Origin": "*",
|
|
375
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
376
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
377
|
+
"Access-Control-Max-Age": "86400"
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
}
|
|
381
|
+
|
|
362
382
|
export {
|
|
363
383
|
JSON_HEADERS,
|
|
364
384
|
headResponse,
|
|
@@ -367,5 +387,7 @@ export {
|
|
|
367
387
|
oauthConfigurationErrorResponse,
|
|
368
388
|
getOAuthRuntime,
|
|
369
389
|
assertRestResourceBinding,
|
|
370
|
-
createRequestAuthorizer
|
|
390
|
+
createRequestAuthorizer,
|
|
391
|
+
withCors,
|
|
392
|
+
corsPreflightResponse
|
|
371
393
|
};
|
|
@@ -446,6 +446,26 @@ var ToolContext = class {
|
|
|
446
446
|
}
|
|
447
447
|
};
|
|
448
448
|
|
|
449
|
+
// src/core/cors.ts
|
|
450
|
+
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
451
|
+
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
452
|
+
function withCors(response) {
|
|
453
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
454
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
455
|
+
return response;
|
|
456
|
+
}
|
|
457
|
+
function corsPreflightResponse(allowMethods) {
|
|
458
|
+
return new Response(null, {
|
|
459
|
+
status: 204,
|
|
460
|
+
headers: {
|
|
461
|
+
"Access-Control-Allow-Origin": "*",
|
|
462
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
463
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
464
|
+
"Access-Control-Max-Age": "86400"
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
|
|
449
469
|
// src/protocols/mcp/protocol.ts
|
|
450
470
|
function adaptToolToSdkCallback(tool, auth) {
|
|
451
471
|
return async (first) => {
|
|
@@ -464,7 +484,7 @@ function adaptToolToSdkCallback(tool, auth) {
|
|
|
464
484
|
}
|
|
465
485
|
function createMcpProtocolHandler(mcp, options = {}) {
|
|
466
486
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
467
|
-
|
|
487
|
+
const handle = async (request) => {
|
|
468
488
|
const authResult = await authorizer.authorize(request);
|
|
469
489
|
if (!authResult.ok)
|
|
470
490
|
return authResult.response;
|
|
@@ -498,6 +518,11 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
498
518
|
);
|
|
499
519
|
}
|
|
500
520
|
};
|
|
521
|
+
return async (request) => {
|
|
522
|
+
if (request.method === "OPTIONS")
|
|
523
|
+
return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
|
|
524
|
+
return withCors(await handle(request));
|
|
525
|
+
};
|
|
501
526
|
}
|
|
502
527
|
// Annotate the CommonJS export names for ESM import in node:
|
|
503
528
|
0 && (module.exports = {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpProtocolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-NJ5WBRYI.js";
|
|
4
4
|
import "../../chunk-MA5H6PSF.js";
|
|
5
|
-
import "../../chunk-
|
|
5
|
+
import "../../chunk-ZKKLOL2C.js";
|
|
6
6
|
import "../../chunk-QA3FWDUV.js";
|
|
7
7
|
import "../../chunk-6DXGZZA4.js";
|
|
8
8
|
export {
|
|
@@ -317,20 +317,37 @@ function getOAuthRuntime(mcp, options = {}) {
|
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
319
|
|
|
320
|
-
// src/
|
|
321
|
-
var
|
|
320
|
+
// src/core/cors.ts
|
|
321
|
+
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
322
|
+
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
322
323
|
function withCors(response) {
|
|
323
324
|
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
325
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
324
326
|
return response;
|
|
325
327
|
}
|
|
326
|
-
function
|
|
327
|
-
return new Response(
|
|
328
|
-
status:
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
328
|
+
function corsPreflightResponse(allowMethods) {
|
|
329
|
+
return new Response(null, {
|
|
330
|
+
status: 204,
|
|
331
|
+
headers: {
|
|
332
|
+
"Access-Control-Allow-Origin": "*",
|
|
333
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
334
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
335
|
+
"Access-Control-Max-Age": "86400"
|
|
336
|
+
}
|
|
332
337
|
});
|
|
333
338
|
}
|
|
339
|
+
|
|
340
|
+
// src/protocols/oauth-metadata.ts
|
|
341
|
+
function notFound() {
|
|
342
|
+
return withCors(
|
|
343
|
+
new Response(JSON.stringify({ error: "not found" }), {
|
|
344
|
+
status: 404,
|
|
345
|
+
// `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
|
|
346
|
+
// then served past a later deploy that enables OAuth and starts returning 200.
|
|
347
|
+
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
348
|
+
})
|
|
349
|
+
);
|
|
350
|
+
}
|
|
334
351
|
async function buildProtectedResourceMetadata(mcp, auth, request, options, discovery) {
|
|
335
352
|
const issuer = await discovery.resolveIssuer();
|
|
336
353
|
const body = {
|
|
@@ -354,17 +371,12 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
354
371
|
return async (request) => {
|
|
355
372
|
if (runtime.kind !== "configured" || runtime.auth.protectedResourceMetadataUrl !== void 0)
|
|
356
373
|
return notFound();
|
|
357
|
-
if (request.method === "OPTIONS")
|
|
358
|
-
return
|
|
359
|
-
status: 204,
|
|
360
|
-
headers: { ...CORS_ORIGIN, "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS" }
|
|
361
|
-
});
|
|
362
|
-
}
|
|
374
|
+
if (request.method === "OPTIONS")
|
|
375
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
363
376
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
364
377
|
return withCors(methodNotAllowed("GET, HEAD, OPTIONS"));
|
|
365
378
|
const headers = {
|
|
366
379
|
...JSON_HEADERS,
|
|
367
|
-
...CORS_ORIGIN,
|
|
368
380
|
"Cache-Control": "public, max-age=300",
|
|
369
381
|
Vary: "Host"
|
|
370
382
|
};
|
|
@@ -376,7 +388,7 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
376
388
|
runtime.options,
|
|
377
389
|
runtime.discovery
|
|
378
390
|
);
|
|
379
|
-
const response = Response.json(metadata, { headers });
|
|
391
|
+
const response = withCors(Response.json(metadata, { headers }));
|
|
380
392
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
381
393
|
} catch {
|
|
382
394
|
const response = withCors(oauthConfigurationErrorResponse());
|
|
@@ -421,6 +421,26 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
421
421
|
};
|
|
422
422
|
}
|
|
423
423
|
|
|
424
|
+
// src/core/cors.ts
|
|
425
|
+
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
426
|
+
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
427
|
+
function withCors(response) {
|
|
428
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
429
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
430
|
+
return response;
|
|
431
|
+
}
|
|
432
|
+
function corsPreflightResponse(allowMethods) {
|
|
433
|
+
return new Response(null, {
|
|
434
|
+
status: 204,
|
|
435
|
+
headers: {
|
|
436
|
+
"Access-Control-Allow-Origin": "*",
|
|
437
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
438
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
439
|
+
"Access-Control-Max-Age": "86400"
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
424
444
|
// src/protocols/rest/list-tools.ts
|
|
425
445
|
function shapeToJsonSchema(shape) {
|
|
426
446
|
if (!shape)
|
|
@@ -434,12 +454,12 @@ function shapeToJsonSchema(shape) {
|
|
|
434
454
|
function createListToolsHandler(mcp, options = {}) {
|
|
435
455
|
assertRestResourceBinding(mcp, options);
|
|
436
456
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
437
|
-
|
|
457
|
+
const handle = async (request) => {
|
|
438
458
|
const authResult = await authorizer.authorize(request);
|
|
439
459
|
if (!authResult.ok)
|
|
440
460
|
return authResult.response;
|
|
441
461
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
442
|
-
return methodNotAllowed("GET, HEAD");
|
|
462
|
+
return methodNotAllowed("GET, HEAD, OPTIONS");
|
|
443
463
|
const body = {
|
|
444
464
|
server: { name: mcp.name, version: mcp.version, title: mcp.title },
|
|
445
465
|
tools: mcp.tools.map((tool) => ({
|
|
@@ -454,6 +474,11 @@ function createListToolsHandler(mcp, options = {}) {
|
|
|
454
474
|
const response = Response.json(body);
|
|
455
475
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
456
476
|
};
|
|
477
|
+
return async (request) => {
|
|
478
|
+
if (request.method === "OPTIONS")
|
|
479
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
480
|
+
return withCors(await handle(request));
|
|
481
|
+
};
|
|
457
482
|
}
|
|
458
483
|
|
|
459
484
|
// src/protocols/rest/invoke-tool.ts
|
|
@@ -518,12 +543,12 @@ function isEmptyArgs(value) {
|
|
|
518
543
|
function createInvokeToolHandler(mcp, options = {}) {
|
|
519
544
|
assertRestResourceBinding(mcp, options);
|
|
520
545
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
521
|
-
|
|
546
|
+
const handle = async (request, toolName) => {
|
|
522
547
|
const authResult = await authorizer.authorize(request);
|
|
523
548
|
if (!authResult.ok)
|
|
524
549
|
return authResult.response;
|
|
525
550
|
if (request.method !== "POST")
|
|
526
|
-
return methodNotAllowed("POST");
|
|
551
|
+
return methodNotAllowed("POST, OPTIONS");
|
|
527
552
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
528
553
|
if (!tool) {
|
|
529
554
|
return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
|
|
@@ -591,6 +616,11 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
591
616
|
isError: result.isError
|
|
592
617
|
});
|
|
593
618
|
};
|
|
619
|
+
return async (request, toolName) => {
|
|
620
|
+
if (request.method === "OPTIONS")
|
|
621
|
+
return corsPreflightResponse("POST, OPTIONS");
|
|
622
|
+
return withCors(await handle(request, toolName));
|
|
623
|
+
};
|
|
594
624
|
}
|
|
595
625
|
// Annotate the CommonJS export names for ESM import in node:
|
|
596
626
|
0 && (module.exports = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createInvokeToolHandler,
|
|
3
3
|
createListToolsHandler
|
|
4
|
-
} from "../../chunk-
|
|
4
|
+
} from "../../chunk-SYI32IRK.js";
|
|
5
5
|
import "../../chunk-MA5H6PSF.js";
|
|
6
|
-
import "../../chunk-
|
|
6
|
+
import "../../chunk-ZKKLOL2C.js";
|
|
7
7
|
import "../../chunk-QA3FWDUV.js";
|
|
8
8
|
import "../../chunk-6DXGZZA4.js";
|
|
9
9
|
export {
|
|
@@ -466,6 +466,26 @@ var ToolContext = class {
|
|
|
466
466
|
}
|
|
467
467
|
};
|
|
468
468
|
|
|
469
|
+
// src/core/cors.ts
|
|
470
|
+
var EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
471
|
+
var ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
472
|
+
function withCors(response) {
|
|
473
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
474
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
475
|
+
return response;
|
|
476
|
+
}
|
|
477
|
+
function corsPreflightResponse(allowMethods) {
|
|
478
|
+
return new Response(null, {
|
|
479
|
+
status: 204,
|
|
480
|
+
headers: {
|
|
481
|
+
"Access-Control-Allow-Origin": "*",
|
|
482
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
483
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
484
|
+
"Access-Control-Max-Age": "86400"
|
|
485
|
+
}
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
|
|
469
489
|
// src/protocols/mcp/protocol.ts
|
|
470
490
|
function adaptToolToSdkCallback(tool, auth) {
|
|
471
491
|
return async (first) => {
|
|
@@ -484,7 +504,7 @@ function adaptToolToSdkCallback(tool, auth) {
|
|
|
484
504
|
}
|
|
485
505
|
function createMcpProtocolHandler(mcp, options = {}) {
|
|
486
506
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
487
|
-
|
|
507
|
+
const handle = async (request) => {
|
|
488
508
|
const authResult = await authorizer.authorize(request);
|
|
489
509
|
if (!authResult.ok)
|
|
490
510
|
return authResult.response;
|
|
@@ -518,21 +538,23 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
518
538
|
);
|
|
519
539
|
}
|
|
520
540
|
};
|
|
541
|
+
return async (request) => {
|
|
542
|
+
if (request.method === "OPTIONS")
|
|
543
|
+
return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
|
|
544
|
+
return withCors(await handle(request));
|
|
545
|
+
};
|
|
521
546
|
}
|
|
522
547
|
|
|
523
548
|
// src/protocols/oauth-metadata.ts
|
|
524
|
-
var CORS_ORIGIN = { "Access-Control-Allow-Origin": "*" };
|
|
525
|
-
function withCors(response) {
|
|
526
|
-
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
527
|
-
return response;
|
|
528
|
-
}
|
|
529
549
|
function notFound() {
|
|
530
|
-
return
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
550
|
+
return withCors(
|
|
551
|
+
new Response(JSON.stringify({ error: "not found" }), {
|
|
552
|
+
status: 404,
|
|
553
|
+
// `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
|
|
554
|
+
// then served past a later deploy that enables OAuth and starts returning 200.
|
|
555
|
+
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
556
|
+
})
|
|
557
|
+
);
|
|
536
558
|
}
|
|
537
559
|
async function buildProtectedResourceMetadata(mcp, auth, request, options, discovery) {
|
|
538
560
|
const issuer = await discovery.resolveIssuer();
|
|
@@ -557,17 +579,12 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
557
579
|
return async (request) => {
|
|
558
580
|
if (runtime.kind !== "configured" || runtime.auth.protectedResourceMetadataUrl !== void 0)
|
|
559
581
|
return notFound();
|
|
560
|
-
if (request.method === "OPTIONS")
|
|
561
|
-
return
|
|
562
|
-
status: 204,
|
|
563
|
-
headers: { ...CORS_ORIGIN, "Access-Control-Allow-Methods": "GET, HEAD, OPTIONS" }
|
|
564
|
-
});
|
|
565
|
-
}
|
|
582
|
+
if (request.method === "OPTIONS")
|
|
583
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
566
584
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
567
585
|
return withCors(methodNotAllowed("GET, HEAD, OPTIONS"));
|
|
568
586
|
const headers = {
|
|
569
587
|
...JSON_HEADERS,
|
|
570
|
-
...CORS_ORIGIN,
|
|
571
588
|
"Cache-Control": "public, max-age=300",
|
|
572
589
|
Vary: "Host"
|
|
573
590
|
};
|
|
@@ -579,7 +596,7 @@ function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
|
579
596
|
runtime.options,
|
|
580
597
|
runtime.discovery
|
|
581
598
|
);
|
|
582
|
-
const response = Response.json(metadata, { headers });
|
|
599
|
+
const response = withCors(Response.json(metadata, { headers }));
|
|
583
600
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
584
601
|
} catch {
|
|
585
602
|
const response = withCors(oauthConfigurationErrorResponse());
|
|
@@ -603,12 +620,12 @@ function shapeToJsonSchema(shape) {
|
|
|
603
620
|
function createListToolsHandler(mcp, options = {}) {
|
|
604
621
|
assertRestResourceBinding(mcp, options);
|
|
605
622
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
606
|
-
|
|
623
|
+
const handle = async (request) => {
|
|
607
624
|
const authResult = await authorizer.authorize(request);
|
|
608
625
|
if (!authResult.ok)
|
|
609
626
|
return authResult.response;
|
|
610
627
|
if (request.method !== "GET" && request.method !== "HEAD")
|
|
611
|
-
return methodNotAllowed("GET, HEAD");
|
|
628
|
+
return methodNotAllowed("GET, HEAD, OPTIONS");
|
|
612
629
|
const body = {
|
|
613
630
|
server: { name: mcp.name, version: mcp.version, title: mcp.title },
|
|
614
631
|
tools: mcp.tools.map((tool) => ({
|
|
@@ -623,6 +640,11 @@ function createListToolsHandler(mcp, options = {}) {
|
|
|
623
640
|
const response = Response.json(body);
|
|
624
641
|
return request.method === "HEAD" ? headResponse(response) : response;
|
|
625
642
|
};
|
|
643
|
+
return async (request) => {
|
|
644
|
+
if (request.method === "OPTIONS")
|
|
645
|
+
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
646
|
+
return withCors(await handle(request));
|
|
647
|
+
};
|
|
626
648
|
}
|
|
627
649
|
|
|
628
650
|
// src/protocols/rest/invoke-tool.ts
|
|
@@ -642,12 +664,12 @@ function isEmptyArgs(value) {
|
|
|
642
664
|
function createInvokeToolHandler(mcp, options = {}) {
|
|
643
665
|
assertRestResourceBinding(mcp, options);
|
|
644
666
|
const authorizer = createRequestAuthorizer(mcp, options);
|
|
645
|
-
|
|
667
|
+
const handle = async (request, toolName) => {
|
|
646
668
|
const authResult = await authorizer.authorize(request);
|
|
647
669
|
if (!authResult.ok)
|
|
648
670
|
return authResult.response;
|
|
649
671
|
if (request.method !== "POST")
|
|
650
|
-
return methodNotAllowed("POST");
|
|
672
|
+
return methodNotAllowed("POST, OPTIONS");
|
|
651
673
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
652
674
|
if (!tool) {
|
|
653
675
|
return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
|
|
@@ -715,6 +737,11 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
715
737
|
isError: result.isError
|
|
716
738
|
});
|
|
717
739
|
};
|
|
740
|
+
return async (request, toolName) => {
|
|
741
|
+
if (request.method === "OPTIONS")
|
|
742
|
+
return corsPreflightResponse("POST, OPTIONS");
|
|
743
|
+
return withCors(await handle(request, toolName));
|
|
744
|
+
};
|
|
718
745
|
}
|
|
719
746
|
|
|
720
747
|
// src/stacks/tanstack/handlers.ts
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpProtocolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-NJ5WBRYI.js";
|
|
4
4
|
import {
|
|
5
5
|
createOAuthProtectedResourceMetadataHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-K2T4WTKX.js";
|
|
7
7
|
import {
|
|
8
8
|
createInvokeToolHandler,
|
|
9
9
|
createListToolsHandler
|
|
10
|
-
} from "../../chunk-
|
|
10
|
+
} from "../../chunk-SYI32IRK.js";
|
|
11
11
|
import "../../chunk-MA5H6PSF.js";
|
|
12
|
-
import "../../chunk-
|
|
12
|
+
import "../../chunk-ZKKLOL2C.js";
|
|
13
13
|
import "../../chunk-QA3FWDUV.js";
|
|
14
14
|
import "../../chunk-6DXGZZA4.js";
|
|
15
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovable.dev/mcp-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Author MCP servers for Lovable apps. Declare tools with defineTool, register them in defineMcp, and the framework adapter (TanStack today, Supabase Edge Functions next) emits the route(s) at build time.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|