@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.
@@ -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
- } from "./chunk-XEDRJFAR.js";
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 new Response(JSON.stringify({ error: "not found" }), {
18
- status: 404,
19
- // `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
20
- // then served past a later deploy that enables OAuth and starts returning 200.
21
- headers: { ...JSON_HEADERS, ...CORS_ORIGIN, "Cache-Control": "no-store" }
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 new Response(null, {
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
- createRequestAuthorizer
6
- } from "./chunk-XEDRJFAR.js";
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
- return async (request) => {
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
- } from "./chunk-XEDRJFAR.js";
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
- return async (request) => {
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
- return async (request, toolName) => {
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
- return async (request) => {
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-GLG5RZGE.js";
3
+ } from "../../chunk-NJ5WBRYI.js";
4
4
  import "../../chunk-MA5H6PSF.js";
5
- import "../../chunk-XEDRJFAR.js";
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/protocols/oauth-metadata.ts
321
- var CORS_ORIGIN = { "Access-Control-Allow-Origin": "*" };
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 notFound() {
327
- return new Response(JSON.stringify({ error: "not found" }), {
328
- status: 404,
329
- // `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
330
- // then served past a later deploy that enables OAuth and starts returning 200.
331
- headers: { ...JSON_HEADERS, ...CORS_ORIGIN, "Cache-Control": "no-store" }
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 new Response(null, {
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());
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createOAuthProtectedResourceMetadataHandler
3
- } from "../chunk-DDF63QWG.js";
4
- import "../chunk-XEDRJFAR.js";
3
+ } from "../chunk-K2T4WTKX.js";
4
+ import "../chunk-ZKKLOL2C.js";
5
5
  import "../chunk-QA3FWDUV.js";
6
6
  import "../chunk-6DXGZZA4.js";
7
7
  export {
@@ -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
- return async (request) => {
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
- return async (request, toolName) => {
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-VD6CS7Y6.js";
4
+ } from "../../chunk-SYI32IRK.js";
5
5
  import "../../chunk-MA5H6PSF.js";
6
- import "../../chunk-XEDRJFAR.js";
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
- return async (request) => {
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 new Response(JSON.stringify({ error: "not found" }), {
531
- status: 404,
532
- // `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
533
- // then served past a later deploy that enables OAuth and starts returning 200.
534
- headers: { ...JSON_HEADERS, ...CORS_ORIGIN, "Cache-Control": "no-store" }
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 new Response(null, {
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
- return async (request) => {
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
- return async (request, toolName) => {
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-GLG5RZGE.js";
3
+ } from "../../chunk-NJ5WBRYI.js";
4
4
  import {
5
5
  createOAuthProtectedResourceMetadataHandler
6
- } from "../../chunk-DDF63QWG.js";
6
+ } from "../../chunk-K2T4WTKX.js";
7
7
  import {
8
8
  createInvokeToolHandler,
9
9
  createListToolsHandler
10
- } from "../../chunk-VD6CS7Y6.js";
10
+ } from "../../chunk-SYI32IRK.js";
11
11
  import "../../chunk-MA5H6PSF.js";
12
- import "../../chunk-XEDRJFAR.js";
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.5.1",
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": {