diff --git a/README.md b/README.md
index 82c3aac..7dc8cc1 100644
--- a/README.md
+++ b/README.md
@@ -108,9 +108,11 @@ Try it immediately on the bundled example: `node packages/cli/dist/index.js scan
| Package | Purpose |
|---------|---------|
-| [`@coderadar/core`](packages/core) | The `LineageGraph` schema + query primitives (`matchComponentsByText`, `traceLineage`) |
-| [`@coderadar/parser-react`](packages/parser-react) | ts-morph static parser — components (incl. `memo`/`forwardRef`), hooks, `fetch`/`axios`/react-query/SWR endpoints, `useState`/`useSelector`/`useContext`, JSX event handlers, rendered-text extraction |
-| [`@coderadar/cli`](packages/cli) | `coderadar scan` · `find` · `trace` |
+| [`@coderadar/core`](packages/core) | The `LineageGraph` schema + query primitives (`matchComponents`, `traceLineage`, `journeys`, `blastRadius`) |
+| [`@coderadar/parser-react`](packages/parser-react) | ts-morph static parser — components (incl. `memo`/`forwardRef`), hooks, `fetch`/`axios`/react-query/SWR endpoints, `useState`/`useSelector`/`useContext`, JSX event handlers, rendered-text extraction, test coverage, response types |
+| [`@coderadar/agent-sdk`](packages/agent-sdk) | `resolveContext` / `buildBundle` — classifies a ticket and assembles a budgeted context bundle (deterministic, no LLM) |
+| [`@coderadar/mcp`](packages/mcp) | MCP server exposing `resolve_context` · `find_component` · `trace_lineage` · `journeys` · `blast_radius` over stdio |
+| [`ui-lineage`](packages/cli) | Published CLI + library bundle: `scan` · `find` · `trace` · `journeys` · `impact` · `resolve` · `bundle`, plus the `ui-lineage-mcp` server bin |
### What the graph captures
diff --git a/TRACKER.md b/TRACKER.md
index 4d55cf9..b001e61 100644
--- a/TRACKER.md
+++ b/TRACKER.md
@@ -4,10 +4,10 @@
## Status
-- **Current phase:** 5 — Context bundle & agent interface
-- **Next step:** 5.7 — MCP server (→ Gate 5)
-- **Done:** 0.1–0.4, 1.1–1.6, 2.1–2.5, 3.1–3.6, 4.1–4.6, 5.1–5.6
-- **Gates passed:** Gate 0 (CI + red-path, #5/#6) · Gate 1 (precision 1.000, recall 0.895, zero poison) · Gate 2 (C1 instance attribution 1.000 · B1 4-level handler chains · C6 store writers↔readers · A9 portals — scorecard 137/0/0, precision & recall 1.000) · Gate 3 (B3 action effects · B4 routers · B6 cyclic journeys terminate · B7/B8 form & non-JSX events · G5 flag/role conditions — precision & recall 1.000) · Gate 4 (A4 rarity · A10 fuzzy/OCR · A1 structural · A6 subtree · E3 vision annotations · E2 aliases · G4 corrections — high-conf correct 1.000, ambiguity honesty 1.000, poison rate 0.000)
+- **Current phase:** 6 — Lifecycle, scale, hardening
+- **Next step:** 6.1 (Phase 5 complete — Gate 5 passed, M5 reached)
+- **Done:** 0.1–0.4, 1.1–1.6, 2.1–2.5, 3.1–3.6, 4.1–4.6, 5.1–5.7
+- **Gates passed:** Gate 0 (CI + red-path, #5/#6) · Gate 1 (precision 1.000, recall 0.895, zero poison) · Gate 2 (C1 instance attribution 1.000 · B1 4-level handler chains · C6 store writers↔readers · A9 portals — scorecard 137/0/0, precision & recall 1.000) · Gate 3 (B3 action effects · B4 routers · B6 cyclic journeys terminate · B7/B8 form & non-JSX events · G5 flag/role conditions — precision & recall 1.000) · Gate 4 (A4 rarity · A10 fuzzy/OCR · A1 structural · A6 subtree · E3 vision annotations · E2 aliases · G4 corrections — high-conf correct 1.000, ambiguity honesty 1.000, poison rate 0.000) · Gate 5 (F1 context bundle · F2 blast radius · F3 test coverage · F4 response schema · F5 git history · MCP server over stdio — scorecard 265/0/0, all honesty metrics 1.000; **M5 reached** — ticket in → budgeted context bundle out, over MCP)
## What CodeRadar is
@@ -303,10 +303,11 @@ The heart of the project. C1 and B1 live here.
**Accept:** integration test on this repo's own history; graceful empty section outside a git repo.
**Done:** `gitHistory(root, files, limit)` in agent-sdk — per-file `git log --follow` (via `execFileSync`, no network), commits deduped across files and sorted newest-first by committer time, `parsePrNumber` pulls `#NN` from merge/squash subjects. Any failure (not a repo, git missing, untracked path) yields `[]` — the bundle degrades gracefully. Bundle `history` section (default 5) is populated from the matched component's files + render subtree; `BundleCommit` gains optional `pr` (context-bundle schema regenerated, drift gate green). Integration tests run against this repo's own history; 5 agent-sdk unit tests + a bundle-wiring test. eval 265/0/0, gate OK.
-### [ ] 5.7 MCP server
+### [x] 5.7 MCP server
**Failure modes:** G1 (surface), pipeline integration
**Build:** `@coderadar/mcp` exposing tools: `resolve_context(ticket)`, `find_component(terms)`, `trace_lineage(id)`, `journeys(id, depth)`, `blast_radius(id)` — thin wrappers over agent-sdk against a pre-built graph (path from env/config). Tool descriptions written for agent consumption (when to use which, what `ambiguous` means, that `disambiguation` should be relayed to a human).
**Accept:** MCP integration test via stdio client: scan fixture → each tool returns schema-valid envelopes; `ambiguous`/`declined` statuses round-trip. **Gate 5 passes.** *CodeRadar is now pluggable into the multi-agent system.*
+**Done:** new `@coderadar/mcp` package (MCP SDK 1.29). `createServer(graph)` registers all five tools over `@modelcontextprotocol/sdk`'s `McpServer` with zod input schemas and agent-facing descriptions (`resolve_context` returns the full budgeted `ContextBundle`; each tool returns its QueryResult envelope as JSON text; descriptions state that `ambiguous`/`disambiguation` goes to a human). `resolve_context` = `buildBundle`; `find_component`/`trace_lineage`/`journeys`/`blast_radius` wrap core. Bin `coderadar-mcp` loads a graph from `CODERADAR_GRAPH` (or argv) and serves stdio; also shipped in the published `ui-lineage` bundle as the `ui-lineage-mcp` bin (MCP SDK + zod kept external). Integration test via a real stdio `Client`: lists all five tools and round-trips `ok`/`ambiguous`/`declined` over `a4-generic-text` (6 tests). **Gate 5 passed. M5 reached — ticket in → budgeted context bundle out, over MCP.**
---
@@ -368,6 +369,6 @@ Sketch level — detail before starting the phase, after v1 feedback.
| M2 | **Headline correct:** per-instance API attribution (C1) + handler resolution (B1) | 2 |
| M3 | n-level journeys, lazily expanded | 3 |
| M4 | Screenshot/text → ranked, calibrated, honest matches | 4 |
-| M5 | **Pluggable node:** ticket in → budgeted context bundle out, over MCP | 5 |
+| M5 ✅ | **Pluggable node:** ticket in → budgeted context bundle out, over MCP | 5 |
| M6 | Production-grade: incremental, fast, deterministic, versioned | 6 |
| M7 | Full-stack lineage: pixel → backend handler | 7 |
diff --git a/packages/cli/README.md b/packages/cli/README.md
index fbd985d..5219e5e 100644
--- a/packages/cli/README.md
+++ b/packages/cli/README.md
@@ -48,6 +48,30 @@ its distance — so a change can be reviewed for what it might break:
▸ /users • onClick() ⇢ fetch /api/users
```
+## MCP server
+
+`ui-lineage` also ships an MCP (Model Context Protocol) server, so an agent can
+query a pre-built graph over stdio. Build a graph, then point an MCP client at
+the `ui-lineage-mcp` bin with the graph path in `CODERADAR_GRAPH`:
+
+```jsonc
+// e.g. an MCP client config
+{
+ "mcpServers": {
+ "coderadar": {
+ "command": "ui-lineage-mcp",
+ "env": { "CODERADAR_GRAPH": "/abs/path/to/app.graph.json" }
+ }
+ }
+}
+```
+
+Tools: `resolve_context(ticket)` (→ a budgeted context bundle), `find_component(terms)`,
+`trace_lineage(id)`, `journeys(start, depth?)`, `blast_radius(node, depth?)`. Every
+tool returns a QueryResult envelope — ranked candidates with confidence, or an
+honest `ambiguous` / `declined`. There is no LLM in the server; it is a
+deterministic context provider.
+
## Library
```ts
diff --git a/packages/cli/package.json b/packages/cli/package.json
index d64232f..9b4886c 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -5,7 +5,8 @@
"license": "MIT",
"type": "module",
"bin": {
- "ui-lineage": "dist/index.js"
+ "ui-lineage": "dist/index.js",
+ "ui-lineage-mcp": "dist/mcp.js"
},
"main": "dist/lib.js",
"module": "dist/lib.js",
@@ -45,13 +46,16 @@
"prepublishOnly": "pnpm build"
},
"dependencies": {
+ "@modelcontextprotocol/sdk": "^1.12.0",
"commander": "^13.0.0",
"ts-morph": "^24.0.0",
- "yaml": "^2.9.0"
+ "yaml": "^2.9.0",
+ "zod": "^3.23.8"
},
"devDependencies": {
"@coderadar/agent-sdk": "workspace:*",
"@coderadar/core": "workspace:*",
+ "@coderadar/mcp": "workspace:*",
"@coderadar/parser-react": "workspace:*",
"@coderadar/vision": "workspace:*",
"@types/node": "^22.20.1",
diff --git a/packages/cli/src/mcp.ts b/packages/cli/src/mcp.ts
new file mode 100644
index 0000000..09a802d
--- /dev/null
+++ b/packages/cli/src/mcp.ts
@@ -0,0 +1,39 @@
+#!/usr/bin/env node
+/**
+ * `ui-lineage-mcp` — the CodeRadar MCP server as a self-contained bin.
+ *
+ * Serves a pre-built lineage graph over stdio so an MCP-speaking agent can call
+ * resolve_context / find_component / trace_lineage / journeys / blast_radius.
+ * Build the graph first: `ui-lineage scan
-o app.graph.json`, then point a
+ * client at `ui-lineage-mcp` with CODERADAR_GRAPH=app.graph.json (or pass the
+ * path as the first argument).
+ */
+
+import { loadGraph } from "@coderadar/core";
+import { createServer } from "@coderadar/mcp";
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
+
+async function main(): Promise {
+ const graphPath = process.env["CODERADAR_GRAPH"] ?? process.argv[2];
+ if (graphPath === undefined) {
+ process.stderr.write(
+ "ui-lineage-mcp: set CODERADAR_GRAPH (or pass a path) to a graph built with `ui-lineage scan`.\n",
+ );
+ process.exit(1);
+ }
+ let graph;
+ try {
+ graph = loadGraph(graphPath);
+ } catch (error) {
+ process.stderr.write(`ui-lineage-mcp: cannot load ${graphPath}: ${String(error)}\n`);
+ process.exit(1);
+ }
+ const server = createServer(graph);
+ await server.connect(new StdioServerTransport());
+ process.stderr.write(`ui-lineage-mcp ready — ${graph.nodes.length} nodes from ${graphPath}\n`);
+}
+
+main().catch((error: unknown) => {
+ process.stderr.write(`ui-lineage-mcp: fatal ${String(error)}\n`);
+ process.exit(1);
+});
diff --git a/packages/cli/tsup.config.ts b/packages/cli/tsup.config.ts
index 43cd1bc..63d5d68 100644
--- a/packages/cli/tsup.config.ts
+++ b/packages/cli/tsup.config.ts
@@ -6,6 +6,7 @@ import { defineConfig } from "tsup";
export default defineConfig({
entry: {
index: "src/index.ts", // CLI bin (keeps its #!/usr/bin/env node shebang)
+ mcp: "src/mcp.ts", // ui-lineage-mcp bin (MCP stdio server)
lib: "src/lib.ts", // library entry
vision: "src/vision.ts", // ui-lineage/vision subpath
},
@@ -18,5 +19,5 @@ export default defineConfig({
sourcemap: true,
noExternal: [/^@coderadar\//],
// @anthropic-ai/sdk is a lazy, optional runtime dep of the vision adapter.
- external: ["ts-morph", "yaml", "commander", "@anthropic-ai/sdk"],
+ external: ["ts-morph", "yaml", "commander", "@anthropic-ai/sdk", "@modelcontextprotocol/sdk", "zod"],
});
diff --git a/packages/mcp/package.json b/packages/mcp/package.json
new file mode 100644
index 0000000..a9662fe
--- /dev/null
+++ b/packages/mcp/package.json
@@ -0,0 +1,39 @@
+{
+ "name": "@coderadar/mcp",
+ "version": "0.2.0",
+ "private": true,
+ "description": "Model Context Protocol server exposing CodeRadar as a context-provider node: resolve_context, find_component, trace_lineage, journeys, blast_radius over a pre-built graph.",
+ "license": "MIT",
+ "type": "module",
+ "main": "dist/server.js",
+ "types": "dist/server.d.ts",
+ "exports": {
+ ".": {
+ "types": "./dist/server.d.ts",
+ "default": "./dist/server.js"
+ }
+ },
+ "bin": {
+ "coderadar-mcp": "dist/index.js"
+ },
+ "files": [
+ "dist"
+ ],
+ "scripts": {
+ "build": "tsc -p tsconfig.json",
+ "typecheck": "tsc -p tsconfig.json --noEmit",
+ "test": "vitest run"
+ },
+ "dependencies": {
+ "@coderadar/agent-sdk": "workspace:*",
+ "@coderadar/core": "workspace:*",
+ "@modelcontextprotocol/sdk": "^1.12.0",
+ "zod": "^3.23.8"
+ },
+ "devDependencies": {
+ "@coderadar/parser-react": "workspace:*",
+ "@types/node": "^22.20.1",
+ "typescript": "^5.7.0",
+ "vitest": "^3.2.7"
+ }
+}
diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts
new file mode 100644
index 0000000..b0f65fc
--- /dev/null
+++ b/packages/mcp/src/index.ts
@@ -0,0 +1,40 @@
+#!/usr/bin/env node
+/**
+ * CodeRadar MCP stdio entry point.
+ *
+ * Loads a pre-built lineage graph (path from the CODERADAR_GRAPH env var, or the
+ * first CLI argument) and serves it over stdio. Build the graph first with
+ * `ui-lineage scan -o app.graph.json`, then point this server at it.
+ */
+
+import { loadGraph } from "@coderadar/core";
+import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
+
+import { createServer } from "./server.js";
+
+async function main(): Promise {
+ const graphPath = process.env["CODERADAR_GRAPH"] ?? process.argv[2];
+ if (graphPath === undefined) {
+ process.stderr.write(
+ "CodeRadar MCP: set CODERADAR_GRAPH (or pass a path) to a graph built with `ui-lineage scan`.\n",
+ );
+ process.exit(1);
+ }
+
+ let graph;
+ try {
+ graph = loadGraph(graphPath);
+ } catch (error) {
+ process.stderr.write(`CodeRadar MCP: cannot load ${graphPath}: ${String(error)}\n`);
+ process.exit(1);
+ }
+
+ const server = createServer(graph);
+ await server.connect(new StdioServerTransport());
+ process.stderr.write(`CodeRadar MCP ready — ${graph.nodes.length} nodes from ${graphPath}\n`);
+}
+
+main().catch((error: unknown) => {
+ process.stderr.write(`CodeRadar MCP: fatal ${String(error)}\n`);
+ process.exit(1);
+});
diff --git a/packages/mcp/src/mcp.test.ts b/packages/mcp/src/mcp.test.ts
new file mode 100644
index 0000000..feb9cc4
--- /dev/null
+++ b/packages/mcp/src/mcp.test.ts
@@ -0,0 +1,106 @@
+import fs from "node:fs";
+import os from "node:os";
+import path from "node:path";
+import { fileURLToPath } from "node:url";
+
+import { saveGraph } from "@coderadar/core";
+import { resolveHookEdges, scanReact } from "@coderadar/parser-react";
+import { Client } from "@modelcontextprotocol/sdk/client/index.js";
+import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
+import { afterAll, beforeAll, describe, expect, it } from "vitest";
+
+const here = path.dirname(fileURLToPath(import.meta.url));
+const repoRoot = path.resolve(here, "../../..");
+const fixtureApp = path.join(repoRoot, "eval/fixtures/a4-generic-text/app");
+const serverEntry = path.join(here, "../dist/index.js");
+
+let client: Client;
+let transport: StdioClientTransport;
+let graphPath: string;
+
+// Parse the single text-content envelope a tool returns.
+async function call(name: string, args: Record): Promise> {
+ const result = (await client.callTool({ name, arguments: args })) as {
+ content: { type: string; text: string }[];
+ };
+ const text = result.content.find((c) => c.type === "text")?.text ?? "{}";
+ return JSON.parse(text) as Record;
+}
+
+beforeAll(async () => {
+ // Build a real graph from a fixture and persist it for the server to load.
+ const graph = resolveHookEdges(scanReact({ root: fixtureApp }));
+ graphPath = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "coderadar-mcp-")), "graph.json");
+ saveGraph(graph, graphPath);
+
+ client = new Client({ name: "coderadar-mcp-test", version: "0.0.0" });
+ transport = new StdioClientTransport({
+ command: process.execPath,
+ args: [serverEntry],
+ env: { ...process.env, CODERADAR_GRAPH: graphPath },
+ });
+ await client.connect(transport);
+}, 30_000);
+
+afterAll(async () => {
+ await client?.close();
+});
+
+describe("CodeRadar MCP server (TRACKER 5.7, Gate 5)", () => {
+ it("advertises all five tools", async () => {
+ const { tools } = await client.listTools();
+ expect(tools.map((t) => t.name).sort()).toEqual([
+ "blast_radius",
+ "find_component",
+ "journeys",
+ "resolve_context",
+ "trace_lineage",
+ ]);
+ // Descriptions are written for the calling agent.
+ expect(tools.find((t) => t.name === "resolve_context")?.description).toMatch(/bundle/i);
+ });
+
+ it("resolve_context returns a matched context bundle for a UI ticket", async () => {
+ const bundle = await call("resolve_context", {
+ ticket: "the Card number field on the billing form is broken",
+ });
+ expect(bundle["status"]).toBe("matched");
+ expect(Array.isArray(bundle["match"])).toBe(true);
+ expect(bundle["budget"]).toBeDefined();
+ });
+
+ it("resolve_context declines an out-of-domain (backend) ticket", async () => {
+ const bundle = await call("resolve_context", {
+ ticket: "the SQL migration on the orders table failed in production",
+ });
+ expect(bundle["status"]).toBe("declined");
+ });
+
+ it("find_component round-trips ok / ambiguous / declined envelopes", async () => {
+ const ok = await call("find_component", { terms: ["Card number"] });
+ expect(ok["status"]).toBe("ok");
+ expect(Array.isArray(ok["candidates"])).toBe(true);
+
+ const ambiguous = await call("find_component", { terms: ["Save"] });
+ expect(ambiguous["status"]).toBe("ambiguous");
+ expect(typeof ambiguous["disambiguation"]).toBe("string");
+
+ const declined = await call("find_component", { terms: ["zzqqnope"] });
+ expect(declined["status"]).toBe("declined");
+ expect(declined["declineReason"]).toBe("no-signal");
+ });
+
+ it("trace_lineage resolves a component name and declines unknown ids", async () => {
+ const ok = await call("trace_lineage", { id: "BillingForm" });
+ expect(ok["status"]).toBe("ok");
+ const missing = await call("trace_lineage", { id: "NoSuchComponent" });
+ expect(missing["status"]).toBe("declined");
+ expect(missing["declineReason"]).toBe("not-found");
+ });
+
+ it("journeys and blast_radius return ok envelopes, declining unknown targets", async () => {
+ expect((await call("journeys", { start: "BillingForm" }))["status"]).toBe("ok");
+ expect((await call("blast_radius", { node: "BillingForm" }))["status"]).toBe("ok");
+ expect((await call("blast_radius", { node: "NoSuchNode" }))["status"]).toBe("declined");
+ });
+});
diff --git a/packages/mcp/src/server.ts b/packages/mcp/src/server.ts
new file mode 100644
index 0000000..9a030ca
--- /dev/null
+++ b/packages/mcp/src/server.ts
@@ -0,0 +1,144 @@
+/**
+ * CodeRadar MCP server (TRACKER step 5.7 → Gate 5).
+ *
+ * Exposes the deterministic query layer over a PRE-BUILT lineage graph as MCP
+ * tools an agent can call. Every tool returns a QueryResult / ContextBundle
+ * envelope as JSON text: ranked candidates with evidence and confidence, or an
+ * honest `ambiguous` / `declined`. The tool descriptions tell the calling agent
+ * when to reach for each one and how to treat those statuses.
+ *
+ * There is NO LLM in this node — it is a context provider, not an agent.
+ */
+
+import {
+ blastRadius,
+ journeys,
+ type LineageGraph,
+ matchComponents,
+ traceLineage,
+} from "@coderadar/core";
+import { buildBundle } from "@coderadar/agent-sdk";
+import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
+import { z } from "zod";
+
+type ToolResult = {
+ content: { type: "text"; text: string }[];
+ isError?: boolean;
+};
+
+/** Serialize any query envelope as pretty JSON text content. */
+function envelope(value: unknown): ToolResult {
+ return { content: [{ type: "text", text: JSON.stringify(value, null, 2) }] };
+}
+
+/** Build a configured MCP server bound to one pre-built graph. */
+export function createServer(graph: LineageGraph): McpServer {
+ const server = new McpServer({ name: "coderadar", version: "0.2.0" });
+
+ server.registerTool(
+ "resolve_context",
+ {
+ title: "Resolve a ticket to a budgeted context bundle",
+ description:
+ "PRIMARY TOOL. Given a bug/feature ticket, return a deterministic, token-budgeted context bundle: the matched component(s), their data/state/event lineage, user journeys, blast radius, tests, and recent git history. Use this first for any UI ticket. `status` is 'matched', 'ambiguous', or 'declined'; on 'declined' the ticket is out of scope (e.g. backend-only) — read `warnings`. On 'ambiguous' relay the `warnings` disambiguation question to a human rather than guessing.",
+ inputSchema: {
+ ticket: z.string().describe("The ticket text (title + body)."),
+ screenshots: z
+ .number()
+ .int()
+ .optional()
+ .describe("How many screenshots are attached, if any (routes the ticket as visual)."),
+ budgetTokens: z
+ .number()
+ .int()
+ .positive()
+ .optional()
+ .describe("Token budget the bundle must fit under. Default 4000."),
+ },
+ },
+ ({ ticket, screenshots, budgetTokens }) =>
+ envelope(
+ buildBundle(
+ graph,
+ { text: ticket, ...(screenshots !== undefined ? { screenshots } : {}) },
+ budgetTokens !== undefined ? { budgetTokens } : {},
+ ),
+ ),
+ );
+
+ server.registerTool(
+ "find_component",
+ {
+ title: "Find components by on-screen text",
+ description:
+ "Rank components by text read off a screenshot or ticket (labels, headings, button text). Returns ranked candidates with evidence and confidence. `status: 'ambiguous'` means several components fit equally — relay the `disambiguation` question to a human. `status: 'declined'` with reason 'no-signal' means nothing matched.",
+ inputSchema: {
+ terms: z
+ .array(z.string())
+ .min(1)
+ .describe("Text fragments visible in the UI, e.g. ['All invoices', 'Download']."),
+ },
+ },
+ ({ terms }) => envelope(matchComponents(graph, { terms })),
+ );
+
+ server.registerTool(
+ "trace_lineage",
+ {
+ title: "Trace a component's data, state, and events",
+ description:
+ "Given a component name, definition id, or instance id, return every data source (with response type when known), state slice, and event that feeds it — kept per-instance so a shared component doesn't leak one page's API onto another. `declined` reason 'not-found' means the id/name isn't in the graph.",
+ inputSchema: {
+ id: z.string().describe("Component name, definition id, or instance id."),
+ },
+ },
+ ({ id }) => {
+ const node =
+ graph.nodes.find((n) => n.id === id) ??
+ graph.nodes.find((n) => n.kind === "component" && n.name === id);
+ return envelope(traceLineage(graph, node?.id ?? id));
+ },
+ );
+
+ server.registerTool(
+ "journeys",
+ {
+ title: "Enumerate user-journey paths from a screen",
+ description:
+ "From a route path ('/users/:id'), component name, or instance id, enumerate user-journey paths (click → navigate → click…). Each path ends 'terminal', 'cycle' (a finite list ⇄ detail loop), or 'depth-limit'. Use to understand what a screen leads to.",
+ inputSchema: {
+ start: z.string().describe("Route path, component name, or instance id to start from."),
+ depth: z
+ .number()
+ .int()
+ .positive()
+ .optional()
+ .describe("Max navigation levels per path. Default 3."),
+ },
+ },
+ ({ start, depth }) =>
+ envelope(journeys(graph, start, depth !== undefined ? { depth } : {})),
+ );
+
+ server.registerTool(
+ "blast_radius",
+ {
+ title: "Find everything that depends on a node",
+ description:
+ "Reverse-dependency traversal: everything affected by changing a node — instances of a component, consumers of an API endpoint, readers of a state slice, and the tests over them — each with its distance. Pass a component name, API endpoint, state name, or route path. Use to scope the impact of a change before making it.",
+ inputSchema: {
+ node: z.string().describe("Component name, API endpoint, state name, or route path."),
+ depth: z
+ .number()
+ .int()
+ .positive()
+ .optional()
+ .describe("Max dependency hops to follow. Default: unlimited."),
+ },
+ },
+ ({ node, depth }) =>
+ envelope(blastRadius(graph, node, depth !== undefined ? { depth } : {})),
+ );
+
+ return server;
+}
diff --git a/packages/mcp/tsconfig.json b/packages/mcp/tsconfig.json
new file mode 100644
index 0000000..90d6d34
--- /dev/null
+++ b/packages/mcp/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "outDir": "dist"
+ },
+ "include": ["src"],
+ "exclude": ["src/**/*.test.ts"]
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ee27026..5d769fb 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -51,6 +51,9 @@ importers:
packages/cli:
dependencies:
+ '@modelcontextprotocol/sdk':
+ specifier: ^1.12.0
+ version: 1.29.0(zod@3.25.76)
commander:
specifier: ^13.0.0
version: 13.1.0
@@ -60,6 +63,9 @@ importers:
yaml:
specifier: ^2.9.0
version: 2.9.0
+ zod:
+ specifier: ^3.23.8
+ version: 3.25.76
devDependencies:
'@coderadar/agent-sdk':
specifier: workspace:*
@@ -67,6 +73,9 @@ importers:
'@coderadar/core':
specifier: workspace:*
version: link:../core
+ '@coderadar/mcp':
+ specifier: workspace:*
+ version: link:../mcp
'@coderadar/parser-react':
specifier: workspace:*
version: link:../parser-react
@@ -98,6 +107,34 @@ importers:
specifier: ^3.2.7
version: 3.2.7(@types/node@22.20.1)(yaml@2.9.0)
+ packages/mcp:
+ dependencies:
+ '@coderadar/agent-sdk':
+ specifier: workspace:*
+ version: link:../agent-sdk
+ '@coderadar/core':
+ specifier: workspace:*
+ version: link:../core
+ '@modelcontextprotocol/sdk':
+ specifier: ^1.12.0
+ version: 1.29.0(zod@3.25.76)
+ zod:
+ specifier: ^3.23.8
+ version: 3.25.76
+ devDependencies:
+ '@coderadar/parser-react':
+ specifier: workspace:*
+ version: link:../parser-react
+ '@types/node':
+ specifier: ^22.20.1
+ version: 22.20.1
+ typescript:
+ specifier: ^5.7.0
+ version: 5.9.3
+ vitest:
+ specifier: ^3.2.7
+ version: 3.2.7(@types/node@22.20.1)(yaml@2.9.0)
+
packages/parser-react:
dependencies:
'@coderadar/core':
@@ -456,6 +493,12 @@ packages:
cpu: [x64]
os: [win32]
+ '@hono/node-server@1.19.14':
+ resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==}
+ engines: {node: '>=18.14.1'}
+ peerDependencies:
+ hono: ^4
+
'@jridgewell/gen-mapping@0.3.13':
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
@@ -469,6 +512,16 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@modelcontextprotocol/sdk@1.29.0':
+ resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@cfworker/json-schema': ^4.1.1
+ zod: ^3.25 || ^4.0
+ peerDependenciesMeta:
+ '@cfworker/json-schema':
+ optional: true
+
'@rollup/rollup-android-arm-eabi@4.62.2':
resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==}
cpu: [arm]
@@ -654,11 +707,26 @@ packages:
'@vitest/utils@3.2.7':
resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==}
+ accepts@2.0.0:
+ resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==}
+ engines: {node: '>= 0.6'}
+
acorn@8.17.0:
resolution: {integrity: sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==}
engines: {node: '>=0.4.0'}
hasBin: true
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
+ ajv@8.20.0:
+ resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==}
+
any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
@@ -673,6 +741,10 @@ packages:
resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==}
engines: {node: 18 || 20 || >=22}
+ body-parser@2.3.0:
+ resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==}
+ engines: {node: '>=18'}
+
brace-expansion@2.1.2:
resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==}
@@ -686,10 +758,22 @@ packages:
peerDependencies:
esbuild: '>=0.18'
+ bytes@3.1.2:
+ resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
+ engines: {node: '>= 0.8'}
+
cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ call-bound@1.0.4:
+ resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
+ engines: {node: '>= 0.4'}
+
chai@5.3.3:
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
engines: {node: '>=18'}
@@ -724,6 +808,34 @@ packages:
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
engines: {node: ^14.18.0 || >=16.10.0}
+ content-disposition@1.1.0:
+ resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==}
+ engines: {node: '>=18'}
+
+ content-type@1.0.5:
+ resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==}
+ engines: {node: '>= 0.6'}
+
+ content-type@2.0.0:
+ resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==}
+ engines: {node: '>=18'}
+
+ cookie-signature@1.2.2:
+ resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==}
+ engines: {node: '>=6.6.0'}
+
+ cookie@0.7.2:
+ resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
+ engines: {node: '>= 0.6'}
+
+ cors@2.8.6:
+ resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==}
+ engines: {node: '>= 0.10'}
+
+ cross-spawn@7.0.6:
+ resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
+ engines: {node: '>= 8'}
+
debug@4.4.3:
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
engines: {node: '>=6.0'}
@@ -737,9 +849,36 @@ packages:
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
engines: {node: '>=6'}
+ depd@2.0.0:
+ resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==}
+ engines: {node: '>= 0.8'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ ee-first@1.1.1:
+ resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+
+ encodeurl@2.0.0:
+ resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
+ engines: {node: '>= 0.8'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
es-module-lexer@1.7.0:
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
+ engines: {node: '>= 0.4'}
+
esbuild@0.27.7:
resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
engines: {node: '>=18'}
@@ -750,13 +889,44 @@ packages:
engines: {node: '>=18'}
hasBin: true
+ escape-html@1.0.3:
+ resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
+
estree-walker@3.0.3:
resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+ etag@1.8.1:
+ resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
+ engines: {node: '>= 0.6'}
+
+ eventsource-parser@3.1.0:
+ resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==}
+ engines: {node: '>=18.0.0'}
+
+ eventsource@3.0.7:
+ resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==}
+ engines: {node: '>=18.0.0'}
+
expect-type@1.4.0:
resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
engines: {node: '>=12.0.0'}
+ express-rate-limit@8.5.2:
+ resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==}
+ engines: {node: '>= 16'}
+ peerDependencies:
+ express: '>= 4.11'
+
+ express@5.2.1:
+ resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
+ engines: {node: '>= 18'}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-uri@3.1.3:
+ resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==}
+
fdir@6.5.0:
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
engines: {node: '>=12.0.0'}
@@ -766,18 +936,85 @@ packages:
picomatch:
optional: true
+ finalhandler@2.1.1:
+ resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
+ engines: {node: '>= 18.0.0'}
+
fix-dts-default-cjs-exports@1.0.1:
resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
+ forwarded@0.2.0:
+ resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==}
+ engines: {node: '>= 0.6'}
+
+ fresh@2.0.0:
+ resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
+ engines: {node: '>= 0.8'}
+
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
glob@13.0.6:
resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==}
engines: {node: 18 || 20 || >=22}
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ hono@4.12.30:
+ resolution: {integrity: sha512-emn+JoJjrN9YTpRDS5it/UI2SO9BAE37T6I3d963RxcZ81G9A4pr2SZTEiiaiKbzx+NKRg5BZ89fCL7gCJCUog==}
+ engines: {node: '>=16.9.0'}
+
+ http-errors@2.0.1:
+ resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==}
+ engines: {node: '>= 0.8'}
+
+ iconv-lite@0.7.3:
+ resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==}
+ engines: {node: '>=0.10.0'}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ip-address@10.2.0:
+ resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==}
+ engines: {node: '>= 12'}
+
+ ipaddr.js@1.9.1:
+ resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
+ engines: {node: '>= 0.10'}
+
+ is-promise@4.0.0:
+ resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jose@6.2.3:
+ resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==}
+
joycon@3.1.1:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
@@ -785,6 +1022,12 @@ packages:
js-tokens@9.0.1:
resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json-schema-typed@8.0.2:
+ resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==}
+
json5@2.2.3:
resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
engines: {node: '>=6'}
@@ -811,6 +1054,26 @@ packages:
magic-string@0.30.21:
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ media-typer@1.1.0:
+ resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==}
+ engines: {node: '>= 0.8'}
+
+ merge-descriptors@2.0.0:
+ resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==}
+ engines: {node: '>=18'}
+
+ mime-db@1.54.0:
+ resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@3.0.2:
+ resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==}
+ engines: {node: '>=18'}
+
minimatch@10.2.5:
resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==}
engines: {node: 18 || 20 || >=22}
@@ -837,6 +1100,10 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
+ negotiator@1.0.0:
+ resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==}
+ engines: {node: '>= 0.6'}
+
normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
@@ -845,13 +1112,35 @@ packages:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
+ object-inspect@1.13.4:
+ resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
+ engines: {node: '>= 0.4'}
+
+ on-finished@2.4.1:
+ resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
+ engines: {node: '>= 0.8'}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ parseurl@1.3.3:
+ resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
+ engines: {node: '>= 0.8'}
+
path-browserify@1.0.1:
resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
path-scurry@2.0.2:
resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==}
engines: {node: 18 || 20 || >=22}
+ path-to-regexp@8.4.2:
+ resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
+
pathe@2.0.3:
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
@@ -870,6 +1159,10 @@ packages:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
+ pkce-challenge@5.0.1:
+ resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==}
+ engines: {node: '>=16.20.0'}
+
pkg-types@1.3.1:
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
@@ -895,10 +1188,30 @@ packages:
resolution: {integrity: sha512-J7EF+8X+CzRPaJPOv9Ck2wNWJvGnnl3PcNPAdGg6GTLjyVpyQ0yATMSXRFRV01BviT/9Gwuc3rjEyJbDJG9a4w==}
engines: {node: ^10 || ^12 || >=14}
+ proxy-addr@2.0.7:
+ resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
+ engines: {node: '>= 0.10'}
+
+ qs@6.15.3:
+ resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==}
+ engines: {node: '>=0.6'}
+
+ range-parser@1.3.0:
+ resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==}
+ engines: {node: '>= 0.6'}
+
+ raw-body@3.0.2:
+ resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==}
+ engines: {node: '>= 0.10'}
+
readdirp@4.1.2:
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
engines: {node: '>= 14.18.0'}
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
@@ -908,10 +1221,52 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
+ router@2.2.0:
+ resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
+ engines: {node: '>= 18'}
+
safe-stable-stringify@2.5.0:
resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==}
engines: {node: '>=10'}
+ safer-buffer@2.1.2:
+ resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
+
+ send@1.2.1:
+ resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
+ engines: {node: '>= 18'}
+
+ serve-static@2.2.1:
+ resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
+ engines: {node: '>= 18'}
+
+ setprototypeof@1.2.0:
+ resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ side-channel-list@1.0.1:
+ resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-map@1.0.1:
+ resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
+ engines: {node: '>= 0.4'}
+
+ side-channel-weakmap@1.0.2:
+ resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
+ engines: {node: '>= 0.4'}
+
+ side-channel@1.1.1:
+ resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==}
+ engines: {node: '>= 0.4'}
+
siginfo@2.0.0:
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
@@ -926,6 +1281,10 @@ packages:
stackback@0.0.2:
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+ statuses@2.0.2:
+ resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
+ engines: {node: '>= 0.8'}
+
std-env@3.10.0:
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
@@ -966,6 +1325,10 @@ packages:
resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==}
engines: {node: '>=14.0.0'}
+ toidentifier@1.0.1:
+ resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
+ engines: {node: '>=0.6'}
+
tree-kill@1.2.2:
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
hasBin: true
@@ -1003,6 +1366,10 @@ packages:
typescript:
optional: true
+ type-is@2.1.0:
+ resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==}
+ engines: {node: '>= 18'}
+
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
@@ -1014,6 +1381,14 @@ packages:
undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+ unpipe@1.0.0:
+ resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
+ engines: {node: '>= 0.8'}
+
+ vary@1.1.2:
+ resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
+ engines: {node: '>= 0.8'}
+
vite-node@3.2.4:
resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==}
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
@@ -1087,16 +1462,32 @@ packages:
jsdom:
optional: true
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
why-is-node-running@2.3.0:
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
engines: {node: '>=8'}
hasBin: true
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
yaml@2.9.0:
resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==}
engines: {node: '>= 14.6'}
hasBin: true
+ zod-to-json-schema@3.25.2:
+ resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==}
+ peerDependencies:
+ zod: ^3.25.28 || ^4
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
snapshots:
'@esbuild/aix-ppc64@0.27.7':
@@ -1255,6 +1646,10 @@ snapshots:
'@esbuild/win32-x64@0.28.1':
optional: true
+ '@hono/node-server@1.19.14(hono@4.12.30)':
+ dependencies:
+ hono: 4.12.30
+
'@jridgewell/gen-mapping@0.3.13':
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
@@ -1269,6 +1664,28 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)':
+ dependencies:
+ '@hono/node-server': 1.19.14(hono@4.12.30)
+ ajv: 8.20.0
+ ajv-formats: 3.0.1(ajv@8.20.0)
+ content-type: 1.0.5
+ cors: 2.8.6
+ cross-spawn: 7.0.6
+ eventsource: 3.0.7
+ eventsource-parser: 3.1.0
+ express: 5.2.1
+ express-rate-limit: 8.5.2(express@5.2.1)
+ hono: 4.12.30
+ jose: 6.2.3
+ json-schema-typed: 8.0.2
+ pkce-challenge: 5.0.1
+ raw-body: 3.0.2
+ zod: 3.25.76
+ zod-to-json-schema: 3.25.2(zod@3.25.76)
+ transitivePeerDependencies:
+ - supports-color
+
'@rollup/rollup-android-arm-eabi@4.62.2':
optional: true
@@ -1407,8 +1824,24 @@ snapshots:
loupe: 3.2.1
tinyrainbow: 2.0.0
+ accepts@2.0.0:
+ dependencies:
+ mime-types: 3.0.2
+ negotiator: 1.0.0
+
acorn@8.17.0: {}
+ ajv-formats@3.0.1(ajv@8.20.0):
+ optionalDependencies:
+ ajv: 8.20.0
+
+ ajv@8.20.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.1.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
any-promise@1.3.0: {}
assertion-error@2.0.1: {}
@@ -1417,6 +1850,20 @@ snapshots:
balanced-match@4.0.4: {}
+ body-parser@2.3.0:
+ dependencies:
+ bytes: 3.1.2
+ content-type: 2.0.0
+ debug: 4.4.3
+ http-errors: 2.0.1
+ iconv-lite: 0.7.3
+ on-finished: 2.4.1
+ qs: 6.15.3
+ raw-body: 3.0.2
+ type-is: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
brace-expansion@2.1.2:
dependencies:
balanced-match: 1.0.2
@@ -1430,8 +1877,20 @@ snapshots:
esbuild: 0.27.7
load-tsconfig: 0.2.5
+ bytes@3.1.2: {}
+
cac@6.7.14: {}
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ call-bound@1.0.4:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ get-intrinsic: 1.3.0
+
chai@5.3.3:
dependencies:
assertion-error: 2.0.1
@@ -1458,14 +1917,55 @@ snapshots:
consola@3.4.2: {}
+ content-disposition@1.1.0: {}
+
+ content-type@1.0.5: {}
+
+ content-type@2.0.0: {}
+
+ cookie-signature@1.2.2: {}
+
+ cookie@0.7.2: {}
+
+ cors@2.8.6:
+ dependencies:
+ object-assign: 4.1.1
+ vary: 1.1.2
+
+ cross-spawn@7.0.6:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
debug@4.4.3:
dependencies:
ms: 2.1.3
deep-eql@5.0.2: {}
+ depd@2.0.0: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ ee-first@1.1.1: {}
+
+ encodeurl@2.0.0: {}
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
es-module-lexer@1.7.0: {}
+ es-object-atoms@1.1.2:
+ dependencies:
+ es-errors: 1.3.0
+
esbuild@0.27.7:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.7
@@ -1524,35 +2024,160 @@ snapshots:
'@esbuild/win32-ia32': 0.28.1
'@esbuild/win32-x64': 0.28.1
+ escape-html@1.0.3: {}
+
estree-walker@3.0.3:
dependencies:
'@types/estree': 1.0.9
+ etag@1.8.1: {}
+
+ eventsource-parser@3.1.0: {}
+
+ eventsource@3.0.7:
+ dependencies:
+ eventsource-parser: 3.1.0
+
expect-type@1.4.0: {}
+ express-rate-limit@8.5.2(express@5.2.1):
+ dependencies:
+ express: 5.2.1
+ ip-address: 10.2.0
+
+ express@5.2.1:
+ dependencies:
+ accepts: 2.0.0
+ body-parser: 2.3.0
+ content-disposition: 1.1.0
+ content-type: 1.0.5
+ cookie: 0.7.2
+ cookie-signature: 1.2.2
+ debug: 4.4.3
+ depd: 2.0.0
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ finalhandler: 2.1.1
+ fresh: 2.0.0
+ http-errors: 2.0.1
+ merge-descriptors: 2.0.0
+ mime-types: 3.0.2
+ on-finished: 2.4.1
+ once: 1.4.0
+ parseurl: 1.3.3
+ proxy-addr: 2.0.7
+ qs: 6.15.3
+ range-parser: 1.3.0
+ router: 2.2.0
+ send: 1.2.1
+ serve-static: 2.2.1
+ statuses: 2.0.2
+ type-is: 2.1.0
+ vary: 1.1.2
+ transitivePeerDependencies:
+ - supports-color
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-uri@3.1.3: {}
+
fdir@6.5.0(picomatch@4.0.5):
optionalDependencies:
picomatch: 4.0.5
+ finalhandler@2.1.1:
+ dependencies:
+ debug: 4.4.3
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ on-finished: 2.4.1
+ parseurl: 1.3.3
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
fix-dts-default-cjs-exports@1.0.1:
dependencies:
magic-string: 0.30.21
mlly: 1.8.2
rollup: 4.62.2
+ forwarded@0.2.0: {}
+
+ fresh@2.0.0: {}
+
fsevents@2.3.3:
optional: true
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.2
+
glob@13.0.6:
dependencies:
minimatch: 10.2.5
minipass: 7.1.3
path-scurry: 2.0.2
+ gopd@1.2.0: {}
+
+ has-symbols@1.1.0: {}
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ hono@4.12.30: {}
+
+ http-errors@2.0.1:
+ dependencies:
+ depd: 2.0.0
+ inherits: 2.0.4
+ setprototypeof: 1.2.0
+ statuses: 2.0.2
+ toidentifier: 1.0.1
+
+ iconv-lite@0.7.3:
+ dependencies:
+ safer-buffer: 2.1.2
+
+ inherits@2.0.4: {}
+
+ ip-address@10.2.0: {}
+
+ ipaddr.js@1.9.1: {}
+
+ is-promise@4.0.0: {}
+
+ isexe@2.0.0: {}
+
+ jose@6.2.3: {}
+
joycon@3.1.1: {}
js-tokens@9.0.1: {}
+ json-schema-traverse@1.0.0: {}
+
+ json-schema-typed@8.0.2: {}
+
json5@2.2.3: {}
lilconfig@3.1.3: {}
@@ -1569,6 +2194,18 @@ snapshots:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.5
+ math-intrinsics@1.1.0: {}
+
+ media-typer@1.1.0: {}
+
+ merge-descriptors@2.0.0: {}
+
+ mime-db@1.54.0: {}
+
+ mime-types@3.0.2:
+ dependencies:
+ mime-db: 1.54.0
+
minimatch@10.2.5:
dependencies:
brace-expansion: 5.0.7
@@ -1596,17 +2233,35 @@ snapshots:
nanoid@3.3.15: {}
+ negotiator@1.0.0: {}
+
normalize-path@3.0.0: {}
object-assign@4.1.1: {}
+ object-inspect@1.13.4: {}
+
+ on-finished@2.4.1:
+ dependencies:
+ ee-first: 1.1.1
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ parseurl@1.3.3: {}
+
path-browserify@1.0.1: {}
+ path-key@3.1.1: {}
+
path-scurry@2.0.2:
dependencies:
lru-cache: 11.5.2
minipass: 7.1.3
+ path-to-regexp@8.4.2: {}
+
pathe@2.0.3: {}
pathval@2.0.1: {}
@@ -1617,6 +2272,8 @@ snapshots:
pirates@4.0.7: {}
+ pkce-challenge@5.0.1: {}
+
pkg-types@1.3.1:
dependencies:
confbox: 0.1.8
@@ -1636,8 +2293,29 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
+ proxy-addr@2.0.7:
+ dependencies:
+ forwarded: 0.2.0
+ ipaddr.js: 1.9.1
+
+ qs@6.15.3:
+ dependencies:
+ es-define-property: 1.0.1
+ side-channel: 1.1.1
+
+ range-parser@1.3.0: {}
+
+ raw-body@3.0.2:
+ dependencies:
+ bytes: 3.1.2
+ http-errors: 2.0.1
+ iconv-lite: 0.7.3
+ unpipe: 1.0.0
+
readdirp@4.1.2: {}
+ require-from-string@2.0.2: {}
+
resolve-from@5.0.0: {}
rollup@4.62.2:
@@ -1671,8 +2349,81 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.62.2
fsevents: 2.3.3
+ router@2.2.0:
+ dependencies:
+ debug: 4.4.3
+ depd: 2.0.0
+ is-promise: 4.0.0
+ parseurl: 1.3.3
+ path-to-regexp: 8.4.2
+ transitivePeerDependencies:
+ - supports-color
+
safe-stable-stringify@2.5.0: {}
+ safer-buffer@2.1.2: {}
+
+ send@1.2.1:
+ dependencies:
+ debug: 4.4.3
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ etag: 1.8.1
+ fresh: 2.0.0
+ http-errors: 2.0.1
+ mime-types: 3.0.2
+ ms: 2.1.3
+ on-finished: 2.4.1
+ range-parser: 1.3.0
+ statuses: 2.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ serve-static@2.2.1:
+ dependencies:
+ encodeurl: 2.0.0
+ escape-html: 1.0.3
+ parseurl: 1.3.3
+ send: 1.2.1
+ transitivePeerDependencies:
+ - supports-color
+
+ setprototypeof@1.2.0: {}
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ side-channel-list@1.0.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-map@1.0.1:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+
+ side-channel-weakmap@1.0.2:
+ dependencies:
+ call-bound: 1.0.4
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-map: 1.0.1
+
+ side-channel@1.1.1:
+ dependencies:
+ es-errors: 1.3.0
+ object-inspect: 1.13.4
+ side-channel-list: 1.0.1
+ side-channel-map: 1.0.1
+ side-channel-weakmap: 1.0.2
+
siginfo@2.0.0: {}
source-map-js@1.2.1: {}
@@ -1681,6 +2432,8 @@ snapshots:
stackback@0.0.2: {}
+ statuses@2.0.2: {}
+
std-env@3.10.0: {}
strip-literal@3.1.0:
@@ -1720,6 +2473,8 @@ snapshots:
tinyspy@4.0.4: {}
+ toidentifier@1.0.1: {}
+
tree-kill@1.2.2: {}
ts-interface-checker@0.1.13: {}
@@ -1770,12 +2525,22 @@ snapshots:
- tsx
- yaml
+ type-is@2.1.0:
+ dependencies:
+ content-type: 2.0.0
+ media-typer: 1.1.0
+ mime-types: 3.0.2
+
typescript@5.9.3: {}
ufo@1.6.4: {}
undici-types@6.21.0: {}
+ unpipe@1.0.0: {}
+
+ vary@1.1.2: {}
+
vite-node@3.2.4(@types/node@22.20.1)(yaml@2.9.0):
dependencies:
cac: 6.7.14
@@ -1851,9 +2616,21 @@ snapshots:
- tsx
- yaml
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
why-is-node-running@2.3.0:
dependencies:
siginfo: 2.0.0
stackback: 0.0.2
+ wrappy@1.0.2: {}
+
yaml@2.9.0: {}
+
+ zod-to-json-schema@3.25.2(zod@3.25.76):
+ dependencies:
+ zod: 3.25.76
+
+ zod@3.25.76: {}