@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/index.cjs
CHANGED
|
@@ -1,149 +1,349 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
ToolContext: () => ToolContext,
|
|
24
|
+
auth: () => auth,
|
|
25
|
+
defineMcp: () => defineMcp,
|
|
26
|
+
defineTool: () => defineTool,
|
|
27
|
+
setLogLevel: () => setLogLevel
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(src_exports);
|
|
30
|
+
|
|
31
|
+
// src/metrics/config.ts
|
|
32
|
+
var DEFAULT_METRICS_ENDPOINT = "https://api.lovable.dev/v1/app-mcp-usage";
|
|
33
|
+
var METRICS_API_KEY_ENV_VAR = "LOVABLE_API_KEY";
|
|
34
|
+
function assertMetricsEndpoint(endpoint) {
|
|
35
|
+
let url;
|
|
36
|
+
try {
|
|
37
|
+
url = new URL(endpoint);
|
|
38
|
+
} catch {
|
|
39
|
+
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be an absolute URL, got ${JSON.stringify(endpoint)}`);
|
|
40
|
+
}
|
|
41
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
42
|
+
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be http(s), got ${JSON.stringify(endpoint)}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function resolveMetricsConfig(config = true) {
|
|
46
|
+
const options = typeof config === "boolean" ? { enabled: config } : config;
|
|
47
|
+
const endpoint = options.endpoint ?? DEFAULT_METRICS_ENDPOINT;
|
|
48
|
+
assertMetricsEndpoint(endpoint);
|
|
49
|
+
return Object.freeze({
|
|
50
|
+
enabled: options.enabled ?? true,
|
|
51
|
+
endpoint,
|
|
52
|
+
headers: options.headers ?? {},
|
|
53
|
+
apiKeyEnvVar: METRICS_API_KEY_ENV_VAR
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/core/url.ts
|
|
58
|
+
function trimTrailingSlash(value) {
|
|
59
|
+
return value.replace(/\/+$/, "");
|
|
60
|
+
}
|
|
61
|
+
function isLocalHTTPHost(hostname) {
|
|
62
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]";
|
|
63
|
+
}
|
|
64
|
+
function urlSafetyProblem(url) {
|
|
65
|
+
const isAllowedHTTP = url.protocol === "http:" && isLocalHTTPHost(url.hostname);
|
|
66
|
+
if (url.protocol !== "https:" && !isAllowedHTTP) {
|
|
67
|
+
return "must use https://, except localhost development URLs";
|
|
68
|
+
}
|
|
69
|
+
if (url.username || url.password) {
|
|
70
|
+
return "must not include credentials";
|
|
71
|
+
}
|
|
72
|
+
if (url.search || url.hash) {
|
|
73
|
+
return "must not include query or fragment";
|
|
74
|
+
}
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/core/validation.ts
|
|
79
|
+
function parseSafeUrl(subject, raw, ErrorClass = Error) {
|
|
80
|
+
let url;
|
|
81
|
+
try {
|
|
82
|
+
url = new URL(raw);
|
|
83
|
+
} catch {
|
|
84
|
+
throw new ErrorClass(`${subject} must be an absolute URL`);
|
|
85
|
+
}
|
|
86
|
+
const problem = urlSafetyProblem(url);
|
|
87
|
+
if (problem) {
|
|
88
|
+
throw new ErrorClass(`${subject} ${problem}`);
|
|
89
|
+
}
|
|
90
|
+
return url;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// src/core/define.ts
|
|
5
94
|
function assertUniqueNames(mcp) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
95
|
+
const seen = /* @__PURE__ */ new Set();
|
|
96
|
+
for (const tool of mcp.tools) {
|
|
97
|
+
if (seen.has(tool.name)) {
|
|
98
|
+
throw new Error(`@lovable.dev/mcp-js: duplicate tool name "${tool.name}"`);
|
|
99
|
+
}
|
|
100
|
+
seen.add(tool.name);
|
|
101
|
+
}
|
|
11
102
|
}
|
|
12
103
|
function assertNonEmptyString(label, value) {
|
|
13
|
-
|
|
14
|
-
|
|
104
|
+
if (value.trim() === "") {
|
|
105
|
+
throw new Error(`@lovable.dev/mcp-js: ${label} must not be empty`);
|
|
106
|
+
}
|
|
107
|
+
if (value !== value.trim()) {
|
|
108
|
+
throw new Error(`@lovable.dev/mcp-js: ${label} must not have leading or trailing whitespace`);
|
|
109
|
+
}
|
|
15
110
|
}
|
|
16
111
|
function assertHttpsUrlField(name, value) {
|
|
17
|
-
|
|
18
|
-
|
|
112
|
+
assertNonEmptyString(`auth.${name}`, value);
|
|
113
|
+
parseSafeUrl(`@lovable.dev/mcp-js: auth.${name}`, value);
|
|
19
114
|
}
|
|
20
115
|
function assertScope(scope) {
|
|
21
|
-
|
|
116
|
+
if (scope.trim() === "" || /\s/.test(scope)) {
|
|
117
|
+
throw new Error(`@lovable.dev/mcp-js: OAuth scopes must be non-empty space-free tokens`);
|
|
118
|
+
}
|
|
22
119
|
}
|
|
23
120
|
function assertJwtAlgorithm(algorithm) {
|
|
24
|
-
|
|
25
|
-
|
|
121
|
+
if (algorithm.trim() === "" || /\s/.test(algorithm)) {
|
|
122
|
+
throw new Error(`@lovable.dev/mcp-js: auth.algorithms must contain non-empty space-free tokens`);
|
|
123
|
+
}
|
|
124
|
+
if (/^HS\d+$/i.test(algorithm) || algorithm.toLowerCase() === "none") {
|
|
125
|
+
throw new Error(`@lovable.dev/mcp-js: auth.algorithms cannot include "${algorithm}"; this verifier is JWKS-only`);
|
|
126
|
+
}
|
|
26
127
|
}
|
|
27
|
-
|
|
128
|
+
var MAX_CLOCK_TOLERANCE_SECONDS = 300;
|
|
28
129
|
function assertClockToleranceSeconds(value) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
130
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > MAX_CLOCK_TOLERANCE_SECONDS) {
|
|
131
|
+
throw new Error(
|
|
132
|
+
`@lovable.dev/mcp-js: auth.clockToleranceSeconds must be a non-negative number of seconds no greater than ${MAX_CLOCK_TOLERANCE_SECONDS}`
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function assertOAuthConfig(auth2) {
|
|
137
|
+
if (auth2.type !== "oauth") {
|
|
138
|
+
const authType = String(auth2.type);
|
|
139
|
+
throw new Error(`@lovable.dev/mcp-js: unsupported auth type "${authType}"`);
|
|
140
|
+
}
|
|
141
|
+
if (auth2.issuer === void 0) {
|
|
142
|
+
throw new Error(`@lovable.dev/mcp-js: auth.issuer is required`);
|
|
143
|
+
}
|
|
144
|
+
assertHttpsUrlField("issuer", auth2.issuer);
|
|
145
|
+
if (auth2.jwksUri !== void 0) {
|
|
146
|
+
assertHttpsUrlField("jwksUri", auth2.jwksUri);
|
|
147
|
+
}
|
|
148
|
+
if (auth2.resource !== void 0) {
|
|
149
|
+
assertHttpsUrlField("resource", auth2.resource);
|
|
150
|
+
}
|
|
151
|
+
if (auth2.resourceName !== void 0) {
|
|
152
|
+
assertNonEmptyString("auth.resourceName", auth2.resourceName);
|
|
153
|
+
}
|
|
154
|
+
if (auth2.resourceDocumentation !== void 0) {
|
|
155
|
+
assertHttpsUrlField("resourceDocumentation", auth2.resourceDocumentation);
|
|
156
|
+
}
|
|
157
|
+
if (auth2.protectedResourceMetadataUrl !== void 0) {
|
|
158
|
+
assertHttpsUrlField("protectedResourceMetadataUrl", auth2.protectedResourceMetadataUrl);
|
|
159
|
+
}
|
|
160
|
+
if (auth2.acceptedAudiences !== void 0) {
|
|
161
|
+
if (!Array.isArray(auth2.acceptedAudiences)) {
|
|
162
|
+
throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must be an array`);
|
|
163
|
+
}
|
|
164
|
+
if (auth2.acceptedAudiences.length === 0) {
|
|
165
|
+
throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must not be empty`);
|
|
166
|
+
}
|
|
167
|
+
for (const audience of auth2.acceptedAudiences) {
|
|
168
|
+
if (typeof audience !== "string") {
|
|
169
|
+
throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must contain strings`);
|
|
170
|
+
}
|
|
171
|
+
assertNonEmptyString("auth.acceptedAudiences", audience);
|
|
172
|
+
if (trimTrailingSlash(audience) === "") {
|
|
173
|
+
throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences entries must not be only slashes`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (auth2.requireOAuthClientClaim !== void 0 && typeof auth2.requireOAuthClientClaim !== "boolean") {
|
|
178
|
+
throw new Error(`@lovable.dev/mcp-js: auth.requireOAuthClientClaim must be a boolean`);
|
|
179
|
+
}
|
|
180
|
+
if (auth2.acceptResourceClaim !== void 0 && typeof auth2.acceptResourceClaim !== "boolean") {
|
|
181
|
+
throw new Error(`@lovable.dev/mcp-js: auth.acceptResourceClaim must be a boolean`);
|
|
182
|
+
}
|
|
183
|
+
if (auth2.requiredScopes !== void 0) {
|
|
184
|
+
if (!Array.isArray(auth2.requiredScopes)) {
|
|
185
|
+
throw new Error(`@lovable.dev/mcp-js: auth.requiredScopes must be an array`);
|
|
186
|
+
}
|
|
187
|
+
for (const scope of auth2.requiredScopes)
|
|
188
|
+
assertScope(scope);
|
|
189
|
+
}
|
|
190
|
+
if (auth2.algorithms !== void 0) {
|
|
191
|
+
if (!Array.isArray(auth2.algorithms)) {
|
|
192
|
+
throw new Error(`@lovable.dev/mcp-js: auth.algorithms must be an array`);
|
|
193
|
+
}
|
|
194
|
+
if (auth2.algorithms.length === 0) {
|
|
195
|
+
throw new Error(`@lovable.dev/mcp-js: auth.algorithms must not be empty`);
|
|
196
|
+
}
|
|
197
|
+
for (const algorithm of auth2.algorithms)
|
|
198
|
+
assertJwtAlgorithm(algorithm);
|
|
199
|
+
}
|
|
200
|
+
if (auth2.accessTokenTyp !== void 0) {
|
|
201
|
+
if (!Array.isArray(auth2.accessTokenTyp)) {
|
|
202
|
+
throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must be an array`);
|
|
203
|
+
}
|
|
204
|
+
if (auth2.accessTokenTyp.length === 0) {
|
|
205
|
+
throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must not be empty`);
|
|
206
|
+
}
|
|
207
|
+
for (const typ of auth2.accessTokenTyp) {
|
|
208
|
+
if (typeof typ !== "string") {
|
|
209
|
+
throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must contain strings`);
|
|
210
|
+
}
|
|
211
|
+
assertNonEmptyString("auth.accessTokenTyp", typ);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (auth2.clockToleranceSeconds !== void 0)
|
|
215
|
+
assertClockToleranceSeconds(auth2.clockToleranceSeconds);
|
|
216
|
+
if (auth2.resource === void 0 && auth2.acceptedAudiences === void 0) {
|
|
217
|
+
throw new Error(`@lovable.dev/mcp-js: auth.resource or auth.acceptedAudiences is required`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
function freezeAuth(auth2) {
|
|
221
|
+
if (!auth2)
|
|
222
|
+
return;
|
|
223
|
+
if (auth2.acceptedAudiences)
|
|
224
|
+
Object.freeze(auth2.acceptedAudiences);
|
|
225
|
+
if (auth2.requiredScopes)
|
|
226
|
+
Object.freeze(auth2.requiredScopes);
|
|
227
|
+
if (auth2.algorithms)
|
|
228
|
+
Object.freeze(auth2.algorithms);
|
|
229
|
+
if (auth2.accessTokenTyp)
|
|
230
|
+
Object.freeze(auth2.accessTokenTyp);
|
|
231
|
+
Object.freeze(auth2);
|
|
232
|
+
}
|
|
90
233
|
function defineTool(def) {
|
|
91
|
-
|
|
234
|
+
return def;
|
|
92
235
|
}
|
|
93
|
-
/**
|
|
94
|
-
* Declare the MCP server. `export default` the result from your MCP
|
|
95
|
-
* entrypoint (default `lib/mcp/index.ts`); the Vite plugin reads it to
|
|
96
|
-
* emit the framework-specific route(s) at build time.
|
|
97
|
-
*/
|
|
98
236
|
function defineMcp(def) {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
237
|
+
assertNonEmptyString("name", def.name);
|
|
238
|
+
assertNonEmptyString("title", def.title);
|
|
239
|
+
assertNonEmptyString("version", def.version);
|
|
240
|
+
assertUniqueNames(def);
|
|
241
|
+
if (def.auth)
|
|
242
|
+
assertOAuthConfig(def.auth);
|
|
243
|
+
resolveMetricsConfig(def.metrics);
|
|
244
|
+
freezeAuth(def.auth);
|
|
245
|
+
Object.freeze(def.tools);
|
|
246
|
+
for (const tool of def.tools)
|
|
247
|
+
Object.freeze(tool);
|
|
248
|
+
return def;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/auth/config.ts
|
|
112
252
|
function frozenArray(value) {
|
|
113
|
-
|
|
253
|
+
return value === void 0 ? void 0 : Object.freeze([...value]);
|
|
114
254
|
}
|
|
115
255
|
function frozenAudiences(value) {
|
|
116
|
-
|
|
256
|
+
return frozenArray(typeof value === "string" ? [value] : value);
|
|
117
257
|
}
|
|
118
|
-
/** Mutates `value` in place; callers pass a fresh literal so deleting keys is safe. */
|
|
119
258
|
function stripUndefined(value) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
* carrying an accepted `aud` passes. When an issuer mints broad project-wide
|
|
127
|
-
* audiences (e.g. Supabase's `aud: "authenticated"`), a token for one resource
|
|
128
|
-
* is structurally accepted by another sharing that audience — so gate per-tool
|
|
129
|
-
* authorization on `ctx.getClaims()` / `ctx.getClientId()`, never on the
|
|
130
|
-
* accepted audience.
|
|
131
|
-
*/
|
|
259
|
+
for (const key of Object.keys(value)) {
|
|
260
|
+
if (value[key] === void 0)
|
|
261
|
+
delete value[key];
|
|
262
|
+
}
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
132
265
|
function issuer(options) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
266
|
+
return Object.freeze(
|
|
267
|
+
stripUndefined({
|
|
268
|
+
type: "oauth",
|
|
269
|
+
...options,
|
|
270
|
+
acceptedAudiences: frozenAudiences(options.acceptedAudiences),
|
|
271
|
+
requiredScopes: frozenArray(options.requiredScopes),
|
|
272
|
+
algorithms: frozenArray(options.algorithms),
|
|
273
|
+
accessTokenTyp: frozenArray(options.accessTokenTyp)
|
|
274
|
+
})
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
var oauth = Object.freeze({ issuer });
|
|
278
|
+
var auth = Object.freeze({ oauth });
|
|
279
|
+
|
|
280
|
+
// src/auth/context.ts
|
|
281
|
+
var ToolContext = class {
|
|
282
|
+
#auth;
|
|
283
|
+
constructor(auth2) {
|
|
284
|
+
this.#auth = auth2;
|
|
285
|
+
}
|
|
286
|
+
/** Whether the in-flight tool call carries a verified auth context. */
|
|
287
|
+
isAuthenticated() {
|
|
288
|
+
return this.#auth !== void 0;
|
|
289
|
+
}
|
|
290
|
+
/** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
|
|
291
|
+
getToken() {
|
|
292
|
+
return this.#auth?.bearer.token;
|
|
293
|
+
}
|
|
294
|
+
/** The verified user id (the token `sub`), or `undefined`. */
|
|
295
|
+
getUserId() {
|
|
296
|
+
return this.#auth?.principal.sub;
|
|
297
|
+
}
|
|
298
|
+
/** The verified user email, or `undefined` when absent. */
|
|
299
|
+
getUserEmail() {
|
|
300
|
+
return this.#auth?.principal.email;
|
|
301
|
+
}
|
|
302
|
+
/** The verified OAuth `client_id`, or `undefined`. */
|
|
303
|
+
getClientId() {
|
|
304
|
+
return this.#auth?.principal.clientId;
|
|
305
|
+
}
|
|
306
|
+
/** The verified OAuth scopes, or `undefined` when unauthenticated. */
|
|
307
|
+
getScopes() {
|
|
308
|
+
return this.#auth?.principal.scopes;
|
|
309
|
+
}
|
|
310
|
+
/** The verified token issuer, or `undefined`. */
|
|
311
|
+
getIssuer() {
|
|
312
|
+
return this.#auth?.principal.issuer;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* The full verified JWT claims, or `undefined`. Use this for app/business
|
|
316
|
+
* authorization on issuer-specific claims that have no dedicated accessor.
|
|
317
|
+
*/
|
|
318
|
+
getClaims() {
|
|
319
|
+
return this.#auth?.principal.claims;
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
|
|
323
|
+
// src/core/logger.ts
|
|
324
|
+
var LEVEL_RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
|
|
325
|
+
function isLogLevel(value) {
|
|
326
|
+
return typeof value === "string" && value in LEVEL_RANK;
|
|
327
|
+
}
|
|
328
|
+
var LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
|
|
329
|
+
function readEnvLevel() {
|
|
330
|
+
try {
|
|
331
|
+
const raw = typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0;
|
|
332
|
+
const normalized = raw?.trim().toLowerCase();
|
|
333
|
+
return isLogLevel(normalized) ? normalized : void 0;
|
|
334
|
+
} catch {
|
|
335
|
+
return void 0;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
var currentLevel = readEnvLevel() ?? "debug";
|
|
339
|
+
function setLogLevel(level) {
|
|
340
|
+
currentLevel = level;
|
|
341
|
+
}
|
|
342
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
343
|
+
0 && (module.exports = {
|
|
344
|
+
ToolContext,
|
|
345
|
+
auth,
|
|
346
|
+
defineMcp,
|
|
347
|
+
defineTool,
|
|
348
|
+
setLogLevel
|
|
349
|
+
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-qqrmJ736.js';
|
|
2
|
+
export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-qqrmJ736.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Declare a single MCP tool. Import the result into your MCP definition's
|
|
5
7
|
* `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
|
|
@@ -15,28 +17,27 @@ declare function defineTool<TInput extends ZodRawShape | undefined = undefined,
|
|
|
15
17
|
* emit the framework-specific route(s) at build time.
|
|
16
18
|
*/
|
|
17
19
|
declare function defineMcp(def: McpDefinitionInput): McpDefinition;
|
|
18
|
-
|
|
19
|
-
//#region src/auth/config.d.ts
|
|
20
|
+
|
|
20
21
|
type IssuerAcceptedAudiences = string | readonly string[];
|
|
21
22
|
interface IssuerOAuthOptionsBase {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
readonly resourceName?: string;
|
|
24
|
+
readonly resourceDocumentation?: string;
|
|
25
|
+
readonly protectedResourceMetadataUrl?: string;
|
|
26
|
+
readonly requireOAuthClientClaim?: boolean;
|
|
27
|
+
readonly acceptResourceClaim?: boolean;
|
|
28
|
+
readonly issuer: string;
|
|
29
|
+
readonly requiredScopes?: readonly string[];
|
|
30
|
+
readonly jwksUri?: string;
|
|
31
|
+
readonly algorithms?: readonly string[];
|
|
32
|
+
readonly clockToleranceSeconds?: number;
|
|
33
|
+
readonly accessTokenTyp?: readonly string[];
|
|
33
34
|
}
|
|
34
35
|
type IssuerOAuthOptions = IssuerOAuthOptionsBase & ({
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
readonly resource: string;
|
|
37
|
+
readonly acceptedAudiences?: IssuerAcceptedAudiences;
|
|
37
38
|
} | {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
readonly resource?: string;
|
|
40
|
+
readonly acceptedAudiences: IssuerAcceptedAudiences;
|
|
40
41
|
});
|
|
41
42
|
/**
|
|
42
43
|
* Configure OAuth against an issuer. `acceptedAudiences` (or `resource`) is the
|
|
@@ -49,12 +50,11 @@ type IssuerOAuthOptions = IssuerOAuthOptionsBase & ({
|
|
|
49
50
|
*/
|
|
50
51
|
declare function issuer(options: IssuerOAuthOptions): McpAuthConfig;
|
|
51
52
|
declare const auth: Readonly<{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
oauth: Readonly<{
|
|
54
|
+
issuer: typeof issuer;
|
|
55
|
+
}>;
|
|
55
56
|
}>;
|
|
56
|
-
|
|
57
|
-
//#region src/core/logger.d.ts
|
|
57
|
+
|
|
58
58
|
type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
59
59
|
/**
|
|
60
60
|
* Set the runtime log level programmatically. Use this when the deployment can't
|
|
@@ -62,5 +62,5 @@ type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
|
62
62
|
* passes vars via bindings): call `setLogLevel("debug")` once at server startup.
|
|
63
63
|
*/
|
|
64
64
|
declare function setLogLevel(level: LogLevel): void;
|
|
65
|
-
|
|
66
|
-
export { type
|
|
65
|
+
|
|
66
|
+
export { type IssuerOAuthOptions, type LogLevel, McpDefinitionInput, ToolDefinition, ZodRawShape, auth, defineMcp, defineTool, setLogLevel };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-qqrmJ736.js';
|
|
2
|
+
export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-qqrmJ736.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Declare a single MCP tool. Import the result into your MCP definition's
|
|
5
7
|
* `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
|
|
@@ -15,28 +17,27 @@ declare function defineTool<TInput extends ZodRawShape | undefined = undefined,
|
|
|
15
17
|
* emit the framework-specific route(s) at build time.
|
|
16
18
|
*/
|
|
17
19
|
declare function defineMcp(def: McpDefinitionInput): McpDefinition;
|
|
18
|
-
|
|
19
|
-
//#region src/auth/config.d.ts
|
|
20
|
+
|
|
20
21
|
type IssuerAcceptedAudiences = string | readonly string[];
|
|
21
22
|
interface IssuerOAuthOptionsBase {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
readonly resourceName?: string;
|
|
24
|
+
readonly resourceDocumentation?: string;
|
|
25
|
+
readonly protectedResourceMetadataUrl?: string;
|
|
26
|
+
readonly requireOAuthClientClaim?: boolean;
|
|
27
|
+
readonly acceptResourceClaim?: boolean;
|
|
28
|
+
readonly issuer: string;
|
|
29
|
+
readonly requiredScopes?: readonly string[];
|
|
30
|
+
readonly jwksUri?: string;
|
|
31
|
+
readonly algorithms?: readonly string[];
|
|
32
|
+
readonly clockToleranceSeconds?: number;
|
|
33
|
+
readonly accessTokenTyp?: readonly string[];
|
|
33
34
|
}
|
|
34
35
|
type IssuerOAuthOptions = IssuerOAuthOptionsBase & ({
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
readonly resource: string;
|
|
37
|
+
readonly acceptedAudiences?: IssuerAcceptedAudiences;
|
|
37
38
|
} | {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
readonly resource?: string;
|
|
40
|
+
readonly acceptedAudiences: IssuerAcceptedAudiences;
|
|
40
41
|
});
|
|
41
42
|
/**
|
|
42
43
|
* Configure OAuth against an issuer. `acceptedAudiences` (or `resource`) is the
|
|
@@ -49,12 +50,11 @@ type IssuerOAuthOptions = IssuerOAuthOptionsBase & ({
|
|
|
49
50
|
*/
|
|
50
51
|
declare function issuer(options: IssuerOAuthOptions): McpAuthConfig;
|
|
51
52
|
declare const auth: Readonly<{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
oauth: Readonly<{
|
|
54
|
+
issuer: typeof issuer;
|
|
55
|
+
}>;
|
|
55
56
|
}>;
|
|
56
|
-
|
|
57
|
-
//#region src/core/logger.d.ts
|
|
57
|
+
|
|
58
58
|
type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
59
59
|
/**
|
|
60
60
|
* Set the runtime log level programmatically. Use this when the deployment can't
|
|
@@ -62,5 +62,5 @@ type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
|
62
62
|
* passes vars via bindings): call `setLogLevel("debug")` once at server startup.
|
|
63
63
|
*/
|
|
64
64
|
declare function setLogLevel(level: LogLevel): void;
|
|
65
|
-
|
|
66
|
-
export { type
|
|
65
|
+
|
|
66
|
+
export { type IssuerOAuthOptions, type LogLevel, McpDefinitionInput, ToolDefinition, ZodRawShape, auth, defineMcp, defineTool, setLogLevel };
|