@polyxd/mcp 0.4.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/dist/check.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Validation and static verification, reported for a model that has to fix what it wrote: each
3
+ * issue carries its JSON Pointer, the component it is in, and a hint saying what to change.
4
+ */
5
+ import { validateDocument, directionRules } from "@polyxd/spec/browser";
6
+ import { staticAudit } from "@polyxd/verifier/static";
7
+ import { componentDefinitions, componentNamed, exampleDirections } from "./spec.js";
8
+ /** The document with host data merged in: data given separately wins over the document's own. */
9
+ export function withData(document, data) {
10
+ if (data === undefined || !document || typeof document !== "object" || Array.isArray(document))
11
+ return document;
12
+ return { ...document, data };
13
+ }
14
+ function valueAt(doc, pointer) {
15
+ let cur = doc;
16
+ for (const part of pointer.replace(/^\//, "").split("/").filter(Boolean)) {
17
+ if (cur === null || typeof cur !== "object")
18
+ return undefined;
19
+ cur = cur[part.replace(/~1/g, "/").replace(/~0/g, "~")];
20
+ }
21
+ return cur;
22
+ }
23
+ function componentAt(doc, pointer) {
24
+ const m = /^\/components\/(\d+)/.exec(pointer);
25
+ if (!m)
26
+ return undefined;
27
+ const c = valueAt(doc, `/components/${m[1]}`);
28
+ if (!c || typeof c !== "object")
29
+ return undefined;
30
+ // No keys set to undefined: the reports are tool results, checked against the tools' output schemas.
31
+ return { ...(typeof c.id === "string" ? { id: c.id } : {}), ...(typeof c.component === "string" ? { type: c.component } : {}) };
32
+ }
33
+ function distance(a, b) {
34
+ const d = Array.from({ length: a.length + 1 }, (_, i) => [i, ...Array(b.length).fill(0)]);
35
+ for (let j = 1; j <= b.length; j++)
36
+ d[0][j] = j;
37
+ for (let i = 1; i <= a.length; i++) {
38
+ for (let j = 1; j <= b.length; j++) {
39
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1));
40
+ // A swapped pair of letters is one typo, not two.
41
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1])
42
+ d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
43
+ }
44
+ }
45
+ return d[a.length][b.length];
46
+ }
47
+ function closest(word, options) {
48
+ const lower = word.toLowerCase();
49
+ const scored = options.map((o) => ({ o, d: o.toLowerCase().includes(lower) || lower.includes(o.toLowerCase()) ? 1 : distance(lower, o.toLowerCase()) }));
50
+ scored.sort((a, b) => a.d - b.d);
51
+ return scored[0] && scored[0].d <= Math.max(2, Math.floor(word.length / 3)) ? scored[0].o : undefined;
52
+ }
53
+ const generated = () => componentDefinitions().filter((c) => !c.shell).map((c) => c.name);
54
+ const propsOf = (type) => {
55
+ const def = type ? componentNamed(type) : undefined;
56
+ return def ? Object.keys(def.props).map((p) => (def.required.includes(p) ? `${p}*` : p)).join(", ") : undefined;
57
+ };
58
+ /** A hint for each kind of issue the validator and the verifier report. */
59
+ export function hintFor(doc, issue) {
60
+ const { message, at } = issue;
61
+ const type = componentAt(doc, at)?.type;
62
+ let m = null;
63
+ if (issue.code === "data:missing-path")
64
+ return "Add the value to data at this pointer, or point at a field the data has. A binding that reads nothing shows a blank.";
65
+ if (/unknown or missing component type/.test(message) || (m = /unknown component "(.+)"/.exec(message))) {
66
+ const given = valueAt(doc, at)?.component ?? m?.[1];
67
+ const guess = typeof given === "string" ? closest(given, generated()) : undefined;
68
+ return `${guess ? `Did you mean "${guess}"? ` : ""}Set "component" to one of: ${generated().join(", ")}.`;
69
+ }
70
+ if ((m = /unknown property "(.+)"/.exec(message))) {
71
+ const props = propsOf(type);
72
+ return `Remove "${m[1]}".${props ? ` ${type} takes: ${props} (* = required).` : ""}`;
73
+ }
74
+ if ((m = /must have required property '(.+)'/.exec(message))) {
75
+ const props = propsOf(type);
76
+ return `Add "${m[1]}".${props ? ` ${type} takes: ${props} (* = required).` : ""} polyxd_components gives the full definition.`;
77
+ }
78
+ if (/must be equal to one of the allowed values/.test(message))
79
+ return "Use one of the values the component's definition lists (polyxd_components).";
80
+ if (/must be (string|number|boolean|object|array|integer)/.test(message))
81
+ return "Check the prop's type in the component's definition (polyxd_components); a bound value is {\"path\": \"/pointer\"}.";
82
+ if (/duplicate id/.test(message))
83
+ return "Give every component its own id.";
84
+ if (/^root .* is not a component id/.test(message))
85
+ return "Set \"root\" to the id of the outermost component.";
86
+ if (/references unknown component/.test(message))
87
+ return "Add a component with that id to \"components\", or remove the reference. Children are id strings, never nested objects.";
88
+ if (/references itself|^cycle:/.test(message))
89
+ return "A component cannot contain itself; break the loop.";
90
+ if (/must reference/.test(message))
91
+ return "Point this prop at a component of the kind it names.";
92
+ if (/already has parent/.test(message))
93
+ return "A component can appear in one place only. Make a copy with a new id for the second place.";
94
+ if (/is not a renderer action/.test(message))
95
+ return "Names starting with \"ui.\" are reserved for the renderer. Name your action \"domain.verb\", like \"task.save\".";
96
+ if (/placeholders are only for search/.test(message))
97
+ return "Remove the placeholder; put guidance in \"help\" instead.";
98
+ if (/needs alt text/.test(message))
99
+ return "Add \"alt\", or set \"decorative\": true if the image carries no information.";
100
+ if (/not reachable from root/.test(message))
101
+ return "Add its id to a parent's children, or remove the component.";
102
+ if (/primary actions? visible at once/.test(message))
103
+ return "Keep one primary action per view: set \"emphasis\": \"secondary\" on the others, or move them to another step.";
104
+ if (/must point at a list/.test(message))
105
+ return "Point at an array in data.";
106
+ if (/relative path .* used outside a repeated item/.test(message))
107
+ return "Start the path with \"/\" to read from the top of data. Relative paths are only for inside a Collection, Table, Chart or Comparison item.";
108
+ if (/inputs? per view|more than \d+ inputs/.test(message))
109
+ return "Split the inputs across Steps, at most 6 per view.";
110
+ return undefined;
111
+ }
112
+ /** Reads an absolute JSON Pointer ("/a/0/b") in data; anything else is undefined. */
113
+ function readPointer(data, pointer) {
114
+ if (!pointer.startsWith("/"))
115
+ return undefined;
116
+ let at = data;
117
+ for (const raw of pointer.slice(1).split("/")) {
118
+ const key = raw.replace(/~1/g, "/").replace(/~0/g, "~");
119
+ if (at == null || typeof at !== "object")
120
+ return undefined;
121
+ at = at[key];
122
+ }
123
+ return at;
124
+ }
125
+ /**
126
+ * A "percent" format takes a fraction (0.12 is 12%). Models often write the percentage itself, which
127
+ * shows as "1,200%". Warn wherever a percent-formatted value, literal or bound by an absolute path, is
128
+ * bigger than 1.5: a real 150%+ is rare, a mistaken 12 is common.
129
+ */
130
+ function percentWarnings(doc) {
131
+ const out = [];
132
+ const components = Array.isArray(doc?.components) ? doc.components : [];
133
+ const visit = (node, pointer, component) => {
134
+ if (!node || typeof node !== "object")
135
+ return;
136
+ if (node.format?.type === "percent" && "value" in node) {
137
+ const v = node.value;
138
+ const n = typeof v === "number" ? v : v && typeof v.path === "string" ? readPointer(doc.data, v.path) : undefined;
139
+ if (typeof n === "number" && Math.abs(n) > 1.5) {
140
+ const shown = new Intl.NumberFormat("en-GB", { style: "percent", maximumFractionDigits: 1 }).format(n);
141
+ out.push({
142
+ severity: "warning",
143
+ pointer: `${pointer}/value`,
144
+ ...(component ? { component } : {}),
145
+ message: `a "percent" format shows ${n} as "${shown}"`,
146
+ hint: `"percent" takes a fraction. For ${n}%, store ${Number((n / 100).toFixed(6))}${typeof v === "number" ? "" : ` at ${v.path}`}.`,
147
+ });
148
+ }
149
+ }
150
+ for (const [k, child] of Object.entries(node))
151
+ if (child && typeof child === "object" && k !== "format")
152
+ visit(child, `${pointer}/${k}`, component);
153
+ };
154
+ components.forEach((c, i) => {
155
+ const component = { ...(typeof c?.id === "string" ? { id: c.id } : {}), ...(typeof c?.component === "string" ? { type: c.component } : {}) };
156
+ visit(c, `/components/${i}`, Object.keys(component).length ? component : undefined);
157
+ });
158
+ return out;
159
+ }
160
+ export function validate(document, data) {
161
+ const doc = withData(document, data);
162
+ const result = validateDocument(doc);
163
+ const issues = result.issues.map((i) => {
164
+ const component = componentAt(doc, i.at);
165
+ const hint = hintFor(doc, i);
166
+ return { severity: i.severity, pointer: i.at, ...(component ? { component } : {}), message: i.message, ...(hint ? { hint } : {}) };
167
+ });
168
+ issues.push(...percentWarnings(doc));
169
+ const errors = issues.filter((i) => i.severity === "error").length;
170
+ return { valid: errors === 0, errors, warnings: issues.length - errors, issues };
171
+ }
172
+ const where = (i) => `${i.pointer}${i.component?.id || i.component?.type ? ` (${[i.component.type, i.component.id && `"${i.component.id}"`].filter(Boolean).join(" ")})` : ""}`;
173
+ export function formatValidation(r) {
174
+ const head = r.valid
175
+ ? `Valid${r.warnings ? `, with ${r.warnings} warning${r.warnings === 1 ? "" : "s"}` : ""}.`
176
+ : `Not valid: ${r.errors} error${r.errors === 1 ? "" : "s"}${r.warnings ? ` and ${r.warnings} warning${r.warnings === 1 ? "" : "s"}` : ""}. Fix the errors and validate again.`;
177
+ const lines = r.issues.map((i) => `- ${i.severity} at ${where(i)}: ${i.message}${i.hint ? `\n Fix: ${i.hint}` : ""}`);
178
+ return [head, ...lines].join("\n");
179
+ }
180
+ /** A Design Direction by example name, or the object itself. */
181
+ export function resolveDirection(direction) {
182
+ if (typeof direction !== "string")
183
+ return direction;
184
+ const found = exampleDirections().find((d) => d.name === direction);
185
+ if (!found)
186
+ throw new Error(`No example Design Direction named "${direction}". Known: ${exampleDirections().map((d) => d.name).join(", ")}. Or pass the direction object itself.`);
187
+ return JSON.parse(found.json);
188
+ }
189
+ export function verify(document, opts = {}) {
190
+ const doc = withData(document, opts.data);
191
+ const direction = opts.direction === undefined ? undefined : resolveDirection(opts.direction);
192
+ const rules = direction ? directionRules(direction) : undefined;
193
+ const findings = staticAudit(doc, { rules, emphasisBudget: direction?.profile?.emphasisBudget, registry: opts.registry }).map((f) => {
194
+ // Findings from the validator carry "<pointer>: <message>"; the same hints apply.
195
+ const m = /^(\/[^:]*|\/): (.*)$/.exec(f.message);
196
+ const hint = m ? hintFor(doc, { at: m[1], message: m[2], code: f.check }) : undefined;
197
+ // A direction passed as an object is not schema-checked, so its rules' severities are taken as error or warning.
198
+ const severity = f.severity === "error" ? "error" : "warning";
199
+ return { severity, check: f.check, message: f.message, ...(hint ? { hint } : {}) };
200
+ });
201
+ const errors = findings.filter((f) => f.severity === "error").length;
202
+ const name = typeof direction?.name === "string" ? direction.name : undefined;
203
+ return { errors, warnings: findings.length - errors, findings, ...(name ? { direction: name } : {}), rules: rules?.length ?? 0 };
204
+ }
205
+ export function formatVerify(r) {
206
+ const scope = r.direction ? ` against Design Direction "${r.direction}" (${r.rules} rules)` : "";
207
+ const head = r.errors
208
+ ? `Fails${scope}: ${r.errors} error${r.errors === 1 ? "" : "s"}, ${r.warnings} warning${r.warnings === 1 ? "" : "s"}.`
209
+ : `Passes${scope}: no errors${r.warnings ? `, ${r.warnings} warning${r.warnings === 1 ? "" : "s"}` : ""}.`;
210
+ const lines = r.findings.map((f) => `- ${f.severity} [${f.check}] ${f.message}${f.hint ? `\n Fix: ${f.hint}` : ""}`);
211
+ const note = "These are the document checks. Rendered checks (accessibility, layout, agent tasks) need a browser: save the document, run `npx playwright install chromium` once, then `npx -p @polyxd/verifier -p playwright polyxd-verify <file>`.";
212
+ return [head, ...lines, note].join("\n");
213
+ }
214
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { type ServerOptions } from "./server.ts";
2
+ export { VERSION } from "./server.ts";
3
+ /** Everything logged about a request. */
4
+ export interface RequestLog {
5
+ method: string;
6
+ path: string;
7
+ status: number;
8
+ ms: number;
9
+ }
10
+ export interface HttpHandlerOptions extends ServerOptions {
11
+ /** The largest request body accepted, in bytes. Larger is answered 413. Default 1 MiB. */
12
+ maxBodyBytes?: number;
13
+ /** How long a request may take before it is answered 504. Default 15 seconds. */
14
+ timeoutMs?: number;
15
+ /** Decides whether a request may go ahead; false answers 429. Called for every request except CORS preflights. */
16
+ rateLimit?: (request: Request) => boolean | Promise<boolean>;
17
+ /** Where the one line per request goes. Default: JSON on the console. */
18
+ log?: (entry: RequestLog) => void;
19
+ }
20
+ export declare const DEFAULT_MAX_BODY_BYTES: number;
21
+ export declare const DEFAULT_TIMEOUT_MS = 15000;
22
+ /** The Streamable HTTP endpoint, with its safeguards. Serve it at one path (`/mcp`). */
23
+ export declare function createHttpHandler(options: HttpHandlerOptions): (request: Request) => Promise<Response>;
24
+ /**
25
+ * A fixed-window rate limit held in memory: at most `limit` requests per `windowMs` for each key
26
+ * (by default the client's IP from `CF-Connecting-IP`). Best effort: each process, or each Worker
27
+ * isolate, counts on its own, so a client spread over several isolates gets more. Use it where the
28
+ * platform has nothing better; apps/mcp uses Cloudflare's rate limiting binding and falls back to this.
29
+ */
30
+ export declare function rateLimiter(options: {
31
+ limit: number;
32
+ windowMs: number;
33
+ key?: (request: Request) => string;
34
+ }): (request: Request) => boolean;
package/dist/http.js ADDED
@@ -0,0 +1,198 @@
1
+ /**
2
+ * The Polyxd MCP server over Streamable HTTP, as a web-standard `(Request) => Promise<Response>`
3
+ * handler: what `https://mcp.polyxd.com/mcp` runs (apps/mcp), and what any runtime with `fetch`
4
+ * types (Workers, Deno, Bun) can serve.
5
+ *
6
+ * The transport is the SDK's own `createMcpHandler`. It is stateless: every request gets a fresh
7
+ * server from `createServer`, nothing is kept between requests, and there are no sessions. The
8
+ * tools are pure functions of their arguments, so there is nothing a session would hold. For
9
+ * 2025-era clients (`initialize`, then JSON-RPC over POST) GET and DELETE answer 405, which is what
10
+ * the spec asks of a server that offers no standalone stream and no sessions. 2026-07-28 clients,
11
+ * which put the protocol version in every request, are served too.
12
+ *
13
+ * Around it sit the safeguards a public server without authentication needs:
14
+ *
15
+ * - a body limit, checked on Content-Length before anything is read and again by the SDK as it reads;
16
+ * - a per-request timeout, answered with a JSON-RPC error rather than a hung connection;
17
+ * - an optional rate limit, which the caller keys (apps/mcp keys it on the client's IP);
18
+ * - CORS for browser-based clients such as the MCP Inspector. Every origin may call: the server
19
+ * holds no credentials and no one's data, so there is nothing for another origin to reach that
20
+ * it could not fetch itself. (The spec's Origin check exists to stop DNS rebinding against
21
+ * servers on a private network or localhost; this one is public by design.)
22
+ * - one log line per request: method, path, status and duration. Nothing else, ever: not a body,
23
+ * a header, a query string, an IP address or an error message (which can quote the body).
24
+ */
25
+ import { createMcpHandler } from "@modelcontextprotocol/server";
26
+ import { createServer } from "./server.js";
27
+ export { VERSION } from "./server.js";
28
+ export const DEFAULT_MAX_BODY_BYTES = 1024 * 1024;
29
+ export const DEFAULT_TIMEOUT_MS = 15_000;
30
+ const ALLOW_METHODS = "GET, POST, DELETE, OPTIONS";
31
+ /** Asked for when a preflight names no headers; otherwise the preflight's own list is allowed (it includes 2026's Mcp-Param-* headers). */
32
+ const ALLOW_HEADERS = "Content-Type, Accept, Authorization, Last-Event-ID, Mcp-Session-Id, Mcp-Protocol-Version, Mcp-Method, Mcp-Name";
33
+ const EXPOSE_HEADERS = "Mcp-Session-Id, Mcp-Protocol-Version";
34
+ /** A JSON-RPC error with no request id, for failures before the request reached the server. */
35
+ function rpcError(status, code, message, headers = {}) {
36
+ return new Response(JSON.stringify({ jsonrpc: "2.0", id: null, error: { code, message } }), {
37
+ status,
38
+ headers: { "content-type": "application/json", ...headers },
39
+ });
40
+ }
41
+ /** The JSON-RPC messages in a request body (one, or a batch), or none when it is not JSON. Read from a clone, within the body limit. */
42
+ async function requestMessages(request) {
43
+ try {
44
+ const parsed = JSON.parse(await request.text());
45
+ return Array.isArray(parsed) ? parsed : [parsed];
46
+ }
47
+ catch {
48
+ return [];
49
+ }
50
+ }
51
+ /**
52
+ * The response body, cut off at the deadline. An SSE answer still owed a result gets a JSON-RPC
53
+ * error for each request instead (`lateEvents`), so the client hears why rather than seeing the
54
+ * stream stop; any other body just errors.
55
+ */
56
+ function holdToDeadline(body, expired, on, lateEvents) {
57
+ const reader = body.getReader();
58
+ return new ReadableStream({
59
+ async pull(controller) {
60
+ const next = await Promise.race([reader.read(), expired]);
61
+ if (next === "expired") {
62
+ on.expire();
63
+ void reader.cancel().catch(() => { });
64
+ if (lateEvents) {
65
+ controller.enqueue(new TextEncoder().encode(lateEvents));
66
+ controller.close();
67
+ }
68
+ else
69
+ controller.error(new DOMException("The request took too long", "TimeoutError"));
70
+ }
71
+ else if (next.done) {
72
+ on.end();
73
+ controller.close();
74
+ }
75
+ else
76
+ controller.enqueue(next.value);
77
+ },
78
+ cancel(reason) {
79
+ on.end();
80
+ return reader.cancel(reason);
81
+ },
82
+ });
83
+ }
84
+ function withCors(response) {
85
+ const headers = new Headers(response.headers);
86
+ headers.set("access-control-allow-origin", "*");
87
+ headers.set("access-control-expose-headers", EXPOSE_HEADERS);
88
+ if (response.status === 405 && !headers.has("allow"))
89
+ headers.set("allow", "POST, OPTIONS");
90
+ return new Response(response.body, { status: response.status, statusText: response.statusText, headers });
91
+ }
92
+ function preflight(request) {
93
+ return new Response(null, {
94
+ status: 204,
95
+ headers: {
96
+ "access-control-allow-origin": "*",
97
+ "access-control-allow-methods": ALLOW_METHODS,
98
+ "access-control-allow-headers": request.headers.get("access-control-request-headers") || ALLOW_HEADERS,
99
+ "access-control-max-age": "86400",
100
+ vary: "Access-Control-Request-Headers",
101
+ },
102
+ });
103
+ }
104
+ /** The Streamable HTTP endpoint, with its safeguards. Serve it at one path (`/mcp`). */
105
+ export function createHttpHandler(options) {
106
+ const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
107
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
108
+ const log = options.log ?? ((entry) => console.log(JSON.stringify(entry)));
109
+ const mcp = createMcpHandler(() => createServer(options), {
110
+ legacy: "stateless",
111
+ maxRequestBodySize: maxBodyBytes,
112
+ // The tools never change, so a client listening for list changes hears nothing; keep few such streams open.
113
+ maxSubscriptions: 64,
114
+ // Errors are not logged: their messages can quote what the client sent, and the request's own
115
+ // line already carries the status that says it failed.
116
+ onerror: () => { },
117
+ });
118
+ async function serve(request) {
119
+ if (request.method === "OPTIONS")
120
+ return preflight(request);
121
+ if (options.rateLimit && !(await options.rateLimit(request))) {
122
+ return rpcError(429, -32000, "Too many requests from this address. Wait a minute and try again.", { "retry-after": "60" });
123
+ }
124
+ const length = Number(request.headers.get("content-length") ?? 0);
125
+ if (length > maxBodyBytes)
126
+ return rpcError(413, -32600, `The request body is larger than ${maxBodyBytes} bytes.`, { connection: "close" });
127
+ // The deadline covers the whole answer, not just its headers: a 2025-era answer is an SSE
128
+ // stream whose headers go out before the result is ready.
129
+ const timeout = new AbortController();
130
+ const signal = AbortSignal.any([request.signal, timeout.signal]);
131
+ const peek = request.method === "POST" ? request.clone() : undefined;
132
+ let timer;
133
+ const expired = new Promise((resolve) => (timer = setTimeout(() => resolve("expired"), timeoutMs)));
134
+ // A body nobody reads never clears its deadline; in Node, don't let that keep the process up.
135
+ timer?.unref?.();
136
+ const expire = () => timeout.abort(new DOMException("The request took too long", "TimeoutError"));
137
+ const late = `The server did not answer within ${timeoutMs} ms.`;
138
+ try {
139
+ const response = await Promise.race([mcp.fetch(new Request(request, { signal })), expired]);
140
+ if (response === "expired") {
141
+ expire();
142
+ void peek?.body?.cancel();
143
+ return rpcError(504, -32603, late);
144
+ }
145
+ const sse = (response.headers.get("content-type") ?? "").includes("text/event-stream");
146
+ // Only a stream needs the request's ids, and the SDK only streams for a body it accepted, so this read stays within the limit.
147
+ if (!sse)
148
+ void peek?.body?.cancel();
149
+ const messages = sse && peek ? await requestMessages(peek) : [];
150
+ // A subscriptions/listen stream is meant to stay open.
151
+ if (!response.body || (sse && messages.some((m) => m?.method === "subscriptions/listen"))) {
152
+ clearTimeout(timer);
153
+ return response;
154
+ }
155
+ const ids = messages.filter((m) => m && m.id !== undefined && typeof m.method === "string").map((m) => m.id);
156
+ const lateEvents = sse ? ids.map((id) => `\n\nevent: message\ndata: ${JSON.stringify({ jsonrpc: "2.0", id, error: { code: -32603, message: late } })}\n\n`).join("") : "";
157
+ const body = holdToDeadline(response.body, expired, { end: () => clearTimeout(timer), expire }, lateEvents);
158
+ return new Response(body, { status: response.status, statusText: response.statusText, headers: response.headers });
159
+ }
160
+ catch {
161
+ clearTimeout(timer);
162
+ return rpcError(500, -32603, "The server failed to handle the request.");
163
+ }
164
+ }
165
+ return async (request) => {
166
+ const started = Date.now();
167
+ const response = withCors(await serve(request));
168
+ log({ method: request.method, path: new URL(request.url).pathname.slice(0, 200), status: response.status, ms: Date.now() - started });
169
+ return response;
170
+ };
171
+ }
172
+ /**
173
+ * A fixed-window rate limit held in memory: at most `limit` requests per `windowMs` for each key
174
+ * (by default the client's IP from `CF-Connecting-IP`). Best effort: each process, or each Worker
175
+ * isolate, counts on its own, so a client spread over several isolates gets more. Use it where the
176
+ * platform has nothing better; apps/mcp uses Cloudflare's rate limiting binding and falls back to this.
177
+ */
178
+ export function rateLimiter(options) {
179
+ const key = options.key ?? ((request) => request.headers.get("cf-connecting-ip") ?? "unknown");
180
+ const windows = new Map();
181
+ return (request) => {
182
+ const now = Date.now();
183
+ // Forget finished windows now and then, so the map cannot grow without bound.
184
+ if (windows.size > 10_000)
185
+ for (const [k, w] of windows)
186
+ if (now - w.start >= options.windowMs)
187
+ windows.delete(k);
188
+ const k = key(request);
189
+ const w = windows.get(k);
190
+ if (!w || now - w.start >= options.windowMs) {
191
+ windows.set(k, { start: now, count: 1 });
192
+ return true;
193
+ }
194
+ w.count++;
195
+ return w.count <= options.limit;
196
+ };
197
+ }
198
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { McpServer } from "@modelcontextprotocol/server";
2
+ import { type ServerOptions } from "./server.ts";
3
+ import { viewHTML } from "./view-file.ts";
4
+ /** The Polyxd MCP server, its MCP App page read from dist/view.html unless you pass `viewHtml`. */
5
+ export declare function createServer(options?: Partial<ServerOptions>): McpServer;
6
+ export { viewHTML };
7
+ export { appResourceMeta, VERSION, VIEW_URI, VIEW_MIME_TYPE, DEFAULT_PACK, WIDGET_DOMAIN, type ServerOptions } from "./server.ts";
8
+ export { createHttpHandler, rateLimiter, type HttpHandlerOptions, type RequestLog } from "./http.ts";
9
+ export { validate, verify, formatValidation, formatVerify, hintFor, type ReportedIssue, type ValidationReport, type VerifyReport } from "./check.ts";
10
+ export { guide, MCP_NOTES, SYSTEM_PROMPT, SPEC_VERSION } from "./prompt.ts";
11
+ export { PACKS, type Pack } from "./packs.generated.ts";
12
+ export { componentDefinitions, exampleDocuments, exampleDirections, type ComponentDefinition, type Example } from "./spec.ts";
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { createServer as createServerWith } from "./server.js";
2
+ import { viewHTML } from "./view-file.js";
3
+ /** The Polyxd MCP server, its MCP App page read from dist/view.html unless you pass `viewHtml`. */
4
+ export function createServer(options = {}) {
5
+ return createServerWith({ viewHtml: viewHTML, ...options });
6
+ }
7
+ export { viewHTML };
8
+ export { appResourceMeta, VERSION, VIEW_URI, VIEW_MIME_TYPE, DEFAULT_PACK, WIDGET_DOMAIN } from "./server.js";
9
+ export { createHttpHandler, rateLimiter } from "./http.js";
10
+ export { validate, verify, formatValidation, formatVerify, hintFor } from "./check.js";
11
+ export { guide, MCP_NOTES, SYSTEM_PROMPT, SPEC_VERSION } from "./prompt.js";
12
+ export { PACKS } from "./packs.generated.js";
13
+ export { componentDefinitions, exampleDocuments, exampleDirections } from "./spec.js";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,IAAI,gBAAgB,EAAsB,MAAM,aAAa,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,mGAAmG;AACnG,MAAM,UAAU,YAAY,CAAC,OAAO,GAA2B,EAAE;IAC/D,OAAO,gBAAgB,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAsB,MAAM,aAAa,CAAC;AAClI,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAA4C,MAAM,WAAW,CAAC;AACrG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,EAAgE,MAAM,YAAY,CAAC;AACrJ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAa,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,iBAAiB,EAA0C,MAAM,WAAW,CAAC"}