@domphy/mcp 0.12.0 → 0.14.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.
@@ -0,0 +1,143 @@
1
+ // src/tools.ts
2
+ import { readFile } from "fs/promises";
3
+ import { dirname, isAbsolute, resolve } from "path";
4
+ import { diagnose, format, validate } from "@domphy/doctor";
5
+ var ORIGIN = process.env.DOMPHY_ORIGIN ?? "https://www.domphy.com";
6
+ function appManifestSetting() {
7
+ return process.env.DOMPHY_APP_MANIFEST ?? "./app-manifest.json";
8
+ }
9
+ var cache = null;
10
+ async function loadManifest() {
11
+ if (cache) return cache;
12
+ const res = await fetch(`${ORIGIN}/manifest.json`);
13
+ if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);
14
+ cache = await res.json();
15
+ return cache;
16
+ }
17
+ async function listPatches() {
18
+ const m = await loadManifest();
19
+ return m.patches.map(
20
+ (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : ""} \u2014 ${p.signature}`
21
+ ).join("\n");
22
+ }
23
+ async function getPatch(name) {
24
+ const m = await loadManifest();
25
+ const patch = m.patches.find((p) => p.name === name);
26
+ if (!patch) {
27
+ const near = m.patches.filter((p) => p.name.includes(name) || name.includes(p.name)).map((p) => p.name);
28
+ return `No patch named "${name}".${near.length ? ` Did you mean: ${near.join(", ")}?` : ""}`;
29
+ }
30
+ return JSON.stringify(patch, null, 2);
31
+ }
32
+ async function listPackages() {
33
+ const m = await loadManifest();
34
+ return m.packages.map((p) => `${p.name}@${p.version} \u2014 ${p.description}`).join("\n");
35
+ }
36
+ async function getRules() {
37
+ const res = await fetch(`${ORIGIN}/llms.txt`);
38
+ if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);
39
+ return res.text();
40
+ }
41
+ function diagnoseTree(elementJson) {
42
+ let tree;
43
+ try {
44
+ tree = JSON.parse(elementJson);
45
+ } catch (error) {
46
+ return `Invalid JSON: ${error.message}`;
47
+ }
48
+ return format(diagnose(tree));
49
+ }
50
+ function validateTree(elementJson) {
51
+ let tree;
52
+ try {
53
+ tree = JSON.parse(elementJson);
54
+ } catch (error) {
55
+ return `Invalid JSON: ${error.message}`;
56
+ }
57
+ return JSON.stringify(validate(tree), null, 2);
58
+ }
59
+ function appManifestPath() {
60
+ const setting = appManifestSetting();
61
+ return isAbsolute(setting) ? setting : resolve(process.cwd(), setting);
62
+ }
63
+ async function loadAppBlocks() {
64
+ const text = await readFile(appManifestPath(), "utf8");
65
+ return JSON.parse(text);
66
+ }
67
+ function missingManifestHint() {
68
+ return `No app-manifest found at "${appManifestPath()}". Generate it with \`node apps/web/scripts/app-manifest.mjs <srcDir> <outFile>\` and point DOMPHY_APP_MANIFEST at the output (default ./app-manifest.json).`;
69
+ }
70
+ async function listAppBlocks() {
71
+ let blocks;
72
+ try {
73
+ blocks = await loadAppBlocks();
74
+ } catch {
75
+ return missingManifestHint();
76
+ }
77
+ if (blocks.length === 0) {
78
+ return "The app-manifest is empty \u2014 no exported Domphy blocks were found.";
79
+ }
80
+ return blocks.map((b) => `${b.name} [${b.kind}] \u2014 ${b.signature} (${b.file})`).join("\n");
81
+ }
82
+ async function getAppBlock(name) {
83
+ let blocks;
84
+ try {
85
+ blocks = await loadAppBlocks();
86
+ } catch {
87
+ return missingManifestHint();
88
+ }
89
+ const block = blocks.find((b) => b.name === name);
90
+ if (!block) {
91
+ const near = blocks.filter((b) => b.name.includes(name) || name.includes(b.name)).map((b) => b.name);
92
+ return `No app block named "${name}".${near.length ? ` Did you mean: ${near.join(", ")}?` : ""}`;
93
+ }
94
+ let source;
95
+ try {
96
+ source = await readBlockSource(block.file);
97
+ } catch (error) {
98
+ source = `// Could not read source: ${error.message}`;
99
+ }
100
+ return JSON.stringify(
101
+ {
102
+ name: block.name,
103
+ kind: block.kind,
104
+ file: block.file,
105
+ signature: block.signature,
106
+ jsdoc: block.jsdoc,
107
+ exportKind: block.exportKind,
108
+ source
109
+ },
110
+ null,
111
+ 2
112
+ );
113
+ }
114
+ async function readBlockSource(repoRelativeFile) {
115
+ const manifestDir = dirname(appManifestPath());
116
+ const candidates = [
117
+ resolve(manifestDir, "../../..", repoRelativeFile),
118
+ resolve(process.cwd(), repoRelativeFile),
119
+ resolve(manifestDir, repoRelativeFile)
120
+ ];
121
+ let lastError;
122
+ for (const candidate of candidates) {
123
+ try {
124
+ return await readFile(candidate, "utf8");
125
+ } catch (error) {
126
+ lastError = error;
127
+ }
128
+ }
129
+ throw lastError instanceof Error ? lastError : new Error(`file not found: ${repoRelativeFile}`);
130
+ }
131
+
132
+ export {
133
+ loadManifest,
134
+ listPatches,
135
+ getPatch,
136
+ listPackages,
137
+ getRules,
138
+ diagnoseTree,
139
+ validateTree,
140
+ listAppBlocks,
141
+ getAppBlock
142
+ };
143
+ //# sourceMappingURL=chunk-6UXRYQDB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools.ts"],"sourcesContent":["import { readFile } from \"node:fs/promises\";\r\nimport { dirname, isAbsolute, resolve } from \"node:path\";\r\nimport { diagnose, format, validate } from \"@domphy/doctor\";\r\n\r\n/**\r\n * Pure tool implementations for the Domphy MCP server. Kept transport-free so\r\n * they are unit-testable. The server (index.ts) wires these to MCP requests.\r\n */\r\n\r\nconst ORIGIN = process.env.DOMPHY_ORIGIN ?? \"https://www.domphy.com\";\r\n\r\n// Path to the app-block registry produced by `apps/web/scripts/app-manifest.mjs`.\r\n// Read lazily (per call) so the env var can be set after this module loads, and\r\n// overridable so the same MCP server can serve any app's blocks.\r\nfunction appManifestSetting(): string {\r\n return process.env.DOMPHY_APP_MANIFEST ?? \"./app-manifest.json\";\r\n}\r\n\r\ninterface Manifest {\r\n version: string;\r\n packages: Array<{\r\n name: string;\r\n version: string;\r\n description: string;\r\n subpaths: string[];\r\n peerDependencies: string[];\r\n }>;\r\n patches: Array<{\r\n name: string;\r\n hostTag: string | null;\r\n signature: string;\r\n doc: string;\r\n source: string;\r\n }>;\r\n}\r\n\r\nlet cache: Manifest | null = null;\r\n\r\nexport async function loadManifest(): Promise<Manifest> {\r\n if (cache) return cache;\r\n const res = await fetch(`${ORIGIN}/manifest.json`);\r\n if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);\r\n cache = (await res.json()) as Manifest;\r\n return cache;\r\n}\r\n\r\nexport async function listPatches(): Promise<string> {\r\n const m = await loadManifest();\r\n return m.patches\r\n .map(\r\n (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : \"\"} — ${p.signature}`,\r\n )\r\n .join(\"\\n\");\r\n}\r\n\r\nexport async function getPatch(name: string): Promise<string> {\r\n const m = await loadManifest();\r\n const patch = m.patches.find((p) => p.name === name);\r\n if (!patch) {\r\n const near = m.patches\r\n .filter((p) => p.name.includes(name) || name.includes(p.name))\r\n .map((p) => p.name);\r\n return `No patch named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\r\n }\r\n return JSON.stringify(patch, null, 2);\r\n}\r\n\r\nexport async function listPackages(): Promise<string> {\r\n const m = await loadManifest();\r\n return m.packages\r\n .map((p) => `${p.name}@${p.version} — ${p.description}`)\r\n .join(\"\\n\");\r\n}\r\n\r\nexport async function getRules(): Promise<string> {\r\n const res = await fetch(`${ORIGIN}/llms.txt`);\r\n if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);\r\n return res.text();\r\n}\r\n\r\n/** Runs @domphy/doctor on a JSON element tree (static parts only). */\r\nexport function diagnoseTree(elementJson: string): string {\r\n let tree: unknown;\r\n try {\r\n tree = JSON.parse(elementJson);\r\n } catch (error) {\r\n return `Invalid JSON: ${(error as Error).message}`;\r\n }\r\n return format(diagnose(tree));\r\n}\r\n\r\n/**\r\n * Runs @domphy/doctor's aggregate `validate()` on a JSON element tree and\r\n * returns the structured report (ok flag, issues, severity counts) as JSON.\r\n */\r\nexport function validateTree(elementJson: string): string {\r\n let tree: unknown;\r\n try {\r\n tree = JSON.parse(elementJson);\r\n } catch (error) {\r\n return `Invalid JSON: ${(error as Error).message}`;\r\n }\r\n return JSON.stringify(validate(tree), null, 2);\r\n}\r\n\r\n// --- app-block registry (an app's OWN reusable Domphy blocks) ---\r\n\r\ninterface AppBlock {\r\n name: string;\r\n kind: \"block\" | \"patch\";\r\n /** Repo-relative path of the file the block is declared in. */\r\n file: string;\r\n signature: string;\r\n jsdoc: string;\r\n exportKind: \"default\" | \"named\";\r\n}\r\n\r\n/** Resolves the app-manifest path against the manifest dir / cwd as needed. */\r\nfunction appManifestPath(): string {\r\n const setting = appManifestSetting();\r\n return isAbsolute(setting) ? setting : resolve(process.cwd(), setting);\r\n}\r\n\r\nasync function loadAppBlocks(): Promise<AppBlock[]> {\r\n const text = await readFile(appManifestPath(), \"utf8\");\r\n return JSON.parse(text) as AppBlock[];\r\n}\r\n\r\nfunction missingManifestHint(): string {\r\n return (\r\n `No app-manifest found at \"${appManifestPath()}\". ` +\r\n \"Generate it with `node apps/web/scripts/app-manifest.mjs <srcDir> <outFile>` \" +\r\n \"and point DOMPHY_APP_MANIFEST at the output (default ./app-manifest.json).\"\r\n );\r\n}\r\n\r\n/** Lists the app's own blocks (name + signature + file) from the app-manifest. */\r\nexport async function listAppBlocks(): Promise<string> {\r\n let blocks: AppBlock[];\r\n try {\r\n blocks = await loadAppBlocks();\r\n } catch {\r\n return missingManifestHint();\r\n }\r\n if (blocks.length === 0) {\r\n return \"The app-manifest is empty — no exported Domphy blocks were found.\";\r\n }\r\n return blocks\r\n .map((b) => `${b.name} [${b.kind}] — ${b.signature} (${b.file})`)\r\n .join(\"\\n\");\r\n}\r\n\r\n/**\r\n * Returns one app block's full source (the file at the manifest's `file`),\r\n * along with its signature and jsdoc.\r\n */\r\nexport async function getAppBlock(name: string): Promise<string> {\r\n let blocks: AppBlock[];\r\n try {\r\n blocks = await loadAppBlocks();\r\n } catch {\r\n return missingManifestHint();\r\n }\r\n const block = blocks.find((b) => b.name === name);\r\n if (!block) {\r\n const near = blocks\r\n .filter((b) => b.name.includes(name) || name.includes(b.name))\r\n .map((b) => b.name);\r\n return `No app block named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\r\n }\r\n // The manifest stores repo-relative paths; resolve them against the repo root,\r\n // which is the manifest's directory walked up out of apps/web/public, falling\r\n // back to cwd-relative resolution when that layout does not apply.\r\n let source: string;\r\n try {\r\n source = await readBlockSource(block.file);\r\n } catch (error) {\r\n source = `// Could not read source: ${(error as Error).message}`;\r\n }\r\n return JSON.stringify(\r\n {\r\n name: block.name,\r\n kind: block.kind,\r\n file: block.file,\r\n signature: block.signature,\r\n jsdoc: block.jsdoc,\r\n exportKind: block.exportKind,\r\n source,\r\n },\r\n null,\r\n 2,\r\n );\r\n}\r\n\r\n/** Reads a block's source file, resolving its repo-relative `file` path. */\r\nasync function readBlockSource(repoRelativeFile: string): Promise<string> {\r\n // The app-manifest lives at <repo>/apps/web/public/app-manifest.json by\r\n // default, so the repo root is three levels up from the manifest directory.\r\n const manifestDir = dirname(appManifestPath());\r\n const candidates = [\r\n resolve(manifestDir, \"../../..\", repoRelativeFile),\r\n resolve(process.cwd(), repoRelativeFile),\r\n resolve(manifestDir, repoRelativeFile),\r\n ];\r\n let lastError: unknown;\r\n for (const candidate of candidates) {\r\n try {\r\n return await readFile(candidate, \"utf8\");\r\n } catch (error) {\r\n lastError = error;\r\n }\r\n }\r\n throw lastError instanceof Error\r\n ? lastError\r\n : new Error(`file not found: ${repoRelativeFile}`);\r\n}\r\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  diagnoseTree,
4
+ getAppBlock,
4
5
  getPatch,
5
6
  getRules,
7
+ listAppBlocks,
6
8
  listPackages,
7
- listPatches
8
- } from "./chunk-QJ7O62KB.js";
9
+ listPatches,
10
+ validateTree
11
+ } from "./chunk-6UXRYQDB.js";
9
12
 
10
13
  // src/index.ts
11
14
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -47,7 +50,7 @@ var tools = [
47
50
  },
48
51
  {
49
52
  name: "domphy_diagnose",
50
- description: "Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, \u2026).",
53
+ description: "Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, missing/duplicate/unstable _key, \u2026).",
51
54
  inputSchema: {
52
55
  type: "object",
53
56
  properties: {
@@ -58,6 +61,36 @@ var tools = [
58
61
  },
59
62
  required: ["element"]
60
63
  }
64
+ },
65
+ {
66
+ name: "domphy_validate",
67
+ description: "Run @domphy/doctor's aggregate validate() on a JSON Domphy element tree. Returns a structured report { ok, issues, summary } with severity counts.",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ element: {
72
+ type: "string",
73
+ description: "JSON of the Domphy element tree"
74
+ }
75
+ },
76
+ required: ["element"]
77
+ }
78
+ },
79
+ {
80
+ name: "domphy_list_app_blocks",
81
+ description: "List the current app's OWN reusable Domphy blocks (name, kind, signature, file) from its app-manifest.json. Run `app-manifest.mjs` first if absent.",
82
+ inputSchema: { type: "object", properties: {} }
83
+ },
84
+ {
85
+ name: "domphy_get_app_block",
86
+ description: "Get one app block's full source plus signature and jsdoc, by name, from the app-manifest.",
87
+ inputSchema: {
88
+ type: "object",
89
+ properties: {
90
+ name: { type: "string", description: "app block name, e.g. App" }
91
+ },
92
+ required: ["name"]
93
+ }
61
94
  }
62
95
  ];
63
96
  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
@@ -82,6 +115,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
82
115
  case "domphy_diagnose":
83
116
  text = diagnoseTree(String(args.element));
84
117
  break;
118
+ case "domphy_validate":
119
+ text = validateTree(String(args.element));
120
+ break;
121
+ case "domphy_list_app_blocks":
122
+ text = await listAppBlocks();
123
+ break;
124
+ case "domphy_get_app_block":
125
+ text = await getAppBlock(String(args.name));
126
+ break;
85
127
  default:
86
128
  text = `Unknown tool: ${name}`;
87
129
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n diagnoseTree,\n getPatch,\n getRules,\n listPackages,\n listPatches,\n} from \"./tools.js\";\n\nconst server = new Server(\n { name: \"domphy\", version: \"0.10.0\" },\n { capabilities: { tools: {} } },\n);\n\nconst tools = [\n {\n name: \"domphy_list_patches\",\n description: \"List every @domphy/ui patch with its host tag and signature.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_get_patch\",\n description:\n \"Get one patch's full contract (host tag, signature, doc, source).\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\", description: \"patch name, e.g. button\" },\n },\n required: [\"name\"],\n },\n },\n {\n name: \"domphy_list_packages\",\n description: \"List all @domphy/* packages with versions and descriptions.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_rules\",\n description: \"Get the Domphy code-generation rules (llms.txt) to follow.\",\n inputSchema: { type: \"object\", properties: {} },\n },\n {\n name: \"domphy_diagnose\",\n description:\n \"Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, …).\",\n inputSchema: {\n type: \"object\",\n properties: {\n element: {\n type: \"string\",\n description: \"JSON of the Domphy element tree\",\n },\n },\n required: [\"element\"],\n },\n },\n];\n\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));\n\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name } = request.params;\n const args = (request.params.arguments ?? {}) as Record<string, unknown>;\n let text: string;\n try {\n switch (name) {\n case \"domphy_list_patches\":\n text = await listPatches();\n break;\n case \"domphy_get_patch\":\n text = await getPatch(String(args.name));\n break;\n case \"domphy_list_packages\":\n text = await listPackages();\n break;\n case \"domphy_rules\":\n text = await getRules();\n break;\n case \"domphy_diagnose\":\n text = diagnoseTree(String(args.element));\n break;\n default:\n text = `Unknown tool: ${name}`;\n }\n } catch (error) {\n text = `Error: ${(error as Error).message}`;\n }\n return { content: [{ type: \"text\", text }] };\n});\n\nawait server.connect(new StdioServerTransport());\n"],"mappings":";;;;;;;;;;AACA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AASP,IAAM,SAAS,IAAI;AAAA,EACjB,EAAE,MAAM,UAAU,SAAS,SAAS;AAAA,EACpC,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,EAAE;AAChC;AAEA,IAAM,QAAQ;AAAA,EACZ;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,MAAM,EAAE,MAAM,UAAU,aAAa,0BAA0B;AAAA,MACjE;AAAA,MACA,UAAU,CAAC,MAAM;AAAA,IACnB;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa,EAAE,MAAM,UAAU,YAAY,CAAC,EAAE;AAAA,EAChD;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aACE;AAAA,IACF,aAAa;AAAA,MACX,MAAM;AAAA,MACN,YAAY;AAAA,QACV,SAAS;AAAA,UACP,MAAM;AAAA,UACN,aAAa;AAAA,QACf;AAAA,MACF;AAAA,MACA,UAAU,CAAC,SAAS;AAAA,IACtB;AAAA,EACF;AACF;AAEA,OAAO,kBAAkB,wBAAwB,aAAa,EAAE,MAAM,EAAE;AAExE,OAAO,kBAAkB,uBAAuB,OAAO,YAAY;AACjE,QAAM,EAAE,KAAK,IAAI,QAAQ;AACzB,QAAM,OAAQ,QAAQ,OAAO,aAAa,CAAC;AAC3C,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,MAAM,YAAY;AACzB;AAAA,MACF,KAAK;AACH,eAAO,MAAM,SAAS,OAAO,KAAK,IAAI,CAAC;AACvC;AAAA,MACF,KAAK;AACH,eAAO,MAAM,aAAa;AAC1B;AAAA,MACF,KAAK;AACH,eAAO,MAAM,SAAS;AACtB;AAAA,MACF,KAAK;AACH,eAAO,aAAa,OAAO,KAAK,OAAO,CAAC;AACxC;AAAA,MACF;AACE,eAAO,iBAAiB,IAAI;AAAA,IAChC;AAAA,EACF,SAAS,OAAO;AACd,WAAO,UAAW,MAAgB,OAAO;AAAA,EAC3C;AACA,SAAO,EAAE,SAAS,CAAC,EAAE,MAAM,QAAQ,KAAK,CAAC,EAAE;AAC7C,CAAC;AAED,MAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\r\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\r\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\r\nimport {\r\n CallToolRequestSchema,\r\n ListToolsRequestSchema,\r\n} from \"@modelcontextprotocol/sdk/types.js\";\r\nimport {\r\n diagnoseTree,\r\n getAppBlock,\r\n getPatch,\r\n getRules,\r\n listAppBlocks,\r\n listPackages,\r\n listPatches,\r\n validateTree,\r\n} from \"./tools.js\";\r\n\r\nconst server = new Server(\r\n { name: \"domphy\", version: \"0.10.0\" },\r\n { capabilities: { tools: {} } },\r\n);\r\n\r\nconst tools = [\r\n {\r\n name: \"domphy_list_patches\",\r\n description: \"List every @domphy/ui patch with its host tag and signature.\",\r\n inputSchema: { type: \"object\", properties: {} },\r\n },\r\n {\r\n name: \"domphy_get_patch\",\r\n description:\r\n \"Get one patch's full contract (host tag, signature, doc, source).\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"patch name, e.g. button\" },\r\n },\r\n required: [\"name\"],\r\n },\r\n },\r\n {\r\n name: \"domphy_list_packages\",\r\n description: \"List all @domphy/* packages with versions and descriptions.\",\r\n inputSchema: { type: \"object\", properties: {} },\r\n },\r\n {\r\n name: \"domphy_rules\",\r\n description: \"Get the Domphy code-generation rules (llms.txt) to follow.\",\r\n inputSchema: { type: \"object\", properties: {} },\r\n },\r\n {\r\n name: \"domphy_diagnose\",\r\n description:\r\n \"Run @domphy/doctor on a JSON Domphy element tree and return issues to fix (inline-typography, void-content, unknown-tag, missing/duplicate/unstable _key, …).\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n element: {\r\n type: \"string\",\r\n description: \"JSON of the Domphy element tree\",\r\n },\r\n },\r\n required: [\"element\"],\r\n },\r\n },\r\n {\r\n name: \"domphy_validate\",\r\n description:\r\n \"Run @domphy/doctor's aggregate validate() on a JSON Domphy element tree. Returns a structured report { ok, issues, summary } with severity counts.\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n element: {\r\n type: \"string\",\r\n description: \"JSON of the Domphy element tree\",\r\n },\r\n },\r\n required: [\"element\"],\r\n },\r\n },\r\n {\r\n name: \"domphy_list_app_blocks\",\r\n description:\r\n \"List the current app's OWN reusable Domphy blocks (name, kind, signature, file) from its app-manifest.json. Run `app-manifest.mjs` first if absent.\",\r\n inputSchema: { type: \"object\", properties: {} },\r\n },\r\n {\r\n name: \"domphy_get_app_block\",\r\n description:\r\n \"Get one app block's full source plus signature and jsdoc, by name, from the app-manifest.\",\r\n inputSchema: {\r\n type: \"object\",\r\n properties: {\r\n name: { type: \"string\", description: \"app block name, e.g. App\" },\r\n },\r\n required: [\"name\"],\r\n },\r\n },\r\n];\r\n\r\nserver.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));\r\n\r\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\r\n const { name } = request.params;\r\n const args = (request.params.arguments ?? {}) as Record<string, unknown>;\r\n let text: string;\r\n try {\r\n switch (name) {\r\n case \"domphy_list_patches\":\r\n text = await listPatches();\r\n break;\r\n case \"domphy_get_patch\":\r\n text = await getPatch(String(args.name));\r\n break;\r\n case \"domphy_list_packages\":\r\n text = await listPackages();\r\n break;\r\n case \"domphy_rules\":\r\n text = await getRules();\r\n break;\r\n case \"domphy_diagnose\":\r\n text = diagnoseTree(String(args.element));\r\n break;\r\n case \"domphy_validate\":\r\n text = validateTree(String(args.element));\r\n break;\r\n case \"domphy_list_app_blocks\":\r\n text = await listAppBlocks();\r\n break;\r\n case \"domphy_get_app_block\":\r\n text = await getAppBlock(String(args.name));\r\n break;\r\n default:\r\n text = `Unknown tool: ${name}`;\r\n }\r\n } catch (error) {\r\n text = `Error: ${(error as Error).message}`;\r\n }\r\n return { content: [{ type: \"text\", text }] };\r\n});\r\n\r\nawait server.connect(new StdioServerTransport());\r\n"],"mappings":"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","names":[]}
package/dist/tools.d.ts CHANGED
@@ -22,5 +22,17 @@ declare function listPackages(): Promise<string>;
22
22
  declare function getRules(): Promise<string>;
23
23
  /** Runs @domphy/doctor on a JSON element tree (static parts only). */
24
24
  declare function diagnoseTree(elementJson: string): string;
25
+ /**
26
+ * Runs @domphy/doctor's aggregate `validate()` on a JSON element tree and
27
+ * returns the structured report (ok flag, issues, severity counts) as JSON.
28
+ */
29
+ declare function validateTree(elementJson: string): string;
30
+ /** Lists the app's own blocks (name + signature + file) from the app-manifest. */
31
+ declare function listAppBlocks(): Promise<string>;
32
+ /**
33
+ * Returns one app block's full source (the file at the manifest's `file`),
34
+ * along with its signature and jsdoc.
35
+ */
36
+ declare function getAppBlock(name: string): Promise<string>;
25
37
 
26
- export { diagnoseTree, getPatch, getRules, listPackages, listPatches, loadManifest };
38
+ export { diagnoseTree, getAppBlock, getPatch, getRules, listAppBlocks, listPackages, listPatches, loadManifest, validateTree };
package/dist/tools.js CHANGED
@@ -1,17 +1,23 @@
1
1
  import {
2
2
  diagnoseTree,
3
+ getAppBlock,
3
4
  getPatch,
4
5
  getRules,
6
+ listAppBlocks,
5
7
  listPackages,
6
8
  listPatches,
7
- loadManifest
8
- } from "./chunk-QJ7O62KB.js";
9
+ loadManifest,
10
+ validateTree
11
+ } from "./chunk-6UXRYQDB.js";
9
12
  export {
10
13
  diagnoseTree,
14
+ getAppBlock,
11
15
  getPatch,
12
16
  getRules,
17
+ listAppBlocks,
13
18
  listPackages,
14
19
  listPatches,
15
- loadManifest
20
+ loadManifest,
21
+ validateTree
16
22
  };
17
23
  //# sourceMappingURL=tools.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@domphy/mcp",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Domphy MCP server - exposes patches, packages, rules, and the doctor to MCP-capable AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,17 +37,17 @@
37
37
  },
38
38
  "dependencies": {
39
39
  "@modelcontextprotocol/sdk": "^1.29.0",
40
- "@domphy/doctor": "^0.12.0"
40
+ "@domphy/doctor": "^0.14.0"
41
41
  },
42
42
  "peerDependencies": {
43
- "@domphy/core": "^0.12.0"
43
+ "@domphy/core": "^0.14.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^25.9.2",
47
47
  "tsup": "^8.5.0",
48
48
  "typescript": "^5.8.3",
49
49
  "vitest": "^4.0.18",
50
- "@domphy/core": "0.12.0"
50
+ "@domphy/core": "0.14.0"
51
51
  },
52
52
  "files": [
53
53
  "dist",
@@ -1,54 +0,0 @@
1
- // src/tools.ts
2
- import { diagnose, format } from "@domphy/doctor";
3
- var ORIGIN = process.env.DOMPHY_ORIGIN ?? "https://www.domphy.com";
4
- var cache = null;
5
- async function loadManifest() {
6
- if (cache) return cache;
7
- const res = await fetch(`${ORIGIN}/manifest.json`);
8
- if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);
9
- cache = await res.json();
10
- return cache;
11
- }
12
- async function listPatches() {
13
- const m = await loadManifest();
14
- return m.patches.map(
15
- (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : ""} \u2014 ${p.signature}`
16
- ).join("\n");
17
- }
18
- async function getPatch(name) {
19
- const m = await loadManifest();
20
- const patch = m.patches.find((p) => p.name === name);
21
- if (!patch) {
22
- const near = m.patches.filter((p) => p.name.includes(name) || name.includes(p.name)).map((p) => p.name);
23
- return `No patch named "${name}".${near.length ? ` Did you mean: ${near.join(", ")}?` : ""}`;
24
- }
25
- return JSON.stringify(patch, null, 2);
26
- }
27
- async function listPackages() {
28
- const m = await loadManifest();
29
- return m.packages.map((p) => `${p.name}@${p.version} \u2014 ${p.description}`).join("\n");
30
- }
31
- async function getRules() {
32
- const res = await fetch(`${ORIGIN}/llms.txt`);
33
- if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);
34
- return res.text();
35
- }
36
- function diagnoseTree(elementJson) {
37
- let tree;
38
- try {
39
- tree = JSON.parse(elementJson);
40
- } catch (error) {
41
- return `Invalid JSON: ${error.message}`;
42
- }
43
- return format(diagnose(tree));
44
- }
45
-
46
- export {
47
- loadManifest,
48
- listPatches,
49
- getPatch,
50
- listPackages,
51
- getRules,
52
- diagnoseTree
53
- };
54
- //# sourceMappingURL=chunk-QJ7O62KB.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/tools.ts"],"sourcesContent":["import { diagnose, format } from \"@domphy/doctor\";\n\n/**\n * Pure tool implementations for the Domphy MCP server. Kept transport-free so\n * they are unit-testable. The server (index.ts) wires these to MCP requests.\n */\n\nconst ORIGIN = process.env.DOMPHY_ORIGIN ?? \"https://www.domphy.com\";\n\ninterface Manifest {\n version: string;\n packages: Array<{\n name: string;\n version: string;\n description: string;\n subpaths: string[];\n peerDependencies: string[];\n }>;\n patches: Array<{\n name: string;\n hostTag: string | null;\n signature: string;\n doc: string;\n source: string;\n }>;\n}\n\nlet cache: Manifest | null = null;\n\nexport async function loadManifest(): Promise<Manifest> {\n if (cache) return cache;\n const res = await fetch(`${ORIGIN}/manifest.json`);\n if (!res.ok) throw new Error(`Failed to fetch manifest: ${res.status}`);\n cache = (await res.json()) as Manifest;\n return cache;\n}\n\nexport async function listPatches(): Promise<string> {\n const m = await loadManifest();\n return m.patches\n .map(\n (p) => `${p.name}${p.hostTag ? ` <${p.hostTag}>` : \"\"} — ${p.signature}`,\n )\n .join(\"\\n\");\n}\n\nexport async function getPatch(name: string): Promise<string> {\n const m = await loadManifest();\n const patch = m.patches.find((p) => p.name === name);\n if (!patch) {\n const near = m.patches\n .filter((p) => p.name.includes(name) || name.includes(p.name))\n .map((p) => p.name);\n return `No patch named \"${name}\".${near.length ? ` Did you mean: ${near.join(\", \")}?` : \"\"}`;\n }\n return JSON.stringify(patch, null, 2);\n}\n\nexport async function listPackages(): Promise<string> {\n const m = await loadManifest();\n return m.packages\n .map((p) => `${p.name}@${p.version} — ${p.description}`)\n .join(\"\\n\");\n}\n\nexport async function getRules(): Promise<string> {\n const res = await fetch(`${ORIGIN}/llms.txt`);\n if (!res.ok) throw new Error(`Failed to fetch rules: ${res.status}`);\n return res.text();\n}\n\n/** Runs @domphy/doctor on a JSON element tree (static parts only). */\nexport function diagnoseTree(elementJson: string): string {\n let tree: unknown;\n try {\n tree = JSON.parse(elementJson);\n } catch (error) {\n return `Invalid JSON: ${(error as Error).message}`;\n }\n return format(diagnose(tree));\n}\n"],"mappings":";AAAA,SAAS,UAAU,cAAc;AAOjC,IAAM,SAAS,QAAQ,IAAI,iBAAiB;AAoB5C,IAAI,QAAyB;AAE7B,eAAsB,eAAkC;AACtD,MAAI,MAAO,QAAO;AAClB,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,gBAAgB;AACjD,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,6BAA6B,IAAI,MAAM,EAAE;AACtE,UAAS,MAAM,IAAI,KAAK;AACxB,SAAO;AACT;AAEA,eAAsB,cAA+B;AACnD,QAAM,IAAI,MAAM,aAAa;AAC7B,SAAO,EAAE,QACN;AAAA,IACC,CAAC,MAAM,GAAG,EAAE,IAAI,GAAG,EAAE,UAAU,KAAK,EAAE,OAAO,MAAM,EAAE,WAAM,EAAE,SAAS;AAAA,EACxE,EACC,KAAK,IAAI;AACd;AAEA,eAAsB,SAAS,MAA+B;AAC5D,QAAM,IAAI,MAAM,aAAa;AAC7B,QAAM,QAAQ,EAAE,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AACnD,MAAI,CAAC,OAAO;AACV,UAAM,OAAO,EAAE,QACZ,OAAO,CAAC,MAAM,EAAE,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,EAAE,IAAI,CAAC,EAC5D,IAAI,CAAC,MAAM,EAAE,IAAI;AACpB,WAAO,mBAAmB,IAAI,KAAK,KAAK,SAAS,kBAAkB,KAAK,KAAK,IAAI,CAAC,MAAM,EAAE;AAAA,EAC5F;AACA,SAAO,KAAK,UAAU,OAAO,MAAM,CAAC;AACtC;AAEA,eAAsB,eAAgC;AACpD,QAAM,IAAI,MAAM,aAAa;AAC7B,SAAO,EAAE,SACN,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,EAAE,OAAO,WAAM,EAAE,WAAW,EAAE,EACtD,KAAK,IAAI;AACd;AAEA,eAAsB,WAA4B;AAChD,QAAM,MAAM,MAAM,MAAM,GAAG,MAAM,WAAW;AAC5C,MAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,0BAA0B,IAAI,MAAM,EAAE;AACnE,SAAO,IAAI,KAAK;AAClB;AAGO,SAAS,aAAa,aAA6B;AACxD,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAM,WAAW;AAAA,EAC/B,SAAS,OAAO;AACd,WAAO,iBAAkB,MAAgB,OAAO;AAAA,EAClD;AACA,SAAO,OAAO,SAAS,IAAI,CAAC;AAC9B;","names":[]}