@lovable.dev/mcp-js 2.1.0-rc.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +1 -82
  2. package/dist/{authorize-BC4TM__8.d.cts → authorize-CzyL7nmF.d.cts} +1 -1
  3. package/dist/{authorize-DEsM-zTN.d.ts → authorize-Drz_eJ7O.d.ts} +1 -1
  4. package/dist/{base-BnlJz6TE.d.ts → base-COwtdWE8.d.ts} +2 -2
  5. package/dist/{base-4G2k3bMl.d.cts → base-DD4MCXZ6.d.cts} +2 -2
  6. package/dist/cli/extract-manifest.cjs +1 -1
  7. package/dist/cli/extract-manifest.js +1 -1
  8. package/dist/{cors-D4BjUpgU.js → cors-BaRKDl4r.js} +1 -1
  9. package/dist/{cors-0ZCwmwyK.cjs → cors-D-X0aP4O.cjs} +1 -1
  10. package/dist/errors-Bwd1L0Rf.js +100 -0
  11. package/dist/errors-Cr95rSkB.cjs +123 -0
  12. package/dist/index.cjs +147 -4
  13. package/dist/index.d.cts +4 -12
  14. package/dist/index.d.ts +4 -12
  15. package/dist/index.js +147 -3
  16. package/dist/{io-BEoJ_gb5.js → io-DG83CLKx.js} +2 -3
  17. package/dist/{io-Cz81GsrM.cjs → io-DZD6xmJQ.cjs} +2 -3
  18. package/dist/{io-9jGNgPfl.d.cts → io-Ds5MRSiK.d.cts} +1 -1
  19. package/dist/{io-BLZ8jYW6.d.ts → io-pl5npWDw.d.ts} +1 -1
  20. package/dist/{mcp-Q_rjpR99.cjs → mcp-Bx3LUn5O.cjs} +15 -92
  21. package/dist/{mcp-CuHyVOZK.js → mcp-DcmfehoI.js} +15 -92
  22. package/dist/{package-BAYb-3dX.js → package-BNFIhH0F.js} +1 -1
  23. package/dist/{package-DlouusYQ.cjs → package-CFVl3oIe.cjs} +1 -1
  24. package/dist/protocols/mcp/index.cjs +1 -1
  25. package/dist/protocols/mcp/index.d.cts +3 -3
  26. package/dist/protocols/mcp/index.d.ts +3 -3
  27. package/dist/protocols/mcp/index.js +1 -1
  28. package/dist/protocols/oauth-metadata.cjs +1 -1
  29. package/dist/protocols/oauth-metadata.d.cts +3 -3
  30. package/dist/protocols/oauth-metadata.d.ts +3 -3
  31. package/dist/protocols/oauth-metadata.js +1 -1
  32. package/dist/stacks/supabase/index.cjs +2 -2
  33. package/dist/stacks/supabase/index.d.cts +1 -1
  34. package/dist/stacks/supabase/index.d.ts +1 -1
  35. package/dist/stacks/supabase/index.js +2 -2
  36. package/dist/stacks/supabase/vite.cjs +1 -1
  37. package/dist/stacks/supabase/vite.d.cts +1 -1
  38. package/dist/stacks/supabase/vite.d.ts +1 -1
  39. package/dist/stacks/supabase/vite.js +1 -1
  40. package/dist/stacks/tanstack/index.cjs +2 -2
  41. package/dist/stacks/tanstack/index.d.cts +2 -2
  42. package/dist/stacks/tanstack/index.d.ts +2 -2
  43. package/dist/stacks/tanstack/index.js +2 -2
  44. package/dist/stacks/tanstack/vite.d.cts +1 -1
  45. package/dist/stacks/tanstack/vite.d.ts +1 -1
  46. package/dist/{types-S6J_QTXw.d.cts → types-B3_lX-L1.d.cts} +25 -60
  47. package/dist/{types-S6J_QTXw.d.ts → types-B3_lX-L1.d.ts} +25 -60
  48. package/package.json +2 -2
  49. package/dist/errors-CdrGi5aP.cjs +0 -309
  50. package/dist/errors-DTvfh8lb.js +0 -262
package/dist/index.js CHANGED
@@ -1,5 +1,149 @@
1
- import { a as setLogLevel } from "./logger-Ctv5xUSD.js";
2
- import { a as ToolContext, i as AuthContext, o as defineMcp, s as defineTool, t as ToolError } from "./errors-DTvfh8lb.js";
1
+ import { a as setLogLevel, o as parseSafeUrl, s as trimTrailingSlash, u as resolveMetricsConfig } from "./logger-Ctv5xUSD.js";
2
+ import { t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.js";
3
+ import { i as ToolContext, t as ToolError } from "./errors-Bwd1L0Rf.js";
4
+ //#region src/core/define.ts
5
+ function assertUniqueNames(mcp) {
6
+ const seen = /* @__PURE__ */ new Set();
7
+ for (const tool of mcp.tools) {
8
+ if (seen.has(tool.name)) throw new Error(`@lovable.dev/mcp-js: duplicate tool name "${tool.name}"`);
9
+ seen.add(tool.name);
10
+ }
11
+ }
12
+ function assertNonEmptyString(label, value) {
13
+ if (value.trim() === "") throw new Error(`@lovable.dev/mcp-js: ${label} must not be empty`);
14
+ if (value !== value.trim()) throw new Error(`@lovable.dev/mcp-js: ${label} must not have leading or trailing whitespace`);
15
+ }
16
+ function assertHttpsUrlField(name, value) {
17
+ assertNonEmptyString(`auth.${name}`, value);
18
+ parseSafeUrl(`@lovable.dev/mcp-js: auth.${name}`, value);
19
+ }
20
+ function assertScope(scope) {
21
+ if (scope.trim() === "" || /\s/.test(scope)) throw new Error(`@lovable.dev/mcp-js: OAuth scopes must be non-empty space-free tokens`);
22
+ }
23
+ function assertJwtAlgorithm(algorithm) {
24
+ if (algorithm.trim() === "" || /\s/.test(algorithm)) throw new Error(`@lovable.dev/mcp-js: auth.algorithms must contain non-empty space-free tokens`);
25
+ if (/^HS\d+$/i.test(algorithm) || algorithm.toLowerCase() === "none") throw new Error(`@lovable.dev/mcp-js: auth.algorithms cannot include "${algorithm}"; this verifier is JWKS-only`);
26
+ }
27
+ const MAX_CLOCK_TOLERANCE_SECONDS = 300;
28
+ function assertClockToleranceSeconds(value) {
29
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > MAX_CLOCK_TOLERANCE_SECONDS) throw new Error(`@lovable.dev/mcp-js: auth.clockToleranceSeconds must be a non-negative number of seconds no greater than ${MAX_CLOCK_TOLERANCE_SECONDS}`);
30
+ }
31
+ function assertOAuthConfig(auth) {
32
+ if (auth.type !== "oauth") {
33
+ const authType = String(auth.type);
34
+ throw new Error(`@lovable.dev/mcp-js: unsupported auth type "${authType}"`);
35
+ }
36
+ if (auth.issuer === void 0) throw new Error(`@lovable.dev/mcp-js: auth.issuer is required`);
37
+ assertHttpsUrlField("issuer", auth.issuer);
38
+ if (auth.jwksUri !== void 0) assertHttpsUrlField("jwksUri", auth.jwksUri);
39
+ if (auth.resource !== void 0) assertHttpsUrlField("resource", auth.resource);
40
+ if (auth.resourceName !== void 0) assertNonEmptyString("auth.resourceName", auth.resourceName);
41
+ if (auth.resourceDocumentation !== void 0) assertHttpsUrlField("resourceDocumentation", auth.resourceDocumentation);
42
+ if (auth.protectedResourceMetadataUrl !== void 0) assertHttpsUrlField("protectedResourceMetadataUrl", auth.protectedResourceMetadataUrl);
43
+ if (auth.acceptedAudiences !== void 0) {
44
+ if (!Array.isArray(auth.acceptedAudiences)) throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must be an array`);
45
+ if (auth.acceptedAudiences.length === 0) throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must not be empty`);
46
+ for (const audience of auth.acceptedAudiences) {
47
+ if (typeof audience !== "string") throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences must contain strings`);
48
+ assertNonEmptyString("auth.acceptedAudiences", audience);
49
+ if (trimTrailingSlash(audience) === "") throw new Error(`@lovable.dev/mcp-js: auth.acceptedAudiences entries must not be only slashes`);
50
+ }
51
+ }
52
+ if (auth.requireOAuthClientClaim !== void 0 && typeof auth.requireOAuthClientClaim !== "boolean") throw new Error(`@lovable.dev/mcp-js: auth.requireOAuthClientClaim must be a boolean`);
53
+ if (auth.acceptResourceClaim !== void 0 && typeof auth.acceptResourceClaim !== "boolean") throw new Error(`@lovable.dev/mcp-js: auth.acceptResourceClaim must be a boolean`);
54
+ if (auth.requiredScopes !== void 0) {
55
+ if (!Array.isArray(auth.requiredScopes)) throw new Error(`@lovable.dev/mcp-js: auth.requiredScopes must be an array`);
56
+ for (const scope of auth.requiredScopes) assertScope(scope);
57
+ }
58
+ if (auth.algorithms !== void 0) {
59
+ if (!Array.isArray(auth.algorithms)) throw new Error(`@lovable.dev/mcp-js: auth.algorithms must be an array`);
60
+ if (auth.algorithms.length === 0) throw new Error(`@lovable.dev/mcp-js: auth.algorithms must not be empty`);
61
+ for (const algorithm of auth.algorithms) assertJwtAlgorithm(algorithm);
62
+ }
63
+ if (auth.accessTokenTyp !== void 0) {
64
+ if (!Array.isArray(auth.accessTokenTyp)) throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must be an array`);
65
+ if (auth.accessTokenTyp.length === 0) throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must not be empty`);
66
+ for (const typ of auth.accessTokenTyp) {
67
+ if (typeof typ !== "string") throw new Error(`@lovable.dev/mcp-js: auth.accessTokenTyp must contain strings`);
68
+ assertNonEmptyString("auth.accessTokenTyp", typ);
69
+ }
70
+ }
71
+ if (auth.clockToleranceSeconds !== void 0) assertClockToleranceSeconds(auth.clockToleranceSeconds);
72
+ if (auth.resource === void 0 && auth.acceptedAudiences === void 0) throw new Error(`@lovable.dev/mcp-js: auth.resource or auth.acceptedAudiences is required`);
73
+ }
74
+ function freezeAuth(auth) {
75
+ if (!auth) return;
76
+ if (auth.acceptedAudiences) Object.freeze(auth.acceptedAudiences);
77
+ if (auth.requiredScopes) Object.freeze(auth.requiredScopes);
78
+ if (auth.algorithms) Object.freeze(auth.algorithms);
79
+ if (auth.accessTokenTyp) Object.freeze(auth.accessTokenTyp);
80
+ Object.freeze(auth);
81
+ }
82
+ function assertAllowedOrigins(allowedOrigins) {
83
+ if (allowedOrigins === void 0 || allowedOrigins === "any") return;
84
+ if (!Array.isArray(allowedOrigins)) throw new Error(`@lovable.dev/mcp-js: allowedOrigins must be "any" or an array of exact origins`);
85
+ for (const origin of allowedOrigins) {
86
+ if (typeof origin !== "string") throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain strings`);
87
+ let parsed;
88
+ try {
89
+ parsed = new URL(origin);
90
+ } catch {
91
+ throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain valid exact origins`);
92
+ }
93
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.origin !== origin) throw new Error(`@lovable.dev/mcp-js: allowedOrigins entry "${origin}" must be an exact http(s) origin without a path, query, fragment, or trailing slash`);
94
+ }
95
+ }
96
+ function assertToolSchemas(mcp) {
97
+ for (const tool of mcp.tools) for (const [name, definition, strategy] of [[
98
+ "inputSchema",
99
+ tool.inputSchema,
100
+ "input"
101
+ ], [
102
+ "outputSchema",
103
+ tool.outputSchema,
104
+ "output"
105
+ ]]) {
106
+ if (!definition) continue;
107
+ try {
108
+ jsonSchemaFromDefinition(definition, strategy);
109
+ } catch (error) {
110
+ const detail = error instanceof Error ? `: ${error.message}` : "";
111
+ throw new Error(`@lovable.dev/mcp-js: tool "${tool.name}" ${name} cannot be represented as JSON Schema${detail}`);
112
+ }
113
+ }
114
+ }
115
+ /**
116
+ * Declare a single MCP tool. Import the result into your MCP definition's
117
+ * `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
118
+ *
119
+ * `inputSchema` is a raw zod shape (e.g. `{ text: z.string() }`), not a
120
+ * full `z.object(...)` — the MCP SDK builds the object wrapper internally
121
+ * and the raw shape is what the JSON-RPC `tools/list` payload exposes.
122
+ */
123
+ function defineTool(def) {
124
+ return def;
125
+ }
126
+ /**
127
+ * Declare the MCP server. `export default` the result from your MCP
128
+ * entrypoint (default `lib/mcp/index.ts`); the Vite plugin reads it to
129
+ * emit the framework-specific route(s) at build time.
130
+ */
131
+ function defineMcp(def) {
132
+ assertNonEmptyString("name", def.name);
133
+ assertNonEmptyString("title", def.title);
134
+ assertNonEmptyString("version", def.version);
135
+ assertUniqueNames(def);
136
+ if (def.auth) assertOAuthConfig(def.auth);
137
+ assertAllowedOrigins(def.allowedOrigins);
138
+ assertToolSchemas(def);
139
+ resolveMetricsConfig(def.metrics);
140
+ freezeAuth(def.auth);
141
+ if (Array.isArray(def.allowedOrigins)) Object.freeze(def.allowedOrigins);
142
+ Object.freeze(def.tools);
143
+ for (const tool of def.tools) Object.freeze(tool);
144
+ return def;
145
+ }
146
+ //#endregion
3
147
  //#region src/auth/config.ts
4
148
  function frozenArray(value) {
5
149
  return value === void 0 ? void 0 : Object.freeze([...value]);
@@ -34,4 +178,4 @@ function issuer(options) {
34
178
  const oauth = Object.freeze({ issuer });
35
179
  const auth = Object.freeze({ oauth });
36
180
  //#endregion
37
- export { AuthContext, ToolContext, ToolError, auth, defineMcp, defineTool, setLogLevel };
181
+ export { ToolContext, ToolError, auth, defineMcp, defineTool, setLogLevel };
@@ -1,5 +1,5 @@
1
1
  import { t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.js";
2
- import { t as version } from "./package-BAYb-3dX.js";
2
+ import { t as version } from "./package-BNFIhH0F.js";
3
3
  import { t as isFileMissing } from "./fs-errors-PA2t1TIp.js";
4
4
  import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
5
5
  import { dirname, resolve } from "node:path";
@@ -23,8 +23,7 @@ function buildMcpListing(mcp) {
23
23
  description: tool.description,
24
24
  annotations: tool.annotations,
25
25
  inputSchema: schemaToJsonSchema(tool.inputSchema, "input"),
26
- outputSchema: schemaToJsonSchema(tool.outputSchema, "output"),
27
- ...tool.enabled ? { conditional: true } : {}
26
+ outputSchema: schemaToJsonSchema(tool.outputSchema, "output")
28
27
  }))
29
28
  };
30
29
  }
@@ -1,5 +1,5 @@
1
1
  const require_schema = require("./schema-D3vClxb7.cjs");
2
- const require_package = require("./package-DlouusYQ.cjs");
2
+ const require_package = require("./package-CFVl3oIe.cjs");
3
3
  const require_fs_errors = require("./fs-errors-CWNzOV75.cjs");
4
4
  let node_fs = require("node:fs");
5
5
  let node_path = require("node:path");
@@ -23,8 +23,7 @@ function buildMcpListing(mcp) {
23
23
  description: tool.description,
24
24
  annotations: tool.annotations,
25
25
  inputSchema: schemaToJsonSchema(tool.inputSchema, "input"),
26
- outputSchema: schemaToJsonSchema(tool.outputSchema, "output"),
27
- ...tool.enabled ? { conditional: true } : {}
26
+ outputSchema: schemaToJsonSchema(tool.outputSchema, "output")
28
27
  }))
29
28
  };
30
29
  }
@@ -1,4 +1,4 @@
1
- import "./types-S6J_QTXw.cjs";
1
+ import "./types-B3_lX-L1.cjs";
2
2
  //#region src/manifest/io.d.ts
3
3
  /**
4
4
  * Shape every MCP Vite plugin exposes on its `api` so `runExtract` can read
@@ -1,4 +1,4 @@
1
- import "./types-S6J_QTXw.js";
1
+ import "./types-B3_lX-L1.js";
2
2
  //#region src/manifest/io.d.ts
3
3
  /**
4
4
  * Shape every MCP Vite plugin exposes on its `api` so `runExtract` can read
@@ -1,7 +1,7 @@
1
1
  const require_logger = require("./logger-CN1q-KNn.cjs");
2
2
  const require_schema = require("./schema-D3vClxb7.cjs");
3
- const require_errors = require("./errors-CdrGi5aP.cjs");
4
- const require_cors = require("./cors-0ZCwmwyK.cjs");
3
+ const require_errors = require("./errors-Cr95rSkB.cjs");
4
+ const require_cors = require("./cors-D-X0aP4O.cjs");
5
5
  let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
6
6
  let _modelcontextprotocol_server = require("@modelcontextprotocol/server");
7
7
  //#region src/core/content.ts
@@ -117,52 +117,6 @@ function createGatedHandler(gate) {
117
117
  //#endregion
118
118
  //#region src/protocols/mcp/protocol.ts
119
119
  const MODERN_PROTOCOL_VERSION = "2026-07-28";
120
- const HOUR_MS = 3600 * 1e3;
121
- const NO_OPERATIONS = {
122
- listTools: false,
123
- calledTools: /* @__PURE__ */ new Set()
124
- };
125
- function collectRequestOperations(value, calledTools) {
126
- if (Array.isArray(value)) {
127
- let listTools = false;
128
- for (const item of value) listTools = collectRequestOperations(item, calledTools) || listTools;
129
- return listTools;
130
- }
131
- if (!isPlainObject(value)) return false;
132
- if (value.method === "tools/list") return true;
133
- if (value.method === "tools/call" && isPlainObject(value.params) && typeof value.params.name === "string") calledTools.add(value.params.name);
134
- return false;
135
- }
136
- /** Marks a failure in app-owned `createAppContext` or `enabled` code so telemetry
137
- * can attribute it to the author rather than to the transport. */
138
- var AppContextError = class extends Error {
139
- constructor(cause) {
140
- super("app context evaluation failed", { cause });
141
- this.name = "AppContextError";
142
- }
143
- };
144
- async function withAppContextError(run) {
145
- try {
146
- return await run();
147
- } catch (cause) {
148
- throw new AppContextError(cause);
149
- }
150
- }
151
- async function classifyRequest(request) {
152
- try {
153
- const parsedBody = await request.clone().json();
154
- const calledTools = /* @__PURE__ */ new Set();
155
- return {
156
- operations: {
157
- listTools: collectRequestOperations(parsedBody, calledTools),
158
- calledTools
159
- },
160
- parsedBody
161
- };
162
- } catch {
163
- return { operations: NO_OPERATIONS };
164
- }
165
- }
166
120
  function statelessMethodNotAllowed(allow) {
167
121
  return Response.json({
168
122
  jsonrpc: "2.0",
@@ -237,12 +191,12 @@ function toolRequestContext(sdkCtx, protocol) {
237
191
  sendProgress
238
192
  };
239
193
  }
240
- async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appContext) {
194
+ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
241
195
  const endUserId = auth?.principal.sub;
242
196
  const start = require_cors.nowMs();
243
197
  let result;
244
198
  try {
245
- result = await tool.handler(args, new require_errors.ToolContext(auth, toolRequestContext(sdkCtx, protocol), appContext));
199
+ result = await tool.handler(args, new require_errors.ToolContext(auth, toolRequestContext(sdkCtx, protocol)));
246
200
  } catch (err) {
247
201
  const callerMessage = require_errors.resolveToolErrorMessage(err);
248
202
  if (callerMessage === void 0) {
@@ -300,10 +254,10 @@ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appConte
300
254
  });
301
255
  return result;
302
256
  }
303
- function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
257
+ function adaptToolCallback(tool, auth, recorder, protocol) {
304
258
  return async (first, second) => {
305
259
  const sdkCtx = tool.inputSchema ? second : first;
306
- const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx, appContext);
260
+ const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx);
307
261
  return {
308
262
  content: result.content ?? [],
309
263
  structuredContent: result.structuredContent,
@@ -311,52 +265,23 @@ function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
311
265
  };
312
266
  };
313
267
  }
314
- async function buildServer(mcp, auth, recorder, era, signal, operations) {
315
- const calledTools = operations ? mcp.tools.filter((tool) => operations.calledTools.has(tool.name)) : mcp.tools;
316
- const selectedTools = !operations || operations.listTools ? mcp.tools : calledTools;
317
- const hasConditionalTools = mcp.tools.some((tool) => tool.enabled !== void 0);
318
- const needsAppContext = operations?.listTools === true && hasConditionalTools || calledTools.some((tool) => tool.enabled !== void 0 || require_errors.toolRequiresAppContext(tool));
319
- const { createAppContext } = mcp;
320
- const appContext = needsAppContext && createAppContext ? await withAppContextError(() => createAppContext({
321
- auth: new require_errors.AuthContext(auth),
322
- signal
323
- })) : void 0;
324
- const visibilityContext = Object.freeze({ appContext });
325
- const cacheHint = hasConditionalTools ? {
326
- cacheScope: "private",
327
- ttlMs: 12 * HOUR_MS
328
- } : {
329
- cacheScope: "public",
330
- ttlMs: 24 * HOUR_MS
331
- };
268
+ function buildServer(mcp, auth, recorder, era) {
332
269
  const server = new _modelcontextprotocol_server.McpServer({
333
270
  name: mcp.name,
334
271
  version: mcp.version,
335
272
  title: mcp.title
336
273
  }, {
337
274
  instructions: mcp.instructions,
338
- capabilities: { tools: { listChanged: false } },
339
- cacheHints: {
340
- "tools/list": cacheHint,
341
- "server/discover": cacheHint
342
- }
275
+ capabilities: { tools: { listChanged: false } }
343
276
  });
344
- for (const tool of selectedTools) {
345
- if (tool.enabled) {
346
- const { enabled } = tool;
347
- if (!await withAppContextError(() => {
348
- const value = enabled(visibilityContext);
349
- if (typeof value !== "boolean") throw new TypeError(`@lovable.dev/mcp-js: tool "${tool.name}" enabled must return a boolean synchronously`);
350
- return value;
351
- })) continue;
352
- }
277
+ for (const tool of mcp.tools) {
353
278
  const config = {
354
279
  title: tool.title,
355
280
  description: tool.description,
356
281
  annotations: tool.annotations,
357
282
  ...tool.outputSchema ? { outputSchema: standardSchemaFromDefinition(tool.outputSchema) } : {}
358
283
  };
359
- const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION, appContext);
284
+ const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION);
360
285
  if (tool.inputSchema) server.registerTool(tool.name, {
361
286
  ...config,
362
287
  inputSchema: standardSchemaFromDefinition(tool.inputSchema)
@@ -377,28 +302,26 @@ function createMcpProtocolHandler(mcp, options = {}) {
377
302
  const handle = async (request, authResult, recorder) => {
378
303
  let protocolError;
379
304
  const reportTransportError = async (error) => {
380
- const appContextFailure = error instanceof AppContextError;
381
305
  await recorder.emit({
382
306
  tool: null,
383
307
  method: "transport",
384
- outcome: appContextFailure ? "app_context_error" : "transport_error",
308
+ outcome: "transport_error",
385
309
  durationMs: 0,
386
310
  endUserId: authResult.auth?.principal.sub
387
311
  });
388
- require_logger.log.error(appContextFailure ? "mcp.app_context_error" : "mcp.transport_error", {
389
- ...error === void 0 ? {} : require_logger.describeError(appContextFailure ? error.cause : error),
312
+ require_logger.log.error("mcp.transport_error", {
313
+ ...error === void 0 ? {} : require_logger.describeError(error),
390
314
  outcome: "500 internal error"
391
315
  });
392
316
  };
393
317
  try {
394
- const classified = mcp.createAppContext ? await classifyRequest(request) : void 0;
395
- const response = await (0, _modelcontextprotocol_server.createMcpHandler)(({ era, requestInfo }) => buildServer(mcp, authResult.auth, recorder, era, requestInfo?.signal ?? request.signal, classified?.operations), {
318
+ const response = await (0, _modelcontextprotocol_server.createMcpHandler)(({ era }) => buildServer(mcp, authResult.auth, recorder, era), {
396
319
  legacy: "stateless",
397
320
  maxSubscriptions: 0,
398
321
  onerror: (error) => {
399
322
  protocolError = error;
400
323
  }
401
- }).fetch(request, classified?.parsedBody === void 0 ? void 0 : { parsedBody: classified.parsedBody });
324
+ }).fetch(request);
402
325
  if (response.status >= 500) await reportTransportError(protocolError);
403
326
  return response;
404
327
  } catch (err) {
@@ -1,7 +1,7 @@
1
1
  import { i as log, r as describeError } from "./logger-Ctv5xUSD.js";
2
2
  import { n as schemaFromDefinition, t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.js";
3
- import { a as ToolContext, c as toolRequiresAppContext, i as AuthContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-DTvfh8lb.js";
4
- import { d as nowMs, i as normalizeHttpMethod, l as emitBeforeResponse, n as createRequestAuthorizer, p as finalizeWireResponse, t as evaluateCors, u as createNoopRecorder } from "./cors-D4BjUpgU.js";
3
+ import { i as ToolContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-Bwd1L0Rf.js";
4
+ import { d as nowMs, i as normalizeHttpMethod, l as emitBeforeResponse, n as createRequestAuthorizer, p as finalizeWireResponse, t as evaluateCors, u as createNoopRecorder } from "./cors-BaRKDl4r.js";
5
5
  import { getParseErrorMessage, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
6
6
  import { CLIENT_CAPABILITIES_META_KEY, CLIENT_INFO_META_KEY, McpServer, createMcpHandler } from "@modelcontextprotocol/server";
7
7
  //#region src/core/content.ts
@@ -117,52 +117,6 @@ function createGatedHandler(gate) {
117
117
  //#endregion
118
118
  //#region src/protocols/mcp/protocol.ts
119
119
  const MODERN_PROTOCOL_VERSION = "2026-07-28";
120
- const HOUR_MS = 3600 * 1e3;
121
- const NO_OPERATIONS = {
122
- listTools: false,
123
- calledTools: /* @__PURE__ */ new Set()
124
- };
125
- function collectRequestOperations(value, calledTools) {
126
- if (Array.isArray(value)) {
127
- let listTools = false;
128
- for (const item of value) listTools = collectRequestOperations(item, calledTools) || listTools;
129
- return listTools;
130
- }
131
- if (!isPlainObject(value)) return false;
132
- if (value.method === "tools/list") return true;
133
- if (value.method === "tools/call" && isPlainObject(value.params) && typeof value.params.name === "string") calledTools.add(value.params.name);
134
- return false;
135
- }
136
- /** Marks a failure in app-owned `createAppContext` or `enabled` code so telemetry
137
- * can attribute it to the author rather than to the transport. */
138
- var AppContextError = class extends Error {
139
- constructor(cause) {
140
- super("app context evaluation failed", { cause });
141
- this.name = "AppContextError";
142
- }
143
- };
144
- async function withAppContextError(run) {
145
- try {
146
- return await run();
147
- } catch (cause) {
148
- throw new AppContextError(cause);
149
- }
150
- }
151
- async function classifyRequest(request) {
152
- try {
153
- const parsedBody = await request.clone().json();
154
- const calledTools = /* @__PURE__ */ new Set();
155
- return {
156
- operations: {
157
- listTools: collectRequestOperations(parsedBody, calledTools),
158
- calledTools
159
- },
160
- parsedBody
161
- };
162
- } catch {
163
- return { operations: NO_OPERATIONS };
164
- }
165
- }
166
120
  function statelessMethodNotAllowed(allow) {
167
121
  return Response.json({
168
122
  jsonrpc: "2.0",
@@ -237,12 +191,12 @@ function toolRequestContext(sdkCtx, protocol) {
237
191
  sendProgress
238
192
  };
239
193
  }
240
- async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appContext) {
194
+ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
241
195
  const endUserId = auth?.principal.sub;
242
196
  const start = nowMs();
243
197
  let result;
244
198
  try {
245
- result = await tool.handler(args, new ToolContext(auth, toolRequestContext(sdkCtx, protocol), appContext));
199
+ result = await tool.handler(args, new ToolContext(auth, toolRequestContext(sdkCtx, protocol)));
246
200
  } catch (err) {
247
201
  const callerMessage = resolveToolErrorMessage(err);
248
202
  if (callerMessage === void 0) {
@@ -300,10 +254,10 @@ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appConte
300
254
  });
301
255
  return result;
302
256
  }
303
- function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
257
+ function adaptToolCallback(tool, auth, recorder, protocol) {
304
258
  return async (first, second) => {
305
259
  const sdkCtx = tool.inputSchema ? second : first;
306
- const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx, appContext);
260
+ const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx);
307
261
  return {
308
262
  content: result.content ?? [],
309
263
  structuredContent: result.structuredContent,
@@ -311,52 +265,23 @@ function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
311
265
  };
312
266
  };
313
267
  }
314
- async function buildServer(mcp, auth, recorder, era, signal, operations) {
315
- const calledTools = operations ? mcp.tools.filter((tool) => operations.calledTools.has(tool.name)) : mcp.tools;
316
- const selectedTools = !operations || operations.listTools ? mcp.tools : calledTools;
317
- const hasConditionalTools = mcp.tools.some((tool) => tool.enabled !== void 0);
318
- const needsAppContext = operations?.listTools === true && hasConditionalTools || calledTools.some((tool) => tool.enabled !== void 0 || toolRequiresAppContext(tool));
319
- const { createAppContext } = mcp;
320
- const appContext = needsAppContext && createAppContext ? await withAppContextError(() => createAppContext({
321
- auth: new AuthContext(auth),
322
- signal
323
- })) : void 0;
324
- const visibilityContext = Object.freeze({ appContext });
325
- const cacheHint = hasConditionalTools ? {
326
- cacheScope: "private",
327
- ttlMs: 12 * HOUR_MS
328
- } : {
329
- cacheScope: "public",
330
- ttlMs: 24 * HOUR_MS
331
- };
268
+ function buildServer(mcp, auth, recorder, era) {
332
269
  const server = new McpServer({
333
270
  name: mcp.name,
334
271
  version: mcp.version,
335
272
  title: mcp.title
336
273
  }, {
337
274
  instructions: mcp.instructions,
338
- capabilities: { tools: { listChanged: false } },
339
- cacheHints: {
340
- "tools/list": cacheHint,
341
- "server/discover": cacheHint
342
- }
275
+ capabilities: { tools: { listChanged: false } }
343
276
  });
344
- for (const tool of selectedTools) {
345
- if (tool.enabled) {
346
- const { enabled } = tool;
347
- if (!await withAppContextError(() => {
348
- const value = enabled(visibilityContext);
349
- if (typeof value !== "boolean") throw new TypeError(`@lovable.dev/mcp-js: tool "${tool.name}" enabled must return a boolean synchronously`);
350
- return value;
351
- })) continue;
352
- }
277
+ for (const tool of mcp.tools) {
353
278
  const config = {
354
279
  title: tool.title,
355
280
  description: tool.description,
356
281
  annotations: tool.annotations,
357
282
  ...tool.outputSchema ? { outputSchema: standardSchemaFromDefinition(tool.outputSchema) } : {}
358
283
  };
359
- const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION, appContext);
284
+ const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION);
360
285
  if (tool.inputSchema) server.registerTool(tool.name, {
361
286
  ...config,
362
287
  inputSchema: standardSchemaFromDefinition(tool.inputSchema)
@@ -377,28 +302,26 @@ function createMcpProtocolHandler(mcp, options = {}) {
377
302
  const handle = async (request, authResult, recorder) => {
378
303
  let protocolError;
379
304
  const reportTransportError = async (error) => {
380
- const appContextFailure = error instanceof AppContextError;
381
305
  await recorder.emit({
382
306
  tool: null,
383
307
  method: "transport",
384
- outcome: appContextFailure ? "app_context_error" : "transport_error",
308
+ outcome: "transport_error",
385
309
  durationMs: 0,
386
310
  endUserId: authResult.auth?.principal.sub
387
311
  });
388
- log.error(appContextFailure ? "mcp.app_context_error" : "mcp.transport_error", {
389
- ...error === void 0 ? {} : describeError(appContextFailure ? error.cause : error),
312
+ log.error("mcp.transport_error", {
313
+ ...error === void 0 ? {} : describeError(error),
390
314
  outcome: "500 internal error"
391
315
  });
392
316
  };
393
317
  try {
394
- const classified = mcp.createAppContext ? await classifyRequest(request) : void 0;
395
- const response = await createMcpHandler(({ era, requestInfo }) => buildServer(mcp, authResult.auth, recorder, era, requestInfo?.signal ?? request.signal, classified?.operations), {
318
+ const response = await createMcpHandler(({ era }) => buildServer(mcp, authResult.auth, recorder, era), {
396
319
  legacy: "stateless",
397
320
  maxSubscriptions: 0,
398
321
  onerror: (error) => {
399
322
  protocolError = error;
400
323
  }
401
- }).fetch(request, classified?.parsedBody === void 0 ? void 0 : { parsedBody: classified.parsedBody });
324
+ }).fetch(request);
402
325
  if (response.status >= 500) await reportTransportError(protocolError);
403
326
  return response;
404
327
  } catch (err) {
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "2.1.0-rc.0";
2
+ var version = "2.1.0";
3
3
  //#endregion
4
4
  export { version as t };
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "2.1.0-rc.0";
2
+ var version = "2.1.0";
3
3
  //#endregion
4
4
  Object.defineProperty(exports, "version", {
5
5
  enumerable: true,
@@ -1,3 +1,3 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_mcp = require("../../mcp-Q_rjpR99.cjs");
2
+ const require_mcp = require("../../mcp-Bx3LUn5O.cjs");
3
3
  exports.createMcpProtocolHandler = require_mcp.createMcpProtocolHandler;
@@ -1,6 +1,6 @@
1
- import { p as McpDefinition } from "../../types-S6J_QTXw.cjs";
2
- import { t as MetricsRecorder } from "../../base-4G2k3bMl.cjs";
3
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-BC4TM__8.cjs";
1
+ import { d as McpDefinition } from "../../types-B3_lX-L1.cjs";
2
+ import { t as MetricsRecorder } from "../../base-DD4MCXZ6.cjs";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-CzyL7nmF.cjs";
4
4
  //#region src/protocols/mcp/protocol.d.ts
5
5
  type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder, scheduleBackground?: ScheduleBackground) => Promise<Response>;
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { p as McpDefinition } from "../../types-S6J_QTXw.js";
2
- import { t as MetricsRecorder } from "../../base-BnlJz6TE.js";
3
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-DEsM-zTN.js";
1
+ import { d as McpDefinition } from "../../types-B3_lX-L1.js";
2
+ import { t as MetricsRecorder } from "../../base-COwtdWE8.js";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-Drz_eJ7O.js";
4
4
  //#region src/protocols/mcp/protocol.d.ts
5
5
  type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder, scheduleBackground?: ScheduleBackground) => Promise<Response>;
6
6
  /**
@@ -1,2 +1,2 @@
1
- import { t as createMcpProtocolHandler } from "../../mcp-CuHyVOZK.js";
1
+ import { t as createMcpProtocolHandler } from "../../mcp-DcmfehoI.js";
2
2
  export { createMcpProtocolHandler };
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_logger = require("../logger-CN1q-KNn.cjs");
3
- const require_cors = require("../cors-0ZCwmwyK.cjs");
3
+ const require_cors = require("../cors-D-X0aP4O.cjs");
4
4
  //#region src/protocols/oauth-metadata.ts
5
5
  function notFound() {
6
6
  return new Response(JSON.stringify({ error: "not found" }), {
@@ -1,6 +1,6 @@
1
- import { p as McpDefinition } from "../types-S6J_QTXw.cjs";
2
- import { t as MetricsRecorder } from "../base-4G2k3bMl.cjs";
3
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-BC4TM__8.cjs";
1
+ import { d as McpDefinition } from "../types-B3_lX-L1.cjs";
2
+ import { t as MetricsRecorder } from "../base-DD4MCXZ6.cjs";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-CzyL7nmF.cjs";
4
4
  //#region src/protocols/oauth-metadata.d.ts
5
5
  type OAuthProtectedResourceMetadataHandler = (request: Request, recorder?: MetricsRecorder, scheduleBackground?: ScheduleBackground) => Promise<Response>;
6
6
  declare function createOAuthProtectedResourceMetadataHandler(mcp: McpDefinition, options?: McpRuntimeOptions): OAuthProtectedResourceMetadataHandler;
@@ -1,6 +1,6 @@
1
- import { p as McpDefinition } from "../types-S6J_QTXw.js";
2
- import { t as MetricsRecorder } from "../base-BnlJz6TE.js";
3
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-DEsM-zTN.js";
1
+ import { d as McpDefinition } from "../types-B3_lX-L1.js";
2
+ import { t as MetricsRecorder } from "../base-COwtdWE8.js";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-Drz_eJ7O.js";
4
4
  //#region src/protocols/oauth-metadata.d.ts
5
5
  type OAuthProtectedResourceMetadataHandler = (request: Request, recorder?: MetricsRecorder, scheduleBackground?: ScheduleBackground) => Promise<Response>;
6
6
  declare function createOAuthProtectedResourceMetadataHandler(mcp: McpDefinition, options?: McpRuntimeOptions): OAuthProtectedResourceMetadataHandler;
@@ -1,5 +1,5 @@
1
1
  import { i as log, r as describeError } from "../logger-Ctv5xUSD.js";
2
- import { a as oauthConfigurationErrorResponse, f as JSON_HEADERS, i as normalizeHttpMethod, l as emitBeforeResponse, m as methodNotAllowed, p as finalizeWireResponse, r as getOAuthRuntime, s as resolveProtectedResource, t as evaluateCors, u as createNoopRecorder } from "../cors-D4BjUpgU.js";
2
+ import { a as oauthConfigurationErrorResponse, f as JSON_HEADERS, i as normalizeHttpMethod, l as emitBeforeResponse, m as methodNotAllowed, p as finalizeWireResponse, r as getOAuthRuntime, s as resolveProtectedResource, t as evaluateCors, u as createNoopRecorder } from "../cors-BaRKDl4r.js";
3
3
  //#region src/protocols/oauth-metadata.ts
4
4
  function notFound() {
5
5
  return new Response(JSON.stringify({ error: "not found" }), {