@lovable.dev/mcp-js 0.16.0 → 0.19.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 (38) hide show
  1. package/dist/{recorder-qlzUKFxG.d.ts → base-C9rhAHZ0.d.ts} +3 -4
  2. package/dist/{chunk-W2EZWPJ5.js → chunk-57ZH2WW5.js} +11 -12
  3. package/dist/{chunk-H6BKTNJY.js → chunk-5FX6IIQ6.js} +129 -105
  4. package/dist/{chunk-SKSKC747.js → chunk-CDZ7MBXC.js} +1 -1
  5. package/dist/{chunk-EZQVUNXB.js → chunk-CLXKPZZE.js} +13 -14
  6. package/dist/{chunk-DCWYK4CA.js → chunk-H37EB22A.js} +13 -9
  7. package/dist/{chunk-I5CAQUQI.js → chunk-OMWXY6WY.js} +8 -8
  8. package/dist/{chunk-T24Z753F.js → chunk-UEOBGHXF.js} +2 -2
  9. package/dist/cli/extract-manifest.cjs +4 -3
  10. package/dist/cli/extract-manifest.js +4 -4
  11. package/dist/index.cjs +4 -9
  12. package/dist/index.d.cts +2 -2
  13. package/dist/index.d.ts +2 -2
  14. package/dist/index.js +1 -1
  15. package/dist/protocols/mcp/index.cjs +19 -225
  16. package/dist/protocols/mcp/index.d.cts +6 -5
  17. package/dist/protocols/mcp/index.d.ts +6 -5
  18. package/dist/protocols/mcp/index.js +4 -4
  19. package/dist/protocols/oauth-metadata.cjs +3 -2
  20. package/dist/protocols/oauth-metadata.d.cts +1 -1
  21. package/dist/protocols/oauth-metadata.d.ts +1 -1
  22. package/dist/protocols/oauth-metadata.js +4 -4
  23. package/dist/protocols/rest/index.cjs +24 -230
  24. package/dist/protocols/rest/index.d.cts +6 -6
  25. package/dist/protocols/rest/index.d.ts +6 -6
  26. package/dist/protocols/rest/index.js +5 -5
  27. package/dist/stacks/supabase/index.cjs +196 -169
  28. package/dist/stacks/supabase/index.d.cts +1 -1
  29. package/dist/stacks/supabase/index.d.ts +1 -1
  30. package/dist/stacks/supabase/index.js +14 -14
  31. package/dist/stacks/supabase/vite.cjs +1 -1
  32. package/dist/stacks/supabase/vite.js +1 -1
  33. package/dist/stacks/tanstack/index.cjs +205 -177
  34. package/dist/stacks/tanstack/index.d.cts +1 -1
  35. package/dist/stacks/tanstack/index.d.ts +1 -1
  36. package/dist/stacks/tanstack/index.js +13 -10
  37. package/dist/{types-COY42xux.d.ts → types-CPkhCRxc.d.ts} +3 -3
  38. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -31,9 +31,6 @@ module.exports = __toCommonJS(src_exports);
31
31
  // src/metrics/config.ts
32
32
  var DEFAULT_METRICS_ENDPOINT = "https://api.lovable.dev/v1/app-mcp-usage";
33
33
  var METRICS_API_KEY_ENV_VAR = "LOVABLE_API_KEY";
34
- var METRICS_SAMPLE_RATE = 1;
35
- var METRICS_FLUSH_INTERVAL_MS = 5e3;
36
- var METRICS_MAX_BATCH_SIZE = 50;
37
34
  function assertMetricsEndpoint(endpoint) {
38
35
  let url;
39
36
  try {
@@ -53,10 +50,7 @@ function resolveMetricsConfig(config = true) {
53
50
  enabled: options.enabled ?? true,
54
51
  endpoint,
55
52
  headers: options.headers ?? {},
56
- apiKeyEnvVar: METRICS_API_KEY_ENV_VAR,
57
- sampleRate: METRICS_SAMPLE_RATE,
58
- flushIntervalMs: METRICS_FLUSH_INTERVAL_MS,
59
- maxBatchSize: METRICS_MAX_BATCH_SIZE
53
+ apiKeyEnvVar: METRICS_API_KEY_ENV_VAR
60
54
  });
61
55
  }
62
56
 
@@ -319,16 +313,17 @@ var LEVEL_RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
319
313
  function isLogLevel(value) {
320
314
  return typeof value === "string" && value in LEVEL_RANK;
321
315
  }
316
+ var LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
322
317
  function readEnvLevel() {
323
318
  try {
324
- const raw = typeof process !== "undefined" ? process.env?.["LOVABLE_MCP_LOG_LEVEL"] : void 0;
319
+ const raw = typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0;
325
320
  const normalized = raw?.trim().toLowerCase();
326
321
  return isLogLevel(normalized) ? normalized : void 0;
327
322
  } catch {
328
323
  return void 0;
329
324
  }
330
325
  }
331
- var currentLevel = readEnvLevel() ?? "silent";
326
+ var currentLevel = readEnvLevel() ?? "debug";
332
327
  function setLogLevel(level) {
333
328
  currentLevel = level;
334
329
  }
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-COY42xux.js';
2
- export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-COY42xux.js';
1
+ import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-CPkhCRxc.js';
2
+ export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-CPkhCRxc.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-COY42xux.js';
2
- export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-COY42xux.js';
1
+ import { e as McpDefinitionInput, d as McpDefinition, Z as ZodRawShape, l as ToolDefinition, M as McpAuthConfig } from './types-CPkhCRxc.js';
2
+ export { A as AudioContent, C as ContentAnnotations, a as ContentBlock, E as EmbeddedBlobResource, b as EmbeddedResource, c as EmbeddedTextResource, I as ImageContent, J as JwtClaims, f as MetricsConfig, g as MetricsOptions, R as ResourceLink, h as ResourceLinkIcon, T as TextContent, i as ToolAnnotations, j as ToolContent, k as ToolContext, m as ToolHandlerResult, n as ZodSchema } from './types-CPkhCRxc.js';
3
3
  import 'zod';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  parseSafeUrl,
6
6
  resolveMetricsConfig,
7
7
  setLogLevel
8
- } from "./chunk-DCWYK4CA.js";
8
+ } from "./chunk-H37EB22A.js";
9
9
 
10
10
  // src/core/define.ts
11
11
  function assertUniqueNames(mcp) {
@@ -36,16 +36,17 @@ var LEVEL_RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
36
36
  function isLogLevel(value) {
37
37
  return typeof value === "string" && value in LEVEL_RANK;
38
38
  }
39
+ var LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
39
40
  function readEnvLevel() {
40
41
  try {
41
- const raw = typeof process !== "undefined" ? process.env?.["LOVABLE_MCP_LOG_LEVEL"] : void 0;
42
+ const raw = typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0;
42
43
  const normalized = raw?.trim().toLowerCase();
43
44
  return isLogLevel(normalized) ? normalized : void 0;
44
45
  } catch {
45
46
  return void 0;
46
47
  }
47
48
  }
48
- var currentLevel = readEnvLevel() ?? "silent";
49
+ var currentLevel = readEnvLevel() ?? "debug";
49
50
  function enabled(level) {
50
51
  return LEVEL_RANK[level] <= LEVEL_RANK[currentLevel];
51
52
  }
@@ -72,222 +73,15 @@ function describeError(err) {
72
73
  return { value: String(err) };
73
74
  }
74
75
 
75
- // src/metrics/config.ts
76
- var DEFAULT_METRICS_ENDPOINT = "https://api.lovable.dev/v1/app-mcp-usage";
77
- var METRICS_API_KEY_ENV_VAR = "LOVABLE_API_KEY";
78
- var METRICS_SAMPLE_RATE = 1;
79
- var METRICS_FLUSH_INTERVAL_MS = 5e3;
80
- var METRICS_MAX_BATCH_SIZE = 50;
81
- function assertMetricsEndpoint(endpoint) {
82
- let url;
83
- try {
84
- url = new URL(endpoint);
85
- } catch {
86
- throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be an absolute URL, got ${JSON.stringify(endpoint)}`);
87
- }
88
- if (url.protocol !== "https:" && url.protocol !== "http:") {
89
- throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be http(s), got ${JSON.stringify(endpoint)}`);
90
- }
91
- }
92
- function resolveMetricsConfig(config = true) {
93
- const options = typeof config === "boolean" ? { enabled: config } : config;
94
- const endpoint = options.endpoint ?? DEFAULT_METRICS_ENDPOINT;
95
- assertMetricsEndpoint(endpoint);
96
- return Object.freeze({
97
- enabled: options.enabled ?? true,
98
- endpoint,
99
- headers: options.headers ?? {},
100
- apiKeyEnvVar: METRICS_API_KEY_ENV_VAR,
101
- sampleRate: METRICS_SAMPLE_RATE,
102
- flushIntervalMs: METRICS_FLUSH_INTERVAL_MS,
103
- maxBatchSize: METRICS_MAX_BATCH_SIZE
104
- });
105
- }
106
-
107
- // package.json
108
- var version = "0.16.0";
109
-
110
- // src/metrics/otlp.ts
111
- var SCOPE_NAME = "@lovable.dev/mcp-js";
112
- var EVENT_NAME = "mcp.tool.invocation";
113
- var SEVERITY_INFO = 9;
114
- function strAttr(key, value) {
115
- return { key, value: { stringValue: value } };
116
- }
117
- function intAttr(key, value) {
118
- return { key, value: { intValue: String(Math.round(value)) } };
119
- }
120
- function toLogRecord(rec) {
121
- const attributes = [
122
- strAttr("event.name", EVENT_NAME),
123
- strAttr("mcp.method", rec.method),
124
- strAttr("mcp.outcome", rec.outcome),
125
- intAttr("mcp.duration_ms", rec.durationMs)
126
- ];
127
- if (rec.tool !== null)
128
- attributes.push(strAttr("mcp.tool", rec.tool));
129
- if (rec.reqBytes !== void 0)
130
- attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
131
- if (rec.resBytes !== void 0)
132
- attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
133
- return {
134
- timeUnixNano: rec.timeUnixNano,
135
- observedTimeUnixNano: rec.timeUnixNano,
136
- severityNumber: SEVERITY_INFO,
137
- severityText: "INFO",
138
- body: { stringValue: EVENT_NAME },
139
- attributes
140
- };
141
- }
142
- function buildLogsPayload(records, server) {
143
- return JSON.stringify({
144
- resourceLogs: [
145
- {
146
- resource: {
147
- attributes: [
148
- strAttr("service.name", server.name),
149
- strAttr("service.version", server.version),
150
- strAttr("telemetry.sdk.name", SCOPE_NAME),
151
- strAttr("telemetry.sdk.version", version),
152
- strAttr("telemetry.sdk.language", "webjs")
153
- ]
154
- },
155
- scopeLogs: [
156
- {
157
- scope: { name: SCOPE_NAME, version },
158
- logRecords: records.map(toLogRecord)
159
- }
160
- ]
161
- }
162
- ]
163
- });
164
- }
165
- function nowUnixNano() {
166
- return `${Date.now()}000000`;
167
- }
168
-
169
- // src/metrics/recorder.ts
76
+ // src/metrics/impl/base.ts
170
77
  function nowMs() {
171
78
  return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
172
79
  }
173
- function reportInvocation(recorder, ev) {
174
- log.info("tool.invoked", { tool: ev.tool, method: ev.method, outcome: ev.outcome, durationMs: ev.durationMs });
175
- recorder.record(ev);
176
- }
177
- var NOOP_RECORDER = {
178
- record() {
179
- },
180
- async flush() {
181
- }
182
- };
80
+ var NOOP_RECORDER = { async emit() {
81
+ } };
183
82
  function createNoopRecorder() {
184
83
  return NOOP_RECORDER;
185
84
  }
186
- function readRuntimeEnv(name) {
187
- try {
188
- const denoEnv = globalThis.Deno?.env;
189
- const value = denoEnv?.get?.(name);
190
- if (value)
191
- return value;
192
- } catch {
193
- }
194
- try {
195
- if (typeof process !== "undefined") {
196
- const value = process.env?.[name];
197
- if (value)
198
- return value;
199
- }
200
- } catch {
201
- }
202
- return void 0;
203
- }
204
- function probeWaitUntil() {
205
- const fn = globalThis.EdgeRuntime?.waitUntil;
206
- return typeof fn === "function" ? fn.bind(globalThis.EdgeRuntime) : void 0;
207
- }
208
- function createMetricsRecorder(ctx, deps = {}) {
209
- const { config, server } = ctx;
210
- if (!config.enabled)
211
- return NOOP_RECORDER;
212
- const doFetch = deps.fetch ?? globalThis.fetch;
213
- if (!doFetch) {
214
- log.warn("metrics.disabled_no_fetch", { endpoint: config.endpoint });
215
- return NOOP_RECORDER;
216
- }
217
- const usesLovableEndpoint = config.endpoint === DEFAULT_METRICS_ENDPOINT;
218
- const apiKey = usesLovableEndpoint ? (deps.getApiKey ?? (() => readRuntimeEnv(config.apiKeyEnvVar)))() : void 0;
219
- if (usesLovableEndpoint && !apiKey) {
220
- log.warn("metrics.disabled_no_api_key", { envVar: config.apiKeyEnvVar, endpoint: config.endpoint });
221
- return NOOP_RECORDER;
222
- }
223
- const waitUntil = deps.waitUntil ?? probeWaitUntil();
224
- const buffer = [];
225
- let timer;
226
- const schedule = (p) => {
227
- if (waitUntil) {
228
- try {
229
- waitUntil(p);
230
- return;
231
- } catch (err) {
232
- log.warn("metrics.wait_until_failed", describeError(err));
233
- }
234
- }
235
- void p.catch(() => {
236
- });
237
- };
238
- const headers = {};
239
- if (!usesLovableEndpoint) {
240
- for (const [key, value] of Object.entries(config.headers)) {
241
- if (key.toLowerCase() !== "content-type")
242
- headers[key] = value;
243
- }
244
- }
245
- headers["content-type"] = "application/json";
246
- if (apiKey)
247
- headers.authorization = `Bearer ${apiKey}`;
248
- const flush = async () => {
249
- if (buffer.length === 0)
250
- return;
251
- const records = buffer.splice(0, buffer.length);
252
- const dropped = records.length;
253
- try {
254
- const res = await doFetch(config.endpoint, {
255
- method: "POST",
256
- headers,
257
- body: buildLogsPayload(records, server),
258
- keepalive: true
259
- });
260
- if (!res.ok) {
261
- log.warn("metrics.flush_rejected", { status: res.status, dropped, endpoint: config.endpoint });
262
- }
263
- } catch (err) {
264
- log.warn("metrics.flush_failed", { ...describeError(err), dropped, endpoint: config.endpoint });
265
- }
266
- };
267
- const ensureTimer = () => {
268
- if (timer !== void 0)
269
- return;
270
- timer = setInterval(() => schedule(flush()), config.flushIntervalMs);
271
- timer.unref?.();
272
- };
273
- return {
274
- record(ev) {
275
- if (config.sampleRate < 1 && Math.random() >= config.sampleRate)
276
- return;
277
- buffer.push({ ...ev, timeUnixNano: nowUnixNano() });
278
- ensureTimer();
279
- if (buffer.length >= config.maxBatchSize)
280
- schedule(flush());
281
- },
282
- flush
283
- };
284
- }
285
- function createRecorderForRuntime(mcp) {
286
- const config = resolveMetricsConfig(mcp.metrics);
287
- if (!config.enabled)
288
- return createNoopRecorder();
289
- return createMetricsRecorder({ config, server: { name: mcp.name, version: mcp.version } });
290
- }
291
85
 
292
86
  // src/core/promise.ts
293
87
  function cachedPromise(load, label) {
@@ -709,10 +503,10 @@ function assertRequiredScopes(auth, context) {
709
503
  throw new OAuthTokenError(403, "insufficient_scope", "Additional OAuth scope is required");
710
504
  }
711
505
  }
712
- function createRequestAuthorizer(mcp, options = {}, recorder) {
506
+ function createRequestAuthorizer(mcp, options = {}) {
713
507
  const runtime = getOAuthRuntime(mcp, options);
714
508
  return {
715
- async authorize(request) {
509
+ async authorize(request, recorder) {
716
510
  if (runtime.kind === "unconfigured")
717
511
  return { ok: true };
718
512
  const startedAt = nowMs();
@@ -728,7 +522,7 @@ function createRequestAuthorizer(mcp, options = {}, recorder) {
728
522
  } catch (err) {
729
523
  if (err instanceof OAuthConfigurationError) {
730
524
  log.error("auth.config_error", { ...describeError(err), outcome: "500" });
731
- recorder?.record({
525
+ await recorder?.emit({
732
526
  tool: null,
733
527
  method: "authorize",
734
528
  outcome: "auth_config_error",
@@ -839,7 +633,7 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
839
633
  try {
840
634
  result = await tool.handler(args, new ToolContext(auth));
841
635
  } catch {
842
- reportInvocation(recorder, {
636
+ await recorder.emit({
843
637
  tool: tool.name,
844
638
  method: "tools/call",
845
639
  outcome: "handler_error",
@@ -848,7 +642,7 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
848
642
  return { content: [{ type: "text", text: "tool execution failed" }], isError: true };
849
643
  }
850
644
  if (result == null) {
851
- reportInvocation(recorder, {
645
+ await recorder.emit({
852
646
  tool: tool.name,
853
647
  method: "tools/call",
854
648
  outcome: "handler_error",
@@ -856,7 +650,7 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
856
650
  });
857
651
  return { content: [{ type: "text", text: `tool "${tool.name}" returned no result` }], isError: true };
858
652
  }
859
- reportInvocation(recorder, {
653
+ await recorder.emit({
860
654
  tool: tool.name,
861
655
  method: "tools/call",
862
656
  outcome: result.isError ? "tool_error" : "ok",
@@ -865,10 +659,10 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
865
659
  return { content: result.content ?? [], structuredContent: result.structuredContent, isError: result.isError };
866
660
  };
867
661
  }
868
- function createMcpProtocolHandler(mcp, options = {}, recorder = createRecorderForRuntime(mcp)) {
869
- const authorizer = createRequestAuthorizer(mcp, options, recorder);
870
- const handle = async (request) => {
871
- const authResult = await authorizer.authorize(request);
662
+ function createMcpProtocolHandler(mcp, options = {}) {
663
+ const authorizer = createRequestAuthorizer(mcp, options);
664
+ const handle = async (request, recorder) => {
665
+ const authResult = await authorizer.authorize(request, recorder);
872
666
  if (!authResult.ok)
873
667
  return authResult.response;
874
668
  try {
@@ -895,7 +689,7 @@ function createMcpProtocolHandler(mcp, options = {}, recorder = createRecorderFo
895
689
  await server.connect(transport);
896
690
  return await transport.handleRequest(request);
897
691
  } catch (err) {
898
- recorder.record({ tool: null, method: "transport", outcome: "transport_error", durationMs: 0 });
692
+ await recorder.emit({ tool: null, method: "transport", outcome: "transport_error", durationMs: 0 });
899
693
  log.error("mcp.transport_error", { ...describeError(err), outcome: "500 internal error" });
900
694
  return Response.json(
901
695
  { jsonrpc: "2.0", id: null, error: { code: -32603, message: "internal error" } },
@@ -903,10 +697,10 @@ function createMcpProtocolHandler(mcp, options = {}, recorder = createRecorderFo
903
697
  );
904
698
  }
905
699
  };
906
- return async (request) => {
700
+ return async (request, recorder = createNoopRecorder()) => {
907
701
  if (request.method === "OPTIONS")
908
702
  return corsPreflightResponse("GET, POST, DELETE, OPTIONS");
909
- return withCors(await handle(request));
703
+ return withCors(await handle(request, recorder));
910
704
  };
911
705
  }
912
706
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,15 +1,16 @@
1
1
  import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
2
- import { d as McpDefinition } from '../../types-COY42xux.js';
3
- import { M as MetricsRecorder } from '../../recorder-qlzUKFxG.js';
2
+ import { d as McpDefinition } from '../../types-CPkhCRxc.js';
3
+ import { M as MetricsRecorder } from '../../base-C9rhAHZ0.js';
4
4
  import 'zod';
5
5
 
6
- type McpProtocolHandler = (request: Request) => Promise<Response>;
6
+ type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
7
7
  /**
8
8
  * Build a Web-Standard request handler that serves the MCP protocol over
9
9
  * streamable HTTP. A fresh `McpServer` + transport is constructed per
10
10
  * request — the transport is stateless, so this is cheap and there is no
11
- * cross-request state to leak.
11
+ * cross-request state to leak. The per-request `recorder` is supplied by the
12
+ * caller (the stack handler) so telemetry reads the runtime env in-flight.
12
13
  */
13
- declare function createMcpProtocolHandler(mcp: McpDefinition, options?: McpRuntimeOptions, recorder?: MetricsRecorder): McpProtocolHandler;
14
+ declare function createMcpProtocolHandler(mcp: McpDefinition, options?: McpRuntimeOptions): McpProtocolHandler;
14
15
 
15
16
  export { type McpProtocolHandler, createMcpProtocolHandler };
@@ -1,15 +1,16 @@
1
1
  import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
2
- import { d as McpDefinition } from '../../types-COY42xux.js';
3
- import { M as MetricsRecorder } from '../../recorder-qlzUKFxG.js';
2
+ import { d as McpDefinition } from '../../types-CPkhCRxc.js';
3
+ import { M as MetricsRecorder } from '../../base-C9rhAHZ0.js';
4
4
  import 'zod';
5
5
 
6
- type McpProtocolHandler = (request: Request) => Promise<Response>;
6
+ type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
7
7
  /**
8
8
  * Build a Web-Standard request handler that serves the MCP protocol over
9
9
  * streamable HTTP. A fresh `McpServer` + transport is constructed per
10
10
  * request — the transport is stateless, so this is cheap and there is no
11
- * cross-request state to leak.
11
+ * cross-request state to leak. The per-request `recorder` is supplied by the
12
+ * caller (the stack handler) so telemetry reads the runtime env in-flight.
12
13
  */
13
- declare function createMcpProtocolHandler(mcp: McpDefinition, options?: McpRuntimeOptions, recorder?: MetricsRecorder): McpProtocolHandler;
14
+ declare function createMcpProtocolHandler(mcp: McpDefinition, options?: McpRuntimeOptions): McpProtocolHandler;
14
15
 
15
16
  export { type McpProtocolHandler, createMcpProtocolHandler };
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  createMcpProtocolHandler
3
- } from "../../chunk-EZQVUNXB.js";
3
+ } from "../../chunk-CLXKPZZE.js";
4
4
  import "../../chunk-MA5H6PSF.js";
5
- import "../../chunk-H6BKTNJY.js";
6
- import "../../chunk-DCWYK4CA.js";
5
+ import "../../chunk-5FX6IIQ6.js";
6
+ import "../../chunk-H37EB22A.js";
7
7
  import "../../chunk-6DXGZZA4.js";
8
- import "../../chunk-SKSKC747.js";
8
+ import "../../chunk-CDZ7MBXC.js";
9
9
  export {
10
10
  createMcpProtocolHandler
11
11
  };
@@ -41,16 +41,17 @@ var LEVEL_RANK = { silent: 0, error: 1, warn: 2, info: 3, debug: 4 };
41
41
  function isLogLevel(value) {
42
42
  return typeof value === "string" && value in LEVEL_RANK;
43
43
  }
44
+ var LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
44
45
  function readEnvLevel() {
45
46
  try {
46
- const raw = typeof process !== "undefined" ? process.env?.["LOVABLE_MCP_LOG_LEVEL"] : void 0;
47
+ const raw = typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0;
47
48
  const normalized = raw?.trim().toLowerCase();
48
49
  return isLogLevel(normalized) ? normalized : void 0;
49
50
  } catch {
50
51
  return void 0;
51
52
  }
52
53
  }
53
- var currentLevel = readEnvLevel() ?? "silent";
54
+ var currentLevel = readEnvLevel() ?? "debug";
54
55
  function enabled(level) {
55
56
  return LEVEL_RANK[level] <= LEVEL_RANK[currentLevel];
56
57
  }
@@ -1,5 +1,5 @@
1
1
  import { M as McpRuntimeOptions } from '../authorize-BMeXd_Sh.js';
2
- import { d as McpDefinition } from '../types-COY42xux.js';
2
+ import { d as McpDefinition } from '../types-CPkhCRxc.js';
3
3
  import 'zod';
4
4
 
5
5
  type OAuthProtectedResourceMetadataHandler = (request: Request) => Promise<Response>;
@@ -1,5 +1,5 @@
1
1
  import { M as McpRuntimeOptions } from '../authorize-BMeXd_Sh.js';
2
- import { d as McpDefinition } from '../types-COY42xux.js';
2
+ import { d as McpDefinition } from '../types-CPkhCRxc.js';
3
3
  import 'zod';
4
4
 
5
5
  type OAuthProtectedResourceMetadataHandler = (request: Request) => Promise<Response>;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  createOAuthProtectedResourceMetadataHandler
3
- } from "../chunk-T24Z753F.js";
4
- import "../chunk-H6BKTNJY.js";
5
- import "../chunk-DCWYK4CA.js";
3
+ } from "../chunk-UEOBGHXF.js";
4
+ import "../chunk-5FX6IIQ6.js";
5
+ import "../chunk-H37EB22A.js";
6
6
  import "../chunk-6DXGZZA4.js";
7
- import "../chunk-SKSKC747.js";
7
+ import "../chunk-CDZ7MBXC.js";
8
8
  export {
9
9
  createOAuthProtectedResourceMetadataHandler
10
10
  };