@nyuchi/mzizi-mcp 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/README.md +111 -39
  2. package/dist/auth/cors.d.ts +33 -0
  3. package/dist/auth/cors.d.ts.map +1 -0
  4. package/dist/auth/cors.js +110 -0
  5. package/dist/auth/cors.js.map +1 -0
  6. package/dist/auth/front.d.ts +8 -0
  7. package/dist/auth/front.d.ts.map +1 -1
  8. package/dist/auth/front.js +10 -0
  9. package/dist/auth/front.js.map +1 -1
  10. package/dist/auth/mcp-api-handler.d.ts +1 -1
  11. package/dist/auth/mcp-api-handler.d.ts.map +1 -1
  12. package/dist/auth/mcp-api-handler.js +4 -3
  13. package/dist/auth/mcp-api-handler.js.map +1 -1
  14. package/dist/auth/provider-options.d.ts +16 -0
  15. package/dist/auth/provider-options.d.ts.map +1 -0
  16. package/dist/auth/provider-options.js +21 -0
  17. package/dist/auth/provider-options.js.map +1 -0
  18. package/dist/env.d.ts +1 -0
  19. package/dist/env.d.ts.map +1 -1
  20. package/dist/floors.d.ts +117 -0
  21. package/dist/floors.d.ts.map +1 -0
  22. package/dist/floors.js +103 -0
  23. package/dist/floors.js.map +1 -0
  24. package/dist/generated/registry-pin.d.ts +8 -1
  25. package/dist/generated/registry-pin.d.ts.map +1 -1
  26. package/dist/generated/registry-pin.js +3 -1
  27. package/dist/generated/registry-pin.js.map +1 -1
  28. package/dist/generated/registry.d.ts +2 -2
  29. package/dist/generated/registry.js +198 -198
  30. package/dist/generated/registry.js.map +1 -1
  31. package/dist/generated/skills.d.ts +1 -1
  32. package/dist/generated/skills.js +13 -13
  33. package/dist/generated/skills.js.map +1 -1
  34. package/dist/http.d.ts +14 -4
  35. package/dist/http.d.ts.map +1 -1
  36. package/dist/http.js +38 -54
  37. package/dist/http.js.map +1 -1
  38. package/dist/origin.d.ts +68 -0
  39. package/dist/origin.d.ts.map +1 -0
  40. package/dist/origin.js +141 -0
  41. package/dist/origin.js.map +1 -0
  42. package/dist/rate-limit.d.ts +1 -1
  43. package/dist/rate-limit.d.ts.map +1 -1
  44. package/dist/rate-limit.js +3 -2
  45. package/dist/rate-limit.js.map +1 -1
  46. package/dist/server.d.ts +47 -3
  47. package/dist/server.d.ts.map +1 -1
  48. package/dist/server.js +14 -8
  49. package/dist/server.js.map +1 -1
  50. package/dist/tools.d.ts.map +1 -1
  51. package/dist/tools.js +115 -48
  52. package/dist/tools.js.map +1 -1
  53. package/dist/worker.d.ts.map +1 -1
  54. package/dist/worker.js +25 -11
  55. package/dist/worker.js.map +1 -1
  56. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/generated/skills.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/generated/skills.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts CHANGED
@@ -11,6 +11,15 @@
11
11
  import type { FundiToolContext } from "./fundi-client.js";
12
12
  import type { IssueDeskContext } from "./tools.js";
13
13
  import type { DocsFederationOptions } from "./docs-federation.js";
14
+ export { originRejection } from "./origin.js";
15
+ /**
16
+ * Add CORS headers: the caller's `Origin` echoed back when it was allowed (see
17
+ * `origin.ts`), never `*`. `Vary` is appended to, not replaced. Exported for
18
+ * tests only.
19
+ *
20
+ * @internal
21
+ */
22
+ export declare function withCors(response: Response, origin: string | null, allowed: boolean): Response;
14
23
  export interface HttpHandlerOptions {
15
24
  /** When set, expose the fundi trigger tool bound to the signed-in user. */
16
25
  fundi?: FundiToolContext;
@@ -26,12 +35,13 @@ export interface HttpHandlerOptions {
26
35
  /** Docs federation settings, or `false` for none. Defaults to docs.mzizi.dev. */
27
36
  docs?: DocsFederationOptions | false;
28
37
  /**
29
- * Restrict browser origins to these hostnames. Omitted (the default), any
30
- * `https` origin and localhost are allowed: see `originRejection`.
38
+ * Browser origins allowed to call the endpoint, by hostname, with the same
39
+ * scheme and port rules as the default list (see `origin.ts`). Omitted, the
40
+ * first-party sites and localhost. The Worker passes the default plus
41
+ * `MZIZI_ALLOWED_ORIGINS`.
31
42
  */
32
- allowedOrigins?: string[];
43
+ allowedOrigins?: readonly string[];
33
44
  }
34
- export declare function originRejection(request: Request, allowedOrigins?: readonly string[]): Response | undefined;
35
45
  /**
36
46
  * Build a fetch handler that serves the Mzizi MCP over Streamable HTTP, on the
37
47
  * official SDK (v2, `@modelcontextprotocol/server`).
@@ -1 +1 @@
1
- {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAUH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAqCjE,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,gBAAgB,CAAA;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9B,iFAAiF;IACjF,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;IACpC;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAiBD,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,CAa1G;AAiDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,kBAAuB,IAcxC,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAgClE"}
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAClD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAGjE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE7C;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,CAa9F;AAqBD,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,gBAAgB,CAAA;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9B,iFAAiF;IACjF,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;IACpC;;;;;OAKG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CACnC;AAiDD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,kBAAuB,IAcxC,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAsClE"}
package/dist/http.js CHANGED
@@ -8,17 +8,28 @@
8
8
  * anonymous (the free tier) or signed in (WorkOS AuthKit via the OAuth provider)
9
9
  * before it reaches this handler.
10
10
  */
11
- import { createMcpHandler, isLegacyRequest, localhostAllowedOrigins, originValidationResponse, WebStandardStreamableHTTPServerTransport, } from "@modelcontextprotocol/server";
11
+ import { createMcpHandler, isLegacyRequest, WebStandardStreamableHTTPServerTransport, } from "@modelcontextprotocol/server";
12
+ import { corsHeadersFor, forbiddenOrigin, isAllowedOrigin } from "./origin.js";
12
13
  import { createMziziMcpServer } from "./server.js";
13
- const CORS_HEADERS = {
14
- "Access-Control-Allow-Origin": "*",
15
- "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
16
- "Access-Control-Allow-Headers": "Content-Type, MCP-Protocol-Version, MCP-Session-Id, Mcp-Method, Mcp-Name, apikey",
17
- };
18
- function withCors(response) {
14
+ // Part of the public `./http` export since before 0.14.0; kept (same signature).
15
+ export { originRejection } from "./origin.js";
16
+ /**
17
+ * Add CORS headers: the caller's `Origin` echoed back when it was allowed (see
18
+ * `origin.ts`), never `*`. `Vary` is appended to, not replaced. Exported for
19
+ * tests only.
20
+ *
21
+ * @internal
22
+ */
23
+ export function withCors(response, origin, allowed) {
19
24
  const headers = new Headers(response.headers);
20
- for (const [key, value] of Object.entries(CORS_HEADERS))
21
- headers.set(key, value);
25
+ for (const [key, value] of Object.entries(corsHeadersFor(origin, allowed))) {
26
+ if (key === "Vary") {
27
+ if (!/(^|,)\s*origin\s*(,|$)/i.test(headers.get("Vary") ?? ""))
28
+ headers.append(key, value);
29
+ }
30
+ else
31
+ headers.set(key, value);
32
+ }
22
33
  return new Response(response.body, {
23
34
  status: response.status,
24
35
  statusText: response.statusText,
@@ -40,39 +51,6 @@ const OAUTH_DISCOVERY_PREFIXES = [
40
51
  function isOAuthDiscoveryPath(pathname) {
41
52
  return OAUTH_DISCOVERY_PREFIXES.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`));
42
53
  }
43
- /**
44
- * Origin validation (Streamable HTTP §Security: servers MUST validate `Origin`
45
- * and answer 403 to an invalid one).
46
- *
47
- * This is a PUBLIC server: it holds no cookies, answers anonymous callers by
48
- * design, and browser-based MCP clients on other sites (hosted inspectors, web
49
- * chat clients) used it before this check existed. So the default policy is
50
- * not an allowlist of sites. It refuses what DNS rebinding and mixed-content
51
- * abuse need: an `Origin` that does not parse (the opaque `null` included), and
52
- * a plain-`http` origin that is not localhost. Every `https` origin and
53
- * localhost pass, and so does a request with no `Origin` (every non-browser
54
- * client). Pass `allowedOrigins` to restrict to named hostnames instead.
55
- */
56
- const LOCALHOST_ORIGINS = localhostAllowedOrigins();
57
- export function originRejection(request, allowedOrigins) {
58
- if (allowedOrigins)
59
- return originValidationResponse(request, [...allowedOrigins]);
60
- const origin = request.headers.get("origin");
61
- if (!origin)
62
- return undefined;
63
- try {
64
- const url = new URL(origin);
65
- if (url.protocol === "https:")
66
- return undefined;
67
- if (url.protocol === "http:" && LOCALHOST_ORIGINS.includes(url.hostname))
68
- return undefined;
69
- }
70
- catch {
71
- // An unparseable origin (including the opaque "null") is refused below.
72
- }
73
- // Same shape as the SDK's own originValidationResponse.
74
- return originValidationResponse(request, [...LOCALHOST_ORIGINS]);
75
- }
76
54
  /**
77
55
  * Build a fetch handler that serves the Mzizi MCP over Streamable HTTP.
78
56
  * Stateless — each request creates a fresh transport + server pair.
@@ -141,32 +119,38 @@ export function createMziziHttpHandler(options = {}) {
141
119
  return transport.handleRequest(request);
142
120
  }
143
121
  return async function handle(request) {
122
+ const origin = request.headers.get("origin");
123
+ const allowed = isAllowedOrigin(origin, options.allowedOrigins);
124
+ const cors = (response) => withCors(response, origin, allowed);
125
+ // DNS-rebinding / cross-site defence (Streamable HTTP §Security): a
126
+ // request whose Origin is present and not on the allowlist is refused with
127
+ // 403 before anything else, preflight included, and before any server is
128
+ // built. No Origin header (every non-browser client) passes.
129
+ if (!allowed)
130
+ return cors(forbiddenOrigin(origin));
131
+ // (On the Worker the OAuth provider answers OPTIONS on /mcp itself, so this
132
+ // branch serves the embedded `./http` export; see the CHANGELOG, #295.)
144
133
  if (request.method === "OPTIONS") {
145
- return new Response(null, { status: 204, headers: CORS_HEADERS });
134
+ return cors(new Response(null, { status: 204 }));
146
135
  }
147
136
  // Answer auth-discovery probes with 404 so compliant MCP clients fall back
148
137
  // to anonymous access. Without this the request reaches the MCP handler,
149
138
  // which cannot answer a discovery GET with metadata, and clients abort the
150
139
  // connection instead of connecting unauthenticated.
151
140
  if (isOAuthDiscoveryPath(new URL(request.url).pathname)) {
152
- return withCors(new Response("Not Found", { status: 404 }));
141
+ return cors(new Response("Not Found", { status: 404 }));
153
142
  }
154
- // DNS-rebinding / cross-site defence (Streamable HTTP §Security): a
155
- // browser request from an origin that is not on the list is refused with
156
- // 403 before any server is built. No Origin header (every non-browser
157
- // client) passes.
158
- const rejected = originRejection(request, options.allowedOrigins);
159
- if (rejected)
160
- return withCors(rejected);
143
+ // Stateless: there is no standalone SSE stream to open and no session to
144
+ // end, so GET and DELETE are 405 rather than held-open connections.
161
145
  if (request.method !== "POST") {
162
- return withCors(Response.json({ jsonrpc: "2.0", id: null, error: { code: -32000, message: "Method not allowed. This server is stateless: send every request as a POST." } }, { status: 405, headers: { Allow: "POST, OPTIONS" } }));
146
+ return cors(Response.json({ jsonrpc: "2.0", id: null, error: { code: -32000, message: "Method not allowed. This server is stateless: send every request as a POST." } }, { status: 405, headers: { Allow: "POST, OPTIONS" } }));
163
147
  }
164
148
  if (await isLegacyRequest(request, undefined, { maxRequestBodySize: MAX_REQUEST_BODY })) {
165
- return withCors(await serveLegacy(request));
149
+ return cors(await serveLegacy(request));
166
150
  }
167
151
  // The per-request options ride to the shared handler's factory on authInfo,
168
152
  // which the SDK passes through untouched and never reads itself.
169
- return withCors(await modernHandler().fetch(request, { authInfo: carry(options) }));
153
+ return cors(await modernHandler().fetch(request, { authInfo: carry(options) }));
170
154
  };
171
155
  }
172
156
  //# sourceMappingURL=http.js.map
package/dist/http.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Browser `Origin` policy for the MCP endpoint (Streamable HTTP §Security, and
3
+ * the fix list in #295, P0 item 1).
4
+ *
5
+ * Servers MUST validate `Origin` against DNS rebinding and answer 403 to an
6
+ * invalid one. The policy:
7
+ *
8
+ * - no `Origin` header allowed: every non-browser client (the SDKs, curl,
9
+ * Claude, Cursor) sends none;
10
+ * - a present `Origin` allowed only if its host is on the list, otherwise
11
+ * 403 before any MCP server is built;
12
+ * - CORS `Access-Control-Allow-Origin` echoes an allowed
13
+ * `Origin` (with `Vary: Origin`). It is never `*`
14
+ * here; the public discovery documents are `*` (`auth/cors.ts`).
15
+ *
16
+ * The list is hostnames. A localhost name matches over `http` or `https` on any
17
+ * port (the MCP Inspector runs at http://localhost:6274). Every other name
18
+ * matches only over `https` on the default port, exactly: no subdomains, no
19
+ * `http`, no `:8443`. The same rule applies to a list the caller supplies.
20
+ */
21
+ /** The first-party sites: this Worker, the site, the docs and the console. */
22
+ export declare const ALLOWED_ORIGIN_HOSTS: readonly string[];
23
+ /** The default list: the first-party sites and localhost. */
24
+ export declare const DEFAULT_ALLOWED_HOSTS: readonly string[];
25
+ /**
26
+ * The default list plus the extra origins in `MZIZI_ALLOWED_ORIGINS`
27
+ * (comma-separated `https://host` origins; case and a trailing slash are
28
+ * tolerated). An entry that is not an `https` origin with no path, port or
29
+ * credentials is dropped with a `console.warn`, so a typo cannot open the
30
+ * endpoint wider than named. The result is cached per value, so the Worker pays
31
+ * for the parse once per isolate, not once per request.
32
+ */
33
+ export declare function allowedHostsFromEnv(env: {
34
+ MZIZI_ALLOWED_ORIGINS?: string;
35
+ }): readonly string[];
36
+ /**
37
+ * True when `origin` may call the endpoint. `null` (no header at all) is
38
+ * allowed; a header that is present is judged, so an empty value and the opaque
39
+ * `"null"` are refused like any other unparseable origin.
40
+ */
41
+ export declare function isAllowedOrigin(origin: string | null, hosts?: readonly string[]): boolean;
42
+ /** The 403 for a present-but-unlisted `Origin` (a JSON-RPC error body, like the SDK's own). */
43
+ export declare function forbiddenOrigin(origin: string | null): Response;
44
+ /** A 403 for a present-but-unlisted `Origin`, or undefined when the request may proceed. */
45
+ export declare function originRejection(request: Request, hosts?: readonly string[]): Response | undefined;
46
+ /** What a route's CORS answer advertises beyond the origin decision. */
47
+ export interface CorsPolicy {
48
+ readonly methods: string;
49
+ readonly headers: string;
50
+ /** Seconds a browser may cache a preflight; omitted when not set. */
51
+ readonly maxAge?: number;
52
+ }
53
+ /** The MCP endpoint (`/mcp`): its methods and the headers a Streamable HTTP client sends. */
54
+ export declare const MCP_CORS: CorsPolicy;
55
+ /** `/token` and `/register`: POST only, a form or JSON body, and client credentials in `Authorization`. */
56
+ export declare const OAUTH_ENDPOINT_CORS: CorsPolicy;
57
+ /**
58
+ * The CORS headers for a request whose `Origin` is `origin`, already judged
59
+ * `allowed`: the origin echoed back, never `*`. No `Origin`, or one that is not
60
+ * allowed, gets no `Access-Control-Allow-Origin`; `Vary: Origin` is always
61
+ * present so a cache cannot hand one origin's answer to another. Merge `Vary`
62
+ * with `Headers.append`, not `set`. No `Access-Control-Allow-Credentials`: no
63
+ * route reads a cookie cross-origin.
64
+ */
65
+ export declare function corsHeadersFor(origin: string | null, allowed: boolean, policy?: CorsPolicy): Record<string, string>;
66
+ /** `corsHeadersFor`, judging the request's own `Origin` against `hosts`. */
67
+ export declare function corsHeaders(request: Request, hosts?: readonly string[]): Record<string, string>;
68
+ //# sourceMappingURL=origin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.d.ts","sourceRoot":"","sources":["../src/origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAOH,8EAA8E;AAC9E,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAMjD,CAAA;AAED,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAA8C,CAAA;AAIjG;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE;IAAE,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,MAAM,EAAE,CAsB9F;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,GAAE,SAAS,MAAM,EAA0B,GAAG,OAAO,CAahH;AAED,+FAA+F;AAC/F,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAK/D;AAED,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,CAGjG;AAED,wEAAwE;AACxE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,qEAAqE;IACrE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,6FAA6F;AAC7F,eAAO,MAAM,QAAQ,EAAE,UAGtB,CAAA;AAED,2GAA2G;AAC3G,eAAO,MAAM,mBAAmB,EAAE,UAIjC,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAE,UAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAS7H;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG/F"}
package/dist/origin.js ADDED
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Browser `Origin` policy for the MCP endpoint (Streamable HTTP §Security, and
3
+ * the fix list in #295, P0 item 1).
4
+ *
5
+ * Servers MUST validate `Origin` against DNS rebinding and answer 403 to an
6
+ * invalid one. The policy:
7
+ *
8
+ * - no `Origin` header allowed: every non-browser client (the SDKs, curl,
9
+ * Claude, Cursor) sends none;
10
+ * - a present `Origin` allowed only if its host is on the list, otherwise
11
+ * 403 before any MCP server is built;
12
+ * - CORS `Access-Control-Allow-Origin` echoes an allowed
13
+ * `Origin` (with `Vary: Origin`). It is never `*`
14
+ * here; the public discovery documents are `*` (`auth/cors.ts`).
15
+ *
16
+ * The list is hostnames. A localhost name matches over `http` or `https` on any
17
+ * port (the MCP Inspector runs at http://localhost:6274). Every other name
18
+ * matches only over `https` on the default port, exactly: no subdomains, no
19
+ * `http`, no `:8443`. The same rule applies to a list the caller supplies.
20
+ */
21
+ import { localhostAllowedOrigins } from "@modelcontextprotocol/server";
22
+ /** Hostnames that count as local development. */
23
+ const LOCAL_HOSTS = localhostAllowedOrigins();
24
+ /** The first-party sites: this Worker, the site, the docs and the console. */
25
+ export const ALLOWED_ORIGIN_HOSTS = [
26
+ "mzizi.dev",
27
+ "www.mzizi.dev",
28
+ "docs.mzizi.dev",
29
+ "app.mzizi.dev",
30
+ "mcp.mzizi.dev",
31
+ ];
32
+ /** The default list: the first-party sites and localhost. */
33
+ export const DEFAULT_ALLOWED_HOSTS = [...ALLOWED_ORIGIN_HOSTS, ...LOCAL_HOSTS];
34
+ const hostsCache = new Map();
35
+ /**
36
+ * The default list plus the extra origins in `MZIZI_ALLOWED_ORIGINS`
37
+ * (comma-separated `https://host` origins; case and a trailing slash are
38
+ * tolerated). An entry that is not an `https` origin with no path, port or
39
+ * credentials is dropped with a `console.warn`, so a typo cannot open the
40
+ * endpoint wider than named. The result is cached per value, so the Worker pays
41
+ * for the parse once per isolate, not once per request.
42
+ */
43
+ export function allowedHostsFromEnv(env) {
44
+ const raw = env.MZIZI_ALLOWED_ORIGINS;
45
+ if (!raw)
46
+ return DEFAULT_ALLOWED_HOSTS;
47
+ const cached = hostsCache.get(raw);
48
+ if (cached)
49
+ return cached;
50
+ const extra = [];
51
+ for (const entry of raw.split(",")) {
52
+ const value = entry.trim().replace(/\/$/, "").toLowerCase();
53
+ if (!value)
54
+ continue;
55
+ let host;
56
+ try {
57
+ const url = new URL(value);
58
+ if (url.protocol === "https:" && url.origin === value && url.port === "")
59
+ host = url.hostname;
60
+ }
61
+ catch {
62
+ // Not an origin: dropped below.
63
+ }
64
+ if (host)
65
+ extra.push(host);
66
+ else
67
+ console.warn(`mzizi-mcp: MZIZI_ALLOWED_ORIGINS entry ignored (not a plain https origin): ${entry.trim()}`);
68
+ }
69
+ const hosts = [...DEFAULT_ALLOWED_HOSTS, ...extra];
70
+ hostsCache.set(raw, hosts);
71
+ return hosts;
72
+ }
73
+ /**
74
+ * True when `origin` may call the endpoint. `null` (no header at all) is
75
+ * allowed; a header that is present is judged, so an empty value and the opaque
76
+ * `"null"` are refused like any other unparseable origin.
77
+ */
78
+ export function isAllowedOrigin(origin, hosts = DEFAULT_ALLOWED_HOSTS) {
79
+ if (origin === null)
80
+ return true;
81
+ let url;
82
+ try {
83
+ url = new URL(origin);
84
+ }
85
+ catch {
86
+ return false;
87
+ }
88
+ // An Origin is scheme://host[:port] and nothing else.
89
+ if (url.origin !== origin)
90
+ return false;
91
+ if (!hosts.includes(url.hostname))
92
+ return false;
93
+ if (LOCAL_HOSTS.includes(url.hostname))
94
+ return url.protocol === "http:" || url.protocol === "https:";
95
+ return url.protocol === "https:" && url.port === "";
96
+ }
97
+ /** The 403 for a present-but-unlisted `Origin` (a JSON-RPC error body, like the SDK's own). */
98
+ export function forbiddenOrigin(origin) {
99
+ return Response.json({ jsonrpc: "2.0", id: null, error: { code: -32000, message: `Invalid Origin header: ${origin ?? ""}` } }, { status: 403, headers: { Vary: "Origin" } });
100
+ }
101
+ /** A 403 for a present-but-unlisted `Origin`, or undefined when the request may proceed. */
102
+ export function originRejection(request, hosts) {
103
+ const origin = request.headers.get("origin");
104
+ return isAllowedOrigin(origin, hosts) ? undefined : forbiddenOrigin(origin);
105
+ }
106
+ /** The MCP endpoint (`/mcp`): its methods and the headers a Streamable HTTP client sends. */
107
+ export const MCP_CORS = {
108
+ methods: "GET, POST, DELETE, OPTIONS",
109
+ headers: "Content-Type, MCP-Protocol-Version, MCP-Session-Id, Mcp-Method, Mcp-Name, apikey",
110
+ };
111
+ /** `/token` and `/register`: POST only, a form or JSON body, and client credentials in `Authorization`. */
112
+ export const OAUTH_ENDPOINT_CORS = {
113
+ methods: "POST, OPTIONS",
114
+ headers: "Content-Type, Authorization",
115
+ maxAge: 600,
116
+ };
117
+ /**
118
+ * The CORS headers for a request whose `Origin` is `origin`, already judged
119
+ * `allowed`: the origin echoed back, never `*`. No `Origin`, or one that is not
120
+ * allowed, gets no `Access-Control-Allow-Origin`; `Vary: Origin` is always
121
+ * present so a cache cannot hand one origin's answer to another. Merge `Vary`
122
+ * with `Headers.append`, not `set`. No `Access-Control-Allow-Credentials`: no
123
+ * route reads a cookie cross-origin.
124
+ */
125
+ export function corsHeadersFor(origin, allowed, policy = MCP_CORS) {
126
+ const headers = { Vary: "Origin" };
127
+ if (origin && allowed) {
128
+ headers["Access-Control-Allow-Origin"] = origin;
129
+ headers["Access-Control-Allow-Methods"] = policy.methods;
130
+ headers["Access-Control-Allow-Headers"] = policy.headers;
131
+ if (policy.maxAge !== undefined)
132
+ headers["Access-Control-Max-Age"] = String(policy.maxAge);
133
+ }
134
+ return headers;
135
+ }
136
+ /** `corsHeadersFor`, judging the request's own `Origin` against `hosts`. */
137
+ export function corsHeaders(request, hosts) {
138
+ const origin = request.headers.get("origin");
139
+ return corsHeadersFor(origin, isAllowedOrigin(origin, hosts));
140
+ }
141
+ //# sourceMappingURL=origin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"origin.js","sourceRoot":"","sources":["../src/origin.ts"],"names":[],"mappings":"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"}
@@ -37,5 +37,5 @@ export declare function clientKey(request: Request): string;
37
37
  * The body is a JSON-RPC error so an MCP client can show it, and it names the
38
38
  * way past the limit: signing in.
39
39
  */
40
- export declare function limitAnonymous(limiter: RateLimiter | undefined, request: Request): Promise<Response | null>;
40
+ export declare function limitAnonymous(limiter: RateLimiter | undefined, request: Request, allowedHosts?: readonly string[]): Promise<Response | null>;
41
41
  //# sourceMappingURL=rate-limit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAuB1B"}
1
+ {"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,sEAAsE;AACtE,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,CAAC,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAChE,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAElD;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,OAAO,EAAE,OAAO,EAChB,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,GAC/B,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAuB1B"}
@@ -16,6 +16,7 @@
16
16
  * free tier down with a missing binding, and the limit is a guard, not a gate.
17
17
  */
18
18
  import { ANONYMOUS_RATE_LIMIT, SIGN_IN_MCP_URL } from "./access.js";
19
+ import { corsHeaders } from "./origin.js";
19
20
  /**
20
21
  * The key for one client: the connecting IP Cloudflare reports.
21
22
  *
@@ -32,7 +33,7 @@ export function clientKey(request) {
32
33
  * The body is a JSON-RPC error so an MCP client can show it, and it names the
33
34
  * way past the limit: signing in.
34
35
  */
35
- export async function limitAnonymous(limiter, request) {
36
+ export async function limitAnonymous(limiter, request, allowedHosts) {
36
37
  if (!limiter)
37
38
  return null;
38
39
  const { success } = await limiter.limit({ key: clientKey(request) });
@@ -51,7 +52,7 @@ export async function limitAnonymous(limiter, request) {
51
52
  headers: {
52
53
  "Content-Type": "application/json",
53
54
  "Retry-After": String(periodSeconds),
54
- "Access-Control-Allow-Origin": "*",
55
+ ...corsHeaders(request, allowedHosts),
55
56
  },
56
57
  });
57
58
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAOpE;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgC,EAChC,OAAgB;IAEhB,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrE,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAAC;IACtD,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;QACb,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,KAAK;YACZ,OAAO,EAAE,iDAAiD,KAAK,QAAQ,aAAa,iEAAiE,eAAe,gBAAgB;SACrL;KACF,CAAC,EACF;QACE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;YACpC,6BAA6B,EAAE,GAAG;SACnC;KACF,CACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO1C;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,SAAS,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAgC,EAChC,OAAgB,EAChB,YAAgC;IAEhC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACrE,IAAI,OAAO;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,oBAAoB,CAAC;IACtD,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;QACb,OAAO,EAAE,KAAK;QACd,EAAE,EAAE,IAAI;QACR,KAAK,EAAE;YACL,IAAI,EAAE,CAAC,KAAK;YACZ,OAAO,EAAE,iDAAiD,KAAK,QAAQ,aAAa,iEAAiE,eAAe,gBAAgB;SACrL;KACF,CAAC,EACF;QACE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,MAAM,CAAC,aAAa,CAAC;YACpC,GAAG,WAAW,CAAC,OAAO,EAAE,YAAY,CAAC;SACtC;KACF,CACF,CAAC;AACJ,CAAC"}
package/dist/server.d.ts CHANGED
@@ -12,11 +12,12 @@
12
12
  * whatever the docs server lists.
13
13
  */
14
14
  import { McpServer } from "@modelcontextprotocol/server";
15
- import type { Registry } from "./registry.js";
15
+ import { type Registry } from "./registry.js";
16
+ import { floorsOf } from "./floors.js";
16
17
  import { type DocsFederationOptions } from "./docs-federation.js";
17
18
  import type { FundiToolContext } from "./fundi-client.js";
18
19
  import { type IssueDeskContext } from "./tools.js";
19
- export declare const MZIZI_MCP_VERSION = "0.14.0";
20
+ export declare const MZIZI_MCP_VERSION = "0.16.0";
20
21
  export type CreateServerOptions = {
21
22
  fundi?: FundiToolContext;
22
23
  /** The signed-in user's issue desk. See `tools.ts` — absent off the Worker. */
@@ -39,7 +40,7 @@ export type CreateServerOptions = {
39
40
  * hand-maintained fourth copy is how the old `mcp_tool_registry` drifted from
40
41
  * the tools it claimed to describe.
41
42
  */
42
- export declare function describeTools(registered: string[]): {
43
+ export declare function describeTools(registered: string[], floors?: Awaited<ReturnType<typeof floorsOf>>): {
43
44
  version: string;
44
45
  source: {
45
46
  registry: string;
@@ -57,6 +58,27 @@ export declare function describeTools(registered: string[]): {
57
58
  };
58
59
  rateLimit: string;
59
60
  };
61
+ floors: {
62
+ spacing: null;
63
+ hitAreaPx: number | null;
64
+ note: string;
65
+ } | {
66
+ source: string;
67
+ meaning: {
68
+ readonly insetPx: "Padding between text and the edge of its container.";
69
+ readonly controlGapPx: "Gap between adjacent interactive controls, visible edge to visible edge. Hit regions may touch, never overlap.";
70
+ readonly labelGapPx: "Gap between a label and its field.";
71
+ readonly itemGapPx: "Gap between sibling items in a list, grid or toolbar.";
72
+ readonly leadingBody: "Body line height (WCAG 1.4.12). Headings keep their own leading.";
73
+ };
74
+ enforcement: "A base-layer rule in the registry's token layer gives every element the floor even when you add no padding or gap; the token test fails a component spec below it; each component contract asserts its spacing minimums (TypeScript and Rust agree); a rendered geometry guard checks neighbouring controls, text inset and WCAG 1.4.12 stress; `mzizi check` (@nyuchi/mzizi-cli 0.8.0 or later) fails a project's CSS or TSX that goes under it, and `mzizi_check_accessibility` checks values you pass it.";
75
+ nothingGoesUnder: "No brand pack, density layer, component or app may lower a floor. `data-mzizi-sizes=\"legacy\"` on the root is the one opt-out, and it steps out of the other Bundu floors too.";
76
+ whatToDo: "Use the components and the tokens (--inset-floor, --gap-floor, --leading-floor). Never write p-0, gap-0, a negative margin or leading-none on a text container or a row of controls without an exception comment: `mzizi-spacing-exempt: <reason>`.";
77
+ spacing: import("./floors.js").SpacingFloor;
78
+ customProperties: Record<keyof import("./floors.js").SpacingFloor, string>;
79
+ hitAreaPx: number | null;
80
+ note?: undefined;
81
+ } | null;
60
82
  skills: {
61
83
  version: string;
62
84
  tool: string;
@@ -93,6 +115,7 @@ export declare function describeTools(registered: string[]): {
93
115
  export declare function mziziToolCatalogue(opts?: {
94
116
  fundi?: boolean;
95
117
  docs?: DocsFederationOptions | false;
118
+ registry?: () => Promise<Registry>;
96
119
  }): Promise<{
97
120
  version: string;
98
121
  source: {
@@ -111,6 +134,27 @@ export declare function mziziToolCatalogue(opts?: {
111
134
  };
112
135
  rateLimit: string;
113
136
  };
137
+ floors: {
138
+ spacing: null;
139
+ hitAreaPx: number | null;
140
+ note: string;
141
+ } | {
142
+ source: string;
143
+ meaning: {
144
+ readonly insetPx: "Padding between text and the edge of its container.";
145
+ readonly controlGapPx: "Gap between adjacent interactive controls, visible edge to visible edge. Hit regions may touch, never overlap.";
146
+ readonly labelGapPx: "Gap between a label and its field.";
147
+ readonly itemGapPx: "Gap between sibling items in a list, grid or toolbar.";
148
+ readonly leadingBody: "Body line height (WCAG 1.4.12). Headings keep their own leading.";
149
+ };
150
+ enforcement: "A base-layer rule in the registry's token layer gives every element the floor even when you add no padding or gap; the token test fails a component spec below it; each component contract asserts its spacing minimums (TypeScript and Rust agree); a rendered geometry guard checks neighbouring controls, text inset and WCAG 1.4.12 stress; `mzizi check` (@nyuchi/mzizi-cli 0.8.0 or later) fails a project's CSS or TSX that goes under it, and `mzizi_check_accessibility` checks values you pass it.";
151
+ nothingGoesUnder: "No brand pack, density layer, component or app may lower a floor. `data-mzizi-sizes=\"legacy\"` on the root is the one opt-out, and it steps out of the other Bundu floors too.";
152
+ whatToDo: "Use the components and the tokens (--inset-floor, --gap-floor, --leading-floor). Never write p-0, gap-0, a negative margin or leading-none on a text container or a row of controls without an exception comment: `mzizi-spacing-exempt: <reason>`.";
153
+ spacing: import("./floors.js").SpacingFloor;
154
+ customProperties: Record<keyof import("./floors.js").SpacingFloor, string>;
155
+ hitAreaPx: number | null;
156
+ note?: undefined;
157
+ } | null;
114
158
  skills: {
115
159
  version: string;
116
160
  tool: string;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAoB,MAAM,8BAA8B,CAAC;AAG3E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAE7C,OAAO,EAAmC,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAkD,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAIlG,eAAO,MAAM,iBAAiB,WAAW,CAAA;AAEzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,gBAAgB,CAAA;IACvB,yFAAyF;IACzF,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9B,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;CACrC,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BjD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAU5G;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkF7D;AAED,wBAAsB,oBAAoB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAsE7F"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAoB,MAAM,8BAA8B,CAAC;AAG3E,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAA;AAE1D,OAAO,EAAmC,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAClG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,EAAkD,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAIlG,eAAO,MAAM,iBAAiB,WAAW,CAAA;AAEzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,CAAC,EAAE,gBAAgB,CAAA;IACxB,+EAA+E;IAC/E,IAAI,CAAC,EAAE,gBAAgB,CAAA;IACvB,yFAAyF;IACzF,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9B,uFAAuF;IACvF,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;IAClC,sEAAsE;IACtE,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAA;CACrC,CAAA;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmChG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,qBAAqB,GAAG,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAA;CAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAWzG;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAkF7D;AAED,wBAAsB,oBAAoB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAsE7F"}