@lovable.dev/mcp-js 0.29.0-rc.2 → 0.29.0-rc.4
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.internal.md +3 -3
- package/README.md +2 -25
- package/dist/{cors-DNzLB6qa.cjs → authorize-CKMlIxm9.cjs} +29 -78
- package/dist/{authorize-Bpz8oxjF.d.ts → authorize-CqYsQYfa.d.ts} +1 -1
- package/dist/{authorize-Cqr7Jps0.d.cts → authorize-DIYS7zBP.d.cts} +1 -1
- package/dist/{cors-C_VffY86.js → authorize-b3VqTC_7.js} +24 -73
- package/dist/cli/extract-manifest.cjs +12 -7
- package/dist/cli/extract-manifest.js +12 -7
- package/dist/{errors-Cr95rSkB.cjs → errors-CN6Da8iz.cjs} +8 -23
- package/dist/{errors-Bwd1L0Rf.js → errors-DSe96Ffd.js} +8 -23
- package/dist/{forwarded-BC_RHnn5.cjs → forwarded-Bhwcj22u.cjs} +3 -3
- package/dist/{forwarded-B3EBjHnA.js → forwarded-BlLF3dfc.js} +3 -3
- package/dist/index.cjs +1 -38
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -38
- package/dist/{io-DrHivYt0.d.ts → io-DP3icuxa.d.ts} +1 -1
- package/dist/{io-Bh_WpbxU.d.cts → io-Dx0nPc1-.d.cts} +1 -1
- package/dist/mcp-BLs6_g8i.js +174 -0
- package/dist/mcp-DtHM-41c.cjs +179 -0
- package/dist/{package-CYA-5C24.js → package-DMs4EVwG.js} +1 -1
- package/dist/{package-DNSwCau1.cjs → package-Xk8p8Q_E.cjs} +1 -1
- package/dist/protocols/mcp/index.cjs +1 -1
- package/dist/protocols/mcp/index.d.cts +3 -6
- package/dist/protocols/mcp/index.d.ts +3 -6
- package/dist/protocols/mcp/index.js +1 -1
- package/dist/protocols/oauth-metadata.cjs +9 -11
- package/dist/protocols/oauth-metadata.d.cts +2 -2
- package/dist/protocols/oauth-metadata.d.ts +2 -2
- package/dist/protocols/oauth-metadata.js +3 -5
- package/dist/stacks/supabase/index.cjs +5 -5
- package/dist/stacks/supabase/index.d.cts +1 -1
- package/dist/stacks/supabase/index.d.ts +1 -1
- package/dist/stacks/supabase/index.js +3 -3
- 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.d.cts +2 -2
- package/dist/stacks/tanstack/index.d.ts +2 -2
- package/dist/stacks/tanstack/index.js +3 -3
- package/dist/stacks/tanstack/vite.cjs +4 -8
- package/dist/stacks/tanstack/vite.d.cts +1 -4
- package/dist/stacks/tanstack/vite.d.ts +1 -4
- package/dist/stacks/tanstack/vite.js +4 -8
- package/dist/{types-DnGEKnvI.d.cts → types-C0Wgm9zp.d.cts} +26 -57
- package/dist/{types-DnGEKnvI.d.ts → types-C0Wgm9zp.d.ts} +26 -57
- package/package.json +1 -5
- package/dist/mcp-Bl7pQYdv.js +0 -346
- package/dist/mcp-CRdT2Fai.cjs +0 -351
- package/dist/schema-CW1jKvio.js +0 -65
- package/dist/schema-D3vClxb7.cjs +0 -76
package/README.internal.md
CHANGED
|
@@ -4,7 +4,7 @@ Architecture rationale, source layout, and dev scripts for contributors. The use
|
|
|
4
4
|
|
|
5
5
|
## Folder meaning
|
|
6
6
|
|
|
7
|
-
- **`protocols/`** is the wire layer — one folder per externally observable HTTP surface. `protocols/mcp` is the public MCP-over-HTTP surface; `protocols/oauth-metadata` serves the RFC 9728 protected-resource metadata required to bootstrap protected MCP clients. `protocols/gate.ts` is the
|
|
7
|
+
- **`protocols/`** is the wire layer — one folder per externally observable HTTP surface. `protocols/mcp` is the public MCP-over-HTTP surface; `protocols/oauth-metadata` serves the RFC 9728 protected-resource metadata required to bootstrap protected MCP clients. `protocols/gate.ts` is the CORS → auth → method gate the MCP surface runs behind.
|
|
8
8
|
- **`auth/`** (unpublished) is the cross-cutting OAuth middleware — bearer verification, issuer/JWKS discovery, the `auth.oauth.*` config namespace. It depends only on `core/`; `protocols/mcp` depends on it for the bearer gate, so it isn't a wire-format peer of `mcp` and doesn't live under `protocols/`.
|
|
9
9
|
- **`stacks/`** is the framework integration. Two are published: `stacks/tanstack/` (file-router routes emitted by a Vite plugin) and `stacks/supabase/` (a single Deno-served function with URL-suffix dispatch, emitted by the Supabase Vite plugin). Future entries (classic Vite, Cloudflare Workers, …) live alongside them. Each stack forwards to `protocols/{mcp,oauth-metadata}` directly — protocol logic stays shared, only ctx unwrapping and route emission differ.
|
|
10
10
|
- **`manifest/`** is the stack-agnostic snapshot writer. `lovable-mcp-extract-manifest` is one CLI for every stack: it asks Vite for the resolved config, finds any plugin whose name matches `@lovable.dev/mcp-js*`, and reads `mcpEntry` + `urlPath` off its `api`. TanStack publishes its configured route path (`/mcp`); Supabase publishes `/functions/v1/<functionName>`. The projection (`extract.ts` + `listing.ts`) is pure and derives from the same `defineMcp` definition the live `tools/list` serves, so the committed manifest and the served catalog can't drift.
|
|
@@ -79,7 +79,7 @@ The published `.d.ts` files import only from `zod` and `vite`. Three SDK concern
|
|
|
79
79
|
- **`ZodRawShape`, `ZodType`, `infer`** — sourced directly from `zod` (a peer dep). zod v3 and v4 both export all three at the top level; `ZodType` is non-deprecated in both versions with safe generic defaults. We re-export them from `core/types.ts` as `ZodRawShape` / `ZodSchema` / `ShapeOutput` (`ZodSchema` is a no-generic alias for `ZodType`). No dependency on `@modelcontextprotocol/sdk/server/zod-compat.js` types.
|
|
80
80
|
- **`ContentBlock` union** — `TextContent | ImageContent | AudioContent | EmbeddedResource | ResourceLink`, structurally matching MCP's wire format. Consumers can type custom content (`return { content: [<ImageContent>, <TextContent>] }`) without referencing the SDK.
|
|
81
81
|
|
|
82
|
-
The **runtime** still hands off to the MCP
|
|
82
|
+
The **runtime** still hands off to the MCP SDK — we still `import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"` and call `registerTool`, and we still use `objectFromShape` + `toJsonSchemaCompat` from the SDK's zod-compat modules to serialize the tool catalog to JSON Schema. That's a runtime dependency, not a type-surface dependency.
|
|
83
83
|
|
|
84
84
|
### 8. Stale-route cleanup on every regen
|
|
85
85
|
|
|
@@ -141,7 +141,7 @@ src/
|
|
|
141
141
|
vite.ts # mcpPlugin (Vite-lifecycle trigger; exposes McpPluginApi with urlPath=/functions/v1/<functionName>)
|
|
142
142
|
index.ts # barrel
|
|
143
143
|
tests/
|
|
144
|
-
core/{content,
|
|
144
|
+
core/{content,define,errors,forwarded,logger,promise,supabase-config,url}.test.ts
|
|
145
145
|
auth/{claims,config,context,oauth,oauth-fallback,oauth-logging,oauth-metrics}.test.ts # OAuth config + bearer verification
|
|
146
146
|
metrics/{config,dispatch,otlp,recorder}.test.ts
|
|
147
147
|
protocols/
|
package/README.md
CHANGED
|
@@ -49,13 +49,7 @@ That's the whole authoring surface. No imperative server construction, no route
|
|
|
49
49
|
|
|
50
50
|
The table shows the default `path: "/mcp"`; `mcpPlugin({ path: "/api/public/mcp" })` moves the MCP route accordingly.
|
|
51
51
|
|
|
52
|
-
MCP (`POST <path>`, `/mcp` by default) is the wire format clients speak directly. All runtime routes import the same `defineMcp` result, so they stay in sync on which tools exist and which auth
|
|
53
|
-
|
|
54
|
-
The MCP endpoint supports both protocol eras on one URL. Finalized `2026-07-28` clients send the version, client capabilities, and mirrored HTTP headers on every request; the server returns typed results plus cache metadata on discovery and list responses without initialization or protocol sessions. Initialization-era clients continue through a stateless compatibility path: `initialize`, `tools/list`, and `tools/call` work as independent requests, and the endpoint never mints `Mcp-Session-Id`. `GET` and `DELETE` return `405` because there is no standalone stream or session to manage.
|
|
55
|
-
|
|
56
|
-
`outputSchema` accepts either the existing object-shape shorthand (`{ value: z.string() }`) or a JSON-Schema-representable Zod schema such as `z.array(z.string())`; `structuredContent` may be any JSON value. The server returns the schema's parsed output, so coercions are reflected in the result; transforms with no truthful JSON Schema are rejected when `defineMcp` runs. Modern clients receive the natural schema and value. The compatibility path wraps non-object schemas and values under `result` for initialization-era clients whose wire format requires an object root.
|
|
57
|
-
|
|
58
|
-
Browser-origin checks apply to the MCP and OAuth metadata routes before authentication. Omit `allowedOrigins` to allow requests with no `Origin` header (Go, desktop, CLI, and server clients) plus same-origin browser requests. Set `allowedOrigins: ["https://client.example.com"]` for exact additional origins, or `allowedOrigins: "any"` to intentionally restore wildcard CORS. Exact and same origins are reflected with `Vary: Origin`; other browser origins receive `403` without an OAuth challenge. Reverse-proxy adapters compare against the effective public origin after applying only their configured trusted forwarded headers.
|
|
52
|
+
MCP (`POST <path>`, `/mcp` by default) is the wire format clients speak directly. All runtime routes import the same `defineMcp` result, so they stay in sync on which tools exist and which auth policy protects them. If `defineMcp({ auth: ... })` is omitted, the handlers stay unauthenticated; if OAuth auth is configured, clients must pass `Authorization: Bearer <token>`. Rate limiting belongs at the app host or edge.
|
|
59
53
|
|
|
60
54
|
The OAuth metadata route is emitted by default and returns `404` until OAuth auth is configured. Disable it with `mcpPlugin({ protectedResourceMetadataRoute: false })` only if the app owns `/.well-known/oauth-protected-resource` itself.
|
|
61
55
|
|
|
@@ -166,23 +160,6 @@ and no `node:async_hooks` dependency, so it works on any runtime and is safe
|
|
|
166
160
|
under concurrency by construction. A handler that hands `ctx` to deferred work (a
|
|
167
161
|
detached timer, an un-awaited promise) keeps full access to it.
|
|
168
162
|
|
|
169
|
-
Beyond auth, `ToolContext` carries the per-request runtime surface:
|
|
170
|
-
|
|
171
|
-
| Member | Purpose |
|
|
172
|
-
| --- | --- |
|
|
173
|
-
| `signal` | An `AbortSignal` that aborts when the client cancels the request or disconnects. Pass it to `fetch` and other cancelable APIs, or check `signal.aborted` between steps of long work. |
|
|
174
|
-
| `client` | What the calling client declared about itself (`McpClientInfo`): `protocol` (`"2026-07-28"` or `"legacy"`), and for modern requests the envelope's `info`, `capabilities`, and `extensions`. Unverified client input — use it to adapt output, never to authorize. |
|
|
175
|
-
| `progress(update)` | Sends a `notifications/progress` frame (`{ progress, total?, message? }`) for long-running tools. A no-op unless the client requested progress by sending `_meta.progressToken`; safe to call unconditionally. |
|
|
176
|
-
|
|
177
|
-
```ts
|
|
178
|
-
handler: async ({ url }, ctx) => {
|
|
179
|
-
await ctx.progress({ progress: 0, total: 2, message: "fetching" });
|
|
180
|
-
const res = await fetch(url, { signal: ctx.signal });
|
|
181
|
-
await ctx.progress({ progress: 1, total: 2, message: "processing" });
|
|
182
|
-
return { content: [{ type: "text", text: await res.text() }] };
|
|
183
|
-
};
|
|
184
|
-
```
|
|
185
|
-
|
|
186
163
|
**Security contract for the bearer token.** `getToken()` is the only way to read
|
|
187
164
|
the raw token. `ToolContext` holds the verified context in a private field, so the
|
|
188
165
|
credential can't be read off the instance via `JSON.stringify`, object spread, or
|
|
@@ -251,7 +228,7 @@ A `500` on an OAuth-protected route is always one of two causes, logged at `erro
|
|
|
251
228
|
|
|
252
229
|
## Usage metrics
|
|
253
230
|
|
|
254
|
-
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`)
|
|
231
|
+
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).
|
|
255
232
|
|
|
256
233
|
Configure it on the MCP definition:
|
|
257
234
|
|
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
const require_logger = require("./logger-CN1q-KNn.cjs");
|
|
2
|
-
const require_package = require("./package-
|
|
2
|
+
const require_package = require("./package-Xk8p8Q_E.cjs");
|
|
3
3
|
require("./metadata-path-zd7NSNoa.cjs");
|
|
4
4
|
let jose = require("jose");
|
|
5
|
+
//#region src/core/cors.ts
|
|
6
|
+
const EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
7
|
+
const ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
8
|
+
/** Add permissive CORS to a built response, preserving its other headers. */
|
|
9
|
+
function withCors(response) {
|
|
10
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
11
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
12
|
+
return response;
|
|
13
|
+
}
|
|
14
|
+
function corsPreflightResponse(allowMethods) {
|
|
15
|
+
return new Response(null, {
|
|
16
|
+
status: 204,
|
|
17
|
+
headers: {
|
|
18
|
+
"Access-Control-Allow-Origin": "*",
|
|
19
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
20
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
21
|
+
"Access-Control-Max-Age": "86400"
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
5
26
|
//#region src/core/http.ts
|
|
6
27
|
const JSON_HEADERS = { "Content-Type": "application/json" };
|
|
7
28
|
/** Strip the body from a built response, preserving status and headers, for HEAD. */
|
|
@@ -13,7 +34,7 @@ function headResponse(response) {
|
|
|
13
34
|
});
|
|
14
35
|
}
|
|
15
36
|
function finalizeWireResponse(request, response) {
|
|
16
|
-
return request.method === "HEAD" ? headResponse(response) : response;
|
|
37
|
+
return withCors(request.method === "HEAD" ? headResponse(response) : response);
|
|
17
38
|
}
|
|
18
39
|
function methodNotAllowed(allow) {
|
|
19
40
|
return new Response(JSON.stringify({ error: "method not allowed" }), {
|
|
@@ -53,7 +74,6 @@ function toLogRecord(rec) {
|
|
|
53
74
|
if (rec.reqBytes !== void 0) attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
|
|
54
75
|
if (rec.resBytes !== void 0) attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
55
76
|
if (rec.httpMethod !== void 0) attributes.push(strAttr("http.request.method", rec.httpMethod));
|
|
56
|
-
if (rec.protocol !== void 0) attributes.push(strAttr("mcp.protocol", rec.protocol));
|
|
57
77
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
58
78
|
if (rec.endUserId !== void 0) attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
59
79
|
return {
|
|
@@ -157,7 +177,6 @@ var BaseMetricRecorder = class {
|
|
|
157
177
|
outcome: ev.outcome,
|
|
158
178
|
durationMs: ev.durationMs,
|
|
159
179
|
stack: this.stack,
|
|
160
|
-
...ev.protocol !== void 0 && { protocol: ev.protocol },
|
|
161
180
|
...ev.errorText !== void 0 && { errorText: ev.errorText }
|
|
162
181
|
});
|
|
163
182
|
if (!this.config.enabled) return;
|
|
@@ -929,74 +948,6 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
929
948
|
} };
|
|
930
949
|
}
|
|
931
950
|
//#endregion
|
|
932
|
-
//#region src/core/cors.ts
|
|
933
|
-
const EXPOSE_HEADERS = "WWW-Authenticate, MCP-Protocol-Version, Mcp-Session-Id";
|
|
934
|
-
const ALLOW_HEADERS = [
|
|
935
|
-
"Authorization",
|
|
936
|
-
"Content-Type",
|
|
937
|
-
"MCP-Protocol-Version",
|
|
938
|
-
"Mcp-Method",
|
|
939
|
-
"Mcp-Name",
|
|
940
|
-
"Mcp-Session-Id",
|
|
941
|
-
"Last-Event-ID"
|
|
942
|
-
];
|
|
943
|
-
const MCP_PARAM_HEADER = /^mcp-param-[!#$%&'*+.^_`|~0-9A-Za-z-]+$/i;
|
|
944
|
-
function appendVary(headers, value) {
|
|
945
|
-
const values = new Set((headers.get("Vary") ?? "").split(",").map((entry) => entry.trim()).filter(Boolean));
|
|
946
|
-
values.add(value);
|
|
947
|
-
headers.set("Vary", [...values].join(", "));
|
|
948
|
-
}
|
|
949
|
-
function addCorsHeaders(response, allowedOrigin, variesByOrigin) {
|
|
950
|
-
if (allowedOrigin !== void 0) {
|
|
951
|
-
response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
|
|
952
|
-
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
953
|
-
}
|
|
954
|
-
if (variesByOrigin) appendVary(response.headers, "Origin");
|
|
955
|
-
return response;
|
|
956
|
-
}
|
|
957
|
-
function allowedRequestHeaders(request) {
|
|
958
|
-
const allowed = new Map(ALLOW_HEADERS.map((header) => [header.toLowerCase(), header]));
|
|
959
|
-
for (const header of (request.headers.get("Access-Control-Request-Headers") ?? "").split(",")) {
|
|
960
|
-
const normalized = header.trim();
|
|
961
|
-
if (MCP_PARAM_HEADER.test(normalized)) allowed.set(normalized.toLowerCase(), normalized);
|
|
962
|
-
}
|
|
963
|
-
return [...allowed.values()].join(", ");
|
|
964
|
-
}
|
|
965
|
-
function evaluateCors(request, allowedOrigins) {
|
|
966
|
-
const origin = request.headers.get("Origin");
|
|
967
|
-
const allowAny = allowedOrigins === "any";
|
|
968
|
-
const originAllowed = origin === null || origin === new URL(request.url).origin || allowedOrigins?.includes(origin) === true;
|
|
969
|
-
if (!allowAny && !originAllowed) {
|
|
970
|
-
const response = Response.json({ error: "origin not allowed" }, {
|
|
971
|
-
status: 403,
|
|
972
|
-
headers: { "Cache-Control": "no-store" }
|
|
973
|
-
});
|
|
974
|
-
appendVary(response.headers, "Origin");
|
|
975
|
-
return {
|
|
976
|
-
ok: false,
|
|
977
|
-
response
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
const allowedOrigin = allowAny ? "*" : origin ?? void 0;
|
|
981
|
-
return {
|
|
982
|
-
ok: true,
|
|
983
|
-
withHeaders: (response) => addCorsHeaders(response, allowedOrigin, !allowAny),
|
|
984
|
-
preflight: (allowMethods) => {
|
|
985
|
-
const requestedHeaders = request.headers.get("Access-Control-Request-Headers");
|
|
986
|
-
const response = new Response(null, {
|
|
987
|
-
status: 204,
|
|
988
|
-
headers: {
|
|
989
|
-
"Access-Control-Allow-Methods": allowMethods,
|
|
990
|
-
"Access-Control-Allow-Headers": allowedRequestHeaders(request),
|
|
991
|
-
"Access-Control-Max-Age": "86400"
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
if (requestedHeaders) appendVary(response.headers, "Access-Control-Request-Headers");
|
|
995
|
-
return addCorsHeaders(response, allowedOrigin, !allowAny);
|
|
996
|
-
}
|
|
997
|
-
};
|
|
998
|
-
}
|
|
999
|
-
//#endregion
|
|
1000
951
|
Object.defineProperty(exports, "JSON_HEADERS", {
|
|
1001
952
|
enumerable: true,
|
|
1002
953
|
get: function() {
|
|
@@ -1009,6 +960,12 @@ Object.defineProperty(exports, "assertResourcePathShape", {
|
|
|
1009
960
|
return assertResourcePathShape;
|
|
1010
961
|
}
|
|
1011
962
|
});
|
|
963
|
+
Object.defineProperty(exports, "corsPreflightResponse", {
|
|
964
|
+
enumerable: true,
|
|
965
|
+
get: function() {
|
|
966
|
+
return corsPreflightResponse;
|
|
967
|
+
}
|
|
968
|
+
});
|
|
1012
969
|
Object.defineProperty(exports, "createNoopRecorder", {
|
|
1013
970
|
enumerable: true,
|
|
1014
971
|
get: function() {
|
|
@@ -1027,12 +984,6 @@ Object.defineProperty(exports, "createRequestAuthorizer", {
|
|
|
1027
984
|
return createRequestAuthorizer;
|
|
1028
985
|
}
|
|
1029
986
|
});
|
|
1030
|
-
Object.defineProperty(exports, "evaluateCors", {
|
|
1031
|
-
enumerable: true,
|
|
1032
|
-
get: function() {
|
|
1033
|
-
return evaluateCors;
|
|
1034
|
-
}
|
|
1035
|
-
});
|
|
1036
987
|
Object.defineProperty(exports, "finalizeWireResponse", {
|
|
1037
988
|
enumerable: true,
|
|
1038
989
|
get: function() {
|
|
@@ -1,7 +1,28 @@
|
|
|
1
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-
|
|
2
|
+
import { t as version } from "./package-DMs4EVwG.js";
|
|
3
3
|
import "./metadata-path-CAkNcfyY.js";
|
|
4
4
|
import { createLocalJWKSet, decodeProtectedHeader, errors, jwtVerify } from "jose";
|
|
5
|
+
//#region src/core/cors.ts
|
|
6
|
+
const EXPOSE_HEADERS = "WWW-Authenticate, Mcp-Session-Id, Mcp-Protocol-Version";
|
|
7
|
+
const ALLOW_HEADERS = "Authorization, Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID";
|
|
8
|
+
/** Add permissive CORS to a built response, preserving its other headers. */
|
|
9
|
+
function withCors(response) {
|
|
10
|
+
response.headers.set("Access-Control-Allow-Origin", "*");
|
|
11
|
+
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
12
|
+
return response;
|
|
13
|
+
}
|
|
14
|
+
function corsPreflightResponse(allowMethods) {
|
|
15
|
+
return new Response(null, {
|
|
16
|
+
status: 204,
|
|
17
|
+
headers: {
|
|
18
|
+
"Access-Control-Allow-Origin": "*",
|
|
19
|
+
"Access-Control-Allow-Methods": allowMethods,
|
|
20
|
+
"Access-Control-Allow-Headers": ALLOW_HEADERS,
|
|
21
|
+
"Access-Control-Max-Age": "86400"
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
5
26
|
//#region src/core/http.ts
|
|
6
27
|
const JSON_HEADERS = { "Content-Type": "application/json" };
|
|
7
28
|
/** Strip the body from a built response, preserving status and headers, for HEAD. */
|
|
@@ -13,7 +34,7 @@ function headResponse(response) {
|
|
|
13
34
|
});
|
|
14
35
|
}
|
|
15
36
|
function finalizeWireResponse(request, response) {
|
|
16
|
-
return request.method === "HEAD" ? headResponse(response) : response;
|
|
37
|
+
return withCors(request.method === "HEAD" ? headResponse(response) : response);
|
|
17
38
|
}
|
|
18
39
|
function methodNotAllowed(allow) {
|
|
19
40
|
return new Response(JSON.stringify({ error: "method not allowed" }), {
|
|
@@ -53,7 +74,6 @@ function toLogRecord(rec) {
|
|
|
53
74
|
if (rec.reqBytes !== void 0) attributes.push(intAttr("mcp.request_size_bytes", rec.reqBytes));
|
|
54
75
|
if (rec.resBytes !== void 0) attributes.push(intAttr("mcp.response_size_bytes", rec.resBytes));
|
|
55
76
|
if (rec.httpMethod !== void 0) attributes.push(strAttr("http.request.method", rec.httpMethod));
|
|
56
|
-
if (rec.protocol !== void 0) attributes.push(strAttr("mcp.protocol", rec.protocol));
|
|
57
77
|
attributes.push(strAttr("mcp.stack", rec.stack));
|
|
58
78
|
if (rec.endUserId !== void 0) attributes.push(strAttr("mcp.end_user_id", rec.endUserId));
|
|
59
79
|
return {
|
|
@@ -157,7 +177,6 @@ var BaseMetricRecorder = class {
|
|
|
157
177
|
outcome: ev.outcome,
|
|
158
178
|
durationMs: ev.durationMs,
|
|
159
179
|
stack: this.stack,
|
|
160
|
-
...ev.protocol !== void 0 && { protocol: ev.protocol },
|
|
161
180
|
...ev.errorText !== void 0 && { errorText: ev.errorText }
|
|
162
181
|
});
|
|
163
182
|
if (!this.config.enabled) return;
|
|
@@ -929,72 +948,4 @@ function createRequestAuthorizer(mcp, options = {}) {
|
|
|
929
948
|
} };
|
|
930
949
|
}
|
|
931
950
|
//#endregion
|
|
932
|
-
|
|
933
|
-
const EXPOSE_HEADERS = "WWW-Authenticate, MCP-Protocol-Version, Mcp-Session-Id";
|
|
934
|
-
const ALLOW_HEADERS = [
|
|
935
|
-
"Authorization",
|
|
936
|
-
"Content-Type",
|
|
937
|
-
"MCP-Protocol-Version",
|
|
938
|
-
"Mcp-Method",
|
|
939
|
-
"Mcp-Name",
|
|
940
|
-
"Mcp-Session-Id",
|
|
941
|
-
"Last-Event-ID"
|
|
942
|
-
];
|
|
943
|
-
const MCP_PARAM_HEADER = /^mcp-param-[!#$%&'*+.^_`|~0-9A-Za-z-]+$/i;
|
|
944
|
-
function appendVary(headers, value) {
|
|
945
|
-
const values = new Set((headers.get("Vary") ?? "").split(",").map((entry) => entry.trim()).filter(Boolean));
|
|
946
|
-
values.add(value);
|
|
947
|
-
headers.set("Vary", [...values].join(", "));
|
|
948
|
-
}
|
|
949
|
-
function addCorsHeaders(response, allowedOrigin, variesByOrigin) {
|
|
950
|
-
if (allowedOrigin !== void 0) {
|
|
951
|
-
response.headers.set("Access-Control-Allow-Origin", allowedOrigin);
|
|
952
|
-
response.headers.set("Access-Control-Expose-Headers", EXPOSE_HEADERS);
|
|
953
|
-
}
|
|
954
|
-
if (variesByOrigin) appendVary(response.headers, "Origin");
|
|
955
|
-
return response;
|
|
956
|
-
}
|
|
957
|
-
function allowedRequestHeaders(request) {
|
|
958
|
-
const allowed = new Map(ALLOW_HEADERS.map((header) => [header.toLowerCase(), header]));
|
|
959
|
-
for (const header of (request.headers.get("Access-Control-Request-Headers") ?? "").split(",")) {
|
|
960
|
-
const normalized = header.trim();
|
|
961
|
-
if (MCP_PARAM_HEADER.test(normalized)) allowed.set(normalized.toLowerCase(), normalized);
|
|
962
|
-
}
|
|
963
|
-
return [...allowed.values()].join(", ");
|
|
964
|
-
}
|
|
965
|
-
function evaluateCors(request, allowedOrigins) {
|
|
966
|
-
const origin = request.headers.get("Origin");
|
|
967
|
-
const allowAny = allowedOrigins === "any";
|
|
968
|
-
const originAllowed = origin === null || origin === new URL(request.url).origin || allowedOrigins?.includes(origin) === true;
|
|
969
|
-
if (!allowAny && !originAllowed) {
|
|
970
|
-
const response = Response.json({ error: "origin not allowed" }, {
|
|
971
|
-
status: 403,
|
|
972
|
-
headers: { "Cache-Control": "no-store" }
|
|
973
|
-
});
|
|
974
|
-
appendVary(response.headers, "Origin");
|
|
975
|
-
return {
|
|
976
|
-
ok: false,
|
|
977
|
-
response
|
|
978
|
-
};
|
|
979
|
-
}
|
|
980
|
-
const allowedOrigin = allowAny ? "*" : origin ?? void 0;
|
|
981
|
-
return {
|
|
982
|
-
ok: true,
|
|
983
|
-
withHeaders: (response) => addCorsHeaders(response, allowedOrigin, !allowAny),
|
|
984
|
-
preflight: (allowMethods) => {
|
|
985
|
-
const requestedHeaders = request.headers.get("Access-Control-Request-Headers");
|
|
986
|
-
const response = new Response(null, {
|
|
987
|
-
status: 204,
|
|
988
|
-
headers: {
|
|
989
|
-
"Access-Control-Allow-Methods": allowMethods,
|
|
990
|
-
"Access-Control-Allow-Headers": allowedRequestHeaders(request),
|
|
991
|
-
"Access-Control-Max-Age": "86400"
|
|
992
|
-
}
|
|
993
|
-
});
|
|
994
|
-
if (requestedHeaders) appendVary(response.headers, "Access-Control-Request-Headers");
|
|
995
|
-
return addCorsHeaders(response, allowedOrigin, !allowAny);
|
|
996
|
-
}
|
|
997
|
-
};
|
|
998
|
-
}
|
|
999
|
-
//#endregion
|
|
1000
|
-
export { assertResourcePathShape as a, createNoopRecorder as c, finalizeWireResponse as d, methodNotAllowed as f, oauthConfigurationErrorResponse as i, nowMs as l, createRequestAuthorizer as n, resolveProtectedResource as o, getOAuthRuntime as r, createRecorderForRuntime as s, evaluateCors as t, JSON_HEADERS as u };
|
|
951
|
+
export { resolveProtectedResource as a, nowMs as c, methodNotAllowed as d, corsPreflightResponse as f, assertResourcePathShape as i, JSON_HEADERS as l, getOAuthRuntime as n, createRecorderForRuntime as o, oauthConfigurationErrorResponse as r, createNoopRecorder as s, createRequestAuthorizer as t, finalizeWireResponse as u };
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const
|
|
3
|
-
const require_package = require("../package-DNSwCau1.cjs");
|
|
2
|
+
const require_package = require("../package-Xk8p8Q_E.cjs");
|
|
4
3
|
const require_fs_errors = require("../fs-errors-CWNzOV75.cjs");
|
|
5
4
|
let node_fs = require("node:fs");
|
|
6
5
|
let node_path = require("node:path");
|
|
7
6
|
let vite = require("vite");
|
|
8
7
|
let node_crypto = require("node:crypto");
|
|
8
|
+
let _modelcontextprotocol_sdk_server_zod_compat_js = require("@modelcontextprotocol/sdk/server/zod-compat.js");
|
|
9
|
+
let _modelcontextprotocol_sdk_server_zod_json_schema_compat_js = require("@modelcontextprotocol/sdk/server/zod-json-schema-compat.js");
|
|
9
10
|
//#region src/manifest/listing.ts
|
|
10
|
-
function
|
|
11
|
-
if (!
|
|
12
|
-
|
|
11
|
+
function shapeToJsonSchema(shape) {
|
|
12
|
+
if (!shape) return null;
|
|
13
|
+
try {
|
|
14
|
+
return (0, _modelcontextprotocol_sdk_server_zod_json_schema_compat_js.toJsonSchemaCompat)((0, _modelcontextprotocol_sdk_server_zod_compat_js.objectFromShape)(shape));
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
function buildMcpListing(mcp) {
|
|
15
20
|
return {
|
|
@@ -23,8 +28,8 @@ function buildMcpListing(mcp) {
|
|
|
23
28
|
title: tool.title,
|
|
24
29
|
description: tool.description,
|
|
25
30
|
annotations: tool.annotations,
|
|
26
|
-
inputSchema:
|
|
27
|
-
outputSchema:
|
|
31
|
+
inputSchema: shapeToJsonSchema(tool.inputSchema),
|
|
32
|
+
outputSchema: shapeToJsonSchema(tool.outputSchema)
|
|
28
33
|
}))
|
|
29
34
|
};
|
|
30
35
|
}
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as version } from "../package-CYA-5C24.js";
|
|
2
|
+
import { t as version } from "../package-DMs4EVwG.js";
|
|
4
3
|
import { t as isFileMissing } from "../fs-errors-PA2t1TIp.js";
|
|
5
4
|
import { lstatSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
5
|
import { dirname, resolve } from "node:path";
|
|
7
6
|
import { createServer, resolveConfig } from "vite";
|
|
8
7
|
import { randomUUID } from "node:crypto";
|
|
8
|
+
import { objectFromShape } from "@modelcontextprotocol/sdk/server/zod-compat.js";
|
|
9
|
+
import { toJsonSchemaCompat } from "@modelcontextprotocol/sdk/server/zod-json-schema-compat.js";
|
|
9
10
|
//#region src/manifest/listing.ts
|
|
10
|
-
function
|
|
11
|
-
if (!
|
|
12
|
-
|
|
11
|
+
function shapeToJsonSchema(shape) {
|
|
12
|
+
if (!shape) return null;
|
|
13
|
+
try {
|
|
14
|
+
return toJsonSchemaCompat(objectFromShape(shape));
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
13
18
|
}
|
|
14
19
|
function buildMcpListing(mcp) {
|
|
15
20
|
return {
|
|
@@ -23,8 +28,8 @@ function buildMcpListing(mcp) {
|
|
|
23
28
|
title: tool.title,
|
|
24
29
|
description: tool.description,
|
|
25
30
|
annotations: tool.annotations,
|
|
26
|
-
inputSchema:
|
|
27
|
-
outputSchema:
|
|
31
|
+
inputSchema: shapeToJsonSchema(tool.inputSchema),
|
|
32
|
+
outputSchema: shapeToJsonSchema(tool.outputSchema)
|
|
28
33
|
}))
|
|
29
34
|
};
|
|
30
35
|
}
|
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
//#region src/auth/context.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* auth context
|
|
2
|
+
/**
|
|
3
|
+
* The auth surface passed to every tool handler as its second argument. It wraps
|
|
4
|
+
* the verified per-request auth context in a private field, so the context — and
|
|
5
|
+
* the bearer token inside it — can't be read, enumerated, spread, or
|
|
6
|
+
* `JSON.stringify`'d off the instance; the accessors below are the only way out.
|
|
7
|
+
* `getToken()` is the single intentional escape hatch for the raw bearer.
|
|
8
|
+
*/
|
|
5
9
|
var ToolContext = class {
|
|
6
10
|
#auth;
|
|
7
|
-
|
|
8
|
-
#client;
|
|
9
|
-
#sendProgress;
|
|
10
|
-
constructor(auth, request = {}) {
|
|
11
|
+
constructor(auth) {
|
|
11
12
|
this.#auth = auth;
|
|
12
|
-
this.#signal = request.signal ?? NEVER_ABORTED;
|
|
13
|
-
this.#client = request.client ?? { protocol: "legacy" };
|
|
14
|
-
this.#sendProgress = request.sendProgress;
|
|
15
|
-
}
|
|
16
|
-
/** Aborts when the client cancels the request or disconnects. */
|
|
17
|
-
get signal() {
|
|
18
|
-
return this.#signal;
|
|
19
|
-
}
|
|
20
|
-
/** What the client declared about itself on this request. Unverified input. */
|
|
21
|
-
get client() {
|
|
22
|
-
return this.#client;
|
|
23
|
-
}
|
|
24
|
-
/** Send a progress notification for this call. A no-op when the client
|
|
25
|
-
* didn't request progress (no `progressToken` on the request). */
|
|
26
|
-
async progress(update) {
|
|
27
|
-
await this.#sendProgress?.(update);
|
|
28
13
|
}
|
|
29
14
|
/** Whether the in-flight tool call carries a verified auth context. */
|
|
30
15
|
isAuthenticated() {
|
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
//#region src/auth/context.ts
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* auth context
|
|
2
|
+
/**
|
|
3
|
+
* The auth surface passed to every tool handler as its second argument. It wraps
|
|
4
|
+
* the verified per-request auth context in a private field, so the context — and
|
|
5
|
+
* the bearer token inside it — can't be read, enumerated, spread, or
|
|
6
|
+
* `JSON.stringify`'d off the instance; the accessors below are the only way out.
|
|
7
|
+
* `getToken()` is the single intentional escape hatch for the raw bearer.
|
|
8
|
+
*/
|
|
5
9
|
var ToolContext = class {
|
|
6
10
|
#auth;
|
|
7
|
-
|
|
8
|
-
#client;
|
|
9
|
-
#sendProgress;
|
|
10
|
-
constructor(auth, request = {}) {
|
|
11
|
+
constructor(auth) {
|
|
11
12
|
this.#auth = auth;
|
|
12
|
-
this.#signal = request.signal ?? NEVER_ABORTED;
|
|
13
|
-
this.#client = request.client ?? { protocol: "legacy" };
|
|
14
|
-
this.#sendProgress = request.sendProgress;
|
|
15
|
-
}
|
|
16
|
-
/** Aborts when the client cancels the request or disconnects. */
|
|
17
|
-
get signal() {
|
|
18
|
-
return this.#signal;
|
|
19
|
-
}
|
|
20
|
-
/** What the client declared about itself on this request. Unverified input. */
|
|
21
|
-
get client() {
|
|
22
|
-
return this.#client;
|
|
23
|
-
}
|
|
24
|
-
/** Send a progress notification for this call. A no-op when the client
|
|
25
|
-
* didn't request progress (no `progressToken` on the request). */
|
|
26
|
-
async progress(update) {
|
|
27
|
-
await this.#sendProgress?.(update);
|
|
28
13
|
}
|
|
29
14
|
/** Whether the in-flight tool call carries a verified auth context. */
|
|
30
15
|
isAuthenticated() {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* proxy which *overwrites* the header (Lovable's web-proxy does), never by a
|
|
16
16
|
* bare SDK consumer.
|
|
17
17
|
* - `X-Forwarded-Proto` only selects http/https, so it is gated separately:
|
|
18
|
-
* Supabase
|
|
19
|
-
*
|
|
20
|
-
* Vite plugin emits the flag
|
|
18
|
+
* Supabase terminates TLS upstream and forwards over http with a
|
|
19
|
+
* gateway-stamped proto, so that stack always trusts it; the TanStack proxy
|
|
20
|
+
* does not sanitize proto, so its Vite plugin never emits the flag.
|
|
21
21
|
*/
|
|
22
22
|
function applyForwardedOrigin(request, options) {
|
|
23
23
|
const proto = options.trustForwardedProto ? firstForwardedValue(request, "x-forwarded-proto") : void 0;
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* proxy which *overwrites* the header (Lovable's web-proxy does), never by a
|
|
16
16
|
* bare SDK consumer.
|
|
17
17
|
* - `X-Forwarded-Proto` only selects http/https, so it is gated separately:
|
|
18
|
-
* Supabase
|
|
19
|
-
*
|
|
20
|
-
* Vite plugin emits the flag
|
|
18
|
+
* Supabase terminates TLS upstream and forwards over http with a
|
|
19
|
+
* gateway-stamped proto, so that stack always trusts it; the TanStack proxy
|
|
20
|
+
* does not sanitize proto, so its Vite plugin never emits the flag.
|
|
21
21
|
*/
|
|
22
22
|
function applyForwardedOrigin(request, options) {
|
|
23
23
|
const proto = options.trustForwardedProto ? firstForwardedValue(request, "x-forwarded-proto") : void 0;
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_logger = require("./logger-CN1q-KNn.cjs");
|
|
3
|
-
const
|
|
4
|
-
const require_errors = require("./errors-Cr95rSkB.cjs");
|
|
3
|
+
const require_errors = require("./errors-CN6Da8iz.cjs");
|
|
5
4
|
//#region src/core/define.ts
|
|
6
5
|
function assertUniqueNames(mcp) {
|
|
7
6
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -80,39 +79,6 @@ function freezeAuth(auth) {
|
|
|
80
79
|
if (auth.accessTokenTyp) Object.freeze(auth.accessTokenTyp);
|
|
81
80
|
Object.freeze(auth);
|
|
82
81
|
}
|
|
83
|
-
function assertAllowedOrigins(allowedOrigins) {
|
|
84
|
-
if (allowedOrigins === void 0 || allowedOrigins === "any") return;
|
|
85
|
-
if (!Array.isArray(allowedOrigins)) throw new Error(`@lovable.dev/mcp-js: allowedOrigins must be "any" or an array of exact origins`);
|
|
86
|
-
for (const origin of allowedOrigins) {
|
|
87
|
-
if (typeof origin !== "string") throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain strings`);
|
|
88
|
-
let parsed;
|
|
89
|
-
try {
|
|
90
|
-
parsed = new URL(origin);
|
|
91
|
-
} catch {
|
|
92
|
-
throw new Error(`@lovable.dev/mcp-js: allowedOrigins must contain valid exact origins`);
|
|
93
|
-
}
|
|
94
|
-
if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.origin !== origin) throw new Error(`@lovable.dev/mcp-js: allowedOrigins entry "${origin}" must be an exact http(s) origin without a path, query, fragment, or trailing slash`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function assertToolSchemas(mcp) {
|
|
98
|
-
for (const tool of mcp.tools) for (const [name, definition, strategy] of [[
|
|
99
|
-
"inputSchema",
|
|
100
|
-
tool.inputSchema,
|
|
101
|
-
"input"
|
|
102
|
-
], [
|
|
103
|
-
"outputSchema",
|
|
104
|
-
tool.outputSchema,
|
|
105
|
-
"output"
|
|
106
|
-
]]) {
|
|
107
|
-
if (!definition) continue;
|
|
108
|
-
try {
|
|
109
|
-
require_schema.jsonSchemaFromDefinition(definition, strategy);
|
|
110
|
-
} catch (error) {
|
|
111
|
-
const detail = error instanceof Error ? `: ${error.message}` : "";
|
|
112
|
-
throw new Error(`@lovable.dev/mcp-js: tool "${tool.name}" ${name} cannot be represented as JSON Schema${detail}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
82
|
/**
|
|
117
83
|
* Declare a single MCP tool. Import the result into your MCP definition's
|
|
118
84
|
* `tools` array — `defineMcp({ tools: [echoTool, ...] })`.
|
|
@@ -135,11 +101,8 @@ function defineMcp(def) {
|
|
|
135
101
|
assertNonEmptyString("version", def.version);
|
|
136
102
|
assertUniqueNames(def);
|
|
137
103
|
if (def.auth) assertOAuthConfig(def.auth);
|
|
138
|
-
assertAllowedOrigins(def.allowedOrigins);
|
|
139
|
-
assertToolSchemas(def);
|
|
140
104
|
require_logger.resolveMetricsConfig(def.metrics);
|
|
141
105
|
freezeAuth(def.auth);
|
|
142
|
-
if (Array.isArray(def.allowedOrigins)) Object.freeze(def.allowedOrigins);
|
|
143
106
|
Object.freeze(def.tools);
|
|
144
107
|
for (const tool of def.tools) Object.freeze(tool);
|
|
145
108
|
return def;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as McpAuthConfig, S as JwtClaims, _ as ZodRawShape, a as EmbeddedResource, b as MetricsOptions, c as McpDefinition, d as ResourceLinkIcon, f as TextContent, g as ToolHandlerResult, h as ToolDefinition, i as EmbeddedBlobResource, l as McpDefinitionInput, m as ToolContent, n as ContentAnnotations, o as EmbeddedTextResource, p as ToolAnnotations, r as ContentBlock, s as ImageContent, t as AudioContent, u as ResourceLink, v as ZodSchema, x as ToolContext, y as MetricsConfig } from "./types-C0Wgm9zp.cjs";
|
|
2
2
|
//#region src/core/define.d.ts
|
|
3
3
|
/**
|
|
4
4
|
* Declare a single MCP tool. Import the result into your MCP definition's
|
|
@@ -8,7 +8,7 @@ import { C as MetricsOptions, D as JwtClaims, E as ToolContext, O as McpAuthConf
|
|
|
8
8
|
* full `z.object(...)` — the MCP SDK builds the object wrapper internally
|
|
9
9
|
* and the raw shape is what the JSON-RPC `tools/list` payload exposes.
|
|
10
10
|
*/
|
|
11
|
-
declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends
|
|
11
|
+
declare function defineTool<TInput extends ZodRawShape | undefined = undefined, TOutput extends ZodRawShape | undefined = undefined>(def: ToolDefinition<TInput, TOutput>): ToolDefinition<TInput, TOutput>;
|
|
12
12
|
/**
|
|
13
13
|
* Declare the MCP server. `export default` the result from your MCP
|
|
14
14
|
* entrypoint (default `lib/mcp/index.ts`); the Vite plugin reads it to
|
|
@@ -71,4 +71,4 @@ type LogLevel = "silent" | "error" | "warn" | "info" | "debug";
|
|
|
71
71
|
*/
|
|
72
72
|
declare function setLogLevel(level: LogLevel): LogLevel;
|
|
73
73
|
//#endregion
|
|
74
|
-
export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type
|
|
74
|
+
export { type AudioContent, type ContentAnnotations, type ContentBlock, type EmbeddedBlobResource, type EmbeddedResource, type EmbeddedTextResource, type ImageContent, type IssuerOAuthOptions, type JwtClaims, type LogLevel, type McpDefinitionInput, type MetricsConfig, type MetricsOptions, type ResourceLink, type ResourceLinkIcon, type TextContent, type ToolAnnotations, type ToolContent, ToolContext, type ToolDefinition, ToolError, type ToolHandlerResult, type ZodRawShape, type ZodSchema, auth, defineMcp, defineTool, setLogLevel };
|