@lovable.dev/mcp-js 2.1.0 → 2.2.0-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.
Files changed (52) hide show
  1. package/README.md +97 -8
  2. package/dist/{authorize-CzyL7nmF.d.cts → authorize-BmYO5_-I.d.cts} +1 -1
  3. package/dist/{authorize-Drz_eJ7O.d.ts → authorize-d9-8n9u3.d.ts} +1 -1
  4. package/dist/{base-COwtdWE8.d.ts → base-BAxrhVjq.d.ts} +2 -2
  5. package/dist/{base-DD4MCXZ6.d.cts → base-Bmw6Wrb-.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-BaRKDl4r.js → cors-BfacizN-.js} +2 -2
  9. package/dist/{cors-D-X0aP4O.cjs → cors-Dm9Yn8E5.cjs} +2 -2
  10. package/dist/errors-CpTdzogX.cjs +308 -0
  11. package/dist/errors-DGcJ8jPK.js +261 -0
  12. package/dist/index.cjs +5 -148
  13. package/dist/index.d.cts +9 -4
  14. package/dist/index.d.ts +9 -4
  15. package/dist/index.js +3 -147
  16. package/dist/{io-pl5npWDw.d.ts → io-7U860POB.d.ts} +1 -1
  17. package/dist/{io-Ds5MRSiK.d.cts → io-CL1GeE3D.d.cts} +1 -1
  18. package/dist/{io-DG83CLKx.js → io-DD8wjGjd.js} +3 -2
  19. package/dist/{io-DZD6xmJQ.cjs → io-DaqblVaG.cjs} +3 -2
  20. package/dist/{logger-CN1q-KNn.cjs → logger-C-Hdu57K.cjs} +5 -1
  21. package/dist/{logger-Ctv5xUSD.js → logger-CpLgYbCG.js} +5 -1
  22. package/dist/{mcp-Bx3LUn5O.cjs → mcp-BGsPYWs1.cjs} +93 -16
  23. package/dist/{mcp-DcmfehoI.js → mcp-DdJJjYYZ.js} +93 -16
  24. package/dist/{package-BNFIhH0F.js → package-cPx-zYIb.js} +1 -1
  25. package/dist/{package-CFVl3oIe.cjs → package-hWM0Ru0w.cjs} +1 -1
  26. package/dist/protocols/mcp/index.cjs +1 -1
  27. package/dist/protocols/mcp/index.d.cts +3 -3
  28. package/dist/protocols/mcp/index.d.ts +3 -3
  29. package/dist/protocols/mcp/index.js +1 -1
  30. package/dist/protocols/oauth-metadata.cjs +2 -2
  31. package/dist/protocols/oauth-metadata.d.cts +3 -3
  32. package/dist/protocols/oauth-metadata.d.ts +3 -3
  33. package/dist/protocols/oauth-metadata.js +2 -2
  34. package/dist/stacks/supabase/index.cjs +3 -3
  35. package/dist/stacks/supabase/index.d.cts +1 -1
  36. package/dist/stacks/supabase/index.d.ts +1 -1
  37. package/dist/stacks/supabase/index.js +3 -3
  38. package/dist/stacks/supabase/vite.cjs +1 -1
  39. package/dist/stacks/supabase/vite.d.cts +1 -1
  40. package/dist/stacks/supabase/vite.d.ts +1 -1
  41. package/dist/stacks/supabase/vite.js +1 -1
  42. package/dist/stacks/tanstack/index.cjs +2 -2
  43. package/dist/stacks/tanstack/index.d.cts +2 -2
  44. package/dist/stacks/tanstack/index.d.ts +2 -2
  45. package/dist/stacks/tanstack/index.js +2 -2
  46. package/dist/stacks/tanstack/vite.d.cts +1 -1
  47. package/dist/stacks/tanstack/vite.d.ts +1 -1
  48. package/dist/{types-B3_lX-L1.d.ts → types-BCKyT2wb.d.cts} +68 -20
  49. package/dist/{types-B3_lX-L1.d.cts → types-BCKyT2wb.d.ts} +68 -20
  50. package/package.json +2 -2
  51. package/dist/errors-Bwd1L0Rf.js +0 -100
  52. package/dist/errors-Cr95rSkB.cjs +0 -123
@@ -1,4 +1,4 @@
1
- import "./types-B3_lX-L1.js";
1
+ import "./types-BCKyT2wb.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,4 +1,4 @@
1
- import "./types-B3_lX-L1.cjs";
1
+ import "./types-BCKyT2wb.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,5 +1,5 @@
1
1
  import { t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.js";
2
- import { t as version } from "./package-BNFIhH0F.js";
2
+ import { t as version } from "./package-cPx-zYIb.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,7 +23,8 @@ 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")
26
+ outputSchema: schemaToJsonSchema(tool.outputSchema, "output"),
27
+ ...tool.enabled ? { conditional: true } : {}
27
28
  }))
28
29
  };
29
30
  }
@@ -1,5 +1,5 @@
1
1
  const require_schema = require("./schema-D3vClxb7.cjs");
2
- const require_package = require("./package-CFVl3oIe.cjs");
2
+ const require_package = require("./package-hWM0Ru0w.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,7 +23,8 @@ 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")
26
+ outputSchema: schemaToJsonSchema(tool.outputSchema, "output"),
27
+ ...tool.enabled ? { conditional: true } : {}
27
28
  }))
28
29
  };
29
30
  }
@@ -139,7 +139,11 @@ function describeError(err) {
139
139
  ...typeof code === "string" ? { code } : {}
140
140
  };
141
141
  }
142
- return { value: String(err) };
142
+ try {
143
+ return { value: String(err) };
144
+ } catch {
145
+ return { value: "[unprintable object]" };
146
+ }
143
147
  }
144
148
  //#endregion
145
149
  Object.defineProperty(exports, "DEFAULT_METRICS_ENDPOINT", {
@@ -139,7 +139,11 @@ function describeError(err) {
139
139
  ...typeof code === "string" ? { code } : {}
140
140
  };
141
141
  }
142
- return { value: String(err) };
142
+ try {
143
+ return { value: String(err) };
144
+ } catch {
145
+ return { value: "[unprintable object]" };
146
+ }
143
147
  }
144
148
  //#endregion
145
149
  export { setLogLevel as a, DEFAULT_METRICS_ENDPOINT as c, log as i, LEGACY_METRICS_ENDPOINT as l, applyLogLevelFromEnv as n, parseSafeUrl as o, describeError as r, trimTrailingSlash as s, LOG_LEVEL_ENV_VAR as t, resolveMetricsConfig as u };
@@ -1,7 +1,7 @@
1
- const require_logger = require("./logger-CN1q-KNn.cjs");
1
+ const require_logger = require("./logger-C-Hdu57K.cjs");
2
2
  const require_schema = require("./schema-D3vClxb7.cjs");
3
- const require_errors = require("./errors-Cr95rSkB.cjs");
4
- const require_cors = require("./cors-D-X0aP4O.cjs");
3
+ const require_errors = require("./errors-CpTdzogX.cjs");
4
+ const require_cors = require("./cors-Dm9Yn8E5.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,6 +117,52 @@ 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
+ }
120
166
  function statelessMethodNotAllowed(allow) {
121
167
  return Response.json({
122
168
  jsonrpc: "2.0",
@@ -191,12 +237,12 @@ function toolRequestContext(sdkCtx, protocol) {
191
237
  sendProgress
192
238
  };
193
239
  }
194
- async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
240
+ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appContext) {
195
241
  const endUserId = auth?.principal.sub;
196
242
  const start = require_cors.nowMs();
197
243
  let result;
198
244
  try {
199
- result = await tool.handler(args, new require_errors.ToolContext(auth, toolRequestContext(sdkCtx, protocol)));
245
+ result = await tool.handler(args, new require_errors.ToolContext(auth, toolRequestContext(sdkCtx, protocol), appContext));
200
246
  } catch (err) {
201
247
  const callerMessage = require_errors.resolveToolErrorMessage(err);
202
248
  if (callerMessage === void 0) {
@@ -254,10 +300,10 @@ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
254
300
  });
255
301
  return result;
256
302
  }
257
- function adaptToolCallback(tool, auth, recorder, protocol) {
303
+ function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
258
304
  return async (first, second) => {
259
305
  const sdkCtx = tool.inputSchema ? second : first;
260
- const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx);
306
+ const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx, appContext);
261
307
  return {
262
308
  content: result.content ?? [],
263
309
  structuredContent: result.structuredContent,
@@ -265,23 +311,52 @@ function adaptToolCallback(tool, auth, recorder, protocol) {
265
311
  };
266
312
  };
267
313
  }
268
- function buildServer(mcp, auth, recorder, era) {
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
+ };
269
332
  const server = new _modelcontextprotocol_server.McpServer({
270
333
  name: mcp.name,
271
334
  version: mcp.version,
272
335
  title: mcp.title
273
336
  }, {
274
337
  instructions: mcp.instructions,
275
- capabilities: { tools: { listChanged: false } }
338
+ capabilities: { tools: { listChanged: false } },
339
+ cacheHints: {
340
+ "tools/list": cacheHint,
341
+ "server/discover": cacheHint
342
+ }
276
343
  });
277
- for (const tool of mcp.tools) {
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
+ }
278
353
  const config = {
279
354
  title: tool.title,
280
355
  description: tool.description,
281
356
  annotations: tool.annotations,
282
357
  ...tool.outputSchema ? { outputSchema: standardSchemaFromDefinition(tool.outputSchema) } : {}
283
358
  };
284
- const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION);
359
+ const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION, appContext);
285
360
  if (tool.inputSchema) server.registerTool(tool.name, {
286
361
  ...config,
287
362
  inputSchema: standardSchemaFromDefinition(tool.inputSchema)
@@ -302,26 +377,28 @@ function createMcpProtocolHandler(mcp, options = {}) {
302
377
  const handle = async (request, authResult, recorder) => {
303
378
  let protocolError;
304
379
  const reportTransportError = async (error) => {
380
+ const appContextFailure = error instanceof AppContextError;
305
381
  await recorder.emit({
306
382
  tool: null,
307
383
  method: "transport",
308
- outcome: "transport_error",
384
+ outcome: appContextFailure ? "app_context_error" : "transport_error",
309
385
  durationMs: 0,
310
386
  endUserId: authResult.auth?.principal.sub
311
387
  });
312
- require_logger.log.error("mcp.transport_error", {
313
- ...error === void 0 ? {} : require_logger.describeError(error),
388
+ require_logger.log.error(appContextFailure ? "mcp.app_context_error" : "mcp.transport_error", {
389
+ ...error === void 0 ? {} : require_logger.describeError(appContextFailure ? error.cause : error),
314
390
  outcome: "500 internal error"
315
391
  });
316
392
  };
317
393
  try {
318
- const response = await (0, _modelcontextprotocol_server.createMcpHandler)(({ era }) => buildServer(mcp, authResult.auth, recorder, era), {
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), {
319
396
  legacy: "stateless",
320
397
  maxSubscriptions: 0,
321
398
  onerror: (error) => {
322
399
  protocolError = error;
323
400
  }
324
- }).fetch(request);
401
+ }).fetch(request, classified?.parsedBody === void 0 ? void 0 : { parsedBody: classified.parsedBody });
325
402
  if (response.status >= 500) await reportTransportError(protocolError);
326
403
  return response;
327
404
  } catch (err) {
@@ -1,7 +1,7 @@
1
- import { i as log, r as describeError } from "./logger-Ctv5xUSD.js";
1
+ import { i as log, r as describeError } from "./logger-CpLgYbCG.js";
2
2
  import { n as schemaFromDefinition, t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.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";
3
+ import { a as ToolContext, c as toolRequiresAppContext, i as AuthContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-DGcJ8jPK.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-BfacizN-.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,6 +117,52 @@ 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
+ }
120
166
  function statelessMethodNotAllowed(allow) {
121
167
  return Response.json({
122
168
  jsonrpc: "2.0",
@@ -191,12 +237,12 @@ function toolRequestContext(sdkCtx, protocol) {
191
237
  sendProgress
192
238
  };
193
239
  }
194
- async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
240
+ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx, appContext) {
195
241
  const endUserId = auth?.principal.sub;
196
242
  const start = nowMs();
197
243
  let result;
198
244
  try {
199
- result = await tool.handler(args, new ToolContext(auth, toolRequestContext(sdkCtx, protocol)));
245
+ result = await tool.handler(args, new ToolContext(auth, toolRequestContext(sdkCtx, protocol), appContext));
200
246
  } catch (err) {
201
247
  const callerMessage = resolveToolErrorMessage(err);
202
248
  if (callerMessage === void 0) {
@@ -254,10 +300,10 @@ async function invokeTool(tool, auth, recorder, args, protocol, sdkCtx) {
254
300
  });
255
301
  return result;
256
302
  }
257
- function adaptToolCallback(tool, auth, recorder, protocol) {
303
+ function adaptToolCallback(tool, auth, recorder, protocol, appContext) {
258
304
  return async (first, second) => {
259
305
  const sdkCtx = tool.inputSchema ? second : first;
260
- const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx);
306
+ const result = await invokeTool(tool, auth, recorder, tool.inputSchema ? first ?? {} : {}, protocol, sdkCtx, appContext);
261
307
  return {
262
308
  content: result.content ?? [],
263
309
  structuredContent: result.structuredContent,
@@ -265,23 +311,52 @@ function adaptToolCallback(tool, auth, recorder, protocol) {
265
311
  };
266
312
  };
267
313
  }
268
- function buildServer(mcp, auth, recorder, era) {
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
+ };
269
332
  const server = new McpServer({
270
333
  name: mcp.name,
271
334
  version: mcp.version,
272
335
  title: mcp.title
273
336
  }, {
274
337
  instructions: mcp.instructions,
275
- capabilities: { tools: { listChanged: false } }
338
+ capabilities: { tools: { listChanged: false } },
339
+ cacheHints: {
340
+ "tools/list": cacheHint,
341
+ "server/discover": cacheHint
342
+ }
276
343
  });
277
- for (const tool of mcp.tools) {
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
+ }
278
353
  const config = {
279
354
  title: tool.title,
280
355
  description: tool.description,
281
356
  annotations: tool.annotations,
282
357
  ...tool.outputSchema ? { outputSchema: standardSchemaFromDefinition(tool.outputSchema) } : {}
283
358
  };
284
- const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION);
359
+ const callback = adaptToolCallback(tool, auth, recorder, era === "legacy" ? "legacy" : MODERN_PROTOCOL_VERSION, appContext);
285
360
  if (tool.inputSchema) server.registerTool(tool.name, {
286
361
  ...config,
287
362
  inputSchema: standardSchemaFromDefinition(tool.inputSchema)
@@ -302,26 +377,28 @@ function createMcpProtocolHandler(mcp, options = {}) {
302
377
  const handle = async (request, authResult, recorder) => {
303
378
  let protocolError;
304
379
  const reportTransportError = async (error) => {
380
+ const appContextFailure = error instanceof AppContextError;
305
381
  await recorder.emit({
306
382
  tool: null,
307
383
  method: "transport",
308
- outcome: "transport_error",
384
+ outcome: appContextFailure ? "app_context_error" : "transport_error",
309
385
  durationMs: 0,
310
386
  endUserId: authResult.auth?.principal.sub
311
387
  });
312
- log.error("mcp.transport_error", {
313
- ...error === void 0 ? {} : describeError(error),
388
+ log.error(appContextFailure ? "mcp.app_context_error" : "mcp.transport_error", {
389
+ ...error === void 0 ? {} : describeError(appContextFailure ? error.cause : error),
314
390
  outcome: "500 internal error"
315
391
  });
316
392
  };
317
393
  try {
318
- const response = await createMcpHandler(({ era }) => buildServer(mcp, authResult.auth, recorder, era), {
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), {
319
396
  legacy: "stateless",
320
397
  maxSubscriptions: 0,
321
398
  onerror: (error) => {
322
399
  protocolError = error;
323
400
  }
324
- }).fetch(request);
401
+ }).fetch(request, classified?.parsedBody === void 0 ? void 0 : { parsedBody: classified.parsedBody });
325
402
  if (response.status >= 500) await reportTransportError(protocolError);
326
403
  return response;
327
404
  } catch (err) {
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "2.1.0";
2
+ var version = "2.2.0-rc.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";
2
+ var version = "2.2.0-rc.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-Bx3LUn5O.cjs");
2
+ const require_mcp = require("../../mcp-BGsPYWs1.cjs");
3
3
  exports.createMcpProtocolHandler = require_mcp.createMcpProtocolHandler;
@@ -1,6 +1,6 @@
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";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.cjs";
2
+ import { t as MetricsRecorder } from "../../base-Bmw6Wrb-.cjs";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-BmYO5_-I.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 { 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";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.js";
2
+ import { t as MetricsRecorder } from "../../base-BAxrhVjq.js";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-d9-8n9u3.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-DcmfehoI.js";
1
+ import { t as createMcpProtocolHandler } from "../../mcp-DdJJjYYZ.js";
2
2
  export { createMcpProtocolHandler };
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_logger = require("../logger-CN1q-KNn.cjs");
3
- const require_cors = require("../cors-D-X0aP4O.cjs");
2
+ const require_logger = require("../logger-C-Hdu57K.cjs");
3
+ const require_cors = require("../cors-Dm9Yn8E5.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 { 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";
1
+ import { m as McpDefinition } from "../types-BCKyT2wb.cjs";
2
+ import { t as MetricsRecorder } from "../base-Bmw6Wrb-.cjs";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-BmYO5_-I.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 { 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";
1
+ import { m as McpDefinition } from "../types-BCKyT2wb.js";
2
+ import { t as MetricsRecorder } from "../base-BAxrhVjq.js";
3
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../authorize-d9-8n9u3.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
- 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-BaRKDl4r.js";
1
+ import { i as log, r as describeError } from "../logger-CpLgYbCG.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-BfacizN-.js";
3
3
  //#region src/protocols/oauth-metadata.ts
4
4
  function notFound() {
5
5
  return new Response(JSON.stringify({ error: "not found" }), {
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_logger = require("../../logger-CN1q-KNn.cjs");
3
- const require_cors = require("../../cors-D-X0aP4O.cjs");
2
+ const require_logger = require("../../logger-C-Hdu57K.cjs");
3
+ const require_cors = require("../../cors-Dm9Yn8E5.cjs");
4
4
  const require_metadata_path = require("../../metadata-path-zd7NSNoa.cjs");
5
- const require_mcp = require("../../mcp-Bx3LUn5O.cjs");
5
+ const require_mcp = require("../../mcp-BGsPYWs1.cjs");
6
6
  const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
7
7
  const require_forwarded = require("../../forwarded-B37IdmMX.cjs");
8
8
  const require_paths = require("../../paths-OP318a6c.cjs");
@@ -1,4 +1,4 @@
1
- import { d as McpDefinition } from "../../types-B3_lX-L1.cjs";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.cjs";
2
2
  //#region src/stacks/supabase/handler.d.ts
3
3
  type SupabaseHandler = (request: Request) => Promise<Response>;
4
4
  interface SupabaseHandlerOptions {
@@ -1,4 +1,4 @@
1
- import { d as McpDefinition } from "../../types-B3_lX-L1.js";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.js";
2
2
  //#region src/stacks/supabase/handler.d.ts
3
3
  type SupabaseHandler = (request: Request) => Promise<Response>;
4
4
  interface SupabaseHandlerOptions {
@@ -1,7 +1,7 @@
1
- import { s as trimTrailingSlash } from "../../logger-Ctv5xUSD.js";
2
- import { c as createRecorderForRuntime, o as assertResourcePathShape } from "../../cors-BaRKDl4r.js";
1
+ import { s as trimTrailingSlash } from "../../logger-CpLgYbCG.js";
2
+ import { c as createRecorderForRuntime, o as assertResourcePathShape } from "../../cors-BfacizN-.js";
3
3
  import { t as OAUTH_PROTECTED_RESOURCE_METADATA_PATH } from "../../metadata-path-CAkNcfyY.js";
4
- import { t as createMcpProtocolHandler } from "../../mcp-DcmfehoI.js";
4
+ import { t as createMcpProtocolHandler } from "../../mcp-DdJJjYYZ.js";
5
5
  import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
6
6
  import { t as applyForwardedOrigin } from "../../forwarded-BBXvFeh6.js";
7
7
  import { n as assertFunctionName, t as FUNCTIONS_MOUNT_PREFIX } from "../../paths-IS65L6TA.js";
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
2
2
  __esModule: { value: true },
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
- const require_package = require("../../package-CFVl3oIe.cjs");
5
+ const require_package = require("../../package-hWM0Ru0w.cjs");
6
6
  const require_fs_errors = require("../../fs-errors-CWNzOV75.cjs");
7
7
  const require_supabase_config = require("../../supabase-config-Dz7dnUv0.cjs");
8
8
  const require_paths = require("../../paths-OP318a6c.cjs");
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-Ds5MRSiK.cjs";
1
+ import { t as McpPluginApi } from "../../io-CL1GeE3D.cjs";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/supabase/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-pl5npWDw.js";
1
+ import { t as McpPluginApi } from "../../io-7U860POB.js";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/supabase/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -1,4 +1,4 @@
1
- import { t as version } from "../../package-BNFIhH0F.js";
1
+ import { t as version } from "../../package-cPx-zYIb.js";
2
2
  import { t as isFileMissing } from "../../fs-errors-PA2t1TIp.js";
3
3
  import { t as readSupabaseProjectRef } from "../../supabase-config-CakTU8YF.js";
4
4
  import { n as assertFunctionName, t as FUNCTIONS_MOUNT_PREFIX } from "../../paths-IS65L6TA.js";
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_cors = require("../../cors-D-X0aP4O.cjs");
3
- const require_mcp = require("../../mcp-Bx3LUn5O.cjs");
2
+ const require_cors = require("../../cors-Dm9Yn8E5.cjs");
3
+ const require_mcp = require("../../mcp-BGsPYWs1.cjs");
4
4
  const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
5
5
  const require_forwarded = require("../../forwarded-B37IdmMX.cjs");
6
6
  //#region src/stacks/tanstack/handlers.ts
@@ -1,5 +1,5 @@
1
- import { d as McpDefinition } from "../../types-B3_lX-L1.cjs";
2
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-CzyL7nmF.cjs";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.cjs";
2
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-BmYO5_-I.cjs";
3
3
  //#region src/stacks/tanstack/handlers.d.ts
4
4
  interface TanStackRequest extends Request {
5
5
  waitUntil?: ScheduleBackground;
@@ -1,5 +1,5 @@
1
- import { d as McpDefinition } from "../../types-B3_lX-L1.js";
2
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-Drz_eJ7O.js";
1
+ import { m as McpDefinition } from "../../types-BCKyT2wb.js";
2
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-d9-8n9u3.js";
3
3
  //#region src/stacks/tanstack/handlers.d.ts
4
4
  interface TanStackRequest extends Request {
5
5
  waitUntil?: ScheduleBackground;