@lovable.dev/mcp-js 0.22.1-rc.9 → 0.22.2-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/authorize-CumVyk7p.d.cts +27 -0
- package/dist/authorize-D6p4-9_D.d.ts +27 -0
- package/dist/base-DCe0kP79.d.cts +29 -0
- package/dist/base-DCe0kP79.d.ts +29 -0
- package/dist/cli/extract-manifest.cjs +116 -201
- package/dist/cli/extract-manifest.d.cts +1 -1
- package/dist/cli/extract-manifest.d.ts +1 -1
- package/dist/cli/extract-manifest.js +117 -156
- package/dist/content-D5LJAHyM.js +12 -0
- package/dist/content-NCYIGgOb.cjs +17 -0
- package/dist/context-BweeEcoA.cjs +56 -0
- package/dist/context-CIpPzN7P.js +51 -0
- package/dist/cors-CSDhBjFd.cjs +913 -0
- package/dist/cors-rWp_tbLZ.js +830 -0
- package/dist/forwarded--h4efJy-.js +43 -0
- package/dist/forwarded-Pi8Hs5Ps.cjs +48 -0
- package/dist/fs-errors-CWNzOV75.cjs +11 -0
- package/dist/fs-errors-PA2t1TIp.js +6 -0
- package/dist/index.cjs +129 -329
- package/dist/index.d.cts +26 -26
- package/dist/index.d.ts +26 -26
- package/dist/index.js +118 -177
- package/dist/{io-D4srzRKc.d.ts → io-CfSPxeBN.d.ts} +6 -4
- package/dist/io-DPYvBqET.d.cts +15 -0
- package/dist/list-tools-B4TTPEl1.d.cts +8 -0
- package/dist/list-tools-CFUX-uo-.cjs +57 -0
- package/dist/list-tools-DVJrjtmH.js +46 -0
- package/dist/list-tools-bh6-eqZM.d.ts +8 -0
- package/dist/logger-2OXtfiIW.js +141 -0
- package/dist/logger-BqPOa_E1.cjs +194 -0
- package/dist/mcp-BNcpj8o7.cjs +128 -0
- package/dist/mcp-Bx3bJHzH.js +123 -0
- package/dist/metadata-path-CAkNcfyY.js +12 -0
- package/dist/metadata-path-zd7NSNoa.cjs +17 -0
- package/dist/package-CgwD4Ywz.js +4 -0
- package/dist/package-DzstF8Ih.cjs +9 -0
- package/dist/paths-IS65L6TA.js +7 -0
- package/dist/paths-OP318a6c.cjs +18 -0
- package/dist/protocols/mcp/index.cjs +3 -750
- package/dist/protocols/mcp/index.d.cts +6 -7
- package/dist/protocols/mcp/index.d.ts +6 -7
- package/dist/protocols/mcp/index.js +2 -12
- package/dist/protocols/oauth-metadata.cjs +48 -539
- package/dist/protocols/oauth-metadata.d.cts +5 -6
- package/dist/protocols/oauth-metadata.d.ts +5 -6
- package/dist/protocols/oauth-metadata.js +52 -10
- package/dist/protocols/rest/index.cjs +5 -843
- package/dist/protocols/rest/index.d.cts +7 -10
- package/dist/protocols/rest/index.d.ts +7 -10
- package/dist/protocols/rest/index.js +3 -16
- package/dist/rest-BRshnow2.js +117 -0
- package/dist/rest-C4ZEGSIV.cjs +122 -0
- package/dist/stacks/supabase/index.cjs +76 -1318
- package/dist/stacks/supabase/index.d.cts +29 -30
- package/dist/stacks/supabase/index.d.ts +29 -30
- package/dist/stacks/supabase/index.js +73 -89
- package/dist/stacks/supabase/vite.cjs +258 -287
- 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 +42 -1272
- package/dist/stacks/tanstack/index.d.cts +8 -9
- package/dist/stacks/tanstack/index.d.ts +8 -9
- package/dist/stacks/tanstack/index.js +36 -41
- package/dist/stacks/tanstack/vite.cjs +223 -312
- package/dist/stacks/tanstack/vite.d.cts +80 -81
- package/dist/stacks/tanstack/vite.d.ts +80 -81
- package/dist/stacks/tanstack/vite.js +216 -282
- package/dist/types-BYdYYTjk.d.cts +321 -0
- package/dist/types-BYdYYTjk.d.ts +321 -0
- package/package.json +4 -4
- package/dist/authorize-BMeXd_Sh.d.ts +0 -25
- package/dist/base-CM-KCpp6.d.ts +0 -28
- package/dist/chunk-5DFH6VN6.js +0 -741
- package/dist/chunk-6DXGZZA4.js +0 -6
- package/dist/chunk-6QFZYYUV.js +0 -11
- package/dist/chunk-AYV4CWAJ.js +0 -141
- package/dist/chunk-H37EB22A.js +0 -125
- package/dist/chunk-K3OSKUCH.js +0 -79
- package/dist/chunk-KUYKBTCQ.js +0 -58
- package/dist/chunk-MA5H6PSF.js +0 -46
- package/dist/chunk-MTJQGT2W.js +0 -6
- package/dist/chunk-UQK5UO6C.js +0 -26
- package/dist/chunk-XQWJN6DC.js +0 -14
- package/dist/chunk-Y3ZFPEQH.js +0 -8
- package/dist/chunk-Z3ICQ7MB.js +0 -114
- package/dist/types-qqrmJ736.d.ts +0 -321
package/dist/chunk-6DXGZZA4.js
DELETED
package/dist/chunk-6QFZYYUV.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// src/core/content.ts
|
|
2
|
-
function extractTextContent(content) {
|
|
3
|
-
if (!content)
|
|
4
|
-
return void 0;
|
|
5
|
-
const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
|
|
6
|
-
return text.length > 0 ? text : void 0;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
extractTextContent
|
|
11
|
-
};
|
package/dist/chunk-AYV4CWAJ.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
extractTextContent
|
|
3
|
-
} from "./chunk-6QFZYYUV.js";
|
|
4
|
-
import {
|
|
5
|
-
ToolContext
|
|
6
|
-
} from "./chunk-MA5H6PSF.js";
|
|
7
|
-
import {
|
|
8
|
-
JSON_HEADERS,
|
|
9
|
-
assertRestResourceBinding,
|
|
10
|
-
corsPreflightResponse,
|
|
11
|
-
createNoopRecorder,
|
|
12
|
-
createRequestAuthorizer,
|
|
13
|
-
methodNotAllowed,
|
|
14
|
-
nowMs,
|
|
15
|
-
withCors
|
|
16
|
-
} from "./chunk-5DFH6VN6.js";
|
|
17
|
-
|
|
18
|
-
// src/protocols/rest/invoke-tool.ts
|
|
19
|
-
import { getParseErrorMessage, objectFromShape, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
20
|
-
var MAX_REFLECTED_TOOL_NAME = 256;
|
|
21
|
-
function safeReflectName(name) {
|
|
22
|
-
const text = String(name);
|
|
23
|
-
return text.length > MAX_REFLECTED_TOOL_NAME ? `${text.slice(0, MAX_REFLECTED_TOOL_NAME)}\u2026` : text;
|
|
24
|
-
}
|
|
25
|
-
function isEmptyArgs(value) {
|
|
26
|
-
if (value == null)
|
|
27
|
-
return true;
|
|
28
|
-
if (typeof value !== "object" || Array.isArray(value))
|
|
29
|
-
return false;
|
|
30
|
-
return Object.keys(value).length === 0;
|
|
31
|
-
}
|
|
32
|
-
function createInvokeToolHandler(mcp, options = {}) {
|
|
33
|
-
assertRestResourceBinding(mcp, options);
|
|
34
|
-
const authorizer = createRequestAuthorizer(mcp, options);
|
|
35
|
-
const handle = async (request, toolName, recorder) => {
|
|
36
|
-
const authResult = await authorizer.authorize(request, recorder);
|
|
37
|
-
if (!authResult.ok)
|
|
38
|
-
return authResult.response;
|
|
39
|
-
const endUserId = authResult.auth?.principal.sub;
|
|
40
|
-
if (request.method !== "POST")
|
|
41
|
-
return methodNotAllowed("POST, OPTIONS");
|
|
42
|
-
const tool = mcp.tools.find((t) => t.name === toolName);
|
|
43
|
-
if (!tool) {
|
|
44
|
-
return new Response(JSON.stringify({ error: `unknown tool: ${safeReflectName(toolName)}` }), {
|
|
45
|
-
status: 404,
|
|
46
|
-
headers: JSON_HEADERS
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
let rawArgs = {};
|
|
50
|
-
const text = await request.text();
|
|
51
|
-
if (text) {
|
|
52
|
-
try {
|
|
53
|
-
rawArgs = JSON.parse(text);
|
|
54
|
-
} catch {
|
|
55
|
-
return new Response(JSON.stringify({ error: "invalid JSON body" }), {
|
|
56
|
-
status: 400,
|
|
57
|
-
headers: JSON_HEADERS
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
let args = rawArgs;
|
|
62
|
-
if (tool.inputSchema) {
|
|
63
|
-
try {
|
|
64
|
-
const schema = objectFromShape(tool.inputSchema);
|
|
65
|
-
const parsed = await safeParseAsync(schema, rawArgs);
|
|
66
|
-
if (!parsed.success) {
|
|
67
|
-
return new Response(
|
|
68
|
-
JSON.stringify({
|
|
69
|
-
error: "validation failed",
|
|
70
|
-
details: getParseErrorMessage(parsed.error)
|
|
71
|
-
}),
|
|
72
|
-
{ status: 400, headers: JSON_HEADERS }
|
|
73
|
-
);
|
|
74
|
-
}
|
|
75
|
-
args = parsed.data;
|
|
76
|
-
} catch {
|
|
77
|
-
return new Response(JSON.stringify({ error: "schema error", tool: toolName }), {
|
|
78
|
-
status: 500,
|
|
79
|
-
headers: JSON_HEADERS
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
} else if (!isEmptyArgs(rawArgs)) {
|
|
83
|
-
return new Response(JSON.stringify({ error: "tool has no inputSchema; expected empty body" }), {
|
|
84
|
-
status: 400,
|
|
85
|
-
headers: JSON_HEADERS
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
let result;
|
|
89
|
-
const start = nowMs();
|
|
90
|
-
try {
|
|
91
|
-
result = await tool.handler(args, new ToolContext(authResult.auth));
|
|
92
|
-
} catch {
|
|
93
|
-
await recorder.emit({
|
|
94
|
-
tool: tool.name,
|
|
95
|
-
method: "tools/call",
|
|
96
|
-
outcome: "handler_error",
|
|
97
|
-
durationMs: nowMs() - start,
|
|
98
|
-
endUserId
|
|
99
|
-
});
|
|
100
|
-
return new Response(JSON.stringify({ error: "handler threw", tool: toolName }), {
|
|
101
|
-
status: 500,
|
|
102
|
-
headers: JSON_HEADERS
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
if (result == null) {
|
|
106
|
-
await recorder.emit({
|
|
107
|
-
tool: tool.name,
|
|
108
|
-
method: "tools/call",
|
|
109
|
-
outcome: "handler_error",
|
|
110
|
-
durationMs: nowMs() - start,
|
|
111
|
-
endUserId
|
|
112
|
-
});
|
|
113
|
-
return new Response(JSON.stringify({ error: `tool "${toolName}" returned no result` }), {
|
|
114
|
-
status: 500,
|
|
115
|
-
headers: JSON_HEADERS
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
await recorder.emit({
|
|
119
|
-
tool: tool.name,
|
|
120
|
-
method: "tools/call",
|
|
121
|
-
outcome: result.isError ? "tool_error" : "ok",
|
|
122
|
-
durationMs: nowMs() - start,
|
|
123
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
124
|
-
endUserId
|
|
125
|
-
});
|
|
126
|
-
return Response.json({
|
|
127
|
-
content: result.content ?? [],
|
|
128
|
-
structuredContent: result.structuredContent,
|
|
129
|
-
isError: result.isError
|
|
130
|
-
});
|
|
131
|
-
};
|
|
132
|
-
return async (request, toolName, recorder = createNoopRecorder()) => {
|
|
133
|
-
if (request.method === "OPTIONS")
|
|
134
|
-
return corsPreflightResponse("POST, OPTIONS");
|
|
135
|
-
return withCors(await handle(request, toolName, recorder));
|
|
136
|
-
};
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
export {
|
|
140
|
-
createInvokeToolHandler
|
|
141
|
-
};
|
package/dist/chunk-H37EB22A.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
// src/core/logger.ts
|
|
2
|
-
var LEVEL_RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
|
|
3
|
-
function isLogLevel(value) {
|
|
4
|
-
return typeof value === "string" && value in LEVEL_RANK;
|
|
5
|
-
}
|
|
6
|
-
var LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
|
|
7
|
-
function readEnvLevel() {
|
|
8
|
-
try {
|
|
9
|
-
const raw = typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0;
|
|
10
|
-
const normalized = raw?.trim().toLowerCase();
|
|
11
|
-
return isLogLevel(normalized) ? normalized : void 0;
|
|
12
|
-
} catch {
|
|
13
|
-
return void 0;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
var currentLevel = readEnvLevel() ?? "debug";
|
|
17
|
-
function setLogLevel(level) {
|
|
18
|
-
currentLevel = level;
|
|
19
|
-
}
|
|
20
|
-
function parseLogLevel(raw) {
|
|
21
|
-
const normalized = raw?.trim().toLowerCase();
|
|
22
|
-
return isLogLevel(normalized) ? normalized : void 0;
|
|
23
|
-
}
|
|
24
|
-
function applyLogLevelFromEnv(raw) {
|
|
25
|
-
setLogLevel(parseLogLevel(raw) ?? "debug");
|
|
26
|
-
}
|
|
27
|
-
function enabled(level) {
|
|
28
|
-
return LEVEL_RANK[level] <= LEVEL_RANK[currentLevel];
|
|
29
|
-
}
|
|
30
|
-
function emit(level, method, event, fields) {
|
|
31
|
-
if (!enabled(level))
|
|
32
|
-
return;
|
|
33
|
-
const message = `[mcp-js] ${event}`;
|
|
34
|
-
if (fields)
|
|
35
|
-
console[method](message, fields);
|
|
36
|
-
else
|
|
37
|
-
console[method](message);
|
|
38
|
-
}
|
|
39
|
-
var log = {
|
|
40
|
-
error: (event, fields) => emit("error", "error", event, fields),
|
|
41
|
-
warn: (event, fields) => emit("warn", "warn", event, fields),
|
|
42
|
-
info: (event, fields) => emit("info", "info", event, fields),
|
|
43
|
-
debug: (event, fields) => emit("debug", "debug", event, fields)
|
|
44
|
-
};
|
|
45
|
-
function describeError(err) {
|
|
46
|
-
if (err instanceof Error) {
|
|
47
|
-
const code = err.code;
|
|
48
|
-
return { name: err.name, message: err.message, ...typeof code === "string" ? { code } : {} };
|
|
49
|
-
}
|
|
50
|
-
return { value: String(err) };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// src/metrics/config.ts
|
|
54
|
-
var DEFAULT_METRICS_ENDPOINT = "https://api.lovable.dev/v1/app-mcp-usage";
|
|
55
|
-
var METRICS_API_KEY_ENV_VAR = "LOVABLE_API_KEY";
|
|
56
|
-
function assertMetricsEndpoint(endpoint) {
|
|
57
|
-
let url;
|
|
58
|
-
try {
|
|
59
|
-
url = new URL(endpoint);
|
|
60
|
-
} catch {
|
|
61
|
-
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be an absolute URL, got ${JSON.stringify(endpoint)}`);
|
|
62
|
-
}
|
|
63
|
-
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
64
|
-
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be http(s), got ${JSON.stringify(endpoint)}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function resolveMetricsConfig(config = true) {
|
|
68
|
-
const options = typeof config === "boolean" ? { enabled: config } : config;
|
|
69
|
-
const endpoint = options.endpoint ?? DEFAULT_METRICS_ENDPOINT;
|
|
70
|
-
assertMetricsEndpoint(endpoint);
|
|
71
|
-
return Object.freeze({
|
|
72
|
-
enabled: options.enabled ?? true,
|
|
73
|
-
endpoint,
|
|
74
|
-
headers: options.headers ?? {},
|
|
75
|
-
apiKeyEnvVar: METRICS_API_KEY_ENV_VAR
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// src/core/url.ts
|
|
80
|
-
function trimTrailingSlash(value) {
|
|
81
|
-
return value.replace(/\/+$/, "");
|
|
82
|
-
}
|
|
83
|
-
function isLocalHTTPHost(hostname) {
|
|
84
|
-
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
85
|
-
}
|
|
86
|
-
function urlSafetyProblem(url) {
|
|
87
|
-
const isAllowedHTTP = url.protocol === "http:" && isLocalHTTPHost(url.hostname);
|
|
88
|
-
if (url.protocol !== "https:" && !isAllowedHTTP) {
|
|
89
|
-
return "must use https://, except localhost development URLs";
|
|
90
|
-
}
|
|
91
|
-
if (url.username || url.password) {
|
|
92
|
-
return "must not include credentials";
|
|
93
|
-
}
|
|
94
|
-
if (url.search || url.hash) {
|
|
95
|
-
return "must not include query or fragment";
|
|
96
|
-
}
|
|
97
|
-
return void 0;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// src/core/validation.ts
|
|
101
|
-
function parseSafeUrl(subject, raw, ErrorClass = Error) {
|
|
102
|
-
let url;
|
|
103
|
-
try {
|
|
104
|
-
url = new URL(raw);
|
|
105
|
-
} catch {
|
|
106
|
-
throw new ErrorClass(`${subject} must be an absolute URL`);
|
|
107
|
-
}
|
|
108
|
-
const problem = urlSafetyProblem(url);
|
|
109
|
-
if (problem) {
|
|
110
|
-
throw new ErrorClass(`${subject} ${problem}`);
|
|
111
|
-
}
|
|
112
|
-
return url;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export {
|
|
116
|
-
DEFAULT_METRICS_ENDPOINT,
|
|
117
|
-
resolveMetricsConfig,
|
|
118
|
-
trimTrailingSlash,
|
|
119
|
-
parseSafeUrl,
|
|
120
|
-
LOG_LEVEL_ENV_VAR,
|
|
121
|
-
setLogLevel,
|
|
122
|
-
applyLogLevelFromEnv,
|
|
123
|
-
log,
|
|
124
|
-
describeError
|
|
125
|
-
};
|
package/dist/chunk-K3OSKUCH.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
JSON_HEADERS,
|
|
3
|
-
corsPreflightResponse,
|
|
4
|
-
getOAuthRuntime,
|
|
5
|
-
headResponse,
|
|
6
|
-
methodNotAllowed,
|
|
7
|
-
oauthConfigurationErrorResponse,
|
|
8
|
-
resolveProtectedResource,
|
|
9
|
-
withCors
|
|
10
|
-
} from "./chunk-5DFH6VN6.js";
|
|
11
|
-
import {
|
|
12
|
-
describeError,
|
|
13
|
-
log
|
|
14
|
-
} from "./chunk-H37EB22A.js";
|
|
15
|
-
|
|
16
|
-
// src/protocols/oauth-metadata.ts
|
|
17
|
-
function notFound() {
|
|
18
|
-
return withCors(
|
|
19
|
-
new Response(JSON.stringify({ error: "not found" }), {
|
|
20
|
-
status: 404,
|
|
21
|
-
// `no-store` so a 404 (OAuth unconfigured) isn't heuristically cached and
|
|
22
|
-
// then served past a later deploy that enables OAuth and starts returning 200.
|
|
23
|
-
headers: { ...JSON_HEADERS, "Cache-Control": "no-store" }
|
|
24
|
-
})
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
async function buildProtectedResourceMetadata(mcp, auth, request, options, discovery) {
|
|
28
|
-
const issuer = await discovery.resolveIssuer();
|
|
29
|
-
const body = {
|
|
30
|
-
resource: resolveProtectedResource(auth, request, options),
|
|
31
|
-
authorization_servers: [issuer],
|
|
32
|
-
bearer_methods_supported: ["header"],
|
|
33
|
-
resource_name: auth.resourceName ?? mcp.title,
|
|
34
|
-
resource_documentation: auth.resourceDocumentation
|
|
35
|
-
};
|
|
36
|
-
if (auth.requiredScopes && auth.requiredScopes.length > 0)
|
|
37
|
-
body.scopes_supported = auth.requiredScopes;
|
|
38
|
-
return body;
|
|
39
|
-
}
|
|
40
|
-
function createOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
|
|
41
|
-
const runtime = getOAuthRuntime(mcp, options);
|
|
42
|
-
if (runtime.kind === "configured" && runtime.auth.protectedResourceMetadataUrl === void 0 && runtime.auth.resource === void 0 && runtime.options.resourcePath === void 0) {
|
|
43
|
-
throw new Error(
|
|
44
|
-
`@lovable.dev/mcp-js: auth.resource or a resourcePath is required so the protected-resource metadata doesn't advertise the well-known URL as the resource`
|
|
45
|
-
);
|
|
46
|
-
}
|
|
47
|
-
return async (request) => {
|
|
48
|
-
if (runtime.kind !== "configured" || runtime.auth.protectedResourceMetadataUrl !== void 0)
|
|
49
|
-
return notFound();
|
|
50
|
-
if (request.method === "OPTIONS")
|
|
51
|
-
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
52
|
-
if (request.method !== "GET" && request.method !== "HEAD")
|
|
53
|
-
return withCors(methodNotAllowed("GET, HEAD, OPTIONS"));
|
|
54
|
-
const headers = {
|
|
55
|
-
...JSON_HEADERS,
|
|
56
|
-
"Cache-Control": "public, max-age=300",
|
|
57
|
-
Vary: "Host"
|
|
58
|
-
};
|
|
59
|
-
try {
|
|
60
|
-
const metadata = await buildProtectedResourceMetadata(
|
|
61
|
-
mcp,
|
|
62
|
-
runtime.auth,
|
|
63
|
-
request,
|
|
64
|
-
runtime.options,
|
|
65
|
-
runtime.discovery
|
|
66
|
-
);
|
|
67
|
-
const response = withCors(Response.json(metadata, { headers }));
|
|
68
|
-
return request.method === "HEAD" ? headResponse(response) : response;
|
|
69
|
-
} catch (err) {
|
|
70
|
-
log.error("oauth.metadata.config_error", { ...describeError(err), outcome: "500 oauth configuration error" });
|
|
71
|
-
const response = withCors(oauthConfigurationErrorResponse());
|
|
72
|
-
return request.method === "HEAD" ? headResponse(response) : response;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export {
|
|
78
|
-
createOAuthProtectedResourceMetadataHandler
|
|
79
|
-
};
|
package/dist/chunk-KUYKBTCQ.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
assertRestResourceBinding,
|
|
3
|
-
corsPreflightResponse,
|
|
4
|
-
createNoopRecorder,
|
|
5
|
-
createRequestAuthorizer,
|
|
6
|
-
headResponse,
|
|
7
|
-
methodNotAllowed,
|
|
8
|
-
withCors
|
|
9
|
-
} from "./chunk-5DFH6VN6.js";
|
|
10
|
-
|
|
11
|
-
// src/protocols/rest/list-tools.ts
|
|
12
|
-
import { objectFromShape } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
13
|
-
import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
|
|
14
|
-
function shapeToJsonSchema(shape) {
|
|
15
|
-
if (!shape)
|
|
16
|
-
return null;
|
|
17
|
-
try {
|
|
18
|
-
return toJsonSchemaCompat(objectFromShape(shape));
|
|
19
|
-
} catch {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
function buildMcpListing(mcp) {
|
|
24
|
-
return {
|
|
25
|
-
server: { name: mcp.name, version: mcp.version, title: mcp.title },
|
|
26
|
-
tools: mcp.tools.map((tool) => ({
|
|
27
|
-
name: tool.name,
|
|
28
|
-
title: tool.title,
|
|
29
|
-
description: tool.description,
|
|
30
|
-
annotations: tool.annotations,
|
|
31
|
-
inputSchema: shapeToJsonSchema(tool.inputSchema),
|
|
32
|
-
outputSchema: shapeToJsonSchema(tool.outputSchema)
|
|
33
|
-
}))
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
function createListToolsHandler(mcp, options = {}) {
|
|
37
|
-
assertRestResourceBinding(mcp, options);
|
|
38
|
-
const authorizer = createRequestAuthorizer(mcp, options);
|
|
39
|
-
const handle = async (request, recorder) => {
|
|
40
|
-
const authResult = await authorizer.authorize(request, recorder);
|
|
41
|
-
if (!authResult.ok)
|
|
42
|
-
return authResult.response;
|
|
43
|
-
if (request.method !== "GET" && request.method !== "HEAD")
|
|
44
|
-
return methodNotAllowed("GET, HEAD, OPTIONS");
|
|
45
|
-
const response = Response.json(buildMcpListing(mcp));
|
|
46
|
-
return request.method === "HEAD" ? headResponse(response) : response;
|
|
47
|
-
};
|
|
48
|
-
return async (request, recorder = createNoopRecorder()) => {
|
|
49
|
-
if (request.method === "OPTIONS")
|
|
50
|
-
return corsPreflightResponse("GET, HEAD, OPTIONS");
|
|
51
|
-
return withCors(await handle(request, recorder));
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export {
|
|
56
|
-
buildMcpListing,
|
|
57
|
-
createListToolsHandler
|
|
58
|
-
};
|
package/dist/chunk-MA5H6PSF.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
// src/auth/context.ts
|
|
2
|
-
var ToolContext = class {
|
|
3
|
-
#auth;
|
|
4
|
-
constructor(auth) {
|
|
5
|
-
this.#auth = auth;
|
|
6
|
-
}
|
|
7
|
-
/** Whether the in-flight tool call carries a verified auth context. */
|
|
8
|
-
isAuthenticated() {
|
|
9
|
-
return this.#auth !== void 0;
|
|
10
|
-
}
|
|
11
|
-
/** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
|
|
12
|
-
getToken() {
|
|
13
|
-
return this.#auth?.bearer.token;
|
|
14
|
-
}
|
|
15
|
-
/** The verified user id (the token `sub`), or `undefined`. */
|
|
16
|
-
getUserId() {
|
|
17
|
-
return this.#auth?.principal.sub;
|
|
18
|
-
}
|
|
19
|
-
/** The verified user email, or `undefined` when absent. */
|
|
20
|
-
getUserEmail() {
|
|
21
|
-
return this.#auth?.principal.email;
|
|
22
|
-
}
|
|
23
|
-
/** The verified OAuth `client_id`, or `undefined`. */
|
|
24
|
-
getClientId() {
|
|
25
|
-
return this.#auth?.principal.clientId;
|
|
26
|
-
}
|
|
27
|
-
/** The verified OAuth scopes, or `undefined` when unauthenticated. */
|
|
28
|
-
getScopes() {
|
|
29
|
-
return this.#auth?.principal.scopes;
|
|
30
|
-
}
|
|
31
|
-
/** The verified token issuer, or `undefined`. */
|
|
32
|
-
getIssuer() {
|
|
33
|
-
return this.#auth?.principal.issuer;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* The full verified JWT claims, or `undefined`. Use this for app/business
|
|
37
|
-
* authorization on issuer-specific claims that have no dedicated accessor.
|
|
38
|
-
*/
|
|
39
|
-
getClaims() {
|
|
40
|
-
return this.#auth?.principal.claims;
|
|
41
|
-
}
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
export {
|
|
45
|
-
ToolContext
|
|
46
|
-
};
|
package/dist/chunk-MTJQGT2W.js
DELETED
package/dist/chunk-UQK5UO6C.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// src/core/forwarded.ts
|
|
2
|
-
function applyForwardedOrigin(request, options) {
|
|
3
|
-
const proto = options.trustForwardedProto ? firstForwardedValue(request, "x-forwarded-proto") : void 0;
|
|
4
|
-
const host = options.trustForwardedHost ? firstForwardedValue(request, "x-forwarded-host") : void 0;
|
|
5
|
-
if (proto === void 0 && host === void 0)
|
|
6
|
-
return request;
|
|
7
|
-
const url = new URL(request.url);
|
|
8
|
-
let changed = false;
|
|
9
|
-
if (proto !== void 0 && `${proto}:` !== url.protocol) {
|
|
10
|
-
url.protocol = `${proto}:`;
|
|
11
|
-
changed = true;
|
|
12
|
-
}
|
|
13
|
-
if (host !== void 0 && host !== url.host) {
|
|
14
|
-
url.host = host;
|
|
15
|
-
changed = true;
|
|
16
|
-
}
|
|
17
|
-
return changed ? new Request(url.href, request) : request;
|
|
18
|
-
}
|
|
19
|
-
function firstForwardedValue(request, header) {
|
|
20
|
-
const value = request.headers.get(header)?.split(",")[0]?.trim();
|
|
21
|
-
return value ? value : void 0;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export {
|
|
25
|
-
applyForwardedOrigin
|
|
26
|
-
};
|
package/dist/chunk-XQWJN6DC.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// src/stacks/supabase/paths.ts
|
|
2
|
-
var FUNCTIONS_MOUNT_PREFIX = "/functions/v1/";
|
|
3
|
-
function assertFunctionName(value, label = "functionName") {
|
|
4
|
-
if (!/^[a-zA-Z0-9_-]+$/.test(value)) {
|
|
5
|
-
throw new Error(
|
|
6
|
-
`@lovable.dev/mcp-js: ${label} must be a single path segment matching [A-Za-z0-9_-], got ${JSON.stringify(value)}`
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export {
|
|
12
|
-
FUNCTIONS_MOUNT_PREFIX,
|
|
13
|
-
assertFunctionName
|
|
14
|
-
};
|
package/dist/chunk-Y3ZFPEQH.js
DELETED
package/dist/chunk-Z3ICQ7MB.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
extractTextContent
|
|
3
|
-
} from "./chunk-6QFZYYUV.js";
|
|
4
|
-
import {
|
|
5
|
-
ToolContext
|
|
6
|
-
} from "./chunk-MA5H6PSF.js";
|
|
7
|
-
import {
|
|
8
|
-
corsPreflightResponse,
|
|
9
|
-
createNoopRecorder,
|
|
10
|
-
createRequestAuthorizer,
|
|
11
|
-
nowMs,
|
|
12
|
-
withCors
|
|
13
|
-
} from "./chunk-5DFH6VN6.js";
|
|
14
|
-
import {
|
|
15
|
-
describeError,
|
|
16
|
-
log
|
|
17
|
-
} from "./chunk-H37EB22A.js";
|
|
18
|
-
|
|
19
|
-
// src/protocols/mcp/protocol.ts
|
|
20
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
21
|
-
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
22
|
-
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
23
|
-
const endUserId = auth?.principal.sub;
|
|
24
|
-
return async (first) => {
|
|
25
|
-
const args = tool.inputSchema ? first ?? {} : {};
|
|
26
|
-
const start = nowMs();
|
|
27
|
-
let result;
|
|
28
|
-
try {
|
|
29
|
-
result = await tool.handler(args, new ToolContext(auth));
|
|
30
|
-
} catch {
|
|
31
|
-
await recorder.emit({
|
|
32
|
-
tool: tool.name,
|
|
33
|
-
method: "tools/call",
|
|
34
|
-
outcome: "handler_error",
|
|
35
|
-
durationMs: nowMs() - start,
|
|
36
|
-
endUserId
|
|
37
|
-
});
|
|
38
|
-
return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
|
|
39
|
-
}
|
|
40
|
-
if (result == null) {
|
|
41
|
-
await recorder.emit({
|
|
42
|
-
tool: tool.name,
|
|
43
|
-
method: "tools/call",
|
|
44
|
-
outcome: "handler_error",
|
|
45
|
-
durationMs: nowMs() - start,
|
|
46
|
-
endUserId
|
|
47
|
-
});
|
|
48
|
-
return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
|
|
49
|
-
}
|
|
50
|
-
await recorder.emit({
|
|
51
|
-
tool: tool.name,
|
|
52
|
-
method: "tools/call",
|
|
53
|
-
outcome: result.isError ? "tool_error" : "ok",
|
|
54
|
-
durationMs: nowMs() - start,
|
|
55
|
-
errorText: result.isError ? extractTextContent(result.content) : void 0,
|
|
56
|
-
endUserId
|
|
57
|
-
});
|
|
58
|
-
return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function createMcpProtocolHandler(mcp, options = {}) {
|
|
62
|
-
const authorizer = createRequestAuthorizer(mcp, options);
|
|
63
|
-
const handle = async (request, recorder) => {
|
|
64
|
-
const authResult = await authorizer.authorize(request, recorder);
|
|
65
|
-
if (!authResult.ok)
|
|
66
|
-
return authResult.response;
|
|
67
|
-
try {
|
|
68
|
-
const server = new McpServer(
|
|
69
|
-
{ name: mcp.name, version: mcp.version, title: mcp.title },
|
|
70
|
-
{ instructions: mcp.instructions }
|
|
71
|
-
);
|
|
72
|
-
for (const tool of mcp.tools) {
|
|
73
|
-
server.registerTool(
|
|
74
|
-
tool.name,
|
|
75
|
-
{
|
|
76
|
-
title: tool.title,
|
|
77
|
-
description: tool.description,
|
|
78
|
-
inputSchema: tool.inputSchema,
|
|
79
|
-
outputSchema: tool.outputSchema,
|
|
80
|
-
annotations: tool.annotations
|
|
81
|
-
},
|
|
82
|
-
adaptToolToSdkCallback(tool, authResult.auth, recorder)
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
const transport = new WebStandardStreamableHTTPServerTransport({
|
|
86
|
-
sessionIdGenerator: void 0
|
|
87
|
-
});
|
|
88
|
-
await server.connect(transport);
|
|
89
|
-
return await transport.handleRequest(request);
|
|
90
|
-
} catch (err) {
|
|
91
|
-
await recorder.emit({
|
|
92
|
-
tool: null,
|
|
93
|
-
method: "transport",
|
|
94
|
-
outcome: "transport_error",
|
|
95
|
-
durationMs: 0,
|
|
96
|
-
endUserId: authResult.auth?.principal.sub
|
|
97
|
-
});
|
|
98
|
-
log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
|
|
99
|
-
return Response.json(
|
|
100
|
-
{ jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
|
|
101
|
-
{ status: 500 }
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
return async (request, recorder = createNoopRecorder()) => {
|
|
106
|
-
if (request.method === "OPTIONS")
|
|
107
|
-
return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
|
|
108
|
-
return withCors(await handle(request, recorder));
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export {
|
|
113
|
-
createMcpProtocolHandler
|
|
114
|
-
};
|