@lovable.dev/mcp-js 0.27.1 → 0.28.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.
- package/README.md +6 -6
- package/dist/{authorize-FOlzhxrM.js → authorize--rUeMOGU.js} +83 -32
- package/dist/{authorize-CB35c3Wg.cjs → authorize-ChY44o_1.cjs} +82 -31
- package/dist/{base-CReh7d3E.d.cts → base-CUkmyaXJ.d.cts} +6 -3
- package/dist/{base-CReh7d3E.d.ts → base-CUkmyaXJ.d.ts} +6 -3
- package/dist/cli/extract-manifest.cjs +2 -2
- package/dist/cli/extract-manifest.js +2 -2
- package/dist/{gate-BeHmyGxk.js → gate-BiM6EBeA.js} +1 -1
- package/dist/{gate-B9RSzvoI.cjs → gate-CGZl0gjJ.cjs} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{io--MeYrWG7.d.ts → io-SMlD5WeX.d.ts} +1 -1
- package/dist/{io-BzTGjG_c.d.cts → io-VBHO8YH_.d.cts} +1 -1
- package/dist/{list-tools-Bku6XkVc.d.ts → list-tools-BAqQVIHk.d.ts} +1 -1
- package/dist/{list-tools-Dt-mhh52.js → list-tools-BLGr7mot.js} +2 -2
- package/dist/{list-tools-Cn7tpE0V.d.cts → list-tools-BN97L2Yv.d.cts} +1 -1
- package/dist/{list-tools-DiMCRunS.cjs → list-tools-DCF6G4fn.cjs} +2 -2
- package/dist/{logger-BkMMCFTv.cjs → logger-CN1q-KNn.cjs} +6 -6
- package/dist/{logger-rGakBvJ1.js → logger-Ctv5xUSD.js} +6 -6
- package/dist/{mcp-ECo1Ixk8.cjs → mcp-CUGwXkxb.cjs} +3 -3
- package/dist/{mcp-DiVQhHIw.js → mcp-Czp-hHjN.js} +3 -3
- package/dist/{package-BdaLbzEh.cjs → package-CGLPZwz-.cjs} +1 -1
- package/dist/{package-dtiombMt.js → package-DgiA0xuY.js} +1 -1
- package/dist/protocols/mcp/index.cjs +1 -1
- package/dist/protocols/mcp/index.d.cts +1 -1
- package/dist/protocols/mcp/index.d.ts +1 -1
- package/dist/protocols/mcp/index.js +1 -1
- package/dist/protocols/oauth-metadata.cjs +2 -2
- package/dist/protocols/oauth-metadata.js +2 -2
- package/dist/protocols/rest/index.cjs +2 -2
- package/dist/protocols/rest/index.d.cts +2 -2
- package/dist/protocols/rest/index.d.ts +2 -2
- package/dist/protocols/rest/index.js +2 -2
- package/dist/{rest-1Pf9sYNU.cjs → rest-BE05MUNS.cjs} +3 -3
- package/dist/{rest-Cit2862S.js → rest-BS7bBOd9.js} +3 -3
- package/dist/stacks/supabase/index.cjs +5 -5
- package/dist/stacks/supabase/index.js +5 -5
- package/dist/stacks/supabase/vite.cjs +1 -1
- package/dist/stacks/supabase/vite.d.cts +1 -1
- package/dist/stacks/supabase/vite.d.ts +1 -1
- package/dist/stacks/supabase/vite.js +1 -1
- package/dist/stacks/tanstack/index.cjs +4 -4
- package/dist/stacks/tanstack/index.js +4 -4
- package/dist/stacks/tanstack/vite.d.cts +1 -1
- package/dist/stacks/tanstack/vite.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ Use `auth.oauth.issuer(...)`, set `resource` or `acceptedAudiences` to anchor th
|
|
|
211
211
|
|
|
212
212
|
## Debug logging
|
|
213
213
|
|
|
214
|
-
The runtime
|
|
214
|
+
The runtime logs operational events (tool invocations, auth outcomes, warnings, errors) at `info` by default. Raise the level to `debug` to trace OAuth discovery, JWKS resolution, and token verification when a deployed MCP server returns `401`/`500` and you need to see why. Logs go to `console` (so they land in your platform's function logs) and **never include the bearer token, full claims, or PII** — only non-secret fields such as the JWT header `alg`/`kid`, `issuer`, `jwks_uri`, the token `scopes`, and `jose` error codes. End-user identifiers (the token `sub`/`client_id`) appear only at `debug`, as the `oauth.verify.principal` event — the default `info` level never collects them.
|
|
215
215
|
|
|
216
216
|
Enable it either way:
|
|
217
217
|
|
|
@@ -222,17 +222,17 @@ setLogLevel("debug"); // "silent" | "error" | "warn" | "info" | "debug"
|
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
```bash
|
|
225
|
-
# Or via env var
|
|
226
|
-
#
|
|
227
|
-
#
|
|
225
|
+
# Or via env var. Node reads it at startup; on Deno and Cloudflare Workers the
|
|
226
|
+
# recorder applies it at the first request's telemetry emit, so logs before that
|
|
227
|
+
# point may not honor it — prefer `setLogLevel()` there.
|
|
228
228
|
LOVABLE_MCP_LOG_LEVEL=debug
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
A `500` on an OAuth-protected route is always one of two causes, logged at `error`: an `OAuthConfigurationError` from issuer-metadata discovery or a JWKS *fetch* failure (`oauth.discovery.config_error` / `oauth.jwks.fetch_failed` → `auth.config_error`), or a transport-level fault in the MCP handler (`mcp.transport_error`). Auth outcomes are logged at `info`: a granted request as `oauth.verify.ok`, and a
|
|
231
|
+
A `500` on an OAuth-protected route is always one of two causes, logged at `error`: an `OAuthConfigurationError` from issuer-metadata discovery or a JWKS *fetch* failure (`oauth.discovery.config_error` / `oauth.jwks.fetch_failed` → `auth.config_error`), or a transport-level fault in the MCP handler (`mcp.transport_error`). Auth outcomes are logged at `info`: a granted request as `oauth.verify.ok`, a request with no parseable bearer as `auth.no_bearer_token`, and a rejected token as `auth.token_rejected` (a `jose` rejection such as an expired token carries the `jose` error name and code; the full reason appears at `debug` as `oauth.verify.rejected`) — so a request rejected for insufficient scope shows both `oauth.verify.ok` and the `auth.token_rejected` that follows it. A sustained flood of `auth.token_rejected` whose `code` is `ERR_JOSE_NOT_SUPPORTED` or `ERR_JOSE_ALG_NOT_ALLOWED` (rather than `ERR_JWT_EXPIRED`) points at server-side key or algorithm configuration, not client error.
|
|
232
232
|
|
|
233
233
|
## Usage metrics
|
|
234
234
|
|
|
235
|
-
Each MCP server records per-invocation telemetry — tool name, JSON-RPC method, outcome (`
|
|
235
|
+
Each MCP server records per-invocation telemetry — tool name, JSON-RPC method, outcome, and latency — as **OTLP/HTTP JSON logs**, one awaited POST per record, bounded by a 3-second timeout; a failed or slow POST is logged (`metrics.failed`) and swallowed, never failing the request. Outcomes cover tool results (`ok`, `tool_error`, `handler_error`, `transport_error`) and the authorization gate: `auth_challenge` for an unauthenticated request answered with the `401` challenge (so probe traffic produces records), and the `auth_*` discovery/JWKS failure outcomes. No tool arguments or response payloads are ever captured. Emission is **on by default** and self-disables at runtime when `LOVABLE_API_KEY` is absent: records are dropped and one `metrics.disabled_no_api_key` warning is logged per process, so a local `vite dev` stays quiet. With `metrics: false` the recorder never runs — on Deno and Cloudflare Workers that also means `LOVABLE_MCP_LOG_LEVEL` is never applied (use `setLogLevel()` instead).
|
|
236
236
|
|
|
237
237
|
Configure it on the MCP definition:
|
|
238
238
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as log, n as applyLogLevelFromEnv, o as parseSafeUrl, r as describeError, s as trimTrailingSlash, t as LOG_LEVEL_ENV_VAR, u as resolveMetricsConfig } from "./logger-
|
|
2
|
-
import { t as version } from "./package-
|
|
1
|
+
import { i as log, n as applyLogLevelFromEnv, o as parseSafeUrl, r as describeError, s as trimTrailingSlash, t as LOG_LEVEL_ENV_VAR, u as resolveMetricsConfig } from "./logger-Ctv5xUSD.js";
|
|
2
|
+
import { t as version } from "./package-DgiA0xuY.js";
|
|
3
3
|
import "./metadata-path-CAkNcfyY.js";
|
|
4
|
-
import { createLocalJWKSet, decodeProtectedHeader, jwtVerify } from "jose";
|
|
4
|
+
import { createLocalJWKSet, decodeProtectedHeader, errors, jwtVerify } from "jose";
|
|
5
5
|
//#region src/core/cors.ts
|
|
6
6
|
const EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
7
7
|
const ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
@@ -73,6 +73,7 @@ function toLogRecord(rec) {
|
|
|
73
73
|
if (rec.tool !== null) attributes.push(strAttr("mcp.tool", rec.tool));
|
|
74
74
|
if (rec.reqBytes !== void 0) attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
|
|
75
75
|
if (rec.resBytes !== void 0) attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
76
|
+
if (rec.httpMethod !== void 0) attributes.push(strAttr("http.request.method", rec.httpMethod));
|
|
76
77
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
77
78
|
if (rec.endUserId !== void 0) attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
78
79
|
return {
|
|
@@ -120,6 +121,8 @@ function nowUnixNano() {
|
|
|
120
121
|
function nowMs() {
|
|
121
122
|
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
122
123
|
}
|
|
124
|
+
const METRICS_POST_TIMEOUT_MS = 3e3;
|
|
125
|
+
let warnedNoApiKey = false;
|
|
123
126
|
const NOOP_RECORDER = { async emit() {} };
|
|
124
127
|
function createNoopRecorder() {
|
|
125
128
|
return NOOP_RECORDER;
|
|
@@ -168,7 +171,7 @@ var BaseMetricRecorder = class {
|
|
|
168
171
|
}
|
|
169
172
|
async emit(ev) {
|
|
170
173
|
await this.applyLazyLogLevel();
|
|
171
|
-
log.info("tool.invoked", {
|
|
174
|
+
if (ev.outcome !== "auth_challenge") log.info("tool.invoked", {
|
|
172
175
|
tool: ev.tool,
|
|
173
176
|
method: ev.method,
|
|
174
177
|
outcome: ev.outcome,
|
|
@@ -181,30 +184,34 @@ var BaseMetricRecorder = class {
|
|
|
181
184
|
log.warn("metrics.disabled_no_fetch", { endpoint: this.config.endpoint });
|
|
182
185
|
return;
|
|
183
186
|
}
|
|
184
|
-
const headers = { ...this.baseHeaders };
|
|
185
|
-
if (this.usesLovableEndpoint) {
|
|
186
|
-
const key = await this.resolveApiKey();
|
|
187
|
-
if (!key) {
|
|
188
|
-
log.warn("metrics.disabled_no_api_key", {
|
|
189
|
-
envVar: this.config.apiKeyEnvVar,
|
|
190
|
-
endpoint: this.config.endpoint
|
|
191
|
-
});
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
headers.authorization = `Bearer ${key}`;
|
|
195
|
-
}
|
|
196
|
-
const { errorText: _localOnly, ...wireEvent } = ev;
|
|
197
|
-
const body = buildLogsPayload([{
|
|
198
|
-
...wireEvent,
|
|
199
|
-
timeUnixNano: nowUnixNano(),
|
|
200
|
-
stack: this.stack
|
|
201
|
-
}], this.server);
|
|
202
187
|
try {
|
|
188
|
+
const headers = { ...this.baseHeaders };
|
|
189
|
+
if (this.usesLovableEndpoint) {
|
|
190
|
+
const key = await this.resolveApiKey();
|
|
191
|
+
if (!key) {
|
|
192
|
+
if (!warnedNoApiKey) {
|
|
193
|
+
warnedNoApiKey = true;
|
|
194
|
+
log.warn("metrics.disabled_no_api_key", {
|
|
195
|
+
envVar: this.config.apiKeyEnvVar,
|
|
196
|
+
endpoint: this.config.endpoint
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
headers.authorization = `Bearer ${key}`;
|
|
202
|
+
}
|
|
203
|
+
const { errorText: _localOnly, ...wireEvent } = ev;
|
|
204
|
+
const body = buildLogsPayload([{
|
|
205
|
+
...wireEvent,
|
|
206
|
+
timeUnixNano: nowUnixNano(),
|
|
207
|
+
stack: this.stack
|
|
208
|
+
}], this.server);
|
|
203
209
|
const res = await this.doFetch(this.config.endpoint, {
|
|
204
210
|
method: "POST",
|
|
205
211
|
headers,
|
|
206
212
|
body,
|
|
207
|
-
keepalive: true
|
|
213
|
+
keepalive: true,
|
|
214
|
+
signal: AbortSignal.timeout(METRICS_POST_TIMEOUT_MS)
|
|
208
215
|
});
|
|
209
216
|
if (!res.ok) log.warn("metrics.rejected", {
|
|
210
217
|
status: res.status,
|
|
@@ -295,8 +302,8 @@ var SupabaseMetricRecorder = class extends BaseMetricRecorder {
|
|
|
295
302
|
//#endregion
|
|
296
303
|
//#region src/metrics/recorder.ts
|
|
297
304
|
/** Vend the recorder for a stack, in-flight per request. Returns a no-op when
|
|
298
|
-
* metrics are disabled (`metrics: false`); otherwise the stack-specific class,
|
|
299
|
-
*
|
|
305
|
+
* metrics are disabled (`metrics: false`); otherwise the stack-specific class, which
|
|
306
|
+
* logs `tool.invoked` for tool invocations even if the key or endpoint is unavailable. */
|
|
300
307
|
function createRecorderForRuntime(mcp, opts) {
|
|
301
308
|
const config = resolveMetricsConfig(mcp.metrics);
|
|
302
309
|
const server = {
|
|
@@ -593,6 +600,16 @@ async function fetchVerificationKeySet(jwksUri) {
|
|
|
593
600
|
throw new OAuthConfigurationError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`, "jwks");
|
|
594
601
|
}
|
|
595
602
|
}
|
|
603
|
+
function assertCompactJwsShape(token) {
|
|
604
|
+
const parts = token.split(".");
|
|
605
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
606
|
+
log.debug("oauth.verify.bad_shape", {
|
|
607
|
+
tokenLength: token.length,
|
|
608
|
+
outcome: "401 invalid_token"
|
|
609
|
+
});
|
|
610
|
+
throw new OAuthTokenError(401, "invalid_token", "Access token is not a JWT");
|
|
611
|
+
}
|
|
612
|
+
}
|
|
596
613
|
function assertAccessTokenTyp(token, allowed) {
|
|
597
614
|
let header;
|
|
598
615
|
try {
|
|
@@ -694,6 +711,8 @@ function buildMcpAuthContext(args) {
|
|
|
694
711
|
function createOAuthTokenVerifier(auth, discovery) {
|
|
695
712
|
const allowedTyps = auth.accessTokenTyp ?? DEFAULT_ACCESS_TOKEN_TYPS;
|
|
696
713
|
return async (token, request, options) => {
|
|
714
|
+
assertCompactJwsShape(token);
|
|
715
|
+
assertAccessTokenTyp(token, allowedTyps);
|
|
697
716
|
const resource = resolveProtectedResource(auth, request, options);
|
|
698
717
|
const issuer = await discovery.resolveIssuer();
|
|
699
718
|
const acceptedAudiences = resolveAcceptedAudiences(auth, resource);
|
|
@@ -705,9 +724,7 @@ function createOAuthTokenVerifier(auth, discovery) {
|
|
|
705
724
|
});
|
|
706
725
|
const jwksUri = await discovery.resolveJwksUri();
|
|
707
726
|
log.debug("oauth.jwks.fetch", { jwksUri });
|
|
708
|
-
const
|
|
709
|
-
assertAccessTokenTyp(token, allowedTyps);
|
|
710
|
-
const claims = await verifyJwtClaims(token, keySet, issuer, auth);
|
|
727
|
+
const claims = await verifyJwtClaims(token, await fetchVerificationKeySet(jwksUri), issuer, auth);
|
|
711
728
|
const audienceVia = checkAcceptedAudience(claims, acceptedAudiences, auth);
|
|
712
729
|
assertNonEmptySubject(claims);
|
|
713
730
|
const context = buildMcpAuthContext({
|
|
@@ -719,11 +736,13 @@ function createOAuthTokenVerifier(auth, discovery) {
|
|
|
719
736
|
});
|
|
720
737
|
assertOAuthClientClaim(auth, context.principal.clientId);
|
|
721
738
|
log.info("oauth.verify.ok", {
|
|
722
|
-
sub: context.principal.sub,
|
|
723
|
-
clientId: context.principal.clientId,
|
|
724
739
|
scopes: context.principal.scopes,
|
|
725
740
|
audienceVia
|
|
726
741
|
});
|
|
742
|
+
log.debug("oauth.verify.principal", {
|
|
743
|
+
sub: context.principal.sub,
|
|
744
|
+
clientId: context.principal.clientId
|
|
745
|
+
});
|
|
727
746
|
return context;
|
|
728
747
|
};
|
|
729
748
|
}
|
|
@@ -776,6 +795,22 @@ function oauthUpstreamUnreachableResponse() {
|
|
|
776
795
|
}
|
|
777
796
|
});
|
|
778
797
|
}
|
|
798
|
+
const KNOWN_HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
799
|
+
"GET",
|
|
800
|
+
"HEAD",
|
|
801
|
+
"POST",
|
|
802
|
+
"PUT",
|
|
803
|
+
"DELETE",
|
|
804
|
+
"PATCH",
|
|
805
|
+
"OPTIONS",
|
|
806
|
+
"TRACE",
|
|
807
|
+
"CONNECT",
|
|
808
|
+
"QUERY"
|
|
809
|
+
]);
|
|
810
|
+
function normalizeHttpMethod(method) {
|
|
811
|
+
const upper = method.toUpperCase();
|
|
812
|
+
return KNOWN_HTTP_METHODS.has(upper) ? upper : "_OTHER";
|
|
813
|
+
}
|
|
779
814
|
function parseBearerToken(request) {
|
|
780
815
|
const header = request.headers.get("Authorization");
|
|
781
816
|
if (!header) return void 0;
|
|
@@ -838,7 +873,18 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
838
873
|
const startedAt = nowMs();
|
|
839
874
|
const token = parseBearerToken(request);
|
|
840
875
|
if (!token) {
|
|
841
|
-
|
|
876
|
+
const httpMethod = normalizeHttpMethod(request.method);
|
|
877
|
+
log.info("auth.no_bearer_token", {
|
|
878
|
+
httpMethod,
|
|
879
|
+
outcome: "401"
|
|
880
|
+
});
|
|
881
|
+
await recorder?.emit({
|
|
882
|
+
tool: null,
|
|
883
|
+
method: "authorize",
|
|
884
|
+
outcome: "auth_challenge",
|
|
885
|
+
httpMethod,
|
|
886
|
+
durationMs: nowMs() - startedAt
|
|
887
|
+
});
|
|
842
888
|
return {
|
|
843
889
|
ok: false,
|
|
844
890
|
response: challengeResponse(runtime.auth, request, runtime.options, 401)
|
|
@@ -896,7 +942,12 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
896
942
|
response: challengeResponse(runtime.auth, request, runtime.options, err.status, err.oauthError, err.message)
|
|
897
943
|
};
|
|
898
944
|
}
|
|
899
|
-
log.
|
|
945
|
+
if (err instanceof errors.JOSEError) log.info("auth.token_rejected", {
|
|
946
|
+
...describeError(err),
|
|
947
|
+
status: 401,
|
|
948
|
+
oauthError: "invalid_token"
|
|
949
|
+
});
|
|
950
|
+
else log.error("auth.unexpected_error", {
|
|
900
951
|
...describeError(err),
|
|
901
952
|
outcome: "401"
|
|
902
953
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_logger = require("./logger-
|
|
2
|
-
const require_package = require("./package-
|
|
1
|
+
const require_logger = require("./logger-CN1q-KNn.cjs");
|
|
2
|
+
const require_package = require("./package-CGLPZwz-.cjs");
|
|
3
3
|
require("./metadata-path-zd7NSNoa.cjs");
|
|
4
4
|
let jose = require("jose");
|
|
5
5
|
//#region src/core/cors.ts
|
|
@@ -73,6 +73,7 @@ function toLogRecord(rec) {
|
|
|
73
73
|
if (rec.tool !== null) attributes.push(strAttr("mcp.tool", rec.tool));
|
|
74
74
|
if (rec.reqBytes !== void 0) attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
|
|
75
75
|
if (rec.resBytes !== void 0) attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
76
|
+
if (rec.httpMethod !== void 0) attributes.push(strAttr("http.request.method", rec.httpMethod));
|
|
76
77
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
77
78
|
if (rec.endUserId !== void 0) attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
78
79
|
return {
|
|
@@ -120,6 +121,8 @@ function nowUnixNano() {
|
|
|
120
121
|
function nowMs() {
|
|
121
122
|
return typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
|
|
122
123
|
}
|
|
124
|
+
const METRICS_POST_TIMEOUT_MS = 3e3;
|
|
125
|
+
let warnedNoApiKey = false;
|
|
123
126
|
const NOOP_RECORDER = { async emit() {} };
|
|
124
127
|
function createNoopRecorder() {
|
|
125
128
|
return NOOP_RECORDER;
|
|
@@ -168,7 +171,7 @@ var BaseMetricRecorder = class {
|
|
|
168
171
|
}
|
|
169
172
|
async emit(ev) {
|
|
170
173
|
await this.applyLazyLogLevel();
|
|
171
|
-
require_logger.log.info("tool.invoked", {
|
|
174
|
+
if (ev.outcome !== "auth_challenge") require_logger.log.info("tool.invoked", {
|
|
172
175
|
tool: ev.tool,
|
|
173
176
|
method: ev.method,
|
|
174
177
|
outcome: ev.outcome,
|
|
@@ -181,30 +184,34 @@ var BaseMetricRecorder = class {
|
|
|
181
184
|
require_logger.log.warn("metrics.disabled_no_fetch", { endpoint: this.config.endpoint });
|
|
182
185
|
return;
|
|
183
186
|
}
|
|
184
|
-
const headers = { ...this.baseHeaders };
|
|
185
|
-
if (this.usesLovableEndpoint) {
|
|
186
|
-
const key = await this.resolveApiKey();
|
|
187
|
-
if (!key) {
|
|
188
|
-
require_logger.log.warn("metrics.disabled_no_api_key", {
|
|
189
|
-
envVar: this.config.apiKeyEnvVar,
|
|
190
|
-
endpoint: this.config.endpoint
|
|
191
|
-
});
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
headers.authorization = `Bearer ${key}`;
|
|
195
|
-
}
|
|
196
|
-
const { errorText: _localOnly, ...wireEvent } = ev;
|
|
197
|
-
const body = buildLogsPayload([{
|
|
198
|
-
...wireEvent,
|
|
199
|
-
timeUnixNano: nowUnixNano(),
|
|
200
|
-
stack: this.stack
|
|
201
|
-
}], this.server);
|
|
202
187
|
try {
|
|
188
|
+
const headers = { ...this.baseHeaders };
|
|
189
|
+
if (this.usesLovableEndpoint) {
|
|
190
|
+
const key = await this.resolveApiKey();
|
|
191
|
+
if (!key) {
|
|
192
|
+
if (!warnedNoApiKey) {
|
|
193
|
+
warnedNoApiKey = true;
|
|
194
|
+
require_logger.log.warn("metrics.disabled_no_api_key", {
|
|
195
|
+
envVar: this.config.apiKeyEnvVar,
|
|
196
|
+
endpoint: this.config.endpoint
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
headers.authorization = `Bearer ${key}`;
|
|
202
|
+
}
|
|
203
|
+
const { errorText: _localOnly, ...wireEvent } = ev;
|
|
204
|
+
const body = buildLogsPayload([{
|
|
205
|
+
...wireEvent,
|
|
206
|
+
timeUnixNano: nowUnixNano(),
|
|
207
|
+
stack: this.stack
|
|
208
|
+
}], this.server);
|
|
203
209
|
const res = await this.doFetch(this.config.endpoint, {
|
|
204
210
|
method: "POST",
|
|
205
211
|
headers,
|
|
206
212
|
body,
|
|
207
|
-
keepalive: true
|
|
213
|
+
keepalive: true,
|
|
214
|
+
signal: AbortSignal.timeout(METRICS_POST_TIMEOUT_MS)
|
|
208
215
|
});
|
|
209
216
|
if (!res.ok) require_logger.log.warn("metrics.rejected", {
|
|
210
217
|
status: res.status,
|
|
@@ -295,8 +302,8 @@ var SupabaseMetricRecorder = class extends BaseMetricRecorder {
|
|
|
295
302
|
//#endregion
|
|
296
303
|
//#region src/metrics/recorder.ts
|
|
297
304
|
/** Vend the recorder for a stack, in-flight per request. Returns a no-op when
|
|
298
|
-
* metrics are disabled (`metrics: false`); otherwise the stack-specific class,
|
|
299
|
-
*
|
|
305
|
+
* metrics are disabled (`metrics: false`); otherwise the stack-specific class, which
|
|
306
|
+
* logs `tool.invoked` for tool invocations even if the key or endpoint is unavailable. */
|
|
300
307
|
function createRecorderForRuntime(mcp, opts) {
|
|
301
308
|
const config = require_logger.resolveMetricsConfig(mcp.metrics);
|
|
302
309
|
const server = {
|
|
@@ -593,6 +600,16 @@ async function fetchVerificationKeySet(jwksUri) {
|
|
|
593
600
|
throw new OAuthConfigurationError(`JWKS fetch failed: ${err instanceof Error ? err.message : String(err)}`, "jwks");
|
|
594
601
|
}
|
|
595
602
|
}
|
|
603
|
+
function assertCompactJwsShape(token) {
|
|
604
|
+
const parts = token.split(".");
|
|
605
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
606
|
+
require_logger.log.debug("oauth.verify.bad_shape", {
|
|
607
|
+
tokenLength: token.length,
|
|
608
|
+
outcome: "401 invalid_token"
|
|
609
|
+
});
|
|
610
|
+
throw new OAuthTokenError(401, "invalid_token", "Access token is not a JWT");
|
|
611
|
+
}
|
|
612
|
+
}
|
|
596
613
|
function assertAccessTokenTyp(token, allowed) {
|
|
597
614
|
let header;
|
|
598
615
|
try {
|
|
@@ -694,6 +711,8 @@ function buildMcpAuthContext(args) {
|
|
|
694
711
|
function createOAuthTokenVerifier(auth, discovery) {
|
|
695
712
|
const allowedTyps = auth.accessTokenTyp ?? DEFAULT_ACCESS_TOKEN_TYPS;
|
|
696
713
|
return async (token, request, options) => {
|
|
714
|
+
assertCompactJwsShape(token);
|
|
715
|
+
assertAccessTokenTyp(token, allowedTyps);
|
|
697
716
|
const resource = resolveProtectedResource(auth, request, options);
|
|
698
717
|
const issuer = await discovery.resolveIssuer();
|
|
699
718
|
const acceptedAudiences = resolveAcceptedAudiences(auth, resource);
|
|
@@ -705,9 +724,7 @@ function createOAuthTokenVerifier(auth, discovery) {
|
|
|
705
724
|
});
|
|
706
725
|
const jwksUri = await discovery.resolveJwksUri();
|
|
707
726
|
require_logger.log.debug("oauth.jwks.fetch", { jwksUri });
|
|
708
|
-
const
|
|
709
|
-
assertAccessTokenTyp(token, allowedTyps);
|
|
710
|
-
const claims = await verifyJwtClaims(token, keySet, issuer, auth);
|
|
727
|
+
const claims = await verifyJwtClaims(token, await fetchVerificationKeySet(jwksUri), issuer, auth);
|
|
711
728
|
const audienceVia = checkAcceptedAudience(claims, acceptedAudiences, auth);
|
|
712
729
|
assertNonEmptySubject(claims);
|
|
713
730
|
const context = buildMcpAuthContext({
|
|
@@ -719,11 +736,13 @@ function createOAuthTokenVerifier(auth, discovery) {
|
|
|
719
736
|
});
|
|
720
737
|
assertOAuthClientClaim(auth, context.principal.clientId);
|
|
721
738
|
require_logger.log.info("oauth.verify.ok", {
|
|
722
|
-
sub: context.principal.sub,
|
|
723
|
-
clientId: context.principal.clientId,
|
|
724
739
|
scopes: context.principal.scopes,
|
|
725
740
|
audienceVia
|
|
726
741
|
});
|
|
742
|
+
require_logger.log.debug("oauth.verify.principal", {
|
|
743
|
+
sub: context.principal.sub,
|
|
744
|
+
clientId: context.principal.clientId
|
|
745
|
+
});
|
|
727
746
|
return context;
|
|
728
747
|
};
|
|
729
748
|
}
|
|
@@ -776,6 +795,22 @@ function oauthUpstreamUnreachableResponse() {
|
|
|
776
795
|
}
|
|
777
796
|
});
|
|
778
797
|
}
|
|
798
|
+
const KNOWN_HTTP_METHODS = /* @__PURE__ */ new Set([
|
|
799
|
+
"GET",
|
|
800
|
+
"HEAD",
|
|
801
|
+
"POST",
|
|
802
|
+
"PUT",
|
|
803
|
+
"DELETE",
|
|
804
|
+
"PATCH",
|
|
805
|
+
"OPTIONS",
|
|
806
|
+
"TRACE",
|
|
807
|
+
"CONNECT",
|
|
808
|
+
"QUERY"
|
|
809
|
+
]);
|
|
810
|
+
function normalizeHttpMethod(method) {
|
|
811
|
+
const upper = method.toUpperCase();
|
|
812
|
+
return KNOWN_HTTP_METHODS.has(upper) ? upper : "_OTHER";
|
|
813
|
+
}
|
|
779
814
|
function parseBearerToken(request) {
|
|
780
815
|
const header = request.headers.get("Authorization");
|
|
781
816
|
if (!header) return void 0;
|
|
@@ -838,7 +873,18 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
838
873
|
const startedAt = nowMs();
|
|
839
874
|
const token = parseBearerToken(request);
|
|
840
875
|
if (!token) {
|
|
841
|
-
|
|
876
|
+
const httpMethod = normalizeHttpMethod(request.method);
|
|
877
|
+
require_logger.log.info("auth.no_bearer_token", {
|
|
878
|
+
httpMethod,
|
|
879
|
+
outcome: "401"
|
|
880
|
+
});
|
|
881
|
+
await recorder?.emit({
|
|
882
|
+
tool: null,
|
|
883
|
+
method: "authorize",
|
|
884
|
+
outcome: "auth_challenge",
|
|
885
|
+
httpMethod,
|
|
886
|
+
durationMs: nowMs() - startedAt
|
|
887
|
+
});
|
|
842
888
|
return {
|
|
843
889
|
ok: false,
|
|
844
890
|
response: challengeResponse(runtime.auth, request, runtime.options, 401)
|
|
@@ -896,7 +942,12 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
896
942
|
response: challengeResponse(runtime.auth, request, runtime.options, err.status, err.oauthError, err.message)
|
|
897
943
|
};
|
|
898
944
|
}
|
|
899
|
-
require_logger.log.
|
|
945
|
+
if (err instanceof jose.errors.JOSEError) require_logger.log.info("auth.token_rejected", {
|
|
946
|
+
...require_logger.describeError(err),
|
|
947
|
+
status: 401,
|
|
948
|
+
oauthError: "invalid_token"
|
|
949
|
+
});
|
|
950
|
+
else require_logger.log.error("auth.unexpected_error", {
|
|
900
951
|
...require_logger.describeError(err),
|
|
901
952
|
outcome: "401"
|
|
902
953
|
});
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
//#region src/metrics/impl/base.d.ts
|
|
2
|
-
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_discovery_config_error" | "auth_discovery_unreachable" | "auth_jwks_config_error" | "auth_jwks_unreachable";
|
|
2
|
+
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_challenge" | "auth_discovery_config_error" | "auth_discovery_unreachable" | "auth_jwks_config_error" | "auth_jwks_unreachable";
|
|
3
3
|
/** One recorded MCP call. Carries no arguments or response payloads — only the
|
|
4
4
|
* tool name, the JSON-RPC method, the result class, timing, and byte sizes.
|
|
5
5
|
* `errorText` is the sole exception: it is logged locally for debugging and
|
|
6
6
|
* deliberately never included in the OTLP payload (see `emit` / `buildLogsPayload`). */
|
|
7
7
|
interface InvocationRecord {
|
|
8
|
-
/** Tool name for `tools/call`; `null` for list/initialize, transport faults, and
|
|
8
|
+
/** Tool name for `tools/call`; `null` for list/initialize, transport faults, and `authorize` records. */
|
|
9
9
|
tool: string | null;
|
|
10
|
-
/** JSON-RPC method, e.g. `tools/call`; `authorize` for
|
|
10
|
+
/** JSON-RPC method, e.g. `tools/call`; `authorize` for records from the authorization gate. */
|
|
11
11
|
method: string;
|
|
12
12
|
outcome: InvocationOutcome;
|
|
13
13
|
durationMs: number;
|
|
14
14
|
reqBytes?: number;
|
|
15
15
|
resBytes?: number;
|
|
16
|
+
/** HTTP request method. Set on `auth_challenge` so probe traffic (GET vs
|
|
17
|
+
* POST discovery) is distinguishable; absent on tool-call records. */
|
|
18
|
+
httpMethod?: string;
|
|
16
19
|
/** The app end-user that made the call (the access token `sub`), or
|
|
17
20
|
* `undefined` when the request is unauthenticated. Not a Lovable identity. */
|
|
18
21
|
endUserId?: string;
|
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
//#region src/metrics/impl/base.d.ts
|
|
2
|
-
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_discovery_config_error" | "auth_discovery_unreachable" | "auth_jwks_config_error" | "auth_jwks_unreachable";
|
|
2
|
+
type InvocationOutcome = "ok" | "tool_error" | "handler_error" | "transport_error" | "auth_challenge" | "auth_discovery_config_error" | "auth_discovery_unreachable" | "auth_jwks_config_error" | "auth_jwks_unreachable";
|
|
3
3
|
/** One recorded MCP call. Carries no arguments or response payloads — only the
|
|
4
4
|
* tool name, the JSON-RPC method, the result class, timing, and byte sizes.
|
|
5
5
|
* `errorText` is the sole exception: it is logged locally for debugging and
|
|
6
6
|
* deliberately never included in the OTLP payload (see `emit` / `buildLogsPayload`). */
|
|
7
7
|
interface InvocationRecord {
|
|
8
|
-
/** Tool name for `tools/call`; `null` for list/initialize, transport faults, and
|
|
8
|
+
/** Tool name for `tools/call`; `null` for list/initialize, transport faults, and `authorize` records. */
|
|
9
9
|
tool: string | null;
|
|
10
|
-
/** JSON-RPC method, e.g. `tools/call`; `authorize` for
|
|
10
|
+
/** JSON-RPC method, e.g. `tools/call`; `authorize` for records from the authorization gate. */
|
|
11
11
|
method: string;
|
|
12
12
|
outcome: InvocationOutcome;
|
|
13
13
|
durationMs: number;
|
|
14
14
|
reqBytes?: number;
|
|
15
15
|
resBytes?: number;
|
|
16
|
+
/** HTTP request method. Set on `auth_challenge` so probe traffic (GET vs
|
|
17
|
+
* POST discovery) is distinguishable; absent on tool-call records. */
|
|
18
|
+
httpMethod?: string;
|
|
16
19
|
/** The app end-user that made the call (the access token `sub`), or
|
|
17
20
|
* `undefined` when the request is unauthenticated. Not a Lovable identity. */
|
|
18
21
|
endUserId?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_package = require("../package-
|
|
3
|
-
const require_list_tools = require("../list-tools-
|
|
2
|
+
const require_package = require("../package-CGLPZwz-.cjs");
|
|
3
|
+
const require_list_tools = require("../list-tools-DCF6G4fn.cjs");
|
|
4
4
|
const require_fs_errors = require("../fs-errors-CWNzOV75.cjs");
|
|
5
5
|
let node_fs = require("node:fs");
|
|
6
6
|
let node_path = require("node:path");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as version } from "../package-
|
|
3
|
-
import { t as buildMcpListing } from "../list-tools-
|
|
2
|
+
import { t as version } from "../package-DgiA0xuY.js";
|
|
3
|
+
import { t as buildMcpListing } from "../list-tools-BLGr7mot.js";
|
|
4
4
|
import { t as isFileMissing } from "../fs-errors-PA2t1TIp.js";
|
|
5
5
|
import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { dirname, resolve } from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as createNoopRecorder, d as finalizeWireResponse, p as corsPreflightResponse } from "./authorize
|
|
1
|
+
import { c as createNoopRecorder, d as finalizeWireResponse, p as corsPreflightResponse } from "./authorize--rUeMOGU.js";
|
|
2
2
|
//#region src/protocols/gate.ts
|
|
3
3
|
function createGatedHandler(gate) {
|
|
4
4
|
const allow = [...gate.methods, "OPTIONS"].join(", ");
|
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_logger = require("./logger-
|
|
2
|
+
const require_logger = require("./logger-CN1q-KNn.cjs");
|
|
3
3
|
const require_errors = require("./errors-CN6Da8iz.cjs");
|
|
4
4
|
//#region src/core/define.ts
|
|
5
5
|
function assertUniqueNames(mcp) {
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as setLogLevel, o as parseSafeUrl, s as trimTrailingSlash, u as resolveMetricsConfig } from "./logger-
|
|
1
|
+
import { a as setLogLevel, o as parseSafeUrl, s as trimTrailingSlash, u as resolveMetricsConfig } from "./logger-Ctv5xUSD.js";
|
|
2
2
|
import { i as ToolContext, t as ToolError } from "./errors-DSe96Ffd.js";
|
|
3
3
|
//#region src/core/define.ts
|
|
4
4
|
function assertUniqueNames(mcp) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as McpDefinition } from "./types-C0Wgm9zp.js";
|
|
2
|
-
import { t as MetricsRecorder } from "./base-
|
|
2
|
+
import { t as MetricsRecorder } from "./base-CUkmyaXJ.js";
|
|
3
3
|
import { t as McpRuntimeOptions } from "./authorize-Cs1yyLrq.js";
|
|
4
4
|
//#region src/protocols/rest/list-tools.d.ts
|
|
5
5
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as methodNotAllowed, n as createRequestAuthorizer, t as assertRestResourceBinding } from "./authorize
|
|
2
|
-
import { t as createGatedHandler } from "./gate-
|
|
1
|
+
import { f as methodNotAllowed, n as createRequestAuthorizer, t as assertRestResourceBinding } from "./authorize--rUeMOGU.js";
|
|
2
|
+
import { t as createGatedHandler } from "./gate-BiM6EBeA.js";
|
|
3
3
|
import { objectFromShape } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
4
4
|
import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
|
|
5
5
|
//#region src/protocols/rest/list-tools.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as McpDefinition } from "./types-C0Wgm9zp.cjs";
|
|
2
|
-
import { t as MetricsRecorder } from "./base-
|
|
2
|
+
import { t as MetricsRecorder } from "./base-CUkmyaXJ.cjs";
|
|
3
3
|
import { t as McpRuntimeOptions } from "./authorize-BcNuNPtP.cjs";
|
|
4
4
|
//#region src/protocols/rest/list-tools.d.ts
|
|
5
5
|
type RestListToolsHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_authorize = require("./authorize-
|
|
2
|
-
const require_gate = require("./gate-
|
|
1
|
+
const require_authorize = require("./authorize-ChY44o_1.cjs");
|
|
2
|
+
const require_gate = require("./gate-CGZl0gjJ.cjs");
|
|
3
3
|
let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
|
|
4
4
|
let _modelcontextprotocol_sdk_server_zod_json_schema_compat_js = require("@modelcontextprotocol/sdk/server/zod-json-schema-compat.js");
|
|
5
5
|
//#region src/protocols/rest/list-tools.ts
|
|
@@ -84,13 +84,12 @@ function isLogLevel(value) {
|
|
|
84
84
|
const LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
|
|
85
85
|
function readEnvLevel() {
|
|
86
86
|
try {
|
|
87
|
-
|
|
88
|
-
return isLogLevel(normalized) ? normalized : void 0;
|
|
87
|
+
return parseLogLevel(typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0);
|
|
89
88
|
} catch {
|
|
90
89
|
return;
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
|
-
let currentLevel = readEnvLevel() ?? "
|
|
92
|
+
let currentLevel = readEnvLevel() ?? "info";
|
|
94
93
|
/**
|
|
95
94
|
* Set the runtime log level programmatically. Use this when the deployment can't
|
|
96
95
|
* surface `LOVABLE_MCP_LOG_LEVEL` to the package (e.g. a Cloudflare Worker that
|
|
@@ -108,11 +107,12 @@ function parseLogLevel(raw) {
|
|
|
108
107
|
return isLogLevel(normalized) ? normalized : void 0;
|
|
109
108
|
}
|
|
110
109
|
/**
|
|
111
|
-
* Apply the log level from an env value
|
|
112
|
-
*
|
|
110
|
+
* Apply the log level from an env value when it names a valid level; otherwise
|
|
111
|
+
* leave the current level alone so a programmatic `setLogLevel` sticks.
|
|
113
112
|
*/
|
|
114
113
|
function applyLogLevelFromEnv(raw) {
|
|
115
|
-
|
|
114
|
+
const level = parseLogLevel(raw);
|
|
115
|
+
if (level !== void 0) setLogLevel(level);
|
|
116
116
|
}
|
|
117
117
|
function enabled(level) {
|
|
118
118
|
return LEVEL_RANK[level] <= LEVEL_RANK[currentLevel];
|
|
@@ -84,13 +84,12 @@ function isLogLevel(value) {
|
|
|
84
84
|
const LOG_LEVEL_ENV_VAR = "LOVABLE_MCP_LOG_LEVEL";
|
|
85
85
|
function readEnvLevel() {
|
|
86
86
|
try {
|
|
87
|
-
|
|
88
|
-
return isLogLevel(normalized) ? normalized : void 0;
|
|
87
|
+
return parseLogLevel(typeof process !== "undefined" ? process.env?.[LOG_LEVEL_ENV_VAR] : void 0);
|
|
89
88
|
} catch {
|
|
90
89
|
return;
|
|
91
90
|
}
|
|
92
91
|
}
|
|
93
|
-
let currentLevel = readEnvLevel() ?? "
|
|
92
|
+
let currentLevel = readEnvLevel() ?? "info";
|
|
94
93
|
/**
|
|
95
94
|
* Set the runtime log level programmatically. Use this when the deployment can't
|
|
96
95
|
* surface `LOVABLE_MCP_LOG_LEVEL` to the package (e.g. a Cloudflare Worker that
|
|
@@ -108,11 +107,12 @@ function parseLogLevel(raw) {
|
|
|
108
107
|
return isLogLevel(normalized) ? normalized : void 0;
|
|
109
108
|
}
|
|
110
109
|
/**
|
|
111
|
-
* Apply the log level from an env value
|
|
112
|
-
*
|
|
110
|
+
* Apply the log level from an env value when it names a valid level; otherwise
|
|
111
|
+
* leave the current level alone so a programmatic `setLogLevel` sticks.
|
|
113
112
|
*/
|
|
114
113
|
function applyLogLevelFromEnv(raw) {
|
|
115
|
-
|
|
114
|
+
const level = parseLogLevel(raw);
|
|
115
|
+
if (level !== void 0) setLogLevel(level);
|
|
116
116
|
}
|
|
117
117
|
function enabled(level) {
|
|
118
118
|
return LEVEL_RANK[level] <= LEVEL_RANK[currentLevel];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const require_logger = require("./logger-
|
|
1
|
+
const require_logger = require("./logger-CN1q-KNn.cjs");
|
|
2
2
|
const require_errors = require("./errors-CN6Da8iz.cjs");
|
|
3
|
-
const require_authorize = require("./authorize-
|
|
3
|
+
const require_authorize = require("./authorize-ChY44o_1.cjs");
|
|
4
4
|
const require_content = require("./content-NCYIGgOb.cjs");
|
|
5
|
-
const require_gate = require("./gate-
|
|
5
|
+
const require_gate = require("./gate-CGZl0gjJ.cjs");
|
|
6
6
|
let _modelcontextprotocol_sdk_server_mcp_js = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
7
7
|
let _modelcontextprotocol_sdk_server_webStandardStreamableHttp_js = require("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
|
|
8
8
|
//#region src/protocols/mcp/protocol.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { i as log, r as describeError } from "./logger-
|
|
1
|
+
import { i as log, r as describeError } from "./logger-Ctv5xUSD.js";
|
|
2
2
|
import { i as ToolContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-DSe96Ffd.js";
|
|
3
|
-
import { l as nowMs, n as createRequestAuthorizer } from "./authorize
|
|
3
|
+
import { l as nowMs, n as createRequestAuthorizer } from "./authorize--rUeMOGU.js";
|
|
4
4
|
import { t as extractTextContent } from "./content-D5LJAHyM.js";
|
|
5
|
-
import { t as createGatedHandler } from "./gate-
|
|
5
|
+
import { t as createGatedHandler } from "./gate-BiM6EBeA.js";
|
|
6
6
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
7
7
|
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
8
8
|
//#region src/protocols/mcp/protocol.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as McpDefinition } from "../../types-C0Wgm9zp.cjs";
|
|
2
|
-
import { t as MetricsRecorder } from "../../base-
|
|
2
|
+
import { t as MetricsRecorder } from "../../base-CUkmyaXJ.cjs";
|
|
3
3
|
import { t as McpRuntimeOptions } from "../../authorize-BcNuNPtP.cjs";
|
|
4
4
|
//#region src/protocols/mcp/protocol.d.ts
|
|
5
5
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as McpDefinition } from "../../types-C0Wgm9zp.js";
|
|
2
|
-
import { t as MetricsRecorder } from "../../base-
|
|
2
|
+
import { t as MetricsRecorder } from "../../base-CUkmyaXJ.js";
|
|
3
3
|
import { t as McpRuntimeOptions } from "../../authorize-Cs1yyLrq.js";
|
|
4
4
|
//#region src/protocols/mcp/protocol.d.ts
|
|
5
5
|
type McpProtocolHandler = (request: Request, recorder?: MetricsRecorder) => Promise<Response>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createMcpProtocolHandler } from "../../mcp-
|
|
1
|
+
import { t as createMcpProtocolHandler } from "../../mcp-Czp-hHjN.js";
|
|
2
2
|
export { createMcpProtocolHandler };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_logger = require("../logger-
|
|
3
|
-
const require_authorize = require("../authorize-
|
|
2
|
+
const require_logger = require("../logger-CN1q-KNn.cjs");
|
|
3
|
+
const require_authorize = require("../authorize-ChY44o_1.cjs");
|
|
4
4
|
//#region src/protocols/oauth-metadata.ts
|
|
5
5
|
function notFound() {
|
|
6
6
|
return new Response(JSON.stringify({ error: "not found" }), {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { i as log, r as describeError } from "../logger-
|
|
2
|
-
import { d as finalizeWireResponse, f as methodNotAllowed, i as oauthConfigurationErrorResponse, o as resolveProtectedResource, p as corsPreflightResponse, r as getOAuthRuntime, u as JSON_HEADERS } from "../authorize
|
|
1
|
+
import { i as log, r as describeError } from "../logger-Ctv5xUSD.js";
|
|
2
|
+
import { d as finalizeWireResponse, f as methodNotAllowed, i as oauthConfigurationErrorResponse, o as resolveProtectedResource, p as corsPreflightResponse, r as getOAuthRuntime, u as JSON_HEADERS } from "../authorize--rUeMOGU.js";
|
|
3
3
|
//#region src/protocols/oauth-metadata.ts
|
|
4
4
|
function notFound() {
|
|
5
5
|
return new Response(JSON.stringify({ error: "not found" }), {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_list_tools = require("../../list-tools-
|
|
3
|
-
const require_rest = require("../../rest-
|
|
2
|
+
const require_list_tools = require("../../list-tools-DCF6G4fn.cjs");
|
|
3
|
+
const require_rest = require("../../rest-BE05MUNS.cjs");
|
|
4
4
|
exports.createInvokeToolHandler = require_rest.createInvokeToolHandler;
|
|
5
5
|
exports.createListToolsHandler = require_list_tools.createListToolsHandler;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as McpDefinition } from "../../types-C0Wgm9zp.cjs";
|
|
2
|
-
import { t as MetricsRecorder } from "../../base-
|
|
2
|
+
import { t as MetricsRecorder } from "../../base-CUkmyaXJ.cjs";
|
|
3
3
|
import { t as McpRuntimeOptions } from "../../authorize-BcNuNPtP.cjs";
|
|
4
|
-
import { n as createListToolsHandler, t as RestListToolsHandler } from "../../list-tools-
|
|
4
|
+
import { n as createListToolsHandler, t as RestListToolsHandler } from "../../list-tools-BN97L2Yv.cjs";
|
|
5
5
|
//#region src/protocols/rest/invoke-tool.d.ts
|
|
6
6
|
type RestInvokeToolHandler = (request: Request, toolName: string, recorder?: MetricsRecorder) => Promise<Response>;
|
|
7
7
|
declare function createInvokeToolHandler(mcp: McpDefinition, options?: McpRuntimeOptions): RestInvokeToolHandler;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c as McpDefinition } from "../../types-C0Wgm9zp.js";
|
|
2
|
-
import { t as MetricsRecorder } from "../../base-
|
|
2
|
+
import { t as MetricsRecorder } from "../../base-CUkmyaXJ.js";
|
|
3
3
|
import { t as McpRuntimeOptions } from "../../authorize-Cs1yyLrq.js";
|
|
4
|
-
import { n as createListToolsHandler, t as RestListToolsHandler } from "../../list-tools-
|
|
4
|
+
import { n as createListToolsHandler, t as RestListToolsHandler } from "../../list-tools-BAqQVIHk.js";
|
|
5
5
|
//#region src/protocols/rest/invoke-tool.d.ts
|
|
6
6
|
type RestInvokeToolHandler = (request: Request, toolName: string, recorder?: MetricsRecorder) => Promise<Response>;
|
|
7
7
|
declare function createInvokeToolHandler(mcp: McpDefinition, options?: McpRuntimeOptions): RestInvokeToolHandler;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as createListToolsHandler } from "../../list-tools-
|
|
2
|
-
import { t as createInvokeToolHandler } from "../../rest-
|
|
1
|
+
import { n as createListToolsHandler } from "../../list-tools-BLGr7mot.js";
|
|
2
|
+
import { t as createInvokeToolHandler } from "../../rest-BS7bBOd9.js";
|
|
3
3
|
export { createInvokeToolHandler, createListToolsHandler };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const require_errors = require("./errors-CN6Da8iz.cjs");
|
|
2
|
-
const require_authorize = require("./authorize-
|
|
2
|
+
const require_authorize = require("./authorize-ChY44o_1.cjs");
|
|
3
3
|
const require_content = require("./content-NCYIGgOb.cjs");
|
|
4
|
-
const require_gate = require("./gate-
|
|
5
|
-
require("./list-tools-
|
|
4
|
+
const require_gate = require("./gate-CGZl0gjJ.cjs");
|
|
5
|
+
require("./list-tools-DCF6G4fn.cjs");
|
|
6
6
|
let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
|
|
7
7
|
//#region src/protocols/rest/invoke-tool.ts
|
|
8
8
|
const MAX_REFLECTED_TOOL_NAME = 256;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { i as ToolContext, n as errorSummary, r as resolveToolErrorMessage } from "./errors-DSe96Ffd.js";
|
|
2
|
-
import { f as methodNotAllowed, l as nowMs, n as createRequestAuthorizer, t as assertRestResourceBinding, u as JSON_HEADERS } from "./authorize
|
|
2
|
+
import { f as methodNotAllowed, l as nowMs, n as createRequestAuthorizer, t as assertRestResourceBinding, u as JSON_HEADERS } from "./authorize--rUeMOGU.js";
|
|
3
3
|
import { t as extractTextContent } from "./content-D5LJAHyM.js";
|
|
4
|
-
import { t as createGatedHandler } from "./gate-
|
|
5
|
-
import "./list-tools-
|
|
4
|
+
import { t as createGatedHandler } from "./gate-BiM6EBeA.js";
|
|
5
|
+
import "./list-tools-BLGr7mot.js";
|
|
6
6
|
import { getParseErrorMessage, objectFromShape, safeParseAsync } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
7
7
|
//#region src/protocols/rest/invoke-tool.ts
|
|
8
8
|
const MAX_REFLECTED_TOOL_NAME = 256;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_logger = require("../../logger-
|
|
3
|
-
const require_authorize = require("../../authorize-
|
|
2
|
+
const require_logger = require("../../logger-CN1q-KNn.cjs");
|
|
3
|
+
const require_authorize = require("../../authorize-ChY44o_1.cjs");
|
|
4
4
|
const require_metadata_path = require("../../metadata-path-zd7NSNoa.cjs");
|
|
5
|
-
const require_mcp = require("../../mcp-
|
|
5
|
+
const require_mcp = require("../../mcp-CUGwXkxb.cjs");
|
|
6
6
|
const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
|
|
7
|
-
const require_list_tools = require("../../list-tools-
|
|
8
|
-
const require_rest = require("../../rest-
|
|
7
|
+
const require_list_tools = require("../../list-tools-DCF6G4fn.cjs");
|
|
8
|
+
const require_rest = require("../../rest-BE05MUNS.cjs");
|
|
9
9
|
const require_forwarded = require("../../forwarded-Bhwcj22u.cjs");
|
|
10
10
|
const require_paths = require("../../paths-OP318a6c.cjs");
|
|
11
11
|
//#region src/stacks/supabase/handler.ts
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { s as trimTrailingSlash } from "../../logger-
|
|
2
|
-
import { a as assertResourcePathShape, s as createRecorderForRuntime } from "../../authorize
|
|
1
|
+
import { s as trimTrailingSlash } from "../../logger-Ctv5xUSD.js";
|
|
2
|
+
import { a as assertResourcePathShape, s as createRecorderForRuntime } from "../../authorize--rUeMOGU.js";
|
|
3
3
|
import { t as OAUTH_PROTECTED_RESOURCE_METADATA_PATH } from "../../metadata-path-CAkNcfyY.js";
|
|
4
|
-
import { t as createMcpProtocolHandler } from "../../mcp-
|
|
4
|
+
import { t as createMcpProtocolHandler } from "../../mcp-Czp-hHjN.js";
|
|
5
5
|
import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
|
|
6
|
-
import { n as createListToolsHandler } from "../../list-tools-
|
|
7
|
-
import { t as createInvokeToolHandler } from "../../rest-
|
|
6
|
+
import { n as createListToolsHandler } from "../../list-tools-BLGr7mot.js";
|
|
7
|
+
import { t as createInvokeToolHandler } from "../../rest-BS7bBOd9.js";
|
|
8
8
|
import { t as applyForwardedOrigin } from "../../forwarded-BlLF3dfc.js";
|
|
9
9
|
import { n as assertFunctionName, t as FUNCTIONS_MOUNT_PREFIX } from "../../paths-IS65L6TA.js";
|
|
10
10
|
//#region src/stacks/supabase/handler.ts
|
|
@@ -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-
|
|
5
|
+
const require_package = require("../../package-CGLPZwz-.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 version } from "../../package-
|
|
1
|
+
import { t as version } from "../../package-DgiA0xuY.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,9 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_authorize = require("../../authorize-
|
|
3
|
-
const require_mcp = require("../../mcp-
|
|
2
|
+
const require_authorize = require("../../authorize-ChY44o_1.cjs");
|
|
3
|
+
const require_mcp = require("../../mcp-CUGwXkxb.cjs");
|
|
4
4
|
const require_protocols_oauth_metadata = require("../../protocols/oauth-metadata.cjs");
|
|
5
|
-
const require_list_tools = require("../../list-tools-
|
|
6
|
-
const require_rest = require("../../rest-
|
|
5
|
+
const require_list_tools = require("../../list-tools-DCF6G4fn.cjs");
|
|
6
|
+
const require_rest = require("../../rest-BE05MUNS.cjs");
|
|
7
7
|
const require_forwarded = require("../../forwarded-Bhwcj22u.cjs");
|
|
8
8
|
//#region src/stacks/tanstack/handlers.ts
|
|
9
9
|
const STACK = "tanstack";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { s as createRecorderForRuntime } from "../../authorize
|
|
2
|
-
import { t as createMcpProtocolHandler } from "../../mcp-
|
|
1
|
+
import { s as createRecorderForRuntime } from "../../authorize--rUeMOGU.js";
|
|
2
|
+
import { t as createMcpProtocolHandler } from "../../mcp-Czp-hHjN.js";
|
|
3
3
|
import { createOAuthProtectedResourceMetadataHandler } from "../../protocols/oauth-metadata.js";
|
|
4
|
-
import { n as createListToolsHandler } from "../../list-tools-
|
|
5
|
-
import { t as createInvokeToolHandler } from "../../rest-
|
|
4
|
+
import { n as createListToolsHandler } from "../../list-tools-BLGr7mot.js";
|
|
5
|
+
import { t as createInvokeToolHandler } from "../../rest-BS7bBOd9.js";
|
|
6
6
|
import { t as applyForwardedOrigin } from "../../forwarded-BlLF3dfc.js";
|
|
7
7
|
//#region src/stacks/tanstack/handlers.ts
|
|
8
8
|
const STACK = "tanstack";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lovable.dev/mcp-js",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
4
4
|
"description": "Author MCP servers for Lovable apps. Declare tools with defineTool, register them in defineMcp, and a framework adapter (TanStack or Supabase Edge Functions) emits the route(s) at build time.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|