@lovable.dev/mcp-js 0.21.0-rc.4 → 0.21.1-rc.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/{base-CFy5vZ5Z.d.ts → base-CM-KCpp6.d.ts} +3 -0
- package/dist/{chunk-FBR7D3XV.js → chunk-4QNNVJBZ.js} +8 -4
- package/dist/{chunk-PML3SKRA.js → chunk-ACFNK34P.js} +15 -5
- package/dist/{chunk-XPYU4DI6.js → chunk-BLY5L4KI.js} +1 -1
- package/dist/{chunk-2PJKJI76.js → chunk-L5ZOZKAL.js} +1 -1
- package/dist/{chunk-Q22Z6G6N.js → chunk-SJJDRA6X.js} +3 -1
- package/dist/{chunk-7G743K3G.js → chunk-ZLWXDYOZ.js} +1 -1
- package/dist/cli/extract-manifest.cjs +1 -1
- package/dist/cli/extract-manifest.js +3 -3
- package/dist/protocols/mcp/index.cjs +14 -4
- package/dist/protocols/mcp/index.d.cts +1 -1
- package/dist/protocols/mcp/index.d.ts +1 -1
- package/dist/protocols/mcp/index.js +3 -3
- package/dist/protocols/oauth-metadata.js +3 -3
- package/dist/protocols/rest/index.cjs +7 -3
- package/dist/protocols/rest/index.d.cts +1 -1
- package/dist/protocols/rest/index.d.ts +1 -1
- package/dist/protocols/rest/index.js +4 -4
- package/dist/stacks/supabase/index.cjs +24 -8
- package/dist/stacks/supabase/index.js +6 -6
- package/dist/stacks/supabase/vite.cjs +1 -1
- package/dist/stacks/supabase/vite.js +1 -1
- package/dist/stacks/tanstack/index.cjs +24 -8
- package/dist/stacks/tanstack/index.js +6 -6
- package/package.json +1 -1
|
@@ -12,6 +12,9 @@ interface InvocationRecord {
|
|
|
12
12
|
durationMs: number;
|
|
13
13
|
reqBytes?: number;
|
|
14
14
|
resBytes?: number;
|
|
15
|
+
/** The app end-user that made the call (the access token `sub`), or
|
|
16
|
+
* `undefined` when the request is unauthenticated. Not a Lovable identity. */
|
|
17
|
+
endUserId?: string;
|
|
15
18
|
/** The `tool_error` message (text content of an `isError` result). Local log
|
|
16
19
|
* only — never sent to the collector, so it stays on-box for the operator. */
|
|
17
20
|
errorText?: string;
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
methodNotAllowed,
|
|
14
14
|
nowMs,
|
|
15
15
|
withCors
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SJJDRA6X.js";
|
|
17
17
|
|
|
18
18
|
// src/protocols/rest/invoke-tool.ts
|
|
19
19
|
import { getParseErrorMessage, objectFromShape, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
@@ -36,6 +36,7 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
36
36
|
const authResult = await authorizer.authorize(request, recorder);
|
|
37
37
|
if (!authResult.ok)
|
|
38
38
|
return authResult.response;
|
|
39
|
+
const endUserId = authResult.auth?.principal.sub;
|
|
39
40
|
if (request.method !== "POST")
|
|
40
41
|
return methodNotAllowed("POST, OPTIONS");
|
|
41
42
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
@@ -93,7 +94,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
93
94
|
tool: tool.name,
|
|
94
95
|
method: "tools/call",
|
|
95
96
|
outcome: "handler_error",
|
|
96
|
-
durationMs: nowMs() - start
|
|
97
|
+
durationMs: nowMs() - start,
|
|
98
|
+
endUserId
|
|
97
99
|
});
|
|
98
100
|
return new Response(JSON.stringify({ error: "handler threw", tool: toolName }), {
|
|
99
101
|
status: 500,
|
|
@@ -105,7 +107,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
105
107
|
tool: tool.name,
|
|
106
108
|
method: "tools/call",
|
|
107
109
|
outcome: "handler_error",
|
|
108
|
-
durationMs: nowMs() - start
|
|
110
|
+
durationMs: nowMs() - start,
|
|
111
|
+
endUserId
|
|
109
112
|
});
|
|
110
113
|
return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
|
|
111
114
|
status: 500,
|
|
@@ -117,7 +120,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
117
120
|
method: "tools/call",
|
|
118
121
|
outcome: result.isError ? "tool_error" : "ok",
|
|
119
122
|
durationMs: nowMs() - start,
|
|
120
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
123
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
124
|
+
endUserId
|
|
121
125
|
});
|
|
122
126
|
return Response.json({
|
|
123
127
|
content: result.content ?? [],
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
createRequestAuthorizer,
|
|
11
11
|
nowMs,
|
|
12
12
|
withCors
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-SJJDRA6X.js";
|
|
14
14
|
import {
|
|
15
15
|
describeError,
|
|
16
16
|
log
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
21
21
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
22
22
|
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
23
|
+
const endUserId = auth?.principal.sub;
|
|
23
24
|
return async (first) => {
|
|
24
25
|
const args = tool.inputSchema ? first ?? {} : {};
|
|
25
26
|
const start = nowMs();
|
|
@@ -31,7 +32,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
31
32
|
tool: tool.name,
|
|
32
33
|
method: "tools/call",
|
|
33
34
|
outcome: "handler_error",
|
|
34
|
-
durationMs: nowMs() - start
|
|
35
|
+
durationMs: nowMs() - start,
|
|
36
|
+
endUserId
|
|
35
37
|
});
|
|
36
38
|
return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
|
|
37
39
|
}
|
|
@@ -40,7 +42,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
40
42
|
tool: tool.name,
|
|
41
43
|
method: "tools/call",
|
|
42
44
|
outcome: "handler_error",
|
|
43
|
-
durationMs: nowMs() - start
|
|
45
|
+
durationMs: nowMs() - start,
|
|
46
|
+
endUserId
|
|
44
47
|
});
|
|
45
48
|
return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
|
|
46
49
|
}
|
|
@@ -49,7 +52,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
49
52
|
method: "tools/call",
|
|
50
53
|
outcome: result.isError ? "tool_error" : "ok",
|
|
51
54
|
durationMs: nowMs() - start,
|
|
52
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
55
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
56
|
+
endUserId
|
|
53
57
|
});
|
|
54
58
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
55
59
|
};
|
|
@@ -84,7 +88,13 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
84
88
|
await server.connect(transport);
|
|
85
89
|
return await transport.handleRequest(request);
|
|
86
90
|
} catch (err) {
|
|
87
|
-
await recorder.emit({
|
|
91
|
+
await recorder.emit({
|
|
92
|
+
tool: null,
|
|
93
|
+
method: "transport",
|
|
94
|
+
outcome: "transport_error",
|
|
95
|
+
durationMs: 0,
|
|
96
|
+
endUserId: authResult.auth?.principal.sub
|
|
97
|
+
});
|
|
88
98
|
log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
|
|
89
99
|
return Response.json(
|
|
90
100
|
{ jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./chunk-6DXGZZA4.js";
|
|
14
14
|
import {
|
|
15
15
|
version
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-L5ZOZKAL.js";
|
|
17
17
|
|
|
18
18
|
// src/core/http.ts
|
|
19
19
|
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
@@ -75,6 +75,8 @@ function toLogRecord(rec) {
|
|
|
75
75
|
if (rec.resBytes !== void 0)
|
|
76
76
|
attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
77
77
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
78
|
+
if (rec.endUserId !== void 0)
|
|
79
|
+
attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
78
80
|
return {
|
|
79
81
|
timeUnixNano: rec.timeUnixNano,
|
|
80
82
|
observedTimeUnixNano: rec.timeUnixNano,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
buildMcpListing
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-ZLWXDYOZ.js";
|
|
5
|
+
import "../chunk-SJJDRA6X.js";
|
|
6
6
|
import "../chunk-H37EB22A.js";
|
|
7
7
|
import "../chunk-6DXGZZA4.js";
|
|
8
8
|
import {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from "../chunk-Y3ZFPEQH.js";
|
|
11
11
|
import {
|
|
12
12
|
version
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-L5ZOZKAL.js";
|
|
14
14
|
|
|
15
15
|
// src/manifest/io.ts
|
|
16
16
|
import { randomUUID } from "crypto";
|
|
@@ -656,6 +656,7 @@ function corsPreflightResponse(allowMethods) {
|
|
|
656
656
|
|
|
657
657
|
// src/protocols/mcp/protocol.ts
|
|
658
658
|
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
659
|
+
const endUserId = auth?.principal.sub;
|
|
659
660
|
return async (first) => {
|
|
660
661
|
const args = tool.inputSchema ? first ?? {} : {};
|
|
661
662
|
const start = nowMs();
|
|
@@ -667,7 +668,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
667
668
|
tool: tool.name,
|
|
668
669
|
method: "tools/call",
|
|
669
670
|
outcome: "handler_error",
|
|
670
|
-
durationMs: nowMs() - start
|
|
671
|
+
durationMs: nowMs() - start,
|
|
672
|
+
endUserId
|
|
671
673
|
});
|
|
672
674
|
return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
|
|
673
675
|
}
|
|
@@ -676,7 +678,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
676
678
|
tool: tool.name,
|
|
677
679
|
method: "tools/call",
|
|
678
680
|
outcome: "handler_error",
|
|
679
|
-
durationMs: nowMs() - start
|
|
681
|
+
durationMs: nowMs() - start,
|
|
682
|
+
endUserId
|
|
680
683
|
});
|
|
681
684
|
return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
|
|
682
685
|
}
|
|
@@ -685,7 +688,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
685
688
|
method: "tools/call",
|
|
686
689
|
outcome: result.isError ? "tool_error" : "ok",
|
|
687
690
|
durationMs: nowMs() - start,
|
|
688
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
691
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
692
|
+
endUserId
|
|
689
693
|
});
|
|
690
694
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
691
695
|
};
|
|
@@ -720,7 +724,13 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
720
724
|
await server.connect(transport);
|
|
721
725
|
return await transport.handleRequest(request);
|
|
722
726
|
} catch (err) {
|
|
723
|
-
await recorder.emit({
|
|
727
|
+
await recorder.emit({
|
|
728
|
+
tool: null,
|
|
729
|
+
method: "transport",
|
|
730
|
+
outcome: "transport_error",
|
|
731
|
+
durationMs: 0,
|
|
732
|
+
endUserId: authResult.auth?.principal.sub
|
|
733
|
+
});
|
|
724
734
|
log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
|
|
725
735
|
return Response.json(
|
|
726
736
|
{ jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-qqrmJ736.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CM-KCpp6.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-qqrmJ736.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CM-KCpp6.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpProtocolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-ACFNK34P.js";
|
|
4
4
|
import "../../chunk-6QFZYYUV.js";
|
|
5
5
|
import "../../chunk-MA5H6PSF.js";
|
|
6
|
-
import "../../chunk-
|
|
6
|
+
import "../../chunk-SJJDRA6X.js";
|
|
7
7
|
import "../../chunk-H37EB22A.js";
|
|
8
8
|
import "../../chunk-6DXGZZA4.js";
|
|
9
|
-
import "../../chunk-
|
|
9
|
+
import "../../chunk-L5ZOZKAL.js";
|
|
10
10
|
export {
|
|
11
11
|
createMcpProtocolHandler
|
|
12
12
|
};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createOAuthProtectedResourceMetadataHandler
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-BLY5L4KI.js";
|
|
4
|
+
import "../chunk-SJJDRA6X.js";
|
|
5
5
|
import "../chunk-H37EB22A.js";
|
|
6
6
|
import "../chunk-6DXGZZA4.js";
|
|
7
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-L5ZOZKAL.js";
|
|
8
8
|
export {
|
|
9
9
|
createOAuthProtectedResourceMetadataHandler
|
|
10
10
|
};
|
|
@@ -737,6 +737,7 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
737
737
|
const authResult = await authorizer.authorize(request, recorder);
|
|
738
738
|
if (!authResult.ok)
|
|
739
739
|
return authResult.response;
|
|
740
|
+
const endUserId = authResult.auth?.principal.sub;
|
|
740
741
|
if (request.method !== "POST")
|
|
741
742
|
return methodNotAllowed("POST, OPTIONS");
|
|
742
743
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
@@ -794,7 +795,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
794
795
|
tool: tool.name,
|
|
795
796
|
method: "tools/call",
|
|
796
797
|
outcome: "handler_error",
|
|
797
|
-
durationMs: nowMs() - start
|
|
798
|
+
durationMs: nowMs() - start,
|
|
799
|
+
endUserId
|
|
798
800
|
});
|
|
799
801
|
return new Response(JSON.stringify({ error: "handler threw", tool: toolName }), {
|
|
800
802
|
status: 500,
|
|
@@ -806,7 +808,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
806
808
|
tool: tool.name,
|
|
807
809
|
method: "tools/call",
|
|
808
810
|
outcome: "handler_error",
|
|
809
|
-
durationMs: nowMs() - start
|
|
811
|
+
durationMs: nowMs() - start,
|
|
812
|
+
endUserId
|
|
810
813
|
});
|
|
811
814
|
return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
|
|
812
815
|
status: 500,
|
|
@@ -818,7 +821,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
818
821
|
method: "tools/call",
|
|
819
822
|
outcome: result.isError ? "tool_error" : "ok",
|
|
820
823
|
durationMs: nowMs() - start,
|
|
821
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
824
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
825
|
+
endUserId
|
|
822
826
|
});
|
|
823
827
|
return Response.json({
|
|
824
828
|
content: result.content ?? [],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-qqrmJ736.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CM-KCpp6.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-qqrmJ736.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../base-
|
|
3
|
+
import { M as MetricsRecorder } from '../../base-CM-KCpp6.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createInvokeToolHandler
|
|
3
|
-
} from "../../chunk-
|
|
3
|
+
} from "../../chunk-4QNNVJBZ.js";
|
|
4
4
|
import {
|
|
5
5
|
createListToolsHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-ZLWXDYOZ.js";
|
|
7
7
|
import "../../chunk-6QFZYYUV.js";
|
|
8
8
|
import "../../chunk-MA5H6PSF.js";
|
|
9
|
-
import "../../chunk-
|
|
9
|
+
import "../../chunk-SJJDRA6X.js";
|
|
10
10
|
import "../../chunk-H37EB22A.js";
|
|
11
11
|
import "../../chunk-6DXGZZA4.js";
|
|
12
|
-
import "../../chunk-
|
|
12
|
+
import "../../chunk-L5ZOZKAL.js";
|
|
13
13
|
export {
|
|
14
14
|
createInvokeToolHandler,
|
|
15
15
|
createListToolsHandler
|
|
@@ -174,7 +174,7 @@ function describeError(err) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
// package.json
|
|
177
|
-
var version = "0.21.
|
|
177
|
+
var version = "0.21.1-rc.0";
|
|
178
178
|
|
|
179
179
|
// src/metrics/otlp.ts
|
|
180
180
|
var SCOPE_NAME = "@lovable.dev/mcp-js";
|
|
@@ -200,6 +200,8 @@ function toLogRecord(rec) {
|
|
|
200
200
|
if (rec.resBytes !== void 0)
|
|
201
201
|
attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
202
202
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
203
|
+
if (rec.endUserId !== void 0)
|
|
204
|
+
attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
203
205
|
return {
|
|
204
206
|
timeUnixNano: rec.timeUnixNano,
|
|
205
207
|
observedTimeUnixNano: rec.timeUnixNano,
|
|
@@ -930,6 +932,7 @@ function corsPreflightResponse(allowMethods) {
|
|
|
930
932
|
|
|
931
933
|
// src/protocols/mcp/protocol.ts
|
|
932
934
|
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
935
|
+
const endUserId = auth?.principal.sub;
|
|
933
936
|
return async (first) => {
|
|
934
937
|
const args = tool.inputSchema ? first ?? {} : {};
|
|
935
938
|
const start = nowMs();
|
|
@@ -941,7 +944,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
941
944
|
tool: tool.name,
|
|
942
945
|
method: "tools/call",
|
|
943
946
|
outcome: "handler_error",
|
|
944
|
-
durationMs: nowMs() - start
|
|
947
|
+
durationMs: nowMs() - start,
|
|
948
|
+
endUserId
|
|
945
949
|
});
|
|
946
950
|
return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
|
|
947
951
|
}
|
|
@@ -950,7 +954,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
950
954
|
tool: tool.name,
|
|
951
955
|
method: "tools/call",
|
|
952
956
|
outcome: "handler_error",
|
|
953
|
-
durationMs: nowMs() - start
|
|
957
|
+
durationMs: nowMs() - start,
|
|
958
|
+
endUserId
|
|
954
959
|
});
|
|
955
960
|
return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
|
|
956
961
|
}
|
|
@@ -959,7 +964,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
959
964
|
method: "tools/call",
|
|
960
965
|
outcome: result.isError ? "tool_error" : "ok",
|
|
961
966
|
durationMs: nowMs() - start,
|
|
962
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
967
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
968
|
+
endUserId
|
|
963
969
|
});
|
|
964
970
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
965
971
|
};
|
|
@@ -994,7 +1000,13 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
994
1000
|
await server.connect(transport);
|
|
995
1001
|
return await transport.handleRequest(request);
|
|
996
1002
|
} catch (err) {
|
|
997
|
-
await recorder.emit({
|
|
1003
|
+
await recorder.emit({
|
|
1004
|
+
tool: null,
|
|
1005
|
+
method: "transport",
|
|
1006
|
+
outcome: "transport_error",
|
|
1007
|
+
durationMs: 0,
|
|
1008
|
+
endUserId: authResult.auth?.principal.sub
|
|
1009
|
+
});
|
|
998
1010
|
log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
|
|
999
1011
|
return Response.json(
|
|
1000
1012
|
{ jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
|
|
@@ -1135,6 +1147,7 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1135
1147
|
const authResult = await authorizer.authorize(request, recorder);
|
|
1136
1148
|
if (!authResult.ok)
|
|
1137
1149
|
return authResult.response;
|
|
1150
|
+
const endUserId = authResult.auth?.principal.sub;
|
|
1138
1151
|
if (request.method !== "POST")
|
|
1139
1152
|
return methodNotAllowed("POST, OPTIONS");
|
|
1140
1153
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
@@ -1192,7 +1205,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1192
1205
|
tool: tool.name,
|
|
1193
1206
|
method: "tools/call",
|
|
1194
1207
|
outcome: "handler_error",
|
|
1195
|
-
durationMs: nowMs() - start
|
|
1208
|
+
durationMs: nowMs() - start,
|
|
1209
|
+
endUserId
|
|
1196
1210
|
});
|
|
1197
1211
|
return new Response(JSON.stringify({ error: "handler threw", tool: toolName }), {
|
|
1198
1212
|
status: 500,
|
|
@@ -1204,7 +1218,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1204
1218
|
tool: tool.name,
|
|
1205
1219
|
method: "tools/call",
|
|
1206
1220
|
outcome: "handler_error",
|
|
1207
|
-
durationMs: nowMs() - start
|
|
1221
|
+
durationMs: nowMs() - start,
|
|
1222
|
+
endUserId
|
|
1208
1223
|
});
|
|
1209
1224
|
return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
|
|
1210
1225
|
status: 500,
|
|
@@ -1216,7 +1231,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1216
1231
|
method: "tools/call",
|
|
1217
1232
|
outcome: result.isError ? "tool_error" : "ok",
|
|
1218
1233
|
durationMs: nowMs() - start,
|
|
1219
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
1234
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
1235
|
+
endUserId
|
|
1220
1236
|
});
|
|
1221
1237
|
return Response.json({
|
|
1222
1238
|
content: result.content ?? [],
|
|
@@ -3,22 +3,22 @@ import {
|
|
|
3
3
|
} from "../../chunk-UQK5UO6C.js";
|
|
4
4
|
import {
|
|
5
5
|
createMcpProtocolHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-ACFNK34P.js";
|
|
7
7
|
import {
|
|
8
8
|
createOAuthProtectedResourceMetadataHandler
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-BLY5L4KI.js";
|
|
10
10
|
import {
|
|
11
11
|
createInvokeToolHandler
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-4QNNVJBZ.js";
|
|
13
13
|
import {
|
|
14
14
|
createListToolsHandler
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-ZLWXDYOZ.js";
|
|
16
16
|
import "../../chunk-6QFZYYUV.js";
|
|
17
17
|
import "../../chunk-MA5H6PSF.js";
|
|
18
18
|
import {
|
|
19
19
|
assertResourcePathShape,
|
|
20
20
|
createRecorderForRuntime
|
|
21
|
-
} from "../../chunk-
|
|
21
|
+
} from "../../chunk-SJJDRA6X.js";
|
|
22
22
|
import {
|
|
23
23
|
trimTrailingSlash
|
|
24
24
|
} from "../../chunk-H37EB22A.js";
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
FUNCTIONS_MOUNT_PREFIX,
|
|
30
30
|
assertFunctionName
|
|
31
31
|
} from "../../chunk-XQWJN6DC.js";
|
|
32
|
-
import "../../chunk-
|
|
32
|
+
import "../../chunk-L5ZOZKAL.js";
|
|
33
33
|
|
|
34
34
|
// src/stacks/supabase/handler.ts
|
|
35
35
|
function deriveResourcePath(options) {
|
|
@@ -129,7 +129,7 @@ function describeError(err) {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// package.json
|
|
132
|
-
var version = "0.21.
|
|
132
|
+
var version = "0.21.1-rc.0";
|
|
133
133
|
|
|
134
134
|
// src/metrics/otlp.ts
|
|
135
135
|
var SCOPE_NAME = "@lovable.dev/mcp-js";
|
|
@@ -155,6 +155,8 @@ function toLogRecord(rec) {
|
|
|
155
155
|
if (rec.resBytes !== void 0)
|
|
156
156
|
attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
157
157
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
158
|
+
if (rec.endUserId !== void 0)
|
|
159
|
+
attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
158
160
|
return {
|
|
159
161
|
timeUnixNano: rec.timeUnixNano,
|
|
160
162
|
observedTimeUnixNano: rec.timeUnixNano,
|
|
@@ -933,6 +935,7 @@ function corsPreflightResponse(allowMethods) {
|
|
|
933
935
|
|
|
934
936
|
// src/protocols/mcp/protocol.ts
|
|
935
937
|
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
938
|
+
const endUserId = auth?.principal.sub;
|
|
936
939
|
return async (first) => {
|
|
937
940
|
const args = tool.inputSchema ? first ?? {} : {};
|
|
938
941
|
const start = nowMs();
|
|
@@ -944,7 +947,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
944
947
|
tool: tool.name,
|
|
945
948
|
method: "tools/call",
|
|
946
949
|
outcome: "handler_error",
|
|
947
|
-
durationMs: nowMs() - start
|
|
950
|
+
durationMs: nowMs() - start,
|
|
951
|
+
endUserId
|
|
948
952
|
});
|
|
949
953
|
return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
|
|
950
954
|
}
|
|
@@ -953,7 +957,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
953
957
|
tool: tool.name,
|
|
954
958
|
method: "tools/call",
|
|
955
959
|
outcome: "handler_error",
|
|
956
|
-
durationMs: nowMs() - start
|
|
960
|
+
durationMs: nowMs() - start,
|
|
961
|
+
endUserId
|
|
957
962
|
});
|
|
958
963
|
return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
|
|
959
964
|
}
|
|
@@ -962,7 +967,8 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
962
967
|
method: "tools/call",
|
|
963
968
|
outcome: result.isError ? "tool_error" : "ok",
|
|
964
969
|
durationMs: nowMs() - start,
|
|
965
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
970
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
971
|
+
endUserId
|
|
966
972
|
});
|
|
967
973
|
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
968
974
|
};
|
|
@@ -997,7 +1003,13 @@ function createMcpProtocolHandler(mcp, options = {}) {
|
|
|
997
1003
|
await server.connect(transport);
|
|
998
1004
|
return await transport.handleRequest(request);
|
|
999
1005
|
} catch (err) {
|
|
1000
|
-
await recorder.emit({
|
|
1006
|
+
await recorder.emit({
|
|
1007
|
+
tool: null,
|
|
1008
|
+
method: "transport",
|
|
1009
|
+
outcome: "transport_error",
|
|
1010
|
+
durationMs: 0,
|
|
1011
|
+
endUserId: authResult.auth?.principal.sub
|
|
1012
|
+
});
|
|
1001
1013
|
log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
|
|
1002
1014
|
return Response.json(
|
|
1003
1015
|
{ jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
|
|
@@ -1138,6 +1150,7 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1138
1150
|
const authResult = await authorizer.authorize(request, recorder);
|
|
1139
1151
|
if (!authResult.ok)
|
|
1140
1152
|
return authResult.response;
|
|
1153
|
+
const endUserId = authResult.auth?.principal.sub;
|
|
1141
1154
|
if (request.method !== "POST")
|
|
1142
1155
|
return methodNotAllowed("POST, OPTIONS");
|
|
1143
1156
|
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
@@ -1195,7 +1208,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1195
1208
|
tool: tool.name,
|
|
1196
1209
|
method: "tools/call",
|
|
1197
1210
|
outcome: "handler_error",
|
|
1198
|
-
durationMs: nowMs() - start
|
|
1211
|
+
durationMs: nowMs() - start,
|
|
1212
|
+
endUserId
|
|
1199
1213
|
});
|
|
1200
1214
|
return new Response(JSON.stringify({ error: "handler threw", tool: toolName }), {
|
|
1201
1215
|
status: 500,
|
|
@@ -1207,7 +1221,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1207
1221
|
tool: tool.name,
|
|
1208
1222
|
method: "tools/call",
|
|
1209
1223
|
outcome: "handler_error",
|
|
1210
|
-
durationMs: nowMs() - start
|
|
1224
|
+
durationMs: nowMs() - start,
|
|
1225
|
+
endUserId
|
|
1211
1226
|
});
|
|
1212
1227
|
return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
|
|
1213
1228
|
status: 500,
|
|
@@ -1219,7 +1234,8 @@ function createInvokeToolHandler(mcp, options = {}) {
|
|
|
1219
1234
|
method: "tools/call",
|
|
1220
1235
|
outcome: result.isError ? "tool_error" : "ok",
|
|
1221
1236
|
durationMs: nowMs() - start,
|
|
1222
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0
|
|
1237
|
+
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
1238
|
+
endUserId
|
|
1223
1239
|
});
|
|
1224
1240
|
return Response.json({
|
|
1225
1241
|
content: result.content ?? [],
|
|
@@ -3,24 +3,24 @@ import {
|
|
|
3
3
|
} from "../../chunk-UQK5UO6C.js";
|
|
4
4
|
import {
|
|
5
5
|
createMcpProtocolHandler
|
|
6
|
-
} from "../../chunk-
|
|
6
|
+
} from "../../chunk-ACFNK34P.js";
|
|
7
7
|
import {
|
|
8
8
|
createOAuthProtectedResourceMetadataHandler
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-BLY5L4KI.js";
|
|
10
10
|
import {
|
|
11
11
|
createInvokeToolHandler
|
|
12
|
-
} from "../../chunk-
|
|
12
|
+
} from "../../chunk-4QNNVJBZ.js";
|
|
13
13
|
import {
|
|
14
14
|
createListToolsHandler
|
|
15
|
-
} from "../../chunk-
|
|
15
|
+
} from "../../chunk-ZLWXDYOZ.js";
|
|
16
16
|
import "../../chunk-6QFZYYUV.js";
|
|
17
17
|
import "../../chunk-MA5H6PSF.js";
|
|
18
18
|
import {
|
|
19
19
|
createRecorderForRuntime
|
|
20
|
-
} from "../../chunk-
|
|
20
|
+
} from "../../chunk-SJJDRA6X.js";
|
|
21
21
|
import "../../chunk-H37EB22A.js";
|
|
22
22
|
import "../../chunk-6DXGZZA4.js";
|
|
23
|
-
import "../../chunk-
|
|
23
|
+
import "../../chunk-L5ZOZKAL.js";
|
|
24
24
|
|
|
25
25
|
// src/stacks/tanstack/handlers.ts
|
|
26
26
|
var STACK = "tanstack";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovable.dev/mcp-js",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.1-rc.0",
|
|
4
4
|
"description": "Author MCP servers for Lovable apps. Declare tools with defineTool, register them in defineMcp, and a framework adapter (TanStack or Supabase Edge Functions) emits the route(s) at build time.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|