@lovable.dev/mcp-js 0.30.0-rc.0 → 1.0.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 +2 -25
  3. package/dist/{cors-5P69YRDK.js → authorize-9wHgaqeQ.js} +28 -79
  4. package/dist/{authorize-DNUlPT7k.d.ts → authorize-CqYsQYfa.d.ts} +1 -1
  5. package/dist/{cors-DIQIXIHY.cjs → authorize-DBk5GkN_.cjs} +33 -90
  6. package/dist/{authorize-9hTTG-qJ.d.cts → authorize-DIYS7zBP.d.cts} +1 -1
  7. package/dist/cli/extract-manifest.cjs +12 -7
  8. package/dist/cli/extract-manifest.js +12 -7
  9. package/dist/{errors-Cr95rSkB.cjs → errors-CN6Da8iz.cjs} +8 -23
  10. package/dist/{errors-Bwd1L0Rf.js → errors-DSe96Ffd.js} +8 -23
  11. package/dist/forwarded-Bhwcj22u.cjs +48 -0
  12. package/dist/forwarded-BlLF3dfc.js +43 -0
  13. package/dist/index.cjs +1 -38
  14. package/dist/index.d.cts +3 -3
  15. package/dist/index.d.ts +3 -3
  16. package/dist/index.js +1 -38
  17. package/dist/{io-D_5cuaEL.d.ts → io-DP3icuxa.d.ts} +1 -1
  18. package/dist/{io-CDV3mud0.d.cts → io-Dx0nPc1-.d.cts} +1 -1
  19. package/dist/mcp-BDsG9I0t.js +174 -0
  20. package/dist/mcp-CS1MF39p.cjs +179 -0
  21. package/dist/{package-ZFJI6B7S.js → package-CLhOKbJP.js} +1 -1
  22. package/dist/{package-QViIguII.cjs → package-C_8WAZRS.cjs} +1 -1
  23. package/dist/protocols/mcp/index.cjs +1 -1
  24. package/dist/protocols/mcp/index.d.cts +33 -3
  25. package/dist/protocols/mcp/index.d.ts +33 -3
  26. package/dist/protocols/mcp/index.js +1 -1
  27. package/dist/protocols/oauth-metadata.cjs +10 -27
  28. package/dist/protocols/oauth-metadata.d.cts +3 -4
  29. package/dist/protocols/oauth-metadata.d.ts +3 -4
  30. package/dist/protocols/oauth-metadata.js +4 -21
  31. package/dist/stacks/supabase/index.cjs +6 -6
  32. package/dist/stacks/supabase/index.d.cts +1 -1
  33. package/dist/stacks/supabase/index.d.ts +1 -1
  34. package/dist/stacks/supabase/index.js +4 -4
  35. package/dist/stacks/supabase/vite.cjs +1 -1
  36. package/dist/stacks/supabase/vite.d.cts +1 -1
  37. package/dist/stacks/supabase/vite.d.ts +1 -1
  38. package/dist/stacks/supabase/vite.js +1 -1
  39. package/dist/stacks/tanstack/index.cjs +5 -5
  40. package/dist/stacks/tanstack/index.d.cts +2 -2
  41. package/dist/stacks/tanstack/index.d.ts +2 -2
  42. package/dist/stacks/tanstack/index.js +4 -4
  43. package/dist/stacks/tanstack/vite.cjs +4 -8
  44. package/dist/stacks/tanstack/vite.d.cts +1 -4
  45. package/dist/stacks/tanstack/vite.d.ts +1 -4
  46. package/dist/stacks/tanstack/vite.js +4 -8
  47. package/dist/{types-3CZPz364.d.cts → types-C0Wgm9zp.d.cts} +29 -65
  48. package/dist/{types-3CZPz364.d.ts → types-C0Wgm9zp.d.ts} +29 -65
  49. package/package.json +1 -5
  50. package/dist/base-7cq6HCPO.d.ts +0 -36
  51. package/dist/base-CHNFFrMG.d.cts +0 -36
  52. package/dist/forwarded-DG83ubwT.js +0 -26
  53. package/dist/forwarded-zNAIofM2.cjs +0 -31
  54. package/dist/mcp-Cb5SavFT.js +0 -348
  55. package/dist/mcp-Dq6dXUKT.cjs +0 -353
  56. package/dist/schema-CW1jKvio.js +0 -65
  57. package/dist/schema-D3vClxb7.cjs +0 -76
@@ -0,0 +1,48 @@
1
+ //#region src/core/forwarded.ts
2
+ /**
3
+ * Rewrites a request's URL to the public origin a reverse proxy forwards via
4
+ * `X-Forwarded-*`, so SDK-derived OAuth `resource`/metadata/`WWW-Authenticate`
5
+ * URLs name the host the client actually connected to — not the internal
6
+ * backend origin the proxy rewrites `Host` to. Without this, an app on a custom
7
+ * domain advertises its internal `*.lovable.dev`/`*.supabase.co` host and every
8
+ * MCP call 401s on an audience the client can't satisfy.
9
+ *
10
+ * Each header is trusted independently, because a forwarded value is only as
11
+ * trustworthy as the proxy that sets it:
12
+ * - `X-Forwarded-Host` can redirect the advertised resource to an attacker
13
+ * origin (the threat `auth/resource.ts` guards against), so it is honored only
14
+ * when `trustForwardedHost` is set — enabled on emit paths that sit behind a
15
+ * proxy which *overwrites* the header (Lovable's web-proxy does), never by a
16
+ * bare SDK consumer.
17
+ * - `X-Forwarded-Proto` only selects http/https, so it is gated separately:
18
+ * Supabase terminates TLS upstream and forwards over http with a
19
+ * gateway-stamped proto, so that stack always trusts it; the TanStack proxy
20
+ * does not sanitize proto, so its Vite plugin never emits the flag.
21
+ */
22
+ function applyForwardedOrigin(request, options) {
23
+ const proto = options.trustForwardedProto ? firstForwardedValue(request, "x-forwarded-proto") : void 0;
24
+ const host = options.trustForwardedHost ? firstForwardedValue(request, "x-forwarded-host") : void 0;
25
+ if (proto === void 0 && host === void 0) return request;
26
+ const url = new URL(request.url);
27
+ let changed = false;
28
+ if (proto !== void 0 && `${proto}:` !== url.protocol) {
29
+ url.protocol = `${proto}:`;
30
+ changed = true;
31
+ }
32
+ if (host !== void 0 && host !== url.host) {
33
+ url.host = host;
34
+ changed = true;
35
+ }
36
+ return changed ? new Request(url.href, request) : request;
37
+ }
38
+ function firstForwardedValue(request, header) {
39
+ const value = request.headers.get(header)?.split(",")[0]?.trim();
40
+ return value ? value : void 0;
41
+ }
42
+ //#endregion
43
+ Object.defineProperty(exports, "applyForwardedOrigin", {
44
+ enumerable: true,
45
+ get: function() {
46
+ return applyForwardedOrigin;
47
+ }
48
+ });
@@ -0,0 +1,43 @@
1
+ //#region src/core/forwarded.ts
2
+ /**
3
+ * Rewrites a request's URL to the public origin a reverse proxy forwards via
4
+ * `X-Forwarded-*`, so SDK-derived OAuth `resource`/metadata/`WWW-Authenticate`
5
+ * URLs name the host the client actually connected to — not the internal
6
+ * backend origin the proxy rewrites `Host` to. Without this, an app on a custom
7
+ * domain advertises its internal `*.lovable.dev`/`*.supabase.co` host and every
8
+ * MCP call 401s on an audience the client can't satisfy.
9
+ *
10
+ * Each header is trusted independently, because a forwarded value is only as
11
+ * trustworthy as the proxy that sets it:
12
+ * - `X-Forwarded-Host` can redirect the advertised resource to an attacker
13
+ * origin (the threat `auth/resource.ts` guards against), so it is honored only
14
+ * when `trustForwardedHost` is set — enabled on emit paths that sit behind a
15
+ * proxy which *overwrites* the header (Lovable's web-proxy does), never by a
16
+ * bare SDK consumer.
17
+ * - `X-Forwarded-Proto` only selects http/https, so it is gated separately:
18
+ * Supabase terminates TLS upstream and forwards over http with a
19
+ * gateway-stamped proto, so that stack always trusts it; the TanStack proxy
20
+ * does not sanitize proto, so its Vite plugin never emits the flag.
21
+ */
22
+ function applyForwardedOrigin(request, options) {
23
+ const proto = options.trustForwardedProto ? firstForwardedValue(request, "x-forwarded-proto") : void 0;
24
+ const host = options.trustForwardedHost ? firstForwardedValue(request, "x-forwarded-host") : void 0;
25
+ if (proto === void 0 && host === void 0) return request;
26
+ const url = new URL(request.url);
27
+ let changed = false;
28
+ if (proto !== void 0 && `${proto}:` !== url.protocol) {
29
+ url.protocol = `${proto}:`;
30
+ changed = true;
31
+ }
32
+ if (host !== void 0 && host !== url.host) {
33
+ url.host = host;
34
+ changed = true;
35
+ }
36
+ return changed ? new Request(url.href, request) : request;
37
+ }
38
+ function firstForwardedValue(request, header) {
39
+ const value = request.headers.get(header)?.split(",")[0]?.trim();
40
+ return value ? value : void 0;
41
+ }
42
+ //#endregion
43
+ export { applyForwardedOrigin as t };
package/dist/index.cjs CHANGED
@@ -1,7 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_logger = require("./logger-CN1q-KNn.cjs");
3
- const require_schema = require("./schema-D3vClxb7.cjs");
4
- const require_errors = require("./errors-Cr95rSkB.cjs");
3
+ const require_errors = require("./errors-CN6Da8iz.cjs");
5
4
  //#region src/core/define.ts
6
5
  function assertUniqueNames(mcp) {
7
6
  const seen = /* @__PURE__ */ new Set();
@@ -80,39 +79,6 @@ function freezeAuth(auth) {
80
79
  if (auth.accessTokenTyp) Object.freeze(auth.accessTokenTyp);
81
80
  Object.freeze(auth);
82
81
  }
83
- function assertAllowedOrigins(allowedOrigins) {
84
- if (allowedOrigins === void 0 || allowedOrigins === "any") return;
85
- if (!Array.isArray(allowedOrigins)) throw new Error(`@lovable.dev/mcp-js: allowedOrigins must be "any" or an array of exact origins`);
86
- for (const origin of allowedOrigins) {
87
- if (typeof origin !== "string") throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain strings`);
88
- let parsed;
89
- try {
90
- parsed = new URL(origin);
91
- } catch {
92
- throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain valid exact origins`);
93
- }
94
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.origin !== origin) throw new Error(`@lovable.dev/mcp-js: allowedOrigins entry "${origin}" must be an exact http(s) origin without a path, query, fragment, or trailing slash`);
95
- }
96
- }
97
- function assertToolSchemas(mcp) {
98
- for (const tool of mcp.tools) for (const [name, definition, strategy] of [[
99
- "inputSchema",
100
- tool.inputSchema,
101
- "input"
102
- ], [
103
- "outputSchema",
104
- tool.outputSchema,
105
- "output"
106
- ]]) {
107
- if (!definition) continue;
108
- try {
109
- require_schema.jsonSchemaFromDefinition(definition, strategy);
110
- } catch (error) {
111
- const detail = error instanceof Error ? `: ${error.message}` : "";
112
- throw new Error(`@lovable.dev/mcp-js: tool "${tool.name}" ${name} cannot be represented as JSON Schema${detail}`);
113
- }
114
- }
115
- }
116
82
  /**
117
83
  * Declare a single MCP tool. Import the result into your MCP definition's
118
84
  * `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
@@ -135,11 +101,8 @@ function defineMcp(def) {
135
101
  assertNonEmptyString("version", def.version);
136
102
  assertUniqueNames(def);
137
103
  if (def.auth) assertOAuthConfig(def.auth);
138
- assertAllowedOrigins(def.allowedOrigins);
139
- assertToolSchemas(def);
140
104
  require_logger.resolveMetricsConfig(def.metrics);
141
105
  freezeAuth(def.auth);
142
- if (Array.isArray(def.allowedOrigins)) Object.freeze(def.allowedOrigins);
143
106
  Object.freeze(def.tools);
144
107
  for (const tool of def.tools) Object.freeze(tool);
145
108
  return def;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as McpAuthConfig, C as MetricsConfig, D as ProgressUpdate, E as McpProtocolEra, O as ToolContext, S as ZodSchema, T as McpClientInfo, _ as ToolContent, a as EmbeddedResource, b as ZodOutputSchema, c as JsonValue, d as McpDefinition, f as McpDefinitionInput, g as ToolAnnotations, h as TextContent, i as EmbeddedBlobResource, k as JwtClaims, l as JsonValueInput, m as ResourceLinkIcon, n as ContentAnnotations, o as EmbeddedTextResource, p as ResourceLink, r as ContentBlock, s as ImageContent, t as AudioContent, u as McpAllowedOrigins, v as ToolDefinition, w as MetricsOptions, x as ZodRawShape, y as ToolHandlerResult } from "./types-3CZPz364.cjs";
1
+ import { C as McpAuthConfig, S as JwtClaims, _ as ZodRawShape, a as EmbeddedResource, b as MetricsOptions, c as McpDefinition, d as ResourceLinkIcon, f as TextContent, g as ToolHandlerResult, h as ToolDefinition, i as EmbeddedBlobResource, l as McpDefinitionInput, m as ToolContent, n as ContentAnnotations, o as EmbeddedTextResource, p as ToolAnnotations, r as ContentBlock, s as ImageContent, t as AudioContent, u as ResourceLink, v as ZodSchema, x as ToolContext, y as MetricsConfig } from "./types-C0Wgm9zp.cjs";
2
2
  //#region src/core/define.d.ts
3
3
  /**
4
4
  * Declare a single MCP tool. Import the result into your MCP definition's
@@ -8,7 +8,7 @@ import { A as McpAuthConfig, C as MetricsConfig, D as ProgressUpdate, E as McpPr
8
8
  * full `z.object(...)` — the MCP SDK builds the object wrapper internally
9
9
  * and the raw shape is what the JSON-RPC `tools/list` payload exposes.
10
10
  */
11
- declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends ZodOutputSchema | undefined = undefined>(def: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
11
+ declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends ZodRawShape | undefined = undefined>(def: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
12
12
  /**
13
13
  * Declare the MCP server. `export default` the result from your MCP
14
14
  * entrypoint (default `lib/mcp/index.ts`); the Vite plugin reads it to
@@ -71,4 +71,4 @@ type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
71
71
  */
72
72
  declare function setLogLevel(level: LogLevel): LogLevel;
73
73
  //#endregion
74
- export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type JsonValue, type JsonValueInput, type JwtClaims, type LogLevel, type McpAllowedOrigins, type McpClientInfo, type McpDefinitionInput, type McpProtocolEra, type MetricsConfig, type MetricsOptions, type ProgressUpdate, type ResourceLink, type ResourceLinkIcon, type TextContent, type ToolAnnotations, type ToolContent, ToolContext, type ToolDefinition, ToolError, type ToolHandlerResult, type ZodOutputSchema, type ZodRawShape, type ZodSchema, auth, defineMcp, defineTool, setLogLevel };
74
+ export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type JwtClaims, type LogLevel, type McpDefinitionInput, type MetricsConfig, type MetricsOptions, type ResourceLink, type ResourceLinkIcon, type TextContent, type ToolAnnotations, type ToolContent, ToolContext, type ToolDefinition, ToolError, type ToolHandlerResult, type ZodRawShape, type ZodSchema, auth, defineMcp, defineTool, setLogLevel };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as McpAuthConfig, C as MetricsConfig, D as ProgressUpdate, E as McpProtocolEra, O as ToolContext, S as ZodSchema, T as McpClientInfo, _ as ToolContent, a as EmbeddedResource, b as ZodOutputSchema, c as JsonValue, d as McpDefinition, f as McpDefinitionInput, g as ToolAnnotations, h as TextContent, i as EmbeddedBlobResource, k as JwtClaims, l as JsonValueInput, m as ResourceLinkIcon, n as ContentAnnotations, o as EmbeddedTextResource, p as ResourceLink, r as ContentBlock, s as ImageContent, t as AudioContent, u as McpAllowedOrigins, v as ToolDefinition, w as MetricsOptions, x as ZodRawShape, y as ToolHandlerResult } from "./types-3CZPz364.js";
1
+ import { C as McpAuthConfig, S as JwtClaims, _ as ZodRawShape, a as EmbeddedResource, b as MetricsOptions, c as McpDefinition, d as ResourceLinkIcon, f as TextContent, g as ToolHandlerResult, h as ToolDefinition, i as EmbeddedBlobResource, l as McpDefinitionInput, m as ToolContent, n as ContentAnnotations, o as EmbeddedTextResource, p as ToolAnnotations, r as ContentBlock, s as ImageContent, t as AudioContent, u as ResourceLink, v as ZodSchema, x as ToolContext, y as MetricsConfig } from "./types-C0Wgm9zp.js";
2
2
  //#region src/core/define.d.ts
3
3
  /**
4
4
  * Declare a single MCP tool. Import the result into your MCP definition's
@@ -8,7 +8,7 @@ import { A as McpAuthConfig, C as MetricsConfig, D as ProgressUpdate, E as McpPr
8
8
  * full `z.object(...)` — the MCP SDK builds the object wrapper internally
9
9
  * and the raw shape is what the JSON-RPC `tools/list` payload exposes.
10
10
  */
11
- declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends ZodOutputSchema | undefined = undefined>(def: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
11
+ declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends ZodRawShape | undefined = undefined>(def: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
12
12
  /**
13
13
  * Declare the MCP server. `export default` the result from your MCP
14
14
  * entrypoint (default `lib/mcp/index.ts`); the Vite plugin reads it to
@@ -71,4 +71,4 @@ type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
71
71
  */
72
72
  declare function setLogLevel(level: LogLevel): LogLevel;
73
73
  //#endregion
74
- export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type JsonValue, type JsonValueInput, type JwtClaims, type LogLevel, type McpAllowedOrigins, type McpClientInfo, type McpDefinitionInput, type McpProtocolEra, type MetricsConfig, type MetricsOptions, type ProgressUpdate, type ResourceLink, type ResourceLinkIcon, type TextContent, type ToolAnnotations, type ToolContent, ToolContext, type ToolDefinition, ToolError, type ToolHandlerResult, type ZodOutputSchema, type ZodRawShape, type ZodSchema, auth, defineMcp, defineTool, setLogLevel };
74
+ export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type JwtClaims, type LogLevel, type McpDefinitionInput, type MetricsConfig, type MetricsOptions, type ResourceLink, type ResourceLinkIcon, type TextContent, type ToolAnnotations, type ToolContent, ToolContext, type ToolDefinition, ToolError, type ToolHandlerResult, type ZodRawShape, type ZodSchema, auth, defineMcp, defineTool, setLogLevel };
package/dist/index.js CHANGED
@@ -1,6 +1,5 @@
1
1
  import { a as setLogLevel, o as parseSafeUrl, s as trimTrailingSlash, u as resolveMetricsConfig } from "./logger-Ctv5xUSD.js";
2
- import { t as jsonSchemaFromDefinition } from "./schema-CW1jKvio.js";
3
- import { i as ToolContext, t as ToolError } from "./errors-Bwd1L0Rf.js";
2
+ import { i as ToolContext, t as ToolError } from "./errors-DSe96Ffd.js";
4
3
  //#region src/core/define.ts
5
4
  function assertUniqueNames(mcp) {
6
5
  const seen = /* @__PURE__ */ new Set();
@@ -79,39 +78,6 @@ function freezeAuth(auth) {
79
78
  if (auth.accessTokenTyp) Object.freeze(auth.accessTokenTyp);
80
79
  Object.freeze(auth);
81
80
  }
82
- function assertAllowedOrigins(allowedOrigins) {
83
- if (allowedOrigins === void 0 || allowedOrigins === "any") return;
84
- if (!Array.isArray(allowedOrigins)) throw new Error(`@lovable.dev/mcp-js: allowedOrigins must be "any" or an array of exact origins`);
85
- for (const origin of allowedOrigins) {
86
- if (typeof origin !== "string") throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain strings`);
87
- let parsed;
88
- try {
89
- parsed = new URL(origin);
90
- } catch {
91
- throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain valid exact origins`);
92
- }
93
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.origin !== origin) throw new Error(`@lovable.dev/mcp-js: allowedOrigins entry "${origin}" must be an exact http(s) origin without a path, query, fragment, or trailing slash`);
94
- }
95
- }
96
- function assertToolSchemas(mcp) {
97
- for (const tool of mcp.tools) for (const [name, definition, strategy] of [[
98
- "inputSchema",
99
- tool.inputSchema,
100
- "input"
101
- ], [
102
- "outputSchema",
103
- tool.outputSchema,
104
- "output"
105
- ]]) {
106
- if (!definition) continue;
107
- try {
108
- jsonSchemaFromDefinition(definition, strategy);
109
- } catch (error) {
110
- const detail = error instanceof Error ? `: ${error.message}` : "";
111
- throw new Error(`@lovable.dev/mcp-js: tool "${tool.name}" ${name} cannot be represented as JSON Schema${detail}`);
112
- }
113
- }
114
- }
115
81
  /**
116
82
  * Declare a single MCP tool. Import the result into your MCP definition's
117
83
  * `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
@@ -134,11 +100,8 @@ function defineMcp(def) {
134
100
  assertNonEmptyString("version", def.version);
135
101
  assertUniqueNames(def);
136
102
  if (def.auth) assertOAuthConfig(def.auth);
137
- assertAllowedOrigins(def.allowedOrigins);
138
- assertToolSchemas(def);
139
103
  resolveMetricsConfig(def.metrics);
140
104
  freezeAuth(def.auth);
141
- if (Array.isArray(def.allowedOrigins)) Object.freeze(def.allowedOrigins);
142
105
  Object.freeze(def.tools);
143
106
  for (const tool of def.tools) Object.freeze(tool);
144
107
  return def;
@@ -1,4 +1,4 @@
1
- import "./types-3CZPz364.js";
1
+ import "./types-C0Wgm9zp.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-3CZPz364.cjs";
1
+ import "./types-C0Wgm9zp.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
@@ -0,0 +1,174 @@
1
+ import { i as log, r as describeError } from "./logger-Ctv5xUSD.js";
2
+ import { i as ToolContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-DSe96Ffd.js";
3
+ import { c as nowMs, f as corsPreflightResponse, s as createNoopRecorder, t as createRequestAuthorizer, u as finalizeWireResponse } from "./authorize-9wHgaqeQ.js";
4
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
6
+ //#region src/core/content.ts
7
+ /** Join the text of a result's `type: "text"` blocks into one string, dropping
8
+ * binary/resource blocks. Used to surface a `tool_error` message in the local
9
+ * log; never sent over the telemetry wire. Returns undefined when there is no
10
+ * text to show. */
11
+ function extractTextContent(content) {
12
+ if (!content) return void 0;
13
+ const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
14
+ return text.length > 0 ? text : void 0;
15
+ }
16
+ //#endregion
17
+ //#region src/protocols/gate.ts
18
+ function createGatedHandler(gate) {
19
+ const allow = [...gate.methods, "OPTIONS"].join(", ");
20
+ const respond = async (request, recorder) => {
21
+ const authResult = await gate.authorizer.authorize(request, recorder);
22
+ if (!authResult.ok) return authResult.response;
23
+ if (!gate.methods.includes(request.method)) return gate.methodNotAllowed(allow);
24
+ return gate.handle(request, authResult, recorder);
25
+ };
26
+ return async (request, recorder = createNoopRecorder()) => {
27
+ if (request.method === "OPTIONS") return corsPreflightResponse(allow);
28
+ const final = finalizeWireResponse(request, await respond(request, recorder));
29
+ if (!final.headers.has("Cache-Control")) final.headers.set("Cache-Control", "no-store");
30
+ return final;
31
+ };
32
+ }
33
+ //#endregion
34
+ //#region src/protocols/mcp/protocol.ts
35
+ function statelessMethodNotAllowed(allow) {
36
+ return Response.json({
37
+ jsonrpc: "2.0",
38
+ id: null,
39
+ error: {
40
+ code: -32e3,
41
+ message: "Method not allowed: stateless server offers no standalone SSE stream (GET) or session (DELETE)."
42
+ }
43
+ }, {
44
+ status: 405,
45
+ headers: { Allow: allow }
46
+ });
47
+ }
48
+ /**
49
+ * Adapt a Lovable tool to the SDK's tool callback. The boundary cast bridges
50
+ * our SDK-decoupled content-block types to the SDK's; they match structurally.
51
+ */
52
+ function adaptToolToSdkCallback(tool, auth, recorder) {
53
+ const endUserId = auth?.principal.sub;
54
+ return (async (first) => {
55
+ const args = tool.inputSchema ? first ?? {} : {};
56
+ const start = nowMs();
57
+ let result;
58
+ try {
59
+ result = await tool.handler(args, new ToolContext(auth));
60
+ } catch (err) {
61
+ const callerMessage = resolveToolErrorMessage(err);
62
+ if (callerMessage === void 0) {
63
+ await recorder.emit({
64
+ tool: tool.name,
65
+ method: "tools/call",
66
+ outcome: "handler_error",
67
+ durationMs: nowMs() - start,
68
+ errorText: errorSummary(err),
69
+ endUserId
70
+ });
71
+ return {
72
+ content: [{
73
+ type: "text",
74
+ text: "tool execution failed"
75
+ }],
76
+ isError: true
77
+ };
78
+ }
79
+ result = {
80
+ content: [{
81
+ type: "text",
82
+ text: callerMessage
83
+ }],
84
+ isError: true
85
+ };
86
+ }
87
+ if (result == null) {
88
+ await recorder.emit({
89
+ tool: tool.name,
90
+ method: "tools/call",
91
+ outcome: "handler_error",
92
+ durationMs: nowMs() - start,
93
+ endUserId
94
+ });
95
+ return {
96
+ content: [{
97
+ type: "text",
98
+ text: `tool "${tool.name}" returned no result`
99
+ }],
100
+ isError: true
101
+ };
102
+ }
103
+ await recorder.emit({
104
+ tool: tool.name,
105
+ method: "tools/call",
106
+ outcome: result.isError ? "tool_error" : "ok",
107
+ durationMs: nowMs() - start,
108
+ errorText: result.isError ? extractTextContent(result.content) : void 0,
109
+ endUserId
110
+ });
111
+ return {
112
+ content: result.content ?? [],
113
+ structuredContent: result.structuredContent,
114
+ isError: result.isError
115
+ };
116
+ });
117
+ }
118
+ /**
119
+ * Build a Web-Standard request handler that serves the MCP protocol over
120
+ * streamable HTTP. A fresh `McpServer` + transport is constructed per
121
+ * request — the transport is stateless, so this is cheap and there is no
122
+ * cross-request state to leak. The per-request `recorder` is supplied by the
123
+ * caller (the stack handler) so telemetry reads the runtime env in-flight.
124
+ */
125
+ function createMcpProtocolHandler(mcp, options = {}) {
126
+ const authorizer = createRequestAuthorizer(mcp, options);
127
+ const handle = async (request, authResult, recorder) => {
128
+ try {
129
+ const server = new McpServer({
130
+ name: mcp.name,
131
+ version: mcp.version,
132
+ title: mcp.title
133
+ }, { instructions: mcp.instructions });
134
+ for (const tool of mcp.tools) server.registerTool(tool.name, {
135
+ title: tool.title,
136
+ description: tool.description,
137
+ inputSchema: tool.inputSchema,
138
+ outputSchema: tool.outputSchema,
139
+ annotations: tool.annotations
140
+ }, adaptToolToSdkCallback(tool, authResult.auth, recorder));
141
+ const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
142
+ await server.connect(transport);
143
+ return await transport.handleRequest(request);
144
+ } catch (err) {
145
+ await recorder.emit({
146
+ tool: null,
147
+ method: "transport",
148
+ outcome: "transport_error",
149
+ durationMs: 0,
150
+ endUserId: authResult.auth?.principal.sub
151
+ });
152
+ log.error("mcp.transport_error", {
153
+ ...describeError(err),
154
+ outcome: "500 internal error"
155
+ });
156
+ return Response.json({
157
+ jsonrpc: "2.0",
158
+ id: null,
159
+ error: {
160
+ code: -32603,
161
+ message: "internal error"
162
+ }
163
+ }, { status: 500 });
164
+ }
165
+ };
166
+ return createGatedHandler({
167
+ authorizer,
168
+ methods: ["POST"],
169
+ methodNotAllowed: statelessMethodNotAllowed,
170
+ handle
171
+ });
172
+ }
173
+ //#endregion
174
+ export { createMcpProtocolHandler as t };
@@ -0,0 +1,179 @@
1
+ const require_logger = require("./logger-CN1q-KNn.cjs");
2
+ const require_errors = require("./errors-CN6Da8iz.cjs");
3
+ const require_authorize = require("./authorize-DBk5GkN_.cjs");
4
+ let _modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
5
+ let _modelcontextprotocol_sdk_server_webStandardStreamableHttp_js = require("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
6
+ //#region src/core/content.ts
7
+ /** Join the text of a result's `type: "text"` blocks into one string, dropping
8
+ * binary/resource blocks. Used to surface a `tool_error` message in the local
9
+ * log; never sent over the telemetry wire. Returns undefined when there is no
10
+ * text to show. */
11
+ function extractTextContent(content) {
12
+ if (!content) return void 0;
13
+ const text = content.filter((block) => block.type === "text").map((block) => block.text).join("\n").trim();
14
+ return text.length > 0 ? text : void 0;
15
+ }
16
+ //#endregion
17
+ //#region src/protocols/gate.ts
18
+ function createGatedHandler(gate) {
19
+ const allow = [...gate.methods, "OPTIONS"].join(", ");
20
+ const respond = async (request, recorder) => {
21
+ const authResult = await gate.authorizer.authorize(request, recorder);
22
+ if (!authResult.ok) return authResult.response;
23
+ if (!gate.methods.includes(request.method)) return gate.methodNotAllowed(allow);
24
+ return gate.handle(request, authResult, recorder);
25
+ };
26
+ return async (request, recorder = require_authorize.createNoopRecorder()) => {
27
+ if (request.method === "OPTIONS") return require_authorize.corsPreflightResponse(allow);
28
+ const final = require_authorize.finalizeWireResponse(request, await respond(request, recorder));
29
+ if (!final.headers.has("Cache-Control")) final.headers.set("Cache-Control", "no-store");
30
+ return final;
31
+ };
32
+ }
33
+ //#endregion
34
+ //#region src/protocols/mcp/protocol.ts
35
+ function statelessMethodNotAllowed(allow) {
36
+ return Response.json({
37
+ jsonrpc: "2.0",
38
+ id: null,
39
+ error: {
40
+ code: -32e3,
41
+ message: "Method not allowed: stateless server offers no standalone SSE stream (GET) or session (DELETE)."
42
+ }
43
+ }, {
44
+ status: 405,
45
+ headers: { Allow: allow }
46
+ });
47
+ }
48
+ /**
49
+ * Adapt a Lovable tool to the SDK's tool callback. The boundary cast bridges
50
+ * our SDK-decoupled content-block types to the SDK's; they match structurally.
51
+ */
52
+ function adaptToolToSdkCallback(tool, auth, recorder) {
53
+ const endUserId = auth?.principal.sub;
54
+ return (async (first) => {
55
+ const args = tool.inputSchema ? first ?? {} : {};
56
+ const start = require_authorize.nowMs();
57
+ let result;
58
+ try {
59
+ result = await tool.handler(args, new require_errors.ToolContext(auth));
60
+ } catch (err) {
61
+ const callerMessage = require_errors.resolveToolErrorMessage(err);
62
+ if (callerMessage === void 0) {
63
+ await recorder.emit({
64
+ tool: tool.name,
65
+ method: "tools/call",
66
+ outcome: "handler_error",
67
+ durationMs: require_authorize.nowMs() - start,
68
+ errorText: require_errors.errorSummary(err),
69
+ endUserId
70
+ });
71
+ return {
72
+ content: [{
73
+ type: "text",
74
+ text: "tool execution failed"
75
+ }],
76
+ isError: true
77
+ };
78
+ }
79
+ result = {
80
+ content: [{
81
+ type: "text",
82
+ text: callerMessage
83
+ }],
84
+ isError: true
85
+ };
86
+ }
87
+ if (result == null) {
88
+ await recorder.emit({
89
+ tool: tool.name,
90
+ method: "tools/call",
91
+ outcome: "handler_error",
92
+ durationMs: require_authorize.nowMs() - start,
93
+ endUserId
94
+ });
95
+ return {
96
+ content: [{
97
+ type: "text",
98
+ text: `tool "${tool.name}" returned no result`
99
+ }],
100
+ isError: true
101
+ };
102
+ }
103
+ await recorder.emit({
104
+ tool: tool.name,
105
+ method: "tools/call",
106
+ outcome: result.isError ? "tool_error" : "ok",
107
+ durationMs: require_authorize.nowMs() - start,
108
+ errorText: result.isError ? extractTextContent(result.content) : void 0,
109
+ endUserId
110
+ });
111
+ return {
112
+ content: result.content ?? [],
113
+ structuredContent: result.structuredContent,
114
+ isError: result.isError
115
+ };
116
+ });
117
+ }
118
+ /**
119
+ * Build a Web-Standard request handler that serves the MCP protocol over
120
+ * streamable HTTP. A fresh `McpServer` + transport is constructed per
121
+ * request — the transport is stateless, so this is cheap and there is no
122
+ * cross-request state to leak. The per-request `recorder` is supplied by the
123
+ * caller (the stack handler) so telemetry reads the runtime env in-flight.
124
+ */
125
+ function createMcpProtocolHandler(mcp, options = {}) {
126
+ const authorizer = require_authorize.createRequestAuthorizer(mcp, options);
127
+ const handle = async (request, authResult, recorder) => {
128
+ try {
129
+ const server = new _modelcontextprotocol_sdk_server_mcp_js.McpServer({
130
+ name: mcp.name,
131
+ version: mcp.version,
132
+ title: mcp.title
133
+ }, { instructions: mcp.instructions });
134
+ for (const tool of mcp.tools) server.registerTool(tool.name, {
135
+ title: tool.title,
136
+ description: tool.description,
137
+ inputSchema: tool.inputSchema,
138
+ outputSchema: tool.outputSchema,
139
+ annotations: tool.annotations
140
+ }, adaptToolToSdkCallback(tool, authResult.auth, recorder));
141
+ const transport = new _modelcontextprotocol_sdk_server_webStandardStreamableHttp_js.WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: void 0 });
142
+ await server.connect(transport);
143
+ return await transport.handleRequest(request);
144
+ } catch (err) {
145
+ await recorder.emit({
146
+ tool: null,
147
+ method: "transport",
148
+ outcome: "transport_error",
149
+ durationMs: 0,
150
+ endUserId: authResult.auth?.principal.sub
151
+ });
152
+ require_logger.log.error("mcp.transport_error", {
153
+ ...require_logger.describeError(err),
154
+ outcome: "500 internal error"
155
+ });
156
+ return Response.json({
157
+ jsonrpc: "2.0",
158
+ id: null,
159
+ error: {
160
+ code: -32603,
161
+ message: "internal error"
162
+ }
163
+ }, { status: 500 });
164
+ }
165
+ };
166
+ return createGatedHandler({
167
+ authorizer,
168
+ methods: ["POST"],
169
+ methodNotAllowed: statelessMethodNotAllowed,
170
+ handle
171
+ });
172
+ }
173
+ //#endregion
174
+ Object.defineProperty(exports, "createMcpProtocolHandler", {
175
+ enumerable: true,
176
+ get: function() {
177
+ return createMcpProtocolHandler;
178
+ }
179
+ });
@@ -1,4 +1,4 @@
1
1
  //#region package.json
2
- var version = "0.30.0-rc.0";
2
+ var version = "1.0.0";
3
3
  //#endregion
4
4
  export { version as t };
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.30.0-rc.0";
2
+ var version = "1.0.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-Dq6dXUKT.cjs");
2
+ const require_mcp = require("../../mcp-CS1MF39p.cjs");
3
3
  exports.createMcpProtocolHandler = require_mcp.createMcpProtocolHandler;