@lovable.dev/mcp-js 2.0.4-rc.0 → 2.1.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 (50) hide show
  1. package/README.md +82 -1
  2. package/dist/{authorize-oCEahmRv.d.cts → authorize-BC4TM__8.d.cts} +1 -1
  3. package/dist/{authorize-B5VMSzcN.d.ts → authorize-DEsM-zTN.d.ts} +1 -1
  4. package/dist/{base-DnCoJOZN.d.ts → base-4G2k3bMl.d.cts} +2 -2
  5. package/dist/{base-DAkOPRay.d.cts → base-BnlJz6TE.d.ts} +2 -2
  6. package/dist/cli/extract-manifest.cjs +1 -1
  7. package/dist/cli/extract-manifest.js +1 -1
  8. package/dist/{cors-DheH0sX2.cjs → cors-0ZCwmwyK.cjs} +1 -1
  9. package/dist/{cors-K-QaLAV0.js → cors-D4BjUpgU.js} +1 -1
  10. package/dist/errors-CdrGi5aP.cjs +309 -0
  11. package/dist/errors-DTvfh8lb.js +262 -0
  12. package/dist/index.cjs +4 -147
  13. package/dist/index.d.cts +12 -4
  14. package/dist/index.d.ts +12 -4
  15. package/dist/index.js +3 -147
  16. package/dist/{io-D2PGAhYM.d.cts → io-9jGNgPfl.d.cts} +1 -1
  17. package/dist/{io-CanMDPsW.js → io-BEoJ_gb5.js} +3 -2
  18. package/dist/{io-BD2TuqtG.d.ts → io-BLZ8jYW6.d.ts} +1 -1
  19. package/dist/{io-B5Mit9aD.cjs → io-Cz81GsrM.cjs} +3 -2
  20. package/dist/{mcp-TJZHxHwb.js → mcp-CuHyVOZK.js} +92 -15
  21. package/dist/{mcp-CY55D6Km.cjs → mcp-Q_rjpR99.cjs} +92 -15
  22. package/dist/{package-ZzwBAUf7.js → package-BAYb-3dX.js} +1 -1
  23. package/dist/{package-ClsLrfmB.cjs → package-DlouusYQ.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-C6O4ciic.d.ts → types-S6J_QTXw.d.cts} +60 -20
  47. package/dist/{types-C6O4ciic.d.cts → types-S6J_QTXw.d.ts} +60 -20
  48. package/package.json +1 -1
  49. package/dist/errors-Bwd1L0Rf.js +0 -100
  50. package/dist/errors-Cr95rSkB.cjs +0 -123
@@ -1,8 +1,8 @@
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-DheH0sX2.cjs");
3
+ const require_cors = require("../../cors-0ZCwmwyK.cjs");
4
4
  const require_metadata_path = require("../../metadata-path-zd7NSNoa.cjs");
5
- const require_mcp = require("../../mcp-CY55D6Km.cjs");
5
+ const require_mcp = require("../../mcp-Q_rjpR99.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-C6O4ciic.cjs";
1
+ import { p as McpDefinition } from "../../types-S6J_QTXw.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-C6O4ciic.js";
1
+ import { p as McpDefinition } from "../../types-S6J_QTXw.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
1
  import { s as trimTrailingSlash } from "../../logger-Ctv5xUSD.js";
2
- import { c as createRecorderForRuntime, o as assertResourcePathShape } from "../../cors-K-QaLAV0.js";
2
+ import { c as createRecorderForRuntime, o as assertResourcePathShape } from "../../cors-D4BjUpgU.js";
3
3
  import { t as OAUTH_PROTECTED_RESOURCE_METADATA_PATH } from "../../metadata-path-CAkNcfyY.js";
4
- import { t as createMcpProtocolHandler } from "../../mcp-TJZHxHwb.js";
4
+ import { t as createMcpProtocolHandler } from "../../mcp-CuHyVOZK.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-ClsLrfmB.cjs");
5
+ const require_package = require("../../package-DlouusYQ.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-D2PGAhYM.cjs";
1
+ import { t as McpPluginApi } from "../../io-9jGNgPfl.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-BD2TuqtG.js";
1
+ import { t as McpPluginApi } from "../../io-BLZ8jYW6.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-ZzwBAUf7.js";
1
+ import { t as version } from "../../package-BAYb-3dX.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-DheH0sX2.cjs");
3
- const require_mcp = require("../../mcp-CY55D6Km.cjs");
2
+ const require_cors = require("../../cors-0ZCwmwyK.cjs");
3
+ const require_mcp = require("../../mcp-Q_rjpR99.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-C6O4ciic.cjs";
2
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-oCEahmRv.cjs";
1
+ import { p as McpDefinition } from "../../types-S6J_QTXw.cjs";
2
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-BC4TM__8.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-C6O4ciic.js";
2
- import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-B5VMSzcN.js";
1
+ import { p as McpDefinition } from "../../types-S6J_QTXw.js";
2
+ import { n as ScheduleBackground, t as McpRuntimeOptions } from "../../authorize-DEsM-zTN.js";
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 { c as createRecorderForRuntime } from "../../cors-K-QaLAV0.js";
2
- import { t as createMcpProtocolHandler } from "../../mcp-TJZHxHwb.js";
1
+ import { c as createRecorderForRuntime } from "../../cors-D4BjUpgU.js";
2
+ import { t as createMcpProtocolHandler } from "../../mcp-CuHyVOZK.js";
3
3
  import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
4
4
  import { t as applyForwardedOrigin } from "../../forwarded-BBXvFeh6.js";
5
5
  //#region src/stacks/tanstack/handlers.ts
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-D2PGAhYM.cjs";
1
+ import { t as McpPluginApi } from "../../io-9jGNgPfl.cjs";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/tanstack/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-BD2TuqtG.js";
1
+ import { t as McpPluginApi } from "../../io-BLZ8jYW6.js";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/tanstack/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -116,18 +116,11 @@ interface ToolRequestContext {
116
116
  client?: McpClientInfo;
117
117
  sendProgress?: (update: ProgressUpdate) => Promise<void>;
118
118
  }
119
- /** The per-request context passed to every tool handler as its second argument. The
120
- * auth context lives in a private field so the accessors are the only way out; `getToken()` is the sole bearer escape hatch. */
121
- declare class ToolContext {
119
+ /** Verified caller identity exposed to the app-context factory.
120
+ * `getToken()` is the sole bearer escape hatch. */
121
+ declare class AuthContext {
122
122
  #private;
123
- constructor(auth: McpAuthContext | undefined, request?: ToolRequestContext);
124
- /** Aborts when the client cancels the request or disconnects. */
125
- get signal(): AbortSignal;
126
- /** What the client declared about itself on this request. Unverified input. */
127
- get client(): McpClientInfo;
128
- /** Send a progress notification for this call. A no-op when the client
129
- * didn't request progress (no `progressToken` on the request). */
130
- progress(update: ProgressUpdate): Promise<void>;
123
+ constructor(auth: McpAuthContext | undefined);
131
124
  /** Whether the in-flight tool call carries a verified auth context. */
132
125
  isAuthenticated(): boolean;
133
126
  /** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
@@ -148,6 +141,20 @@ declare class ToolContext {
148
141
  */
149
142
  getClaims(): JwtClaims | undefined;
150
143
  }
144
+ /** The per-request context passed to every tool handler as its second argument. */
145
+ declare class ToolContext<TAppContext = undefined> extends AuthContext {
146
+ #private;
147
+ constructor(auth: McpAuthContext | undefined, request?: ToolRequestContext, appContext?: TAppContext);
148
+ /** App-defined context created for this tool call. */
149
+ get appContext(): TAppContext;
150
+ /** Aborts when the client cancels the request or disconnects. */
151
+ get signal(): AbortSignal;
152
+ /** What the client declared about itself on this request. Unverified input. */
153
+ get client(): McpClientInfo;
154
+ /** Send a progress notification for this call. A no-op when the client
155
+ * didn't request progress (no `progressToken` on the request). */
156
+ progress(update: ProgressUpdate): Promise<void>;
157
+ }
151
158
  //#endregion
152
159
  //#region src/metrics/config.d.ts
153
160
  /**
@@ -302,7 +309,16 @@ interface ToolHandlerResult {
302
309
  structuredContent?: JsonValueInput;
303
310
  isError?: boolean;
304
311
  }
305
- interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined> {
312
+ /** Inputs available while creating app context for one MCP request. */
313
+ interface CreateAppContextInput {
314
+ readonly auth: AuthContext;
315
+ readonly signal: AbortSignal;
316
+ }
317
+ /** The restricted surface used to decide whether a tool exists. */
318
+ interface ToolVisibilityContext<TAppContext> {
319
+ readonly appContext: TAppContext;
320
+ }
321
+ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined, TAppContext = undefined> {
306
322
  readonly name: string;
307
323
  /** Human-readable display name shown to the user in MCP clients. Required. */
308
324
  readonly title: string;
@@ -311,22 +327,44 @@ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$
311
327
  readonly inputSchema?: TInput;
312
328
  readonly outputSchema?: TOutput;
313
329
  readonly annotations?: ToolAnnotations;
314
- readonly handler: TInput extends ZodRawShape$1 ? (args: ShapeOutput<TInput>, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult> : (args: Record<string, never> | undefined, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult>;
330
+ /** Synchronously decide whether this tool exists for the current caller. */
331
+ readonly enabled?: (ctx: ToolVisibilityContext<TAppContext>) => boolean;
332
+ readonly handler: TInput extends ZodRawShape$1 ? (args: ShapeOutput<TInput>, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult> : (args: Record<string, never> | undefined, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult>;
333
+ }
334
+ interface AppContextToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined, TAppContext = unknown> extends ToolDefinition<TInput, TOutput, TAppContext> {
335
+ readonly requiresAppContext: true;
315
336
  }
316
337
  /** Type-erased element of `McpDefinition.tools`; per-tool generic typing
317
338
  * happens at the `defineTool` call site. */
318
- interface AnyToolDefinition {
339
+ interface AnyToolDefinition<TAppContext = never> {
319
340
  readonly name: string;
320
341
  readonly title: string;
321
342
  readonly description: string;
322
343
  readonly inputSchema?: ZodRawShape$1 | undefined;
323
344
  readonly outputSchema?: ZodOutputSchema | undefined;
324
345
  readonly annotations?: ToolAnnotations;
325
- readonly handler: (args: any, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult>;
346
+ readonly enabled?: (ctx: ToolVisibilityContext<TAppContext>) => boolean;
347
+ readonly handler: (args: any, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult>;
326
348
  }
349
+ type StaticToolDefinition = Omit<AnyToolDefinition<undefined>, "enabled"> & {
350
+ readonly enabled?: never;
351
+ };
352
+ type AnyAppContextToolDefinition<TAppContext = unknown> = AnyToolDefinition<TAppContext> & {
353
+ readonly requiresAppContext: true;
354
+ };
355
+ type CreateAppContext<TAppContext> = (input: CreateAppContextInput) => TAppContext | Promise<TAppContext>;
356
+ /** Concrete app context requires a factory. `undefined`, `unknown`, and `never`
357
+ * remain optional because the SDK uses them for static or type-erased tools. */
358
+ type AppContextConfiguration<TAppContext> = [TAppContext] extends [undefined] ? {
359
+ readonly createAppContext?: CreateAppContext<TAppContext>;
360
+ } : unknown extends TAppContext ? {
361
+ readonly createAppContext?: CreateAppContext<TAppContext>;
362
+ } : {
363
+ readonly createAppContext: CreateAppContext<TAppContext>;
364
+ };
327
365
  /** Input shape for `defineMcp(...)`, whose branded `McpDefinition` return type is what
328
366
  * `createMcpProtocolHandler` consumes — the brand forces validation + freeze. */
329
- interface McpDefinitionInput {
367
+ type McpDefinitionInput<TAppContext = undefined> = {
330
368
  readonly name: string;
331
369
  /** Human-readable display name shown to MCP clients. Required. */
332
370
  readonly title: string;
@@ -341,17 +379,19 @@ interface McpDefinitionInput {
341
379
  * empty string to opt out.
342
380
  */
343
381
  readonly instructions: string;
344
- readonly tools: readonly AnyToolDefinition[];
382
+ readonly tools: readonly (AnyAppContextToolDefinition<TAppContext> | StaticToolDefinition)[];
345
383
  /**
346
384
  * Usage-metrics emission (runtime telemetry), on by default. `false` opts out;
347
385
  * `{ endpoint, headers }` sends to your own OTLP collector. Self-disables at
348
386
  * runtime without `LOVABLE_API_KEY` on the default Lovable endpoint.
349
387
  */
350
388
  readonly metrics?: MetricsConfig;
351
- }
389
+ } & AppContextConfiguration<TAppContext>;
352
390
  declare const McpDefinitionBrand: unique symbol;
353
- type McpDefinition = McpDefinitionInput & {
391
+ type McpDefinition<TAppContext = unknown> = Omit<McpDefinitionInput<TAppContext>, "createAppContext" | "tools"> & {
392
+ readonly createAppContext?: (input: CreateAppContextInput) => TAppContext | Promise<TAppContext>;
393
+ readonly tools: readonly AnyToolDefinition[];
354
394
  readonly [McpDefinitionBrand]: never;
355
395
  };
356
396
  //#endregion
357
- export { McpAuthConfig as A, MetricsConfig as C, ProgressUpdate as D, McpProtocolEra as E, ToolContext as O, ZodSchema as S, McpClientInfo as T, ToolContent as _, EmbeddedResource as a, ZodOutputSchema as b, JsonValue as c, McpDefinition as d, McpDefinitionInput as f, ToolAnnotations as g, TextContent as h, EmbeddedBlobResource as i, JwtClaims as k, JsonValueInput as l, ResourceLinkIcon as m, ContentAnnotations as n, EmbeddedTextResource as o, ResourceLink as p, ContentBlock as r, ImageContent as s, AudioContent as t, McpAllowedOrigins as u, ToolDefinition as v, MetricsOptions as w, ZodRawShape$1 as x, ToolHandlerResult as y };
397
+ export { McpProtocolEra as A, ZodOutputSchema as C, MetricsOptions as D, MetricsConfig as E, ToolContext as M, JwtClaims as N, AuthContext as O, McpAuthConfig as P, ToolVisibilityContext as S, ZodSchema as T, TextContent as _, CreateAppContextInput as a, ToolDefinition as b, EmbeddedTextResource as c, JsonValueInput as d, McpAllowedOrigins as f, ResourceLinkIcon as g, ResourceLink as h, ContentBlock as i, ProgressUpdate as j, McpClientInfo as k, ImageContent as l, McpDefinitionInput as m, AudioContent as n, EmbeddedBlobResource as o, McpDefinition as p, ContentAnnotations as r, EmbeddedResource as s, AppContextToolDefinition as t, JsonValue as u, ToolAnnotations as v, ZodRawShape$1 as w, ToolHandlerResult as x, ToolContent as y };
@@ -116,18 +116,11 @@ interface ToolRequestContext {
116
116
  client?: McpClientInfo;
117
117
  sendProgress?: (update: ProgressUpdate) => Promise<void>;
118
118
  }
119
- /** The per-request context passed to every tool handler as its second argument. The
120
- * auth context lives in a private field so the accessors are the only way out; `getToken()` is the sole bearer escape hatch. */
121
- declare class ToolContext {
119
+ /** Verified caller identity exposed to the app-context factory.
120
+ * `getToken()` is the sole bearer escape hatch. */
121
+ declare class AuthContext {
122
122
  #private;
123
- constructor(auth: McpAuthContext | undefined, request?: ToolRequestContext);
124
- /** Aborts when the client cancels the request or disconnects. */
125
- get signal(): AbortSignal;
126
- /** What the client declared about itself on this request. Unverified input. */
127
- get client(): McpClientInfo;
128
- /** Send a progress notification for this call. A no-op when the client
129
- * didn't request progress (no `progressToken` on the request). */
130
- progress(update: ProgressUpdate): Promise<void>;
123
+ constructor(auth: McpAuthContext | undefined);
131
124
  /** Whether the in-flight tool call carries a verified auth context. */
132
125
  isAuthenticated(): boolean;
133
126
  /** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
@@ -148,6 +141,20 @@ declare class ToolContext {
148
141
  */
149
142
  getClaims(): JwtClaims | undefined;
150
143
  }
144
+ /** The per-request context passed to every tool handler as its second argument. */
145
+ declare class ToolContext<TAppContext = undefined> extends AuthContext {
146
+ #private;
147
+ constructor(auth: McpAuthContext | undefined, request?: ToolRequestContext, appContext?: TAppContext);
148
+ /** App-defined context created for this tool call. */
149
+ get appContext(): TAppContext;
150
+ /** Aborts when the client cancels the request or disconnects. */
151
+ get signal(): AbortSignal;
152
+ /** What the client declared about itself on this request. Unverified input. */
153
+ get client(): McpClientInfo;
154
+ /** Send a progress notification for this call. A no-op when the client
155
+ * didn't request progress (no `progressToken` on the request). */
156
+ progress(update: ProgressUpdate): Promise<void>;
157
+ }
151
158
  //#endregion
152
159
  //#region src/metrics/config.d.ts
153
160
  /**
@@ -302,7 +309,16 @@ interface ToolHandlerResult {
302
309
  structuredContent?: JsonValueInput;
303
310
  isError?: boolean;
304
311
  }
305
- interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined> {
312
+ /** Inputs available while creating app context for one MCP request. */
313
+ interface CreateAppContextInput {
314
+ readonly auth: AuthContext;
315
+ readonly signal: AbortSignal;
316
+ }
317
+ /** The restricted surface used to decide whether a tool exists. */
318
+ interface ToolVisibilityContext<TAppContext> {
319
+ readonly appContext: TAppContext;
320
+ }
321
+ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined, TAppContext = undefined> {
306
322
  readonly name: string;
307
323
  /** Human-readable display name shown to the user in MCP clients. Required. */
308
324
  readonly title: string;
@@ -311,22 +327,44 @@ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$
311
327
  readonly inputSchema?: TInput;
312
328
  readonly outputSchema?: TOutput;
313
329
  readonly annotations?: ToolAnnotations;
314
- readonly handler: TInput extends ZodRawShape$1 ? (args: ShapeOutput<TInput>, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult> : (args: Record<string, never> | undefined, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult>;
330
+ /** Synchronously decide whether this tool exists for the current caller. */
331
+ readonly enabled?: (ctx: ToolVisibilityContext<TAppContext>) => boolean;
332
+ readonly handler: TInput extends ZodRawShape$1 ? (args: ShapeOutput<TInput>, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult> : (args: Record<string, never> | undefined, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult>;
333
+ }
334
+ interface AppContextToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined, TAppContext = unknown> extends ToolDefinition<TInput, TOutput, TAppContext> {
335
+ readonly requiresAppContext: true;
315
336
  }
316
337
  /** Type-erased element of `McpDefinition.tools`; per-tool generic typing
317
338
  * happens at the `defineTool` call site. */
318
- interface AnyToolDefinition {
339
+ interface AnyToolDefinition<TAppContext = never> {
319
340
  readonly name: string;
320
341
  readonly title: string;
321
342
  readonly description: string;
322
343
  readonly inputSchema?: ZodRawShape$1 | undefined;
323
344
  readonly outputSchema?: ZodOutputSchema | undefined;
324
345
  readonly annotations?: ToolAnnotations;
325
- readonly handler: (args: any, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult>;
346
+ readonly enabled?: (ctx: ToolVisibilityContext<TAppContext>) => boolean;
347
+ readonly handler: (args: any, ctx: ToolContext<TAppContext>) => ToolHandlerResult | Promise<ToolHandlerResult>;
326
348
  }
349
+ type StaticToolDefinition = Omit<AnyToolDefinition<undefined>, "enabled"> & {
350
+ readonly enabled?: never;
351
+ };
352
+ type AnyAppContextToolDefinition<TAppContext = unknown> = AnyToolDefinition<TAppContext> & {
353
+ readonly requiresAppContext: true;
354
+ };
355
+ type CreateAppContext<TAppContext> = (input: CreateAppContextInput) => TAppContext | Promise<TAppContext>;
356
+ /** Concrete app context requires a factory. `undefined`, `unknown`, and `never`
357
+ * remain optional because the SDK uses them for static or type-erased tools. */
358
+ type AppContextConfiguration<TAppContext> = [TAppContext] extends [undefined] ? {
359
+ readonly createAppContext?: CreateAppContext<TAppContext>;
360
+ } : unknown extends TAppContext ? {
361
+ readonly createAppContext?: CreateAppContext<TAppContext>;
362
+ } : {
363
+ readonly createAppContext: CreateAppContext<TAppContext>;
364
+ };
327
365
  /** Input shape for `defineMcp(...)`, whose branded `McpDefinition` return type is what
328
366
  * `createMcpProtocolHandler` consumes — the brand forces validation + freeze. */
329
- interface McpDefinitionInput {
367
+ type McpDefinitionInput<TAppContext = undefined> = {
330
368
  readonly name: string;
331
369
  /** Human-readable display name shown to MCP clients. Required. */
332
370
  readonly title: string;
@@ -341,17 +379,19 @@ interface McpDefinitionInput {
341
379
  * empty string to opt out.
342
380
  */
343
381
  readonly instructions: string;
344
- readonly tools: readonly AnyToolDefinition[];
382
+ readonly tools: readonly (AnyAppContextToolDefinition<TAppContext> | StaticToolDefinition)[];
345
383
  /**
346
384
  * Usage-metrics emission (runtime telemetry), on by default. `false` opts out;
347
385
  * `{ endpoint, headers }` sends to your own OTLP collector. Self-disables at
348
386
  * runtime without `LOVABLE_API_KEY` on the default Lovable endpoint.
349
387
  */
350
388
  readonly metrics?: MetricsConfig;
351
- }
389
+ } & AppContextConfiguration<TAppContext>;
352
390
  declare const McpDefinitionBrand: unique symbol;
353
- type McpDefinition = McpDefinitionInput & {
391
+ type McpDefinition<TAppContext = unknown> = Omit<McpDefinitionInput<TAppContext>, "createAppContext" | "tools"> & {
392
+ readonly createAppContext?: (input: CreateAppContextInput) => TAppContext | Promise<TAppContext>;
393
+ readonly tools: readonly AnyToolDefinition[];
354
394
  readonly [McpDefinitionBrand]: never;
355
395
  };
356
396
  //#endregion
357
- export { McpAuthConfig as A, MetricsConfig as C, ProgressUpdate as D, McpProtocolEra as E, ToolContext as O, ZodSchema as S, McpClientInfo as T, ToolContent as _, EmbeddedResource as a, ZodOutputSchema as b, JsonValue as c, McpDefinition as d, McpDefinitionInput as f, ToolAnnotations as g, TextContent as h, EmbeddedBlobResource as i, JwtClaims as k, JsonValueInput as l, ResourceLinkIcon as m, ContentAnnotations as n, EmbeddedTextResource as o, ResourceLink as p, ContentBlock as r, ImageContent as s, AudioContent as t, McpAllowedOrigins as u, ToolDefinition as v, MetricsOptions as w, ZodRawShape$1 as x, ToolHandlerResult as y };
397
+ export { McpProtocolEra as A, ZodOutputSchema as C, MetricsOptions as D, MetricsConfig as E, ToolContext as M, JwtClaims as N, AuthContext as O, McpAuthConfig as P, ToolVisibilityContext as S, ZodSchema as T, TextContent as _, CreateAppContextInput as a, ToolDefinition as b, EmbeddedTextResource as c, JsonValueInput as d, McpAllowedOrigins as f, ResourceLinkIcon as g, ResourceLink as h, ContentBlock as i, ProgressUpdate as j, McpClientInfo as k, ImageContent as l, McpDefinitionInput as m, AudioContent as n, EmbeddedBlobResource as o, McpDefinition as p, ContentAnnotations as r, EmbeddedResource as s, AppContextToolDefinition as t, JsonValue as u, ToolAnnotations as v, ZodRawShape$1 as w, ToolHandlerResult as x, ToolContent as y };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovable.dev/mcp-js",
3
- "version": "2.0.4-rc.0",
3
+ "version": "2.1.0-rc.0",
4
4
  "engines": {
5
5
  "node": ">=20"
6
6
  },
@@ -1,100 +0,0 @@
1
- //#region src/auth/context.ts
2
- const NEVER_ABORTED = new AbortController().signal;
3
- /** The per-request context passed to every tool handler as its second argument. The
4
- * auth context lives in a private field so the accessors are the only way out; `getToken()` is the sole bearer escape hatch. */
5
- var ToolContext = class {
6
- #auth;
7
- #signal;
8
- #client;
9
- #sendProgress;
10
- constructor(auth, request = {}) {
11
- this.#auth = auth;
12
- this.#signal = request.signal ?? NEVER_ABORTED;
13
- this.#client = request.client ?? { protocol: "legacy" };
14
- this.#sendProgress = request.sendProgress;
15
- }
16
- /** Aborts when the client cancels the request or disconnects. */
17
- get signal() {
18
- return this.#signal;
19
- }
20
- /** What the client declared about itself on this request. Unverified input. */
21
- get client() {
22
- return this.#client;
23
- }
24
- /** Send a progress notification for this call. A no-op when the client
25
- * didn't request progress (no `progressToken` on the request). */
26
- async progress(update) {
27
- await this.#sendProgress?.(update);
28
- }
29
- /** Whether the in-flight tool call carries a verified auth context. */
30
- isAuthenticated() {
31
- return this.#auth !== void 0;
32
- }
33
- /** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
34
- getToken() {
35
- return this.#auth?.bearer.token;
36
- }
37
- /** The verified user id (the token `sub`), or `undefined`. */
38
- getUserId() {
39
- return this.#auth?.principal.sub;
40
- }
41
- /** The verified user email, or `undefined` when absent. */
42
- getUserEmail() {
43
- return this.#auth?.principal.email;
44
- }
45
- /** The verified OAuth `client_id`, or `undefined`. */
46
- getClientId() {
47
- return this.#auth?.principal.clientId;
48
- }
49
- /** The verified OAuth scopes, or `undefined` when unauthenticated. */
50
- getScopes() {
51
- return this.#auth?.principal.scopes;
52
- }
53
- /** The verified token issuer, or `undefined`. */
54
- getIssuer() {
55
- return this.#auth?.principal.issuer;
56
- }
57
- /**
58
- * The full verified JWT claims, or `undefined`. Use this for app/business
59
- * authorization on issuer-specific claims that have no dedicated accessor.
60
- */
61
- getClaims() {
62
- return this.#auth?.principal.claims;
63
- }
64
- };
65
- //#endregion
66
- //#region src/core/errors.ts
67
- const TOOL_ERROR_BRAND = Symbol.for("@lovable.dev/mcp-js/tool-error");
68
- /** Error whose message is meant for the remote MCP caller; thrown from a handler
69
- * it becomes an `isError` result carrying exactly `message`. */
70
- var ToolError = class extends Error {
71
- constructor(message, options) {
72
- super(message, options);
73
- this.name = "ToolError";
74
- Object.defineProperty(this, TOOL_ERROR_BRAND, { value: true });
75
- }
76
- };
77
- function isToolError(err) {
78
- return err instanceof Error && Object.getOwnPropertyDescriptor(err, TOOL_ERROR_BRAND)?.value === true;
79
- }
80
- /** The caller-visible message of a thrown ToolError, or undefined for anything
81
- * else — including when inspecting the value itself throws (fail closed). */
82
- function resolveToolErrorMessage(err) {
83
- try {
84
- return isToolError(err) ? String(err.message) : void 0;
85
- } catch {
86
- return;
87
- }
88
- }
89
- const MAX_ERROR_SUMMARY = 500;
90
- /** Bounded name+message line for local logs; never for wire responses. */
91
- function errorSummary(err) {
92
- try {
93
- const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
94
- return text.length > MAX_ERROR_SUMMARY ? `${text.slice(0, MAX_ERROR_SUMMARY)}…` : text;
95
- } catch {
96
- return "unprintable error";
97
- }
98
- }
99
- //#endregion
100
- export { ToolContext as i, errorSummary as n, resolveToolErrorMessage as r, ToolError as t };
@@ -1,123 +0,0 @@
1
- //#region src/auth/context.ts
2
- const NEVER_ABORTED = new AbortController().signal;
3
- /** The per-request context passed to every tool handler as its second argument. The
4
- * auth context lives in a private field so the accessors are the only way out; `getToken()` is the sole bearer escape hatch. */
5
- var ToolContext = class {
6
- #auth;
7
- #signal;
8
- #client;
9
- #sendProgress;
10
- constructor(auth, request = {}) {
11
- this.#auth = auth;
12
- this.#signal = request.signal ?? NEVER_ABORTED;
13
- this.#client = request.client ?? { protocol: "legacy" };
14
- this.#sendProgress = request.sendProgress;
15
- }
16
- /** Aborts when the client cancels the request or disconnects. */
17
- get signal() {
18
- return this.#signal;
19
- }
20
- /** What the client declared about itself on this request. Unverified input. */
21
- get client() {
22
- return this.#client;
23
- }
24
- /** Send a progress notification for this call. A no-op when the client
25
- * didn't request progress (no `progressToken` on the request). */
26
- async progress(update) {
27
- await this.#sendProgress?.(update);
28
- }
29
- /** Whether the in-flight tool call carries a verified auth context. */
30
- isAuthenticated() {
31
- return this.#auth !== void 0;
32
- }
33
- /** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
34
- getToken() {
35
- return this.#auth?.bearer.token;
36
- }
37
- /** The verified user id (the token `sub`), or `undefined`. */
38
- getUserId() {
39
- return this.#auth?.principal.sub;
40
- }
41
- /** The verified user email, or `undefined` when absent. */
42
- getUserEmail() {
43
- return this.#auth?.principal.email;
44
- }
45
- /** The verified OAuth `client_id`, or `undefined`. */
46
- getClientId() {
47
- return this.#auth?.principal.clientId;
48
- }
49
- /** The verified OAuth scopes, or `undefined` when unauthenticated. */
50
- getScopes() {
51
- return this.#auth?.principal.scopes;
52
- }
53
- /** The verified token issuer, or `undefined`. */
54
- getIssuer() {
55
- return this.#auth?.principal.issuer;
56
- }
57
- /**
58
- * The full verified JWT claims, or `undefined`. Use this for app/business
59
- * authorization on issuer-specific claims that have no dedicated accessor.
60
- */
61
- getClaims() {
62
- return this.#auth?.principal.claims;
63
- }
64
- };
65
- //#endregion
66
- //#region src/core/errors.ts
67
- const TOOL_ERROR_BRAND = Symbol.for("@lovable.dev/mcp-js/tool-error");
68
- /** Error whose message is meant for the remote MCP caller; thrown from a handler
69
- * it becomes an `isError` result carrying exactly `message`. */
70
- var ToolError = class extends Error {
71
- constructor(message, options) {
72
- super(message, options);
73
- this.name = "ToolError";
74
- Object.defineProperty(this, TOOL_ERROR_BRAND, { value: true });
75
- }
76
- };
77
- function isToolError(err) {
78
- return err instanceof Error && Object.getOwnPropertyDescriptor(err, TOOL_ERROR_BRAND)?.value === true;
79
- }
80
- /** The caller-visible message of a thrown ToolError, or undefined for anything
81
- * else — including when inspecting the value itself throws (fail closed). */
82
- function resolveToolErrorMessage(err) {
83
- try {
84
- return isToolError(err) ? String(err.message) : void 0;
85
- } catch {
86
- return;
87
- }
88
- }
89
- const MAX_ERROR_SUMMARY = 500;
90
- /** Bounded name+message line for local logs; never for wire responses. */
91
- function errorSummary(err) {
92
- try {
93
- const text = err instanceof Error ? `${err.name}: ${err.message}` : String(err);
94
- return text.length > MAX_ERROR_SUMMARY ? `${text.slice(0, MAX_ERROR_SUMMARY)}…` : text;
95
- } catch {
96
- return "unprintable error";
97
- }
98
- }
99
- //#endregion
100
- Object.defineProperty(exports, "ToolContext", {
101
- enumerable: true,
102
- get: function() {
103
- return ToolContext;
104
- }
105
- });
106
- Object.defineProperty(exports, "ToolError", {
107
- enumerable: true,
108
- get: function() {
109
- return ToolError;
110
- }
111
- });
112
- Object.defineProperty(exports, "errorSummary", {
113
- enumerable: true,
114
- get: function() {
115
- return errorSummary;
116
- }
117
- });
118
- Object.defineProperty(exports, "resolveToolErrorMessage", {
119
- enumerable: true,
120
- get: function() {
121
- return resolveToolErrorMessage;
122
- }
123
- });