@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.
- package/dist/authorize-BMeXd_Sh.d.ts +25 -0
- package/dist/base-CM-KCpp6.d.ts +28 -0
- package/dist/chunk-4EHZUUS5.js +141 -0
- package/dist/chunk-6DXGZZA4.js +6 -0
- package/dist/chunk-6KNM7RGD.js +79 -0
- package/dist/chunk-6QFZYYUV.js +11 -0
- package/dist/chunk-EOFPMSND.js +6 -0
- package/dist/chunk-H37EB22A.js +125 -0
- package/dist/chunk-MA5H6PSF.js +46 -0
- package/dist/chunk-P43FIUMZ.js +114 -0
- package/dist/chunk-RK62EMPY.js +741 -0
- package/dist/chunk-RLE4UE63.js +58 -0
- package/dist/chunk-UQK5UO6C.js +26 -0
- package/dist/chunk-XQWJN6DC.js +14 -0
- package/dist/chunk-Y3ZFPEQH.js +8 -0
- package/dist/cli/extract-manifest.cjs +201 -116
- package/dist/cli/extract-manifest.d.cts +1 -1
- package/dist/cli/extract-manifest.d.ts +1 -1
- package/dist/cli/extract-manifest.js +156 -117
- package/dist/index.cjs +329 -129
- package/dist/index.d.cts +26 -26
- package/dist/index.d.ts +26 -26
- package/dist/index.js +177 -118
- package/dist/{io-CS4UL6_A.d.ts → io-D4srzRKc.d.ts} +4 -6
- package/dist/protocols/mcp/index.cjs +750 -3
- package/dist/protocols/mcp/index.d.cts +7 -6
- package/dist/protocols/mcp/index.d.ts +7 -6
- package/dist/protocols/mcp/index.js +12 -2
- package/dist/protocols/oauth-metadata.cjs +539 -48
- package/dist/protocols/oauth-metadata.d.cts +6 -5
- package/dist/protocols/oauth-metadata.d.ts +6 -5
- package/dist/protocols/oauth-metadata.js +10 -52
- package/dist/protocols/rest/index.cjs +843 -5
- package/dist/protocols/rest/index.d.cts +10 -7
- package/dist/protocols/rest/index.d.ts +10 -7
- package/dist/protocols/rest/index.js +16 -3
- package/dist/stacks/supabase/index.cjs +1318 -76
- package/dist/stacks/supabase/index.d.cts +30 -29
- package/dist/stacks/supabase/index.d.ts +30 -29
- package/dist/stacks/supabase/index.js +89 -73
- package/dist/stacks/supabase/vite.cjs +287 -258
- package/dist/stacks/supabase/vite.d.cts +24 -24
- package/dist/stacks/supabase/vite.d.ts +24 -24
- package/dist/stacks/supabase/vite.js +252 -252
- package/dist/stacks/tanstack/index.cjs +1272 -42
- package/dist/stacks/tanstack/index.d.cts +9 -8
- package/dist/stacks/tanstack/index.d.ts +9 -8
- package/dist/stacks/tanstack/index.js +41 -36
- package/dist/stacks/tanstack/vite.cjs +312 -223
- package/dist/stacks/tanstack/vite.d.cts +81 -80
- package/dist/stacks/tanstack/vite.d.ts +81 -80
- package/dist/stacks/tanstack/vite.js +282 -216
- package/dist/types-qqrmJ736.d.ts +321 -0
- package/package.json +28 -71
- package/dist/authorize-CumVyk7p.d.cts +0 -27
- package/dist/authorize-D6p4-9_D.d.ts +0 -27
- package/dist/base-CoIFvAmS.d.cts +0 -26
- package/dist/base-CoIFvAmS.d.ts +0 -26
- package/dist/content-D5LJAHyM.js +0 -12
- package/dist/content-NCYIGgOb.cjs +0 -17
- package/dist/context-BweeEcoA.cjs +0 -56
- package/dist/context-CIpPzN7P.js +0 -51
- package/dist/cors-B7CTXIHD.js +0 -829
- package/dist/cors-BebjKPrc.cjs +0 -912
- package/dist/forwarded--h4efJy-.js +0 -43
- package/dist/forwarded-Pi8Hs5Ps.cjs +0 -48
- package/dist/fs-errors-CWNzOV75.cjs +0 -11
- package/dist/fs-errors-PA2t1TIp.js +0 -6
- package/dist/io-CbbUbPY3.d.cts +0 -15
- package/dist/list-tools-CBCuS1Tv.cjs +0 -57
- package/dist/list-tools-CsWgiRy1.d.ts +0 -8
- package/dist/list-tools-CtZHOuPv.d.cts +0 -8
- package/dist/list-tools-D75RGtgs.js +0 -46
- package/dist/logger-2OXtfiIW.js +0 -141
- package/dist/logger-BqPOa_E1.cjs +0 -194
- package/dist/mcp-Cdj0AYst.cjs +0 -123
- package/dist/mcp-GngXbcqN.js +0 -118
- package/dist/metadata-path-CAkNcfyY.js +0 -12
- package/dist/metadata-path-zd7NSNoa.cjs +0 -17
- package/dist/package-7EUptuSJ.js +0 -4
- package/dist/package-BwCGVRcB.cjs +0 -9
- package/dist/paths-IS65L6TA.js +0 -7
- package/dist/paths-OP318a6c.cjs +0 -18
- package/dist/rest-CXH6-zv9.js +0 -113
- package/dist/rest-CyV8LHeB.cjs +0 -118
- package/dist/types-BYdYYTjk.d.cts +0 -321
- package/dist/types-BYdYYTjk.d.ts +0 -321
package/dist/mcp-Cdj0AYst.cjs
DELETED
|
@@ -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
|
-
});
|
package/dist/mcp-GngXbcqN.js
DELETED
|
@@ -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
|
-
});
|
package/dist/package-7EUptuSJ.js
DELETED
package/dist/paths-IS65L6TA.js
DELETED
|
@@ -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 };
|
package/dist/paths-OP318a6c.cjs
DELETED
|
@@ -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
|
-
});
|
package/dist/rest-CXH6-zv9.js
DELETED
|
@@ -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 };
|
package/dist/rest-CyV8LHeB.cjs
DELETED
|
@@ -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
|
-
});
|