@lovable.dev/mcp-js 0.21.1-rc.1 → 0.22.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.
Files changed (87) hide show
  1. package/dist/authorize-BMeXd_Sh.d.ts +25 -0
  2. package/dist/base-CM-KCpp6.d.ts +28 -0
  3. package/dist/chunk-4EHZUUS5.js +141 -0
  4. package/dist/chunk-6DXGZZA4.js +6 -0
  5. package/dist/chunk-6KNM7RGD.js +79 -0
  6. package/dist/chunk-6QFZYYUV.js +11 -0
  7. package/dist/chunk-EOFPMSND.js +6 -0
  8. package/dist/chunk-H37EB22A.js +125 -0
  9. package/dist/chunk-MA5H6PSF.js +46 -0
  10. package/dist/chunk-P43FIUMZ.js +114 -0
  11. package/dist/chunk-RK62EMPY.js +741 -0
  12. package/dist/chunk-RLE4UE63.js +58 -0
  13. package/dist/chunk-UQK5UO6C.js +26 -0
  14. package/dist/chunk-XQWJN6DC.js +14 -0
  15. package/dist/chunk-Y3ZFPEQH.js +8 -0
  16. package/dist/cli/extract-manifest.cjs +201 -116
  17. package/dist/cli/extract-manifest.d.cts +1 -1
  18. package/dist/cli/extract-manifest.d.ts +1 -1
  19. package/dist/cli/extract-manifest.js +156 -117
  20. package/dist/index.cjs +329 -129
  21. package/dist/index.d.cts +26 -26
  22. package/dist/index.d.ts +26 -26
  23. package/dist/index.js +177 -118
  24. package/dist/{io-CS4UL6_A.d.ts → io-D4srzRKc.d.ts} +4 -6
  25. package/dist/protocols/mcp/index.cjs +750 -3
  26. package/dist/protocols/mcp/index.d.cts +7 -6
  27. package/dist/protocols/mcp/index.d.ts +7 -6
  28. package/dist/protocols/mcp/index.js +12 -2
  29. package/dist/protocols/oauth-metadata.cjs +539 -48
  30. package/dist/protocols/oauth-metadata.d.cts +6 -5
  31. package/dist/protocols/oauth-metadata.d.ts +6 -5
  32. package/dist/protocols/oauth-metadata.js +10 -52
  33. package/dist/protocols/rest/index.cjs +843 -5
  34. package/dist/protocols/rest/index.d.cts +10 -7
  35. package/dist/protocols/rest/index.d.ts +10 -7
  36. package/dist/protocols/rest/index.js +16 -3
  37. package/dist/stacks/supabase/index.cjs +1318 -76
  38. package/dist/stacks/supabase/index.d.cts +30 -29
  39. package/dist/stacks/supabase/index.d.ts +30 -29
  40. package/dist/stacks/supabase/index.js +89 -73
  41. package/dist/stacks/supabase/vite.cjs +287 -258
  42. package/dist/stacks/supabase/vite.d.cts +24 -24
  43. package/dist/stacks/supabase/vite.d.ts +24 -24
  44. package/dist/stacks/supabase/vite.js +252 -252
  45. package/dist/stacks/tanstack/index.cjs +1272 -42
  46. package/dist/stacks/tanstack/index.d.cts +9 -8
  47. package/dist/stacks/tanstack/index.d.ts +9 -8
  48. package/dist/stacks/tanstack/index.js +41 -36
  49. package/dist/stacks/tanstack/vite.cjs +312 -223
  50. package/dist/stacks/tanstack/vite.d.cts +81 -80
  51. package/dist/stacks/tanstack/vite.d.ts +81 -80
  52. package/dist/stacks/tanstack/vite.js +282 -216
  53. package/dist/types-qqrmJ736.d.ts +321 -0
  54. package/package.json +28 -71
  55. package/dist/authorize-CumVyk7p.d.cts +0 -27
  56. package/dist/authorize-D6p4-9_D.d.ts +0 -27
  57. package/dist/base-CoIFvAmS.d.cts +0 -26
  58. package/dist/base-CoIFvAmS.d.ts +0 -26
  59. package/dist/content-D5LJAHyM.js +0 -12
  60. package/dist/content-NCYIGgOb.cjs +0 -17
  61. package/dist/context-BweeEcoA.cjs +0 -56
  62. package/dist/context-CIpPzN7P.js +0 -51
  63. package/dist/cors-B7CTXIHD.js +0 -829
  64. package/dist/cors-BebjKPrc.cjs +0 -912
  65. package/dist/forwarded--h4efJy-.js +0 -43
  66. package/dist/forwarded-Pi8Hs5Ps.cjs +0 -48
  67. package/dist/fs-errors-CWNzOV75.cjs +0 -11
  68. package/dist/fs-errors-PA2t1TIp.js +0 -6
  69. package/dist/io-CbbUbPY3.d.cts +0 -15
  70. package/dist/list-tools-CBCuS1Tv.cjs +0 -57
  71. package/dist/list-tools-CsWgiRy1.d.ts +0 -8
  72. package/dist/list-tools-CtZHOuPv.d.cts +0 -8
  73. package/dist/list-tools-D75RGtgs.js +0 -46
  74. package/dist/logger-2OXtfiIW.js +0 -141
  75. package/dist/logger-BqPOa_E1.cjs +0 -194
  76. package/dist/mcp-Cdj0AYst.cjs +0 -123
  77. package/dist/mcp-GngXbcqN.js +0 -118
  78. package/dist/metadata-path-CAkNcfyY.js +0 -12
  79. package/dist/metadata-path-zd7NSNoa.cjs +0 -17
  80. package/dist/package-7EUptuSJ.js +0 -4
  81. package/dist/package-BwCGVRcB.cjs +0 -9
  82. package/dist/paths-IS65L6TA.js +0 -7
  83. package/dist/paths-OP318a6c.cjs +0 -18
  84. package/dist/rest-CXH6-zv9.js +0 -113
  85. package/dist/rest-CyV8LHeB.cjs +0 -118
  86. package/dist/types-BYdYYTjk.d.cts +0 -321
  87. package/dist/types-BYdYYTjk.d.ts +0 -321
@@ -1,123 +0,0 @@
1
- const require_logger = require("./logger-BqPOa_E1.cjs");
2
- const require_context = require("./context-BweeEcoA.cjs");
3
- const require_cors = require("./cors-BebjKPrc.cjs");
4
- const require_content = require("./content-NCYIGgOb.cjs");
5
- let _modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
6
- let _modelcontextprotocol_sdk_server_webStandardStreamableHttp_js = require("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
7
- //#region src/protocols/mcp/protocol.ts
8
- /**
9
- * Adapt a Lovable tool to the SDK's tool callback. The boundary cast bridges
10
- * our SDK-decoupled content-block types to the SDK's; they match structurally.
11
- */
12
- function adaptToolToSdkCallback(tool, auth, recorder) {
13
- return (async (first) => {
14
- const args = tool.inputSchema ? first ?? {} : {};
15
- const start = require_cors.nowMs();
16
- let result;
17
- try {
18
- result = await tool.handler(args, new require_context.ToolContext(auth));
19
- } catch {
20
- await recorder.emit({
21
- tool: tool.name,
22
- method: "tools/call",
23
- outcome: "handler_error",
24
- durationMs: require_cors.nowMs() - start
25
- });
26
- return {
27
- content: [{
28
- type: "text",
29
- text: "tool execution failed"
30
- }],
31
- isError: true
32
- };
33
- }
34
- if (result == null) {
35
- await recorder.emit({
36
- tool: tool.name,
37
- method: "tools/call",
38
- outcome: "handler_error",
39
- durationMs: require_cors.nowMs() - start
40
- });
41
- return {
42
- content: [{
43
- type: "text",
44
- text: `tool "${tool.name}" returned no result`
45
- }],
46
- isError: true
47
- };
48
- }
49
- await recorder.emit({
50
- tool: tool.name,
51
- method: "tools/call",
52
- outcome: result.isError ? "tool_error" : "ok",
53
- durationMs: require_cors.nowMs() - start,
54
- errorText: result.isError ? require_content.extractTextContent(result.content) : void 0
55
- });
56
- return {
57
- content: result.content ?? [],
58
- structuredContent: result.structuredContent,
59
- isError: result.isError
60
- };
61
- });
62
- }
63
- /**
64
- * Build a Web-Standard request handler that serves the MCP protocol over
65
- * streamable HTTP. A fresh `McpServer` + transport is constructed per
66
- * request — the transport is stateless, so this is cheap and there is no
67
- * cross-request state to leak. The per-request `recorder` is supplied by the
68
- * caller (the stack handler) so telemetry reads the runtime env in-flight.
69
- */
70
- function createMcpProtocolHandler(mcp, options = {}) {
71
- const authorizer = require_cors.createRequestAuthorizer(mcp, options);
72
- const handle = async (request, recorder) => {
73
- const authResult = await authorizer.authorize(request, recorder);
74
- if (!authResult.ok) return authResult.response;
75
- try {
76
- const server = new _modelcontextprotocol_sdk_server_mcp_js.McpServer({
77
- name: mcp.name,
78
- version: mcp.version,
79
- title: mcp.title
80
- }, { instructions: mcp.instructions });
81
- for (const tool of mcp.tools) server.registerTool(tool.name, {
82
- title: tool.title,
83
- description: tool.description,
84
- inputSchema: tool.inputSchema,
85
- outputSchema: tool.outputSchema,
86
- annotations: tool.annotations
87
- }, adaptToolToSdkCallback(tool, authResult.auth, recorder));
88
- const transport = new _modelcontextprotocol_sdk_server_webStandardStreamableHttp_js.WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
89
- await server.connect(transport);
90
- return await transport.handleRequest(request);
91
- } catch (err) {
92
- await recorder.emit({
93
- tool: null,
94
- method: "transport",
95
- outcome: "transport_error",
96
- durationMs: 0
97
- });
98
- require_logger.log.error("mcp.transport_error", {
99
- ...require_logger.describeError(err),
100
- outcome: "500 internal error"
101
- });
102
- return Response.json({
103
- jsonrpc: "2.0",
104
- id: null,
105
- error: {
106
- code: -32603,
107
- message: "internal error"
108
- }
109
- }, { status: 500 });
110
- }
111
- };
112
- return async (request, recorder = require_cors.createNoopRecorder()) => {
113
- if (request.method === "OPTIONS") return require_cors.corsPreflightResponse("GET, POST, DELETE, OPTIONS");
114
- return require_cors.withCors(await handle(request, recorder));
115
- };
116
- }
117
- //#endregion
118
- Object.defineProperty(exports, "createMcpProtocolHandler", {
119
- enumerable: true,
120
- get: function() {
121
- return createMcpProtocolHandler;
122
- }
123
- });
@@ -1,118 +0,0 @@
1
- import { i as log, r as describeError } from "./logger-2OXtfiIW.js";
2
- import { t as ToolContext } from "./context-CIpPzN7P.js";
3
- import { d as nowMs, i as createRequestAuthorizer, n as withCors, t as corsPreflightResponse, u as createNoopRecorder } from "./cors-B7CTXIHD.js";
4
- import { t as extractTextContent } from "./content-D5LJAHyM.js";
5
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
- import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
7
- //#region src/protocols/mcp/protocol.ts
8
- /**
9
- * Adapt a Lovable tool to the SDK's tool callback. The boundary cast bridges
10
- * our SDK-decoupled content-block types to the SDK's; they match structurally.
11
- */
12
- function adaptToolToSdkCallback(tool, auth, recorder) {
13
- return (async (first) => {
14
- const args = tool.inputSchema ? first ?? {} : {};
15
- const start = nowMs();
16
- let result;
17
- try {
18
- result = await tool.handler(args, new ToolContext(auth));
19
- } catch {
20
- await recorder.emit({
21
- tool: tool.name,
22
- method: "tools/call",
23
- outcome: "handler_error",
24
- durationMs: nowMs() - start
25
- });
26
- return {
27
- content: [{
28
- type: "text",
29
- text: "tool execution failed"
30
- }],
31
- isError: true
32
- };
33
- }
34
- if (result == null) {
35
- await recorder.emit({
36
- tool: tool.name,
37
- method: "tools/call",
38
- outcome: "handler_error",
39
- durationMs: nowMs() - start
40
- });
41
- return {
42
- content: [{
43
- type: "text",
44
- text: `tool "${tool.name}" returned no result`
45
- }],
46
- isError: true
47
- };
48
- }
49
- await recorder.emit({
50
- tool: tool.name,
51
- method: "tools/call",
52
- outcome: result.isError ? "tool_error" : "ok",
53
- durationMs: nowMs() - start,
54
- errorText: result.isError ? extractTextContent(result.content) : void 0
55
- });
56
- return {
57
- content: result.content ?? [],
58
- structuredContent: result.structuredContent,
59
- isError: result.isError
60
- };
61
- });
62
- }
63
- /**
64
- * Build a Web-Standard request handler that serves the MCP protocol over
65
- * streamable HTTP. A fresh `McpServer` + transport is constructed per
66
- * request — the transport is stateless, so this is cheap and there is no
67
- * cross-request state to leak. The per-request `recorder` is supplied by the
68
- * caller (the stack handler) so telemetry reads the runtime env in-flight.
69
- */
70
- function createMcpProtocolHandler(mcp, options = {}) {
71
- const authorizer = createRequestAuthorizer(mcp, options);
72
- const handle = async (request, recorder) => {
73
- const authResult = await authorizer.authorize(request, recorder);
74
- if (!authResult.ok) return authResult.response;
75
- try {
76
- const server = new McpServer({
77
- name: mcp.name,
78
- version: mcp.version,
79
- title: mcp.title
80
- }, { instructions: mcp.instructions });
81
- for (const tool of mcp.tools) server.registerTool(tool.name, {
82
- title: tool.title,
83
- description: tool.description,
84
- inputSchema: tool.inputSchema,
85
- outputSchema: tool.outputSchema,
86
- annotations: tool.annotations
87
- }, adaptToolToSdkCallback(tool, authResult.auth, recorder));
88
- const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
89
- await server.connect(transport);
90
- return await transport.handleRequest(request);
91
- } catch (err) {
92
- await recorder.emit({
93
- tool: null,
94
- method: "transport",
95
- outcome: "transport_error",
96
- durationMs: 0
97
- });
98
- log.error("mcp.transport_error", {
99
- ...describeError(err),
100
- outcome: "500 internal error"
101
- });
102
- return Response.json({
103
- jsonrpc: "2.0",
104
- id: null,
105
- error: {
106
- code: -32603,
107
- message: "internal error"
108
- }
109
- }, { status: 500 });
110
- }
111
- };
112
- return async (request, recorder = createNoopRecorder()) => {
113
- if (request.method === "OPTIONS") return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
114
- return withCors(await handle(request, recorder));
115
- };
116
- }
117
- //#endregion
118
- export { createMcpProtocolHandler as t };
@@ -1,12 +0,0 @@
1
- //#region src/auth/metadata-path.ts
2
- /**
3
- * Default RFC 9728 protected-resource metadata path. Used by the runtime 401
4
- * challenge (`authorize.ts`, which advertises this URL via the
5
- * `WWW-Authenticate: resource_metadata` param) and the Vite plugin (which emits
6
- * the route that serves it) when no `metadataPath` is configured. A configured
7
- * `metadataPath` overrides it; the plugin injects that same path into every
8
- * emitted handler, so the advertised URL and the served route still can't drift.
9
- */
10
- const OAUTH_PROTECTED_RESOURCE_METADATA_PATH = "/.well-known/oauth-protected-resource";
11
- //#endregion
12
- export { OAUTH_PROTECTED_RESOURCE_METADATA_PATH as t };
@@ -1,17 +0,0 @@
1
- //#region src/auth/metadata-path.ts
2
- /**
3
- * Default RFC 9728 protected-resource metadata path. Used by the runtime 401
4
- * challenge (`authorize.ts`, which advertises this URL via the
5
- * `WWW-Authenticate: resource_metadata` param) and the Vite plugin (which emits
6
- * the route that serves it) when no `metadataPath` is configured. A configured
7
- * `metadataPath` overrides it; the plugin injects that same path into every
8
- * emitted handler, so the advertised URL and the served route still can't drift.
9
- */
10
- const OAUTH_PROTECTED_RESOURCE_METADATA_PATH = "/.well-known/oauth-protected-resource";
11
- //#endregion
12
- Object.defineProperty(exports, "OAUTH_PROTECTED_RESOURCE_METADATA_PATH", {
13
- enumerable: true,
14
- get: function() {
15
- return OAUTH_PROTECTED_RESOURCE_METADATA_PATH;
16
- }
17
- });
@@ -1,4 +0,0 @@
1
- //#region package.json
2
- var version = "0.21.1-rc.1";
3
- //#endregion
4
- export { version as t };
@@ -1,9 +0,0 @@
1
- //#region package.json
2
- var version = "0.21.1-rc.1";
3
- //#endregion
4
- Object.defineProperty(exports, "version", {
5
- enumerable: true,
6
- get: function() {
7
- return version;
8
- }
9
- });
@@ -1,7 +0,0 @@
1
- //#region src/stacks/supabase/paths.ts
2
- const FUNCTIONS_MOUNT_PREFIX = "/functions/v1/";
3
- function assertFunctionName(value, label = "functionName") {
4
- if (!/^[a-zA-Z0-9_-]+$/.test(value)) throw new Error(`@lovable.dev/mcp-js: ${label} must be a single path segment matching [A-Za-z0-9_-], got ${JSON.stringify(value)}`);
5
- }
6
- //#endregion
7
- export { assertFunctionName as n, FUNCTIONS_MOUNT_PREFIX as t };
@@ -1,18 +0,0 @@
1
- //#region src/stacks/supabase/paths.ts
2
- const FUNCTIONS_MOUNT_PREFIX = "/functions/v1/";
3
- function assertFunctionName(value, label = "functionName") {
4
- if (!/^[a-zA-Z0-9_-]+$/.test(value)) throw new Error(`@lovable.dev/mcp-js: ${label} must be a single path segment matching [A-Za-z0-9_-], got ${JSON.stringify(value)}`);
5
- }
6
- //#endregion
7
- Object.defineProperty(exports, "FUNCTIONS_MOUNT_PREFIX", {
8
- enumerable: true,
9
- get: function() {
10
- return FUNCTIONS_MOUNT_PREFIX;
11
- }
12
- });
13
- Object.defineProperty(exports, "assertFunctionName", {
14
- enumerable: true,
15
- get: function() {
16
- return assertFunctionName;
17
- }
18
- });
@@ -1,113 +0,0 @@
1
- import { t as ToolContext } from "./context-CIpPzN7P.js";
2
- import { d as nowMs, f as JSON_HEADERS, i as createRequestAuthorizer, m as methodNotAllowed, n as withCors, r as assertRestResourceBinding, t as corsPreflightResponse, u as createNoopRecorder } from "./cors-B7CTXIHD.js";
3
- import { t as extractTextContent } from "./content-D5LJAHyM.js";
4
- import "./list-tools-D75RGtgs.js";
5
- import { getParseErrorMessage, objectFromShape, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
6
- //#region src/protocols/rest/invoke-tool.ts
7
- const MAX_REFLECTED_TOOL_NAME = 256;
8
- function safeReflectName(name) {
9
- const text = String(name);
10
- return text.length > MAX_REFLECTED_TOOL_NAME ? `${text.slice(0, MAX_REFLECTED_TOOL_NAME)}…` : text;
11
- }
12
- function isEmptyArgs(value) {
13
- if (value == null) return true;
14
- if (typeof value !== "object" || Array.isArray(value)) return false;
15
- return Object.keys(value).length === 0;
16
- }
17
- function createInvokeToolHandler(mcp, options = {}) {
18
- assertRestResourceBinding(mcp, options);
19
- const authorizer = createRequestAuthorizer(mcp, options);
20
- const handle = async (request, toolName, recorder) => {
21
- const authResult = await authorizer.authorize(request, recorder);
22
- if (!authResult.ok) return authResult.response;
23
- if (request.method !== "POST") return methodNotAllowed("POST, OPTIONS");
24
- const tool = mcp.tools.find((t) => t.name === toolName);
25
- if (!tool) return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
26
- status: 404,
27
- headers: JSON_HEADERS
28
- });
29
- let rawArgs = {};
30
- const text = await request.text();
31
- if (text) try {
32
- rawArgs = JSON.parse(text);
33
- } catch {
34
- return new Response(JSON.stringify({ error: "invalid JSON body" }), {
35
- status: 400,
36
- headers: JSON_HEADERS
37
- });
38
- }
39
- let args = rawArgs;
40
- if (tool.inputSchema) try {
41
- const parsed = await safeParseAsync(objectFromShape(tool.inputSchema), rawArgs);
42
- if (!parsed.success) return new Response(JSON.stringify({
43
- error: "validation failed",
44
- details: getParseErrorMessage(parsed.error)
45
- }), {
46
- status: 400,
47
- headers: JSON_HEADERS
48
- });
49
- args = parsed.data;
50
- } catch {
51
- return new Response(JSON.stringify({
52
- error: "schema error",
53
- tool: toolName
54
- }), {
55
- status: 500,
56
- headers: JSON_HEADERS
57
- });
58
- }
59
- else if (!isEmptyArgs(rawArgs)) return new Response(JSON.stringify({ error: "tool has no inputSchema; expected empty body" }), {
60
- status: 400,
61
- headers: JSON_HEADERS
62
- });
63
- let result;
64
- const start = nowMs();
65
- try {
66
- result = await tool.handler(args, new ToolContext(authResult.auth));
67
- } catch {
68
- await recorder.emit({
69
- tool: tool.name,
70
- method: "tools/call",
71
- outcome: "handler_error",
72
- durationMs: nowMs() - start
73
- });
74
- return new Response(JSON.stringify({
75
- error: "handler threw",
76
- tool: toolName
77
- }), {
78
- status: 500,
79
- headers: JSON_HEADERS
80
- });
81
- }
82
- if (result == null) {
83
- await recorder.emit({
84
- tool: tool.name,
85
- method: "tools/call",
86
- outcome: "handler_error",
87
- durationMs: nowMs() - start
88
- });
89
- return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
90
- status: 500,
91
- headers: JSON_HEADERS
92
- });
93
- }
94
- await recorder.emit({
95
- tool: tool.name,
96
- method: "tools/call",
97
- outcome: result.isError ? "tool_error" : "ok",
98
- durationMs: nowMs() - start,
99
- errorText: result.isError ? extractTextContent(result.content) : void 0
100
- });
101
- return Response.json({
102
- content: result.content ?? [],
103
- structuredContent: result.structuredContent,
104
- isError: result.isError
105
- });
106
- };
107
- return async (request, toolName, recorder = createNoopRecorder()) => {
108
- if (request.method === "OPTIONS") return corsPreflightResponse("POST, OPTIONS");
109
- return withCors(await handle(request, toolName, recorder));
110
- };
111
- }
112
- //#endregion
113
- export { createInvokeToolHandler as t };
@@ -1,118 +0,0 @@
1
- const require_context = require("./context-BweeEcoA.cjs");
2
- const require_cors = require("./cors-BebjKPrc.cjs");
3
- const require_content = require("./content-NCYIGgOb.cjs");
4
- require("./list-tools-CBCuS1Tv.cjs");
5
- let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
6
- //#region src/protocols/rest/invoke-tool.ts
7
- const MAX_REFLECTED_TOOL_NAME = 256;
8
- function safeReflectName(name) {
9
- const text = String(name);
10
- return text.length > MAX_REFLECTED_TOOL_NAME ? `${text.slice(0, MAX_REFLECTED_TOOL_NAME)}…` : text;
11
- }
12
- function isEmptyArgs(value) {
13
- if (value == null) return true;
14
- if (typeof value !== "object" || Array.isArray(value)) return false;
15
- return Object.keys(value).length === 0;
16
- }
17
- function createInvokeToolHandler(mcp, options = {}) {
18
- require_cors.assertRestResourceBinding(mcp, options);
19
- const authorizer = require_cors.createRequestAuthorizer(mcp, options);
20
- const handle = async (request, toolName, recorder) => {
21
- const authResult = await authorizer.authorize(request, recorder);
22
- if (!authResult.ok) return authResult.response;
23
- if (request.method !== "POST") return require_cors.methodNotAllowed("POST, OPTIONS");
24
- const tool = mcp.tools.find((t) => t.name === toolName);
25
- if (!tool) return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
26
- status: 404,
27
- headers: require_cors.JSON_HEADERS
28
- });
29
- let rawArgs = {};
30
- const text = await request.text();
31
- if (text) try {
32
- rawArgs = JSON.parse(text);
33
- } catch {
34
- return new Response(JSON.stringify({ error: "invalid JSON body" }), {
35
- status: 400,
36
- headers: require_cors.JSON_HEADERS
37
- });
38
- }
39
- let args = rawArgs;
40
- if (tool.inputSchema) try {
41
- const parsed = await (0, _modelcontextprotocol_sdk_server_zod_compat_js.safeParseAsync)((0, _modelcontextprotocol_sdk_server_zod_compat_js.objectFromShape)(tool.inputSchema), rawArgs);
42
- if (!parsed.success) return new Response(JSON.stringify({
43
- error: "validation failed",
44
- details: (0, _modelcontextprotocol_sdk_server_zod_compat_js.getParseErrorMessage)(parsed.error)
45
- }), {
46
- status: 400,
47
- headers: require_cors.JSON_HEADERS
48
- });
49
- args = parsed.data;
50
- } catch {
51
- return new Response(JSON.stringify({
52
- error: "schema error",
53
- tool: toolName
54
- }), {
55
- status: 500,
56
- headers: require_cors.JSON_HEADERS
57
- });
58
- }
59
- else if (!isEmptyArgs(rawArgs)) return new Response(JSON.stringify({ error: "tool has no inputSchema; expected empty body" }), {
60
- status: 400,
61
- headers: require_cors.JSON_HEADERS
62
- });
63
- let result;
64
- const start = require_cors.nowMs();
65
- try {
66
- result = await tool.handler(args, new require_context.ToolContext(authResult.auth));
67
- } catch {
68
- await recorder.emit({
69
- tool: tool.name,
70
- method: "tools/call",
71
- outcome: "handler_error",
72
- durationMs: require_cors.nowMs() - start
73
- });
74
- return new Response(JSON.stringify({
75
- error: "handler threw",
76
- tool: toolName
77
- }), {
78
- status: 500,
79
- headers: require_cors.JSON_HEADERS
80
- });
81
- }
82
- if (result == null) {
83
- await recorder.emit({
84
- tool: tool.name,
85
- method: "tools/call",
86
- outcome: "handler_error",
87
- durationMs: require_cors.nowMs() - start
88
- });
89
- return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
90
- status: 500,
91
- headers: require_cors.JSON_HEADERS
92
- });
93
- }
94
- await recorder.emit({
95
- tool: tool.name,
96
- method: "tools/call",
97
- outcome: result.isError ? "tool_error" : "ok",
98
- durationMs: require_cors.nowMs() - start,
99
- errorText: result.isError ? require_content.extractTextContent(result.content) : void 0
100
- });
101
- return Response.json({
102
- content: result.content ?? [],
103
- structuredContent: result.structuredContent,
104
- isError: result.isError
105
- });
106
- };
107
- return async (request, toolName, recorder = require_cors.createNoopRecorder()) => {
108
- if (request.method === "OPTIONS") return require_cors.corsPreflightResponse("POST, OPTIONS");
109
- return require_cors.withCors(await handle(request, toolName, recorder));
110
- };
111
- }
112
- //#endregion
113
- Object.defineProperty(exports, "createInvokeToolHandler", {
114
- enumerable: true,
115
- get: function() {
116
- return createInvokeToolHandler;
117
- }
118
- });