@lovable.dev/mcp-js 0.15.0 → 0.15.1
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.
- package/dist/{chunk-T2RED2TG.js → chunk-CEDD57G2.js} +5 -7
- package/dist/{chunk-QC3DXQTH.js → chunk-DCWYK4CA.js} +34 -0
- package/dist/{chunk-LWHVXXKQ.js → chunk-GIHCQT6L.js} +1 -1
- package/dist/{chunk-QDKOF4UF.js → chunk-ILYTJXDR.js} +2 -2
- package/dist/{chunk-P3F324UC.js → chunk-MA5H6PSF.js} +0 -34
- package/dist/{chunk-VNRQPA4K.js → chunk-QT5L4CS3.js} +4 -3
- package/dist/{chunk-RHDEW56Y.js → chunk-UCPYLSNN.js} +6 -8
- package/dist/{chunk-G4XA7IJM.js → chunk-YTOMGJV5.js} +189 -2
- package/dist/cli/extract-manifest.cjs +1 -1
- package/dist/cli/extract-manifest.js +4 -4
- package/dist/index.js +4 -4
- package/dist/protocols/mcp/index.cjs +217 -210
- package/dist/protocols/mcp/index.d.cts +1 -1
- package/dist/protocols/mcp/index.d.ts +1 -1
- package/dist/protocols/mcp/index.js +5 -6
- package/dist/protocols/oauth-metadata.js +4 -3
- package/dist/protocols/rest/index.cjs +219 -212
- package/dist/protocols/rest/index.d.cts +2 -2
- package/dist/protocols/rest/index.d.ts +2 -2
- package/dist/protocols/rest/index.js +6 -7
- package/dist/{recorder-B-eJU4Qu.d.ts → recorder-qlzUKFxG.d.ts} +3 -3
- package/dist/stacks/supabase/index.cjs +14 -7
- package/dist/stacks/supabase/index.js +10 -12
- package/dist/stacks/supabase/vite.cjs +28 -4
- package/dist/stacks/supabase/vite.js +28 -4
- package/dist/stacks/tanstack/index.cjs +220 -213
- package/dist/stacks/tanstack/index.js +8 -9
- package/package.json +1 -1
- package/dist/chunk-XQSTN54Y.js +0 -189
|
@@ -72,6 +72,214 @@ function describeError(err) {
|
|
|
72
72
|
return { value: String(err) };
|
|
73
73
|
}
|
|
74
74
|
|
|
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.15.1";
|
|
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
|
|
170
|
+
function nowMs() {
|
|
171
|
+
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
172
|
+
}
|
|
173
|
+
var NOOP_RECORDER = {
|
|
174
|
+
record() {
|
|
175
|
+
},
|
|
176
|
+
async flush() {
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
function createNoopRecorder() {
|
|
180
|
+
return NOOP_RECORDER;
|
|
181
|
+
}
|
|
182
|
+
function readRuntimeEnv(name) {
|
|
183
|
+
try {
|
|
184
|
+
const denoEnv = globalThis.Deno?.env;
|
|
185
|
+
const value = denoEnv?.get?.(name);
|
|
186
|
+
if (value)
|
|
187
|
+
return value;
|
|
188
|
+
} catch {
|
|
189
|
+
}
|
|
190
|
+
try {
|
|
191
|
+
if (typeof process !== "undefined") {
|
|
192
|
+
const value = process.env?.[name];
|
|
193
|
+
if (value)
|
|
194
|
+
return value;
|
|
195
|
+
}
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
return void 0;
|
|
199
|
+
}
|
|
200
|
+
function probeWaitUntil() {
|
|
201
|
+
const fn = globalThis.EdgeRuntime?.waitUntil;
|
|
202
|
+
return typeof fn === "function" ? fn.bind(globalThis.EdgeRuntime) : void 0;
|
|
203
|
+
}
|
|
204
|
+
function createMetricsRecorder(ctx, deps = {}) {
|
|
205
|
+
const { config, server } = ctx;
|
|
206
|
+
if (!config.enabled)
|
|
207
|
+
return NOOP_RECORDER;
|
|
208
|
+
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
209
|
+
if (!doFetch)
|
|
210
|
+
return NOOP_RECORDER;
|
|
211
|
+
const usesLovableEndpoint = config.endpoint === DEFAULT_METRICS_ENDPOINT;
|
|
212
|
+
const apiKey = usesLovableEndpoint ? (deps.getApiKey ?? (() => readRuntimeEnv(config.apiKeyEnvVar)))() : void 0;
|
|
213
|
+
if (usesLovableEndpoint && !apiKey) {
|
|
214
|
+
log.debug("metrics.disabled_no_api_key", { envVar: config.apiKeyEnvVar });
|
|
215
|
+
return NOOP_RECORDER;
|
|
216
|
+
}
|
|
217
|
+
const waitUntil = deps.waitUntil ?? probeWaitUntil();
|
|
218
|
+
const buffer = [];
|
|
219
|
+
let timer;
|
|
220
|
+
const schedule = (p) => {
|
|
221
|
+
if (waitUntil) {
|
|
222
|
+
try {
|
|
223
|
+
waitUntil(p);
|
|
224
|
+
return;
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
void p.catch(() => {
|
|
229
|
+
});
|
|
230
|
+
};
|
|
231
|
+
const headers = {};
|
|
232
|
+
if (!usesLovableEndpoint) {
|
|
233
|
+
for (const [key, value] of Object.entries(config.headers)) {
|
|
234
|
+
if (key.toLowerCase() !== "content-type")
|
|
235
|
+
headers[key] = value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
headers["content-type"] = "application/json";
|
|
239
|
+
if (apiKey)
|
|
240
|
+
headers.authorization = `Bearer ${apiKey}`;
|
|
241
|
+
const flush = async () => {
|
|
242
|
+
if (buffer.length === 0)
|
|
243
|
+
return;
|
|
244
|
+
const records = buffer.splice(0, buffer.length);
|
|
245
|
+
try {
|
|
246
|
+
const res = await doFetch(config.endpoint, {
|
|
247
|
+
method: "POST",
|
|
248
|
+
headers,
|
|
249
|
+
body: buildLogsPayload(records, server),
|
|
250
|
+
keepalive: true
|
|
251
|
+
});
|
|
252
|
+
if (!res.ok)
|
|
253
|
+
log.debug("metrics.flush_rejected", { status: res.status });
|
|
254
|
+
} catch (err) {
|
|
255
|
+
log.debug("metrics.flush_failed", describeError(err));
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
const ensureTimer = () => {
|
|
259
|
+
if (timer !== void 0)
|
|
260
|
+
return;
|
|
261
|
+
timer = setInterval(() => schedule(flush()), config.flushIntervalMs);
|
|
262
|
+
timer.unref?.();
|
|
263
|
+
};
|
|
264
|
+
return {
|
|
265
|
+
record(ev) {
|
|
266
|
+
if (config.sampleRate < 1 && Math.random() >= config.sampleRate)
|
|
267
|
+
return;
|
|
268
|
+
buffer.push({ ...ev, timeUnixNano: nowUnixNano() });
|
|
269
|
+
ensureTimer();
|
|
270
|
+
if (buffer.length >= config.maxBatchSize)
|
|
271
|
+
schedule(flush());
|
|
272
|
+
},
|
|
273
|
+
flush
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
function createRecorderForRuntime(mcp) {
|
|
277
|
+
const config = resolveMetricsConfig(mcp.metrics);
|
|
278
|
+
if (!config.enabled)
|
|
279
|
+
return createNoopRecorder();
|
|
280
|
+
return createMetricsRecorder({ config, server: { name: mcp.name, version: mcp.version } });
|
|
281
|
+
}
|
|
282
|
+
|
|
75
283
|
// src/core/promise.ts
|
|
76
284
|
function cachedPromise(load, label) {
|
|
77
285
|
let settled = false;
|
|
@@ -492,12 +700,13 @@ function assertRequiredScopes(auth, context) {
|
|
|
492
700
|
throw new OAuthTokenError(403, "insufficient_scope", "Additional OAuth scope is required");
|
|
493
701
|
}
|
|
494
702
|
}
|
|
495
|
-
function createRequestAuthorizer(mcp, options = {}) {
|
|
703
|
+
function createRequestAuthorizer(mcp, options = {}, recorder) {
|
|
496
704
|
const runtime = getOAuthRuntime(mcp, options);
|
|
497
705
|
return {
|
|
498
706
|
async authorize(request) {
|
|
499
707
|
if (runtime.kind === "unconfigured")
|
|
500
708
|
return { ok: true };
|
|
709
|
+
const startedAt = nowMs();
|
|
501
710
|
const token = parseBearerToken(request);
|
|
502
711
|
if (!token) {
|
|
503
712
|
log.info("auth.no_bearer_token", { outcome: "401" });
|
|
@@ -510,6 +719,12 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
510
719
|
} catch (err) {
|
|
511
720
|
if (err instanceof OAuthConfigurationError) {
|
|
512
721
|
log.error("auth.config_error", { ...describeError(err), outcome: "500" });
|
|
722
|
+
recorder?.record({
|
|
723
|
+
tool: null,
|
|
724
|
+
method: "authorize",
|
|
725
|
+
outcome: "auth_config_error",
|
|
726
|
+
durationMs: nowMs() - startedAt
|
|
727
|
+
});
|
|
513
728
|
return { ok: false, response: oauthConfigurationErrorResponse() };
|
|
514
729
|
}
|
|
515
730
|
if (err instanceof OAuthTokenError) {
|
|
@@ -606,214 +821,6 @@ function corsPreflightResponse(allowMethods) {
|
|
|
606
821
|
});
|
|
607
822
|
}
|
|
608
823
|
|
|
609
|
-
// src/metrics/config.ts
|
|
610
|
-
var DEFAULT_METRICS_ENDPOINT = "https://api.lovable.dev/v1/app-mcp-usage";
|
|
611
|
-
var METRICS_API_KEY_ENV_VAR = "LOVABLE_API_KEY";
|
|
612
|
-
var METRICS_SAMPLE_RATE = 1;
|
|
613
|
-
var METRICS_FLUSH_INTERVAL_MS = 5e3;
|
|
614
|
-
var METRICS_MAX_BATCH_SIZE = 50;
|
|
615
|
-
function assertMetricsEndpoint(endpoint) {
|
|
616
|
-
let url;
|
|
617
|
-
try {
|
|
618
|
-
url = new URL(endpoint);
|
|
619
|
-
} catch {
|
|
620
|
-
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be an absolute URL, got ${JSON.stringify(endpoint)}`);
|
|
621
|
-
}
|
|
622
|
-
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
623
|
-
throw new Error(`@lovable.dev/mcp-js: metrics.endpoint must be http(s), got ${JSON.stringify(endpoint)}`);
|
|
624
|
-
}
|
|
625
|
-
}
|
|
626
|
-
function resolveMetricsConfig(config = true) {
|
|
627
|
-
const options = typeof config === "boolean" ? { enabled: config } : config;
|
|
628
|
-
const endpoint = options.endpoint ?? DEFAULT_METRICS_ENDPOINT;
|
|
629
|
-
assertMetricsEndpoint(endpoint);
|
|
630
|
-
return Object.freeze({
|
|
631
|
-
enabled: options.enabled ?? true,
|
|
632
|
-
endpoint,
|
|
633
|
-
headers: options.headers ?? {},
|
|
634
|
-
apiKeyEnvVar: METRICS_API_KEY_ENV_VAR,
|
|
635
|
-
sampleRate: METRICS_SAMPLE_RATE,
|
|
636
|
-
flushIntervalMs: METRICS_FLUSH_INTERVAL_MS,
|
|
637
|
-
maxBatchSize: METRICS_MAX_BATCH_SIZE
|
|
638
|
-
});
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
// package.json
|
|
642
|
-
var version = "0.15.0";
|
|
643
|
-
|
|
644
|
-
// src/metrics/otlp.ts
|
|
645
|
-
var SCOPE_NAME = "@lovable.dev/mcp-js";
|
|
646
|
-
var EVENT_NAME = "mcp.tool.invocation";
|
|
647
|
-
var SEVERITY_INFO = 9;
|
|
648
|
-
function strAttr(key, value) {
|
|
649
|
-
return { key, value: { stringValue: value } };
|
|
650
|
-
}
|
|
651
|
-
function intAttr(key, value) {
|
|
652
|
-
return { key, value: { intValue: String(Math.round(value)) } };
|
|
653
|
-
}
|
|
654
|
-
function toLogRecord(rec) {
|
|
655
|
-
const attributes = [
|
|
656
|
-
strAttr("event.name", EVENT_NAME),
|
|
657
|
-
strAttr("mcp.method", rec.method),
|
|
658
|
-
strAttr("mcp.outcome", rec.outcome),
|
|
659
|
-
intAttr("mcp.duration_ms", rec.durationMs)
|
|
660
|
-
];
|
|
661
|
-
if (rec.tool !== null)
|
|
662
|
-
attributes.push(strAttr("mcp.tool", rec.tool));
|
|
663
|
-
if (rec.reqBytes !== void 0)
|
|
664
|
-
attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
|
|
665
|
-
if (rec.resBytes !== void 0)
|
|
666
|
-
attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
667
|
-
return {
|
|
668
|
-
timeUnixNano: rec.timeUnixNano,
|
|
669
|
-
observedTimeUnixNano: rec.timeUnixNano,
|
|
670
|
-
severityNumber: SEVERITY_INFO,
|
|
671
|
-
severityText: "INFO",
|
|
672
|
-
body: { stringValue: EVENT_NAME },
|
|
673
|
-
attributes
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
function buildLogsPayload(records, server) {
|
|
677
|
-
return JSON.stringify({
|
|
678
|
-
resourceLogs: [
|
|
679
|
-
{
|
|
680
|
-
resource: {
|
|
681
|
-
attributes: [
|
|
682
|
-
strAttr("service.name", server.name),
|
|
683
|
-
strAttr("service.version", server.version),
|
|
684
|
-
strAttr("telemetry.sdk.name", SCOPE_NAME),
|
|
685
|
-
strAttr("telemetry.sdk.version", version),
|
|
686
|
-
strAttr("telemetry.sdk.language", "webjs")
|
|
687
|
-
]
|
|
688
|
-
},
|
|
689
|
-
scopeLogs: [
|
|
690
|
-
{
|
|
691
|
-
scope: { name: SCOPE_NAME, version },
|
|
692
|
-
logRecords: records.map(toLogRecord)
|
|
693
|
-
}
|
|
694
|
-
]
|
|
695
|
-
}
|
|
696
|
-
]
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
function nowUnixNano() {
|
|
700
|
-
return `${Date.now()}000000`;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
// src/metrics/recorder.ts
|
|
704
|
-
function nowMs() {
|
|
705
|
-
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
706
|
-
}
|
|
707
|
-
var NOOP_RECORDER = {
|
|
708
|
-
record() {
|
|
709
|
-
},
|
|
710
|
-
async flush() {
|
|
711
|
-
}
|
|
712
|
-
};
|
|
713
|
-
function createNoopRecorder() {
|
|
714
|
-
return NOOP_RECORDER;
|
|
715
|
-
}
|
|
716
|
-
function readRuntimeEnv(name) {
|
|
717
|
-
try {
|
|
718
|
-
const denoEnv = globalThis.Deno?.env;
|
|
719
|
-
const value = denoEnv?.get?.(name);
|
|
720
|
-
if (value)
|
|
721
|
-
return value;
|
|
722
|
-
} catch {
|
|
723
|
-
}
|
|
724
|
-
try {
|
|
725
|
-
if (typeof process !== "undefined") {
|
|
726
|
-
const value = process.env?.[name];
|
|
727
|
-
if (value)
|
|
728
|
-
return value;
|
|
729
|
-
}
|
|
730
|
-
} catch {
|
|
731
|
-
}
|
|
732
|
-
return void 0;
|
|
733
|
-
}
|
|
734
|
-
function probeWaitUntil() {
|
|
735
|
-
const fn = globalThis.EdgeRuntime?.waitUntil;
|
|
736
|
-
return typeof fn === "function" ? fn.bind(globalThis.EdgeRuntime) : void 0;
|
|
737
|
-
}
|
|
738
|
-
function createMetricsRecorder(ctx, deps = {}) {
|
|
739
|
-
const { config, server } = ctx;
|
|
740
|
-
if (!config.enabled)
|
|
741
|
-
return NOOP_RECORDER;
|
|
742
|
-
const doFetch = deps.fetch ?? globalThis.fetch;
|
|
743
|
-
if (!doFetch)
|
|
744
|
-
return NOOP_RECORDER;
|
|
745
|
-
const usesLovableEndpoint = config.endpoint === DEFAULT_METRICS_ENDPOINT;
|
|
746
|
-
const apiKey = usesLovableEndpoint ? (deps.getApiKey ?? (() => readRuntimeEnv(config.apiKeyEnvVar)))() : void 0;
|
|
747
|
-
if (usesLovableEndpoint && !apiKey) {
|
|
748
|
-
log.debug("metrics.disabled_no_api_key", { envVar: config.apiKeyEnvVar });
|
|
749
|
-
return NOOP_RECORDER;
|
|
750
|
-
}
|
|
751
|
-
const waitUntil = deps.waitUntil ?? probeWaitUntil();
|
|
752
|
-
const buffer = [];
|
|
753
|
-
let timer;
|
|
754
|
-
const schedule = (p) => {
|
|
755
|
-
if (waitUntil) {
|
|
756
|
-
try {
|
|
757
|
-
waitUntil(p);
|
|
758
|
-
return;
|
|
759
|
-
} catch {
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
void p.catch(() => {
|
|
763
|
-
});
|
|
764
|
-
};
|
|
765
|
-
const headers = {};
|
|
766
|
-
if (!usesLovableEndpoint) {
|
|
767
|
-
for (const [key, value] of Object.entries(config.headers)) {
|
|
768
|
-
if (key.toLowerCase() !== "content-type")
|
|
769
|
-
headers[key] = value;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
headers["content-type"] = "application/json";
|
|
773
|
-
if (apiKey)
|
|
774
|
-
headers.authorization = `Bearer ${apiKey}`;
|
|
775
|
-
const flush = async () => {
|
|
776
|
-
if (buffer.length === 0)
|
|
777
|
-
return;
|
|
778
|
-
const records = buffer.splice(0, buffer.length);
|
|
779
|
-
try {
|
|
780
|
-
const res = await doFetch(config.endpoint, {
|
|
781
|
-
method: "POST",
|
|
782
|
-
headers,
|
|
783
|
-
body: buildLogsPayload(records, server),
|
|
784
|
-
keepalive: true
|
|
785
|
-
});
|
|
786
|
-
if (!res.ok)
|
|
787
|
-
log.debug("metrics.flush_rejected", { status: res.status });
|
|
788
|
-
} catch (err) {
|
|
789
|
-
log.debug("metrics.flush_failed", describeError(err));
|
|
790
|
-
}
|
|
791
|
-
};
|
|
792
|
-
const ensureTimer = () => {
|
|
793
|
-
if (timer !== void 0)
|
|
794
|
-
return;
|
|
795
|
-
timer = setInterval(() => schedule(flush()), config.flushIntervalMs);
|
|
796
|
-
timer.unref?.();
|
|
797
|
-
};
|
|
798
|
-
return {
|
|
799
|
-
record(ev) {
|
|
800
|
-
if (config.sampleRate < 1 && Math.random() >= config.sampleRate)
|
|
801
|
-
return;
|
|
802
|
-
buffer.push({ ...ev, timeUnixNano: nowUnixNano() });
|
|
803
|
-
ensureTimer();
|
|
804
|
-
if (buffer.length >= config.maxBatchSize)
|
|
805
|
-
schedule(flush());
|
|
806
|
-
},
|
|
807
|
-
flush
|
|
808
|
-
};
|
|
809
|
-
}
|
|
810
|
-
function createRecorderForRuntime(mcp) {
|
|
811
|
-
const config = resolveMetricsConfig(mcp.metrics);
|
|
812
|
-
if (!config.enabled)
|
|
813
|
-
return createNoopRecorder();
|
|
814
|
-
return createMetricsRecorder({ config, server: { name: mcp.name, version: mcp.version } });
|
|
815
|
-
}
|
|
816
|
-
|
|
817
824
|
// src/protocols/mcp/protocol.ts
|
|
818
825
|
function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
819
826
|
return async (first) => {
|
|
@@ -840,7 +847,7 @@ function adaptToolToSdkCallback(tool, auth, recorder) {
|
|
|
840
847
|
};
|
|
841
848
|
}
|
|
842
849
|
function createMcpProtocolHandler(mcp, options = {}, recorder = createRecorderForRuntime(mcp)) {
|
|
843
|
-
const authorizer = createRequestAuthorizer(mcp, options);
|
|
850
|
+
const authorizer = createRequestAuthorizer(mcp, options, recorder);
|
|
844
851
|
const handle = async (request) => {
|
|
845
852
|
const authResult = await authorizer.authorize(request);
|
|
846
853
|
if (!authResult.ok)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-COY42xux.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../recorder-
|
|
3
|
+
import { M as MetricsRecorder } from '../../recorder-qlzUKFxG.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request) => Promise<Response>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { M as McpRuntimeOptions } from '../../authorize-BMeXd_Sh.js';
|
|
2
2
|
import { d as McpDefinition } from '../../types-COY42xux.js';
|
|
3
|
-
import { M as MetricsRecorder } from '../../recorder-
|
|
3
|
+
import { M as MetricsRecorder } from '../../recorder-qlzUKFxG.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
|
6
6
|
type McpProtocolHandler = (request: Request) => Promise<Response>;
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createMcpProtocolHandler
|
|
3
|
-
} from "../../chunk-
|
|
4
|
-
import "../../chunk-
|
|
5
|
-
import "../../chunk-
|
|
6
|
-
import "../../chunk-
|
|
7
|
-
import "../../chunk-QC3DXQTH.js";
|
|
3
|
+
} from "../../chunk-UCPYLSNN.js";
|
|
4
|
+
import "../../chunk-MA5H6PSF.js";
|
|
5
|
+
import "../../chunk-YTOMGJV5.js";
|
|
6
|
+
import "../../chunk-DCWYK4CA.js";
|
|
8
7
|
import "../../chunk-6DXGZZA4.js";
|
|
9
|
-
import "../../chunk-
|
|
8
|
+
import "../../chunk-GIHCQT6L.js";
|
|
10
9
|
export {
|
|
11
10
|
createMcpProtocolHandler
|
|
12
11
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createOAuthProtectedResourceMetadataHandler
|
|
3
|
-
} from "../chunk-
|
|
4
|
-
import "../chunk-
|
|
5
|
-
import "../chunk-
|
|
3
|
+
} from "../chunk-ILYTJXDR.js";
|
|
4
|
+
import "../chunk-YTOMGJV5.js";
|
|
5
|
+
import "../chunk-DCWYK4CA.js";
|
|
6
6
|
import "../chunk-6DXGZZA4.js";
|
|
7
|
+
import "../chunk-GIHCQT6L.js";
|
|
7
8
|
export {
|
|
8
9
|
createOAuthProtectedResourceMetadataHandler
|
|
9
10
|
};
|