@lovable.dev/mcp-js 0.29.0-rc.4 → 0.30.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 (57) hide show
  1. package/README.internal.md +3 -3
  2. package/README.md +25 -2
  3. package/dist/{authorize-DIYS7zBP.d.cts → authorize-9hTTG-qJ.d.cts} +1 -1
  4. package/dist/{authorize-CqYsQYfa.d.ts → authorize-DNUlPT7k.d.ts} +1 -1
  5. package/dist/base-7cq6HCPO.d.ts +36 -0
  6. package/dist/base-CHNFFrMG.d.cts +36 -0
  7. package/dist/cli/extract-manifest.cjs +7 -12
  8. package/dist/cli/extract-manifest.js +7 -12
  9. package/dist/{authorize-b3VqTC_7.js → cors-5P69YRDK.js} +79 -28
  10. package/dist/{authorize-CKMlIxm9.cjs → cors-DIQIXIHY.cjs} +90 -33
  11. package/dist/{errors-DSe96Ffd.js → errors-Bwd1L0Rf.js} +23 -8
  12. package/dist/{errors-CN6Da8iz.cjs → errors-Cr95rSkB.cjs} +23 -8
  13. package/dist/forwarded-DG83ubwT.js +26 -0
  14. package/dist/forwarded-zNAIofM2.cjs +31 -0
  15. package/dist/index.cjs +38 -1
  16. package/dist/index.d.cts +3 -3
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +38 -1
  19. package/dist/{io-Dx0nPc1-.d.cts → io-CDV3mud0.d.cts} +1 -1
  20. package/dist/{io-DP3icuxa.d.ts → io-D_5cuaEL.d.ts} +1 -1
  21. package/dist/mcp-Cb5SavFT.js +348 -0
  22. package/dist/mcp-Dq6dXUKT.cjs +353 -0
  23. package/dist/{package-Xk8p8Q_E.cjs → package-QViIguII.cjs} +1 -1
  24. package/dist/{package-DMs4EVwG.js → package-ZFJI6B7S.js} +1 -1
  25. package/dist/protocols/mcp/index.cjs +1 -1
  26. package/dist/protocols/mcp/index.d.cts +3 -33
  27. package/dist/protocols/mcp/index.d.ts +3 -33
  28. package/dist/protocols/mcp/index.js +1 -1
  29. package/dist/protocols/oauth-metadata.cjs +27 -10
  30. package/dist/protocols/oauth-metadata.d.cts +4 -3
  31. package/dist/protocols/oauth-metadata.d.ts +4 -3
  32. package/dist/protocols/oauth-metadata.js +21 -4
  33. package/dist/schema-CW1jKvio.js +65 -0
  34. package/dist/schema-D3vClxb7.cjs +76 -0
  35. package/dist/stacks/supabase/index.cjs +6 -6
  36. package/dist/stacks/supabase/index.d.cts +1 -1
  37. package/dist/stacks/supabase/index.d.ts +1 -1
  38. package/dist/stacks/supabase/index.js +4 -4
  39. package/dist/stacks/supabase/vite.cjs +1 -1
  40. package/dist/stacks/supabase/vite.d.cts +1 -1
  41. package/dist/stacks/supabase/vite.d.ts +1 -1
  42. package/dist/stacks/supabase/vite.js +1 -1
  43. package/dist/stacks/tanstack/index.cjs +5 -5
  44. package/dist/stacks/tanstack/index.d.cts +2 -2
  45. package/dist/stacks/tanstack/index.d.ts +2 -2
  46. package/dist/stacks/tanstack/index.js +4 -4
  47. package/dist/stacks/tanstack/vite.cjs +8 -4
  48. package/dist/stacks/tanstack/vite.d.cts +4 -1
  49. package/dist/stacks/tanstack/vite.d.ts +4 -1
  50. package/dist/stacks/tanstack/vite.js +8 -4
  51. package/dist/{types-C0Wgm9zp.d.cts → types-3CZPz364.d.cts} +65 -29
  52. package/dist/{types-C0Wgm9zp.d.ts → types-3CZPz364.d.ts} +65 -29
  53. package/package.json +5 -1
  54. package/dist/forwarded-Bhwcj22u.cjs +0 -48
  55. package/dist/forwarded-BlLF3dfc.js +0 -43
  56. package/dist/mcp-BLs6_g8i.js +0 -174
  57. package/dist/mcp-DtHM-41c.cjs +0 -179
@@ -0,0 +1,76 @@
1
+ let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
2
+ let _modelcontextprotocol_sdk_server_zod_json_schema_compat_js = require("@modelcontextprotocol/sdk/server/zod-json-schema-compat.js");
3
+ //#region src/core/schema.ts
4
+ function isZodSchema(definition) {
5
+ return (typeof definition === "object" || typeof definition === "function") && definition !== null && typeof definition.safeParse === "function";
6
+ }
7
+ function schemaFromDefinition(definition) {
8
+ return isZodSchema(definition) ? definition : (0, _modelcontextprotocol_sdk_server_zod_compat_js.objectFromShape)(definition);
9
+ }
10
+ const NON_JSON_ZOD3_OUTPUTS = /* @__PURE__ */ new Set([
11
+ "ZodBigInt",
12
+ "ZodDate",
13
+ "ZodFunction",
14
+ "ZodMap",
15
+ "ZodNaN",
16
+ "ZodPromise",
17
+ "ZodSet",
18
+ "ZodSymbol",
19
+ "ZodUndefined",
20
+ "ZodVoid"
21
+ ]);
22
+ function unsupportedZod3Output(schema, seen = /* @__PURE__ */ new Set()) {
23
+ if (seen.has(schema)) return void 0;
24
+ seen.add(schema);
25
+ const definition = schema._def;
26
+ if (!definition) return void 0;
27
+ if (definition.effect?.type === "transform") return "Transforms cannot be represented in JSON Schema";
28
+ const typeName = definition.typeName;
29
+ if (typeof typeName === "string" && NON_JSON_ZOD3_OUTPUTS.has(typeName)) return `${typeName} does not produce a JSON value`;
30
+ const shape = definition.shape;
31
+ if (typeof shape === "function") {
32
+ const fields = shape();
33
+ for (const field of Object.values(fields)) {
34
+ const issue = unsupportedZod3Output(field, seen);
35
+ if (issue) return issue;
36
+ }
37
+ }
38
+ const getter = definition.getter;
39
+ if (typeof getter === "function") {
40
+ const issue = unsupportedZod3Output(getter(), seen);
41
+ if (issue) return issue;
42
+ }
43
+ for (const value of Object.values(definition)) if (Array.isArray(value)) for (const entry of value) {
44
+ if (!isZodSchema(entry)) continue;
45
+ const issue = unsupportedZod3Output(entry, seen);
46
+ if (issue) return issue;
47
+ }
48
+ else if (value && typeof value === "object" && isZodSchema(value)) {
49
+ const issue = unsupportedZod3Output(value, seen);
50
+ if (issue) return issue;
51
+ }
52
+ }
53
+ function jsonSchemaFromDefinition(definition, pipeStrategy) {
54
+ const schema = schemaFromDefinition(definition);
55
+ if (pipeStrategy === "output") {
56
+ const issue = unsupportedZod3Output(schema);
57
+ if (issue) throw new Error(issue);
58
+ }
59
+ return (0, _modelcontextprotocol_sdk_server_zod_json_schema_compat_js.toJsonSchemaCompat)(schema, {
60
+ target: "draft-2020-12",
61
+ pipeStrategy
62
+ });
63
+ }
64
+ //#endregion
65
+ Object.defineProperty(exports, "jsonSchemaFromDefinition", {
66
+ enumerable: true,
67
+ get: function() {
68
+ return jsonSchemaFromDefinition;
69
+ }
70
+ });
71
+ Object.defineProperty(exports, "schemaFromDefinition", {
72
+ enumerable: true,
73
+ get: function() {
74
+ return schemaFromDefinition;
75
+ }
76
+ });
@@ -1,10 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_logger = require("../../logger-CN1q-KNn.cjs");
3
- const require_authorize = require("../../authorize-CKMlIxm9.cjs");
3
+ const require_cors = require("../../cors-DIQIXIHY.cjs");
4
4
  const require_metadata_path = require("../../metadata-path-zd7NSNoa.cjs");
5
- const require_mcp = require("../../mcp-DtHM-41c.cjs");
5
+ const require_mcp = require("../../mcp-Dq6dXUKT.cjs");
6
6
  const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
7
- const require_forwarded = require("../../forwarded-Bhwcj22u.cjs");
7
+ const require_forwarded = require("../../forwarded-zNAIofM2.cjs");
8
8
  const require_paths = require("../../paths-OP318a6c.cjs");
9
9
  //#region src/stacks/supabase/handler.ts
10
10
  function deriveResourcePath(options) {
@@ -29,7 +29,7 @@ function isMetadataPath(pathname) {
29
29
  */
30
30
  function createSupabaseHandler(mcp, options = {}) {
31
31
  const resourcePath = deriveResourcePath(options);
32
- if (resourcePath !== void 0) require_authorize.assertResourcePathShape(resourcePath);
32
+ if (resourcePath !== void 0) require_cors.assertResourcePathShape(resourcePath);
33
33
  const servesOwnPrm = !(mcp.auth?.type === "oauth" && mcp.auth.protectedResourceMetadataUrl !== void 0);
34
34
  const metadataPath = resourcePath === void 0 || !servesOwnPrm ? void 0 : `${require_logger.trimTrailingSlash(resourcePath)}${require_metadata_path.OAUTH_PROTECTED_RESOURCE_METADATA_PATH}`;
35
35
  const runtimeOptions = {
@@ -44,8 +44,8 @@ function createSupabaseHandler(mcp, options = {}) {
44
44
  const metadataHandler = require_protocols_oauth_metadata.createOAuthProtectedResourceMetadataHandler(mcp, runtimeOptions);
45
45
  return async (request) => {
46
46
  const req = require_forwarded.applyForwardedOrigin(request, runtimeOptions);
47
- if (isMetadataPath(new URL(req.url).pathname)) return metadataHandler(req);
48
- return mcpHandler(req, require_authorize.createRecorderForRuntime(mcp, { stack: "supabase" }));
47
+ if (isMetadataPath(new URL(req.url).pathname)) return metadataHandler(req, require_cors.createRecorderForRuntime(mcp, { stack: "supabase" }));
48
+ return mcpHandler(req, require_cors.createRecorderForRuntime(mcp, { stack: "supabase" }));
49
49
  };
50
50
  }
51
51
  //#endregion
@@ -1,4 +1,4 @@
1
- import { c as McpDefinition } from "../../types-C0Wgm9zp.cjs";
1
+ import { d as McpDefinition } from "../../types-3CZPz364.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 { c as McpDefinition } from "../../types-C0Wgm9zp.js";
1
+ import { d as McpDefinition } from "../../types-3CZPz364.js";
2
2
  //#region src/stacks/supabase/handler.d.ts
3
3
  type SupabaseHandler = (request: Request) => Promise<Response>;
4
4
  interface SupabaseHandlerOptions {
@@ -1,9 +1,9 @@
1
1
  import { s as trimTrailingSlash } from "../../logger-Ctv5xUSD.js";
2
- import { i as assertResourcePathShape, o as createRecorderForRuntime } from "../../authorize-b3VqTC_7.js";
2
+ import { c as createRecorderForRuntime, o as assertResourcePathShape } from "../../cors-5P69YRDK.js";
3
3
  import { t as OAUTH_PROTECTED_RESOURCE_METADATA_PATH } from "../../metadata-path-CAkNcfyY.js";
4
- import { t as createMcpProtocolHandler } from "../../mcp-BLs6_g8i.js";
4
+ import { t as createMcpProtocolHandler } from "../../mcp-Cb5SavFT.js";
5
5
  import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
6
- import { t as applyForwardedOrigin } from "../../forwarded-BlLF3dfc.js";
6
+ import { t as applyForwardedOrigin } from "../../forwarded-DG83ubwT.js";
7
7
  import { n as assertFunctionName, t as FUNCTIONS_MOUNT_PREFIX } from "../../paths-IS65L6TA.js";
8
8
  //#region src/stacks/supabase/handler.ts
9
9
  function deriveResourcePath(options) {
@@ -43,7 +43,7 @@ function createSupabaseHandler(mcp, options = {}) {
43
43
  const metadataHandler = createOAuthProtectedResourceMetadataHandler(mcp, runtimeOptions);
44
44
  return async (request) => {
45
45
  const req = applyForwardedOrigin(request, runtimeOptions);
46
- if (isMetadataPath(new URL(req.url).pathname)) return metadataHandler(req);
46
+ if (isMetadataPath(new URL(req.url).pathname)) return metadataHandler(req, createRecorderForRuntime(mcp, { stack: "supabase" }));
47
47
  return mcpHandler(req, createRecorderForRuntime(mcp, { stack: "supabase" }));
48
48
  };
49
49
  }
@@ -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-Xk8p8Q_E.cjs");
5
+ const require_package = require("../../package-QViIguII.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-Dx0nPc1-.cjs";
1
+ import { t as McpPluginApi } from "../../io-CDV3mud0.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-DP3icuxa.js";
1
+ import { t as McpPluginApi } from "../../io-D_5cuaEL.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-DMs4EVwG.js";
1
+ import { t as version } from "../../package-ZFJI6B7S.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,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_authorize = require("../../authorize-CKMlIxm9.cjs");
3
- const require_mcp = require("../../mcp-DtHM-41c.cjs");
2
+ const require_cors = require("../../cors-DIQIXIHY.cjs");
3
+ const require_mcp = require("../../mcp-Dq6dXUKT.cjs");
4
4
  const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
5
- const require_forwarded = require("../../forwarded-Bhwcj22u.cjs");
5
+ const require_forwarded = require("../../forwarded-zNAIofM2.cjs");
6
6
  //#region src/stacks/tanstack/handlers.ts
7
7
  const STACK = "tanstack";
8
8
  /**
@@ -11,7 +11,7 @@ const STACK = "tanstack";
11
11
  */
12
12
  function createTanStackMcpHandler(mcp, options = {}) {
13
13
  const handler = require_mcp.createMcpProtocolHandler(mcp, options);
14
- return ({ request }) => handler(require_forwarded.applyForwardedOrigin(request, options), require_authorize.createRecorderForRuntime(mcp, { stack: STACK }));
14
+ return ({ request }) => handler(require_forwarded.applyForwardedOrigin(request, options), require_cors.createRecorderForRuntime(mcp, { stack: STACK }));
15
15
  }
16
16
  /**
17
17
  * Build a TanStack Start handler for `GET /.well-known/oauth-protected-resource`.
@@ -19,7 +19,7 @@ function createTanStackMcpHandler(mcp, options = {}) {
19
19
  */
20
20
  function createTanStackOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
21
21
  const handler = require_protocols_oauth_metadata.createOAuthProtectedResourceMetadataHandler(mcp, options);
22
- return ({ request }) => handler(require_forwarded.applyForwardedOrigin(request, options));
22
+ return ({ request }) => handler(require_forwarded.applyForwardedOrigin(request, options), require_cors.createRecorderForRuntime(mcp, { stack: STACK }));
23
23
  }
24
24
  //#endregion
25
25
  exports.createTanStackMcpHandler = createTanStackMcpHandler;
@@ -1,5 +1,5 @@
1
- import { c as McpDefinition } from "../../types-C0Wgm9zp.cjs";
2
- import { t as McpRuntimeOptions } from "../../authorize-DIYS7zBP.cjs";
1
+ import { d as McpDefinition } from "../../types-3CZPz364.cjs";
2
+ import { t as McpRuntimeOptions } from "../../authorize-9hTTG-qJ.cjs";
3
3
  //#region src/stacks/tanstack/handlers.d.ts
4
4
  interface TanStackRouteCtx {
5
5
  request: Request;
@@ -1,5 +1,5 @@
1
- import { c as McpDefinition } from "../../types-C0Wgm9zp.js";
2
- import { t as McpRuntimeOptions } from "../../authorize-CqYsQYfa.js";
1
+ import { d as McpDefinition } from "../../types-3CZPz364.js";
2
+ import { t as McpRuntimeOptions } from "../../authorize-DNUlPT7k.js";
3
3
  //#region src/stacks/tanstack/handlers.d.ts
4
4
  interface TanStackRouteCtx {
5
5
  request: Request;
@@ -1,7 +1,7 @@
1
- import { o as createRecorderForRuntime } from "../../authorize-b3VqTC_7.js";
2
- import { t as createMcpProtocolHandler } from "../../mcp-BLs6_g8i.js";
1
+ import { c as createRecorderForRuntime } from "../../cors-5P69YRDK.js";
2
+ import { t as createMcpProtocolHandler } from "../../mcp-Cb5SavFT.js";
3
3
  import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
4
- import { t as applyForwardedOrigin } from "../../forwarded-BlLF3dfc.js";
4
+ import { t as applyForwardedOrigin } from "../../forwarded-DG83ubwT.js";
5
5
  //#region src/stacks/tanstack/handlers.ts
6
6
  const STACK = "tanstack";
7
7
  /**
@@ -18,7 +18,7 @@ function createTanStackMcpHandler(mcp, options = {}) {
18
18
  */
19
19
  function createTanStackOAuthProtectedResourceMetadataHandler(mcp, options = {}) {
20
20
  const handler = createOAuthProtectedResourceMetadataHandler(mcp, options);
21
- return ({ request }) => handler(applyForwardedOrigin(request, options));
21
+ return ({ request }) => handler(applyForwardedOrigin(request, options), createRecorderForRuntime(mcp, { stack: STACK }));
22
22
  }
23
23
  //#endregion
24
24
  export { createTanStackMcpHandler, createTanStackOAuthProtectedResourceMetadataHandler };
@@ -64,13 +64,16 @@ function relativeImportSpecifier(routeFile, target) {
64
64
  const withoutExt = normalizePath((0, node_path.relative)((0, node_path.dirname)(routeFile), target)).replace(/\.ts$/, "");
65
65
  return withoutExt.startsWith(".") ? withoutExt : `./${withoutExt}`;
66
66
  }
67
- function buildRouteSource(route, resourcePath, metadataPath, trustForwardedHost, mcpEntry, projectRoot) {
67
+ function buildRouteSource(route, resourcePath, metadataPath, trustForwardedHost, trustForwardedProto, mcpEntry, projectRoot) {
68
68
  const mcpImport = relativeImportSpecifier(route.file, mcpEntry);
69
69
  const routeRel = normalizePath((0, node_path.relative)(projectRoot, route.file));
70
70
  const optionEntries = [`resourcePath: "${resourcePath}"`];
71
71
  if (metadataPath !== void 0) optionEntries.push(`metadataPath: "${metadataPath}"`);
72
- if (trustForwardedHost) if (route.attestsForwardedHost) optionEntries.push("// Trusting X-Forwarded-Host is safe on Lovable hosting only (its proxy\n // overwrites the header); remove both options behind other proxies.\n trustForwardedHost: true", "forwardedHostTrustedByPlatform: true");
73
- else optionEntries.push("trustForwardedHost: true");
72
+ if (trustForwardedHost) if (route.attestsForwardedHost) {
73
+ const trustNote = trustForwardedProto ? "// Trusting X-Forwarded-Host/-Proto is safe on Lovable hosting only (its\n // proxies overwrite both headers); remove these options behind other proxies." : "// Trusting X-Forwarded-Host is safe on Lovable hosting only (its proxy\n // overwrites the header); remove both options behind other proxies.";
74
+ optionEntries.push(`${trustNote}\n trustForwardedHost: true`, "forwardedHostTrustedByPlatform: true");
75
+ } else optionEntries.push("trustForwardedHost: true");
76
+ if (trustForwardedProto) optionEntries.push("trustForwardedProto: true");
74
77
  const optionsObject = `{\n${optionEntries.map((entry) => ` ${entry},`).join("\n")}\n }`;
75
78
  const inlineRouteOpen = `export const Route = createFileRoute("${route.routeLiteral}")({`;
76
79
  const routeOpen = inlineRouteOpen.length <= OXFMT_PRINT_WIDTH ? inlineRouteOpen : `export const Route = createFileRoute(\n "${route.routeLiteral}",\n)({`;
@@ -176,6 +179,7 @@ function mcpPlugin(options = {}) {
176
179
  const metadataUrlPath = canonicalUrlPath(options.metadataPath ?? "/.well-known/oauth-protected-resource");
177
180
  const injectedMetadataPath = emitProtectedResourceMetadataRoute ? metadataUrlPath : void 0;
178
181
  const trustForwardedHost = options.trustForwardedHost !== false;
182
+ const trustForwardedProto = options.trustForwardedProto !== false;
179
183
  let projectRoot = process.cwd();
180
184
  let mcpEntry = (0, node_path.resolve)(projectRoot, mcpEntryOption);
181
185
  let { routesDir, mcpRouteFile, metadataRouteFile } = resolveAllRoutes(projectRoot, routesDirOption, routeFileName, metadataUrlPath);
@@ -202,7 +206,7 @@ function mcpPlugin(options = {}) {
202
206
  });
203
207
  for (const route of routes) {
204
208
  expected.add(route.file);
205
- writeIfChanged(route.file, buildRouteSource(route, urlPath, injectedMetadataPath, trustForwardedHost, mcpEntry, projectRoot));
209
+ writeIfChanged(route.file, buildRouteSource(route, urlPath, injectedMetadataPath, trustForwardedHost, trustForwardedProto, mcpEntry, projectRoot));
206
210
  }
207
211
  }
208
212
  for (const file of findAdoptedFiles(routesDir)) if (!expected.has(file)) try {
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-Dx0nPc1-.cjs";
1
+ import { t as McpPluginApi } from "../../io-CDV3mud0.cjs";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/tanstack/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -57,6 +57,9 @@ interface McpPluginOptions {
57
57
  * @default true
58
58
  */
59
59
  trustForwardedHost?: boolean;
60
+ /** Derive the public scheme from `X-Forwarded-Proto`; safe only behind an
61
+ * overwriting proxy. @default true */
62
+ trustForwardedProto?: boolean;
60
63
  }
61
64
  declare function assertUrlPathShape(urlPath: string): string;
62
65
  declare function deriveRouteFileName(urlPath: string): string;
@@ -1,4 +1,4 @@
1
- import { t as McpPluginApi } from "../../io-DP3icuxa.js";
1
+ import { t as McpPluginApi } from "../../io-D_5cuaEL.js";
2
2
  import { Plugin } from "vite";
3
3
  //#region src/stacks/tanstack/vite.d.ts
4
4
  interface McpPluginOptions {
@@ -57,6 +57,9 @@ interface McpPluginOptions {
57
57
  * @default true
58
58
  */
59
59
  trustForwardedHost?: boolean;
60
+ /** Derive the public scheme from `X-Forwarded-Proto`; safe only behind an
61
+ * overwriting proxy. @default true */
62
+ trustForwardedProto?: boolean;
60
63
  }
61
64
  declare function assertUrlPathShape(urlPath: string): string;
62
65
  declare function deriveRouteFileName(urlPath: string): string;
@@ -60,13 +60,16 @@ function relativeImportSpecifier(routeFile, target) {
60
60
  const withoutExt = normalizePath(relative(dirname(routeFile), target)).replace(/\.ts$/, "");
61
61
  return withoutExt.startsWith(".") ? withoutExt : `./${withoutExt}`;
62
62
  }
63
- function buildRouteSource(route, resourcePath, metadataPath, trustForwardedHost, mcpEntry, projectRoot) {
63
+ function buildRouteSource(route, resourcePath, metadataPath, trustForwardedHost, trustForwardedProto, mcpEntry, projectRoot) {
64
64
  const mcpImport = relativeImportSpecifier(route.file, mcpEntry);
65
65
  const routeRel = normalizePath(relative(projectRoot, route.file));
66
66
  const optionEntries = [`resourcePath: "${resourcePath}"`];
67
67
  if (metadataPath !== void 0) optionEntries.push(`metadataPath: "${metadataPath}"`);
68
- if (trustForwardedHost) if (route.attestsForwardedHost) optionEntries.push("// Trusting X-Forwarded-Host is safe on Lovable hosting only (its proxy\n // overwrites the header); remove both options behind other proxies.\n trustForwardedHost: true", "forwardedHostTrustedByPlatform: true");
69
- else optionEntries.push("trustForwardedHost: true");
68
+ if (trustForwardedHost) if (route.attestsForwardedHost) {
69
+ const trustNote = trustForwardedProto ? "// Trusting X-Forwarded-Host/-Proto is safe on Lovable hosting only (its\n // proxies overwrite both headers); remove these options behind other proxies." : "// Trusting X-Forwarded-Host is safe on Lovable hosting only (its proxy\n // overwrites the header); remove both options behind other proxies.";
70
+ optionEntries.push(`${trustNote}\n trustForwardedHost: true`, "forwardedHostTrustedByPlatform: true");
71
+ } else optionEntries.push("trustForwardedHost: true");
72
+ if (trustForwardedProto) optionEntries.push("trustForwardedProto: true");
70
73
  const optionsObject = `{\n${optionEntries.map((entry) => ` ${entry},`).join("\n")}\n }`;
71
74
  const inlineRouteOpen = `export const Route = createFileRoute("${route.routeLiteral}")({`;
72
75
  const routeOpen = inlineRouteOpen.length <= OXFMT_PRINT_WIDTH ? inlineRouteOpen : `export const Route = createFileRoute(\n "${route.routeLiteral}",\n)({`;
@@ -172,6 +175,7 @@ function mcpPlugin(options = {}) {
172
175
  const metadataUrlPath = canonicalUrlPath(options.metadataPath ?? "/.well-known/oauth-protected-resource");
173
176
  const injectedMetadataPath = emitProtectedResourceMetadataRoute ? metadataUrlPath : void 0;
174
177
  const trustForwardedHost = options.trustForwardedHost !== false;
178
+ const trustForwardedProto = options.trustForwardedProto !== false;
175
179
  let projectRoot = process.cwd();
176
180
  let mcpEntry = resolve(projectRoot, mcpEntryOption);
177
181
  let { routesDir, mcpRouteFile, metadataRouteFile } = resolveAllRoutes(projectRoot, routesDirOption, routeFileName, metadataUrlPath);
@@ -198,7 +202,7 @@ function mcpPlugin(options = {}) {
198
202
  });
199
203
  for (const route of routes) {
200
204
  expected.add(route.file);
201
- writeIfChanged(route.file, buildRouteSource(route, urlPath, injectedMetadataPath, trustForwardedHost, mcpEntry, projectRoot));
205
+ writeIfChanged(route.file, buildRouteSource(route, urlPath, injectedMetadataPath, trustForwardedHost, trustForwardedProto, mcpEntry, projectRoot));
202
206
  }
203
207
  }
204
208
  for (const file of findAdoptedFiles(routesDir)) if (!expected.has(file)) try {
@@ -85,16 +85,49 @@ interface McpAuthConfig {
85
85
  }
86
86
  //#endregion
87
87
  //#region src/auth/context.d.ts
88
- /**
89
- * The auth surface passed to every tool handler as its second argument. It wraps
90
- * the verified per-request auth context in a private field, so the context — and
91
- * the bearer token inside it can't be read, enumerated, spread, or
92
- * `JSON.stringify`'d off the instance; the accessors below are the only way out.
93
- * `getToken()` is the single intentional escape hatch for the raw bearer.
94
- */
88
+ /** Protocol era of an in-flight request: self-describing `2026-07-28` or the
89
+ * initialization-era `legacy` fallback. */
90
+ type McpProtocolEra = "2026-07-28" | "legacy";
91
+ /** What the client declared about itself on the in-flight request. Unverified
92
+ * client input a hint, never an authorization signal (use the auth accessors). */
93
+ interface McpClientInfo {
94
+ /** Protocol era of the in-flight request. */
95
+ protocol: McpProtocolEra;
96
+ /** Client name/version from the request envelope (`2026-07-28` era only). */
97
+ info?: {
98
+ name: string;
99
+ version: string;
100
+ title?: string;
101
+ };
102
+ /** Client capabilities from the request envelope (`2026-07-28` era only). */
103
+ capabilities?: Record<string, unknown>;
104
+ /** Extension declarations (`capabilities.extensions`), keyed by extension id. */
105
+ extensions?: Record<string, Record<string, unknown>>;
106
+ }
107
+ /** A progress notification payload. `progress` should increase monotonically. */
108
+ interface ProgressUpdate {
109
+ progress: number;
110
+ total?: number;
111
+ message?: string;
112
+ }
113
+ /** Per-request runtime surface threaded into `ToolContext` by the protocol layer. */
114
+ interface ToolRequestContext {
115
+ signal?: AbortSignal;
116
+ client?: McpClientInfo;
117
+ sendProgress?: (update: ProgressUpdate) => Promise<void>;
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. */
95
121
  declare class ToolContext {
96
122
  #private;
97
- constructor(auth: McpAuthContext | undefined);
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>;
98
131
  /** Whether the in-flight tool call carries a verified auth context. */
99
132
  isAuthenticated(): boolean;
100
133
  /** The verified bearer token, or `undefined` when unauthenticated. Pass it to downstream APIs; never return or log it. */
@@ -148,11 +181,10 @@ type MetricsConfig = boolean | MetricsOptions;
148
181
  * `inputSchema`, use `ZodRawShape`.
149
182
  */
150
183
  type ZodSchema = ZodType;
151
- /**
152
- * A raw zod shape (`{ text: z.string(), n: z.number() }`) — the format
153
- * `defineTool`'s `inputSchema`/`outputSchema` expects.
154
- */
184
+ /** A raw zod shape (`{ text: z.string() }`) — the format `defineTool`'s
185
+ * `inputSchema` expects and the object shorthand accepted by `outputSchema`. */
155
186
  type ZodRawShape$1 = ZodRawShape;
187
+ type ZodOutputSchema = ZodSchema | ZodRawShape$1;
156
188
  /**
157
189
  * Infer the parsed-output type of a zod raw shape — given
158
190
  * `{ text: ZodString, n: ZodNumber }`, produces `{ text: string, n: number }`.
@@ -217,8 +249,8 @@ type EmbeddedResource = EmbeddedTextResource | EmbeddedBlobResource;
217
249
  interface ResourceLinkIcon {
218
250
  src: string;
219
251
  mimeType?: string;
220
- /** Space-separated dimension string, HTML `<link sizes>` convention (e.g. `"16x16 32x32"`). */
221
- sizes?: string;
252
+ /** Array per MCP 2026-07-28; legacy space-separated strings remain accepted. */
253
+ sizes?: string | string[];
222
254
  theme?: "light" | "dark";
223
255
  }
224
256
  interface ResourceLink extends ContentBlockBase {
@@ -241,6 +273,15 @@ type ContentBlock = TextContent | ImageContent | AudioContent | EmbeddedResource
241
273
  * the tool returns to the caller.
242
274
  */
243
275
  type ToolContent = ContentBlock[];
276
+ type JsonValue = null | boolean | number | string | JsonValue[] | {
277
+ [key: string]: JsonValue;
278
+ };
279
+ /** Handler-input relaxation of `JsonValue`: object properties may be `undefined`
280
+ * (they serialize away, matching `JSON.stringify` semantics). */
281
+ type JsonValueInput = null | boolean | number | string | JsonValueInput[] | {
282
+ [key: string]: JsonValueInput | undefined;
283
+ };
284
+ type McpAllowedOrigins = "any" | readonly string[];
244
285
  /**
245
286
  * Per-tool client hints (not enforcement). `annotations.title` is
246
287
  * intentionally omitted — use `ToolDefinition.title`, which the MCP
@@ -258,10 +299,10 @@ interface ToolAnnotations {
258
299
  }
259
300
  interface ToolHandlerResult {
260
301
  content?: ToolContent;
261
- structuredContent?: Record<string, unknown>;
302
+ structuredContent?: JsonValueInput;
262
303
  isError?: boolean;
263
304
  }
264
- interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined> {
305
+ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$1 | undefined, TOutput extends ZodOutputSchema | undefined = ZodOutputSchema | undefined> {
265
306
  readonly name: string;
266
307
  /** Human-readable display name shown to the user in MCP clients. Required. */
267
308
  readonly title: string;
@@ -272,32 +313,27 @@ interface ToolDefinition<TInput extends ZodRawShape$1 | undefined = ZodRawShape$
272
313
  readonly annotations?: ToolAnnotations;
273
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>;
274
315
  }
275
- /**
276
- * Type-erased element of `McpDefinition.tools`. Per-tool generic typing
277
- * happens at the `defineTool` call site; see README §6 for the rationale.
278
- */
316
+ /** Type-erased element of `McpDefinition.tools`; per-tool generic typing
317
+ * happens at the `defineTool` call site. */
279
318
  interface AnyToolDefinition {
280
319
  readonly name: string;
281
320
  readonly title: string;
282
321
  readonly description: string;
283
322
  readonly inputSchema?: ZodRawShape$1;
284
- readonly outputSchema?: ZodRawShape$1;
323
+ readonly outputSchema?: ZodOutputSchema;
285
324
  readonly annotations?: ToolAnnotations;
286
325
  readonly handler: (args: any, ctx: ToolContext) => ToolHandlerResult | Promise<ToolHandlerResult>;
287
326
  }
288
- /**
289
- * Fields a caller supplies when constructing an MCP definition. Pass this
290
- * shape to `defineMcp(...)` — its return type is the branded `McpDefinition`,
291
- * which is the type every internal factory (`createInvokeToolHandler`,
292
- * `createMcpProtocolHandler`, …) consumes. The brand forces consumers
293
- * through `defineMcp`'s `assertUniqueNames` + freeze.
294
- */
327
+ /** Input shape for `defineMcp(...)`, whose branded `McpDefinition` return type is what
328
+ * `createMcpProtocolHandler` consumes the brand forces validation + freeze. */
295
329
  interface McpDefinitionInput {
296
330
  readonly name: string;
297
331
  /** Human-readable display name shown to MCP clients. Required. */
298
332
  readonly title: string;
299
333
  readonly version: string;
300
334
  readonly auth?: McpAuthConfig;
335
+ /** Cross-origin browser access. Omit to allow only same-origin and non-browser requests. */
336
+ readonly allowedOrigins?: McpAllowedOrigins;
301
337
  /**
302
338
  * Server-level prose the LLM reads as context for all tools on this server.
303
339
  * Required for the same reason `ToolDefinition.description` is — optional
@@ -318,4 +354,4 @@ type McpDefinition = McpDefinitionInput & {
318
354
  readonly [McpDefinitionBrand]: never;
319
355
  };
320
356
  //#endregion
321
- export { McpAuthConfig as C, JwtClaims as S, ZodRawShape$1 as _, EmbeddedResource as a, MetricsOptions as b, McpDefinition as c, ResourceLinkIcon as d, TextContent as f, ToolHandlerResult as g, ToolDefinition as h, EmbeddedBlobResource as i, McpDefinitionInput as l, ToolContent as m, ContentAnnotations as n, EmbeddedTextResource as o, ToolAnnotations as p, ContentBlock as r, ImageContent as s, AudioContent as t, ResourceLink as u, ZodSchema as v, ToolContext as x, MetricsConfig as y };
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 };