ply-ui-mcp 0.1.30 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -6
- package/dist/index.js +224 -49
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -116,7 +116,7 @@ Metadata always. Free source only when `includeSource` is true. Pro source is ne
|
|
|
116
116
|
{ "names": ["button", "card"], "cwd": "/path/to/your-app" }
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
-
Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process (or `licenseKey` on the tool).
|
|
119
|
+
Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process (or `licenseKey` on the tool). The result includes `missingPackages` and, when something is missing, `installCommand`. `overwrite: true` asks the host to confirm before any file is replaced.
|
|
120
120
|
|
|
121
121
|
### `init_project`
|
|
122
122
|
|
|
@@ -124,7 +124,7 @@ Runs `ply-ui-cli add --yes`. Pro names need `PLY_LICENSE_KEY` on the MCP process
|
|
|
124
124
|
{ "cwd": "/path/to/your-app" }
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, and
|
|
127
|
+
Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, the Cursor rule, snippets, and the UI design skill at `.cursor/skills/ply-ui-design/` and `.agents/skills/ply-ui-design/` when those files are missing. `refreshEditorKit: true` replaces a kit that is already there.
|
|
128
128
|
|
|
129
129
|
### `doctor`
|
|
130
130
|
|
|
@@ -132,7 +132,7 @@ Runs `ply-ui-cli init --yes`. Writes `ply-ui.json`, styles, icons, and editor ru
|
|
|
132
132
|
{ "cwd": "/path/to/your-app" }
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
Read-only. `isError` is set when `ply-ui-cli doctor` exits non-zero.
|
|
135
|
+
Read-only. The result lists each check. `isError` is set when `ply-ui-cli doctor` exits non-zero.
|
|
136
136
|
|
|
137
137
|
### `diff_components`
|
|
138
138
|
|
|
@@ -148,7 +148,7 @@ Omit `names` (or pass `[]`) to diff every tracked component. Read-only.
|
|
|
148
148
|
{ "names": ["card"], "cwd": "/path/to/your-app", "force": false, "overwriteLocal": false, "merge": false }
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
Runs `ply-ui-cli update --yes`. `force` takes upstream on conflicts. `merge` applies a 3-way merge. `overwriteLocal` reverts files you edited that upstream did not change.
|
|
151
|
+
Runs `ply-ui-cli update --yes`. The result lists one row per file. `force` takes upstream on conflicts. `merge` applies a 3-way merge. `overwriteLocal` reverts files you edited that upstream did not change. `force` or `overwriteLocal` asks the host to confirm before replace.
|
|
152
152
|
|
|
153
153
|
## Resources
|
|
154
154
|
|
|
@@ -197,10 +197,10 @@ Run npx ply-ui-cli doctor. It checks ply-ui.json, the Angular workspace, @angula
|
|
|
197
197
|
Open Theme Studio at https://ply-ui.com/theme/ or the docs customizer, pick a preset or hue, then copy the Tailwind v4 @theme block into src/tailwind.css. ply-ui.css points --ply-primary and Tailwind blue-* utilities at that palette (--ply-brand and --ply-scale-*). The live preview shows buttons, tabs, forms, and overlays together.
|
|
198
198
|
|
|
199
199
|
**Can AI agents install Ply?**
|
|
200
|
-
Yes. npx -y ply-ui-mcp runs over stdio in Cursor, VS Code, Claude Code, Claude Desktop, Codex, Antigravity, Grok Build, Kimi Code, Qwen Code, Windsurf, and other local hosts. ChatGPT and Gemini chat apps use the Streamable HTTP connector at https://mcp.ply-ui.com/mcp (catalog tools) or a local npx -y ply-ui-mcp --http without --read-only so add/init/update can see the project.
|
|
200
|
+
Yes. npx -y ply-ui-mcp runs over stdio in Cursor, VS Code, Claude Code, Claude Desktop, Codex, Antigravity, Grok Build, Kimi Code, Qwen Code, Windsurf, and other local hosts. ChatGPT and Gemini chat apps use the Streamable HTTP connector at https://mcp.ply-ui.com/mcp (catalog tools) or a local npx -y ply-ui-mcp --http without --read-only so add/init/update can see the project. doctor, add_components, and update_components return structuredContent: checks, missing packages with the install command, and one result per file. Hosts that can ask confirm an overwrite before replace. init_project accepts refreshEditorKit. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call. Setup for each host: https://ply-ui.com/getting-started/#ai-agents-mcp. Editors that skip MCP can copy the Cursor rule and snippet pack from https://ply-ui.com/getting-started/#editor-rules.
|
|
201
201
|
|
|
202
202
|
**What does init install for AI agents?**
|
|
203
|
-
npx ply-ui-cli init writes ply-ui.json, ply-ui.css, icon sprites, .cursor/rules/ply-ui.mdc, .vscode/ply-ui.code-snippets, and the UI design skill at .cursor/skills/ply-ui-design/ (SKILL.md, reference.md, examples.md) when those files are missing. The skill tells the agent to reuse ply-button, ply-card, and ply-input-group, keep one accent, and include loading, error, empty, and data states. It does not install components. Published copy: https://ply-ui.com/docs/ai/skills/ply-ui-design/SKILL.md. Walkthrough: https://ply-ui.com/learn/ply-ui-design-skill/.
|
|
203
|
+
npx ply-ui-cli init writes ply-ui.json, ply-ui.css, icon sprites, .cursor/rules/ply-ui.mdc, .vscode/ply-ui.code-snippets, and the UI design skill at .cursor/skills/ply-ui-design/ and .agents/skills/ply-ui-design/ (SKILL.md, reference.md, examples.md) when those files are missing. npx ply-ui-cli init --refresh-editor-kit replaces a kit that is already there. The skill tells the agent to reuse ply-button, ply-card, and ply-input-group, keep one accent, and include loading, error, empty, and data states. It does not install components. Published copy: https://ply-ui.com/docs/ai/skills/ply-ui-design/SKILL.md. Walkthrough: https://ply-ui.com/learn/ply-ui-design-skill/.
|
|
204
204
|
|
|
205
205
|
**Do AI agents use fewer tokens with Ply?**
|
|
206
206
|
Usually, yes. With Ply the agent copies a finished component (CLI or MCP) and wires it, instead of generating a toolbar, selection model, sanitizer, and SSR guards from a blank file. Token use still depends on the prompt and the model. A reconstructed Claude/Grok session for the rich text editor is at https://ply-ui.com/learn/ai-agent-tokens-rich-text-editor/ — that is a teaching simulation, not a lab benchmark.
|
package/dist/index.js
CHANGED
|
@@ -350,18 +350,28 @@ function installHint(name) {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
// src/result.ts
|
|
353
|
+
function asRecord(data) {
|
|
354
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
355
|
+
return data;
|
|
356
|
+
}
|
|
357
|
+
return void 0;
|
|
358
|
+
}
|
|
353
359
|
function okJson(data) {
|
|
360
|
+
const structuredContent = asRecord(data);
|
|
354
361
|
return {
|
|
355
|
-
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
362
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
363
|
+
...structuredContent ? { structuredContent } : {}
|
|
356
364
|
};
|
|
357
365
|
}
|
|
358
366
|
function failJson(message, extra = {}) {
|
|
367
|
+
const structuredContent = { ok: false, error: message, ...extra };
|
|
359
368
|
return {
|
|
360
369
|
isError: true,
|
|
370
|
+
structuredContent,
|
|
361
371
|
content: [
|
|
362
372
|
{
|
|
363
373
|
type: "text",
|
|
364
|
-
text: JSON.stringify(
|
|
374
|
+
text: JSON.stringify(structuredContent, null, 2)
|
|
365
375
|
}
|
|
366
376
|
]
|
|
367
377
|
};
|
|
@@ -582,7 +592,7 @@ async function searchComponents(args) {
|
|
|
582
592
|
// package.json
|
|
583
593
|
var package_default = {
|
|
584
594
|
name: "ply-ui-mcp",
|
|
585
|
-
version: "0.1.
|
|
595
|
+
version: "0.1.32",
|
|
586
596
|
description: "Ply MCP server \u2014 stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.",
|
|
587
597
|
type: "commonjs",
|
|
588
598
|
main: "dist/index.js",
|
|
@@ -644,7 +654,7 @@ var package_default = {
|
|
|
644
654
|
esbuild: "0.28.2",
|
|
645
655
|
"fast-uri": "3.1.8",
|
|
646
656
|
"proxy-addr": "2.0.8",
|
|
647
|
-
hono: "4.13.
|
|
657
|
+
hono: "4.13.13",
|
|
648
658
|
qs: "6.16.0"
|
|
649
659
|
}
|
|
650
660
|
};
|
|
@@ -653,6 +663,7 @@ var package_default = {
|
|
|
653
663
|
var PACKAGE_VERSION = package_default.version;
|
|
654
664
|
|
|
655
665
|
// src/catalog.ts
|
|
666
|
+
var SERVER_INSTRUCTIONS = "Search the catalog before inventing a component name. The hosted catalog cannot write files. A local install is init_project, then add_components. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call.";
|
|
656
667
|
var catalogAnnotations = {
|
|
657
668
|
readOnlyHint: true,
|
|
658
669
|
destructiveHint: false,
|
|
@@ -660,10 +671,13 @@ var catalogAnnotations = {
|
|
|
660
671
|
openWorldHint: true
|
|
661
672
|
};
|
|
662
673
|
function createCatalogMcpServer() {
|
|
663
|
-
const server = new import_mcp2.McpServer(
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
674
|
+
const server = new import_mcp2.McpServer(
|
|
675
|
+
{
|
|
676
|
+
name: MCP_SERVER_NAME,
|
|
677
|
+
version: PACKAGE_VERSION
|
|
678
|
+
},
|
|
679
|
+
{ instructions: SERVER_INSTRUCTIONS }
|
|
680
|
+
);
|
|
667
681
|
server.registerTool(
|
|
668
682
|
"list_components",
|
|
669
683
|
{
|
|
@@ -698,8 +712,44 @@ function createCatalogMcpServer() {
|
|
|
698
712
|
return server;
|
|
699
713
|
}
|
|
700
714
|
|
|
715
|
+
// src/elicit.ts
|
|
716
|
+
async function confirmReplace(server, message) {
|
|
717
|
+
try {
|
|
718
|
+
const result = await server.server.elicitInput({
|
|
719
|
+
mode: "form",
|
|
720
|
+
message,
|
|
721
|
+
requestedSchema: {
|
|
722
|
+
type: "object",
|
|
723
|
+
properties: {
|
|
724
|
+
replace: {
|
|
725
|
+
type: "boolean",
|
|
726
|
+
title: "Replace existing files",
|
|
727
|
+
description: "Overwrite the copies already in the project.",
|
|
728
|
+
default: false
|
|
729
|
+
}
|
|
730
|
+
},
|
|
731
|
+
required: ["replace"]
|
|
732
|
+
}
|
|
733
|
+
});
|
|
734
|
+
if (result.action === "accept" && result.content?.replace === true) return "replace";
|
|
735
|
+
return "keep";
|
|
736
|
+
} catch (err) {
|
|
737
|
+
const text = err instanceof Error ? err.message : String(err);
|
|
738
|
+
if (text.includes("does not support form elicitation")) return "unsupported";
|
|
739
|
+
throw err;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
async function resolveReplace(requested, confirm, message) {
|
|
743
|
+
if (!requested) return { apply: false };
|
|
744
|
+
if (!confirm) return { apply: true };
|
|
745
|
+
const decision = await confirm(message);
|
|
746
|
+
if (decision === "keep") return { apply: false, confirmation: "declined" };
|
|
747
|
+
if (decision === "unsupported") return { apply: true, confirmation: "unsupported" };
|
|
748
|
+
return { apply: true, confirmation: "accepted" };
|
|
749
|
+
}
|
|
750
|
+
|
|
701
751
|
// src/tools/add-components.ts
|
|
702
|
-
var
|
|
752
|
+
var import_zod6 = require("zod");
|
|
703
753
|
|
|
704
754
|
// src/cli.ts
|
|
705
755
|
var import_fs = __toESM(require("fs"));
|
|
@@ -775,18 +825,96 @@ function resolveProjectCwd(cwd) {
|
|
|
775
825
|
return import_path.default.resolve(root);
|
|
776
826
|
}
|
|
777
827
|
|
|
828
|
+
// src/cli-report.ts
|
|
829
|
+
var import_zod5 = require("zod");
|
|
830
|
+
var STATUS = {
|
|
831
|
+
"\u2714": "ok",
|
|
832
|
+
"\u26A0": "warn",
|
|
833
|
+
"\u2716": "error"
|
|
834
|
+
};
|
|
835
|
+
var FILE_ACTION = {
|
|
836
|
+
"\u2191": "updated",
|
|
837
|
+
"+": "added",
|
|
838
|
+
"\u2193": "reverted",
|
|
839
|
+
"=": "kept",
|
|
840
|
+
"\u22C8": "merged",
|
|
841
|
+
"\u26A0": "merge-conflict",
|
|
842
|
+
"\u21C4": "saved-aside"
|
|
843
|
+
};
|
|
844
|
+
var doctorOutput = import_zod5.z.looseObject({
|
|
845
|
+
ok: import_zod5.z.boolean(),
|
|
846
|
+
checks: import_zod5.z.array(
|
|
847
|
+
import_zod5.z.looseObject({
|
|
848
|
+
name: import_zod5.z.string(),
|
|
849
|
+
status: import_zod5.z.enum(["ok", "warn", "error"]),
|
|
850
|
+
message: import_zod5.z.string()
|
|
851
|
+
})
|
|
852
|
+
)
|
|
853
|
+
});
|
|
854
|
+
var addOutput = import_zod5.z.looseObject({
|
|
855
|
+
ok: import_zod5.z.boolean(),
|
|
856
|
+
missingPackages: import_zod5.z.array(import_zod5.z.string()),
|
|
857
|
+
installCommand: import_zod5.z.string().optional()
|
|
858
|
+
});
|
|
859
|
+
var updateOutput = import_zod5.z.looseObject({
|
|
860
|
+
ok: import_zod5.z.boolean(),
|
|
861
|
+
files: import_zod5.z.array(
|
|
862
|
+
import_zod5.z.looseObject({
|
|
863
|
+
path: import_zod5.z.string(),
|
|
864
|
+
action: import_zod5.z.enum(["updated", "added", "reverted", "kept", "merged", "merge-conflict", "saved-aside"]),
|
|
865
|
+
detail: import_zod5.z.string().optional()
|
|
866
|
+
})
|
|
867
|
+
)
|
|
868
|
+
});
|
|
869
|
+
function plain(text) {
|
|
870
|
+
return text.replace(/\u001b\[[0-9;]*m/g, "").replace(/\r\n/g, "\n");
|
|
871
|
+
}
|
|
872
|
+
function parseDoctorChecks(stdout) {
|
|
873
|
+
const checks = [];
|
|
874
|
+
for (const line of plain(stdout).split("\n")) {
|
|
875
|
+
const match = line.match(/^([✔⚠✖])\s+([^:]+):\s*(.*)$/);
|
|
876
|
+
if (!match) continue;
|
|
877
|
+
const status = STATUS[match[1]];
|
|
878
|
+
if (!status) continue;
|
|
879
|
+
checks.push({ name: match[2].trim(), status, message: match[3].trim() });
|
|
880
|
+
}
|
|
881
|
+
return checks;
|
|
882
|
+
}
|
|
883
|
+
function parseAddReport(stdout) {
|
|
884
|
+
const match = plain(stdout).match(/Install missing npm dependenc(?:y|ies):\n\s+(.+)/);
|
|
885
|
+
if (!match) return { missingPackages: [] };
|
|
886
|
+
const installCommand = match[1].trim();
|
|
887
|
+
const packages = installCommand.match(/^(?:npm install|pnpm add|yarn add|bun add)\s+(.+)$/);
|
|
888
|
+
return {
|
|
889
|
+
installCommand,
|
|
890
|
+
missingPackages: packages ? packages[1].split(/\s+/).filter(Boolean) : []
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
function parseUpdateFiles(stdout) {
|
|
894
|
+
const files = [];
|
|
895
|
+
for (const line of plain(stdout).split("\n")) {
|
|
896
|
+
const match = line.match(/^\s*([↑+↓=⋈⚠⇄])\s+(\S+)(?:\s+\((.*)\))?\s*$/);
|
|
897
|
+
if (!match) continue;
|
|
898
|
+
const action = FILE_ACTION[match[1]];
|
|
899
|
+
if (!action) continue;
|
|
900
|
+
const detail = match[3]?.trim();
|
|
901
|
+
files.push(detail ? { path: match[2], action, detail } : { path: match[2], action });
|
|
902
|
+
}
|
|
903
|
+
return files;
|
|
904
|
+
}
|
|
905
|
+
|
|
778
906
|
// src/tools/add-components.ts
|
|
779
907
|
var addComponentsInput = {
|
|
780
|
-
names:
|
|
781
|
-
cwd:
|
|
908
|
+
names: import_zod6.z.array(import_zod6.z.string().min(1)).min(1).describe("One or more registry component names to install (aliases like sheet \u2192 drawer are resolved)"),
|
|
909
|
+
cwd: import_zod6.z.string().optional().describe(
|
|
782
910
|
"Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)"
|
|
783
911
|
),
|
|
784
|
-
overwrite:
|
|
785
|
-
licenseKey:
|
|
912
|
+
overwrite: import_zod6.z.boolean().optional().default(false).describe("Overwrite existing component folders (maps to CLI --overwrite)"),
|
|
913
|
+
licenseKey: import_zod6.z.string().optional().describe(
|
|
786
914
|
"Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat."
|
|
787
915
|
)
|
|
788
916
|
};
|
|
789
|
-
async function addComponents(args) {
|
|
917
|
+
async function addComponents(args, hooks = {}) {
|
|
790
918
|
try {
|
|
791
919
|
const cwd = resolveProjectCwd(args.cwd);
|
|
792
920
|
const names = [
|
|
@@ -868,19 +996,33 @@ async function addComponents(args) {
|
|
|
868
996
|
);
|
|
869
997
|
}
|
|
870
998
|
const toInstall = [...free, ...pro];
|
|
999
|
+
const replace = await resolveReplace(
|
|
1000
|
+
Boolean(args.overwrite),
|
|
1001
|
+
hooks.confirmReplace,
|
|
1002
|
+
`Replace existing files for ${toInstall.join(", ")}? This overwrites the copies already in the project.`
|
|
1003
|
+
);
|
|
871
1004
|
const cliArgs = ["add", ...toInstall, "--yes"];
|
|
872
|
-
if (
|
|
1005
|
+
if (replace.apply) cliArgs.push("--overwrite");
|
|
873
1006
|
const result = await runCli(cliArgs, {
|
|
874
1007
|
cwd,
|
|
875
1008
|
env: licenseKey ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey } : void 0
|
|
876
1009
|
});
|
|
1010
|
+
const stdout = result.stdout.trim();
|
|
1011
|
+
const install = parseAddReport(stdout);
|
|
1012
|
+
const note = [
|
|
1013
|
+
`Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,
|
|
1014
|
+
replace.confirmation === "declined" ? "Overwrite was not confirmed. Existing files were left in place." : ""
|
|
1015
|
+
].filter(Boolean).join(" ");
|
|
877
1016
|
if (!result.ok) {
|
|
878
1017
|
return failJson(`${CLI_BIN} add failed.`, {
|
|
879
1018
|
cwd,
|
|
880
1019
|
names: toInstall,
|
|
881
1020
|
exitCode: result.code,
|
|
882
|
-
stdout
|
|
1021
|
+
stdout,
|
|
883
1022
|
stderr: result.stderr.trim(),
|
|
1023
|
+
missingPackages: install.missingPackages,
|
|
1024
|
+
...install.installCommand ? { installCommand: install.installCommand } : {},
|
|
1025
|
+
...replace.confirmation ? { confirmation: replace.confirmation } : {},
|
|
884
1026
|
hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`
|
|
885
1027
|
});
|
|
886
1028
|
}
|
|
@@ -889,9 +1031,12 @@ async function addComponents(args) {
|
|
|
889
1031
|
cwd,
|
|
890
1032
|
installed: toInstall,
|
|
891
1033
|
cli: `${CLI_BIN} add --yes`,
|
|
892
|
-
stdout
|
|
1034
|
+
stdout,
|
|
893
1035
|
stderr: result.stderr.trim() || void 0,
|
|
894
|
-
|
|
1036
|
+
missingPackages: install.missingPackages,
|
|
1037
|
+
...install.installCommand ? { installCommand: install.installCommand } : {},
|
|
1038
|
+
...replace.confirmation ? { confirmation: replace.confirmation } : {},
|
|
1039
|
+
note
|
|
895
1040
|
});
|
|
896
1041
|
} catch (err) {
|
|
897
1042
|
return failJson(err.message || String(err));
|
|
@@ -899,12 +1044,12 @@ async function addComponents(args) {
|
|
|
899
1044
|
}
|
|
900
1045
|
|
|
901
1046
|
// src/tools/diff-components.ts
|
|
902
|
-
var
|
|
1047
|
+
var import_zod7 = require("zod");
|
|
903
1048
|
var diffComponentsInput = {
|
|
904
|
-
names:
|
|
1049
|
+
names: import_zod7.z.array(import_zod7.z.string().min(1)).optional().describe(
|
|
905
1050
|
"Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json."
|
|
906
1051
|
),
|
|
907
|
-
cwd:
|
|
1052
|
+
cwd: import_zod7.z.string().optional().describe(
|
|
908
1053
|
"Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)"
|
|
909
1054
|
)
|
|
910
1055
|
};
|
|
@@ -944,9 +1089,9 @@ async function diffComponents(args = {}) {
|
|
|
944
1089
|
}
|
|
945
1090
|
|
|
946
1091
|
// src/tools/doctor.ts
|
|
947
|
-
var
|
|
1092
|
+
var import_zod8 = require("zod");
|
|
948
1093
|
var doctorInput = {
|
|
949
|
-
cwd:
|
|
1094
|
+
cwd: import_zod8.z.string().optional().describe(
|
|
950
1095
|
"Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only."
|
|
951
1096
|
)
|
|
952
1097
|
};
|
|
@@ -954,12 +1099,14 @@ async function doctor(args = {}) {
|
|
|
954
1099
|
try {
|
|
955
1100
|
const cwd = resolveProjectCwd(args.cwd);
|
|
956
1101
|
const result = await runCli(["doctor"], { cwd });
|
|
1102
|
+
const stdout = result.stdout.trim();
|
|
957
1103
|
const body = {
|
|
958
1104
|
cwd,
|
|
959
1105
|
cli: `${CLI_BIN} doctor`,
|
|
960
1106
|
exitCode: result.code,
|
|
961
|
-
stdout
|
|
962
|
-
stderr: result.stderr.trim() || void 0
|
|
1107
|
+
stdout,
|
|
1108
|
+
stderr: result.stderr.trim() || void 0,
|
|
1109
|
+
checks: parseDoctorChecks(stdout)
|
|
963
1110
|
};
|
|
964
1111
|
if (!result.ok) {
|
|
965
1112
|
return failJson(`${CLI_BIN} doctor reported problems.`, body);
|
|
@@ -971,16 +1118,21 @@ async function doctor(args = {}) {
|
|
|
971
1118
|
}
|
|
972
1119
|
|
|
973
1120
|
// src/tools/init-project.ts
|
|
974
|
-
var
|
|
1121
|
+
var import_zod9 = require("zod");
|
|
975
1122
|
var initProjectInput = {
|
|
976
|
-
cwd:
|
|
1123
|
+
cwd: import_zod9.z.string().optional().describe(
|
|
977
1124
|
"Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`)."
|
|
1125
|
+
),
|
|
1126
|
+
refreshEditorKit: import_zod9.z.boolean().optional().default(false).describe(
|
|
1127
|
+
"Replace an editor kit that is already there (Cursor rule, snippets, and the design skill in .cursor/skills and .agents/skills). Maps to `init --refresh-editor-kit`."
|
|
978
1128
|
)
|
|
979
1129
|
};
|
|
980
1130
|
async function initProject(args = {}) {
|
|
981
1131
|
try {
|
|
982
1132
|
const cwd = resolveProjectCwd(args.cwd);
|
|
983
|
-
const
|
|
1133
|
+
const cliArgs = ["init", "--yes"];
|
|
1134
|
+
if (args.refreshEditorKit) cliArgs.push("--refresh-editor-kit");
|
|
1135
|
+
const result = await runCli(cliArgs, { cwd });
|
|
984
1136
|
if (!result.ok) {
|
|
985
1137
|
return failJson(`${CLI_BIN} init failed.`, {
|
|
986
1138
|
cwd,
|
|
@@ -993,7 +1145,7 @@ async function initProject(args = {}) {
|
|
|
993
1145
|
return okJson({
|
|
994
1146
|
ok: true,
|
|
995
1147
|
cwd,
|
|
996
|
-
cli:
|
|
1148
|
+
cli: [CLI_BIN, ...cliArgs].join(" "),
|
|
997
1149
|
stdout: result.stdout.trim(),
|
|
998
1150
|
stderr: result.stderr.trim() || void 0
|
|
999
1151
|
});
|
|
@@ -1003,25 +1155,25 @@ async function initProject(args = {}) {
|
|
|
1003
1155
|
}
|
|
1004
1156
|
|
|
1005
1157
|
// src/tools/update-components.ts
|
|
1006
|
-
var
|
|
1158
|
+
var import_zod10 = require("zod");
|
|
1007
1159
|
var updateComponentsInput = {
|
|
1008
|
-
names:
|
|
1160
|
+
names: import_zod10.z.array(import_zod10.z.string().min(1)).optional().describe(
|
|
1009
1161
|
"Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json."
|
|
1010
1162
|
),
|
|
1011
|
-
cwd:
|
|
1163
|
+
cwd: import_zod10.z.string().optional().describe(
|
|
1012
1164
|
"Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)"
|
|
1013
1165
|
),
|
|
1014
|
-
force:
|
|
1166
|
+
force: import_zod10.z.boolean().optional().default(false).describe(
|
|
1015
1167
|
"On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits."
|
|
1016
1168
|
),
|
|
1017
|
-
overwriteLocal:
|
|
1169
|
+
overwriteLocal: import_zod10.z.boolean().optional().default(false).describe(
|
|
1018
1170
|
"Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files."
|
|
1019
1171
|
),
|
|
1020
|
-
merge:
|
|
1172
|
+
merge: import_zod10.z.boolean().optional().default(false).describe(
|
|
1021
1173
|
"On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins."
|
|
1022
1174
|
)
|
|
1023
1175
|
};
|
|
1024
|
-
async function updateComponents(args = {}) {
|
|
1176
|
+
async function updateComponents(args = {}, hooks = {}) {
|
|
1025
1177
|
try {
|
|
1026
1178
|
const cwd = resolveProjectCwd(args.cwd);
|
|
1027
1179
|
const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);
|
|
@@ -1030,18 +1182,32 @@ async function updateComponents(args = {}) {
|
|
|
1030
1182
|
return failJson(`Invalid component name: '${name}'.`);
|
|
1031
1183
|
}
|
|
1032
1184
|
}
|
|
1185
|
+
const target = names.length ? names.join(", ") : "tracked components";
|
|
1186
|
+
const replace = await resolveReplace(
|
|
1187
|
+
Boolean(args.force || args.overwriteLocal),
|
|
1188
|
+
hooks.confirmReplace,
|
|
1189
|
+
`Replace local files while updating ${target}? This overwrites copies already in the project.`
|
|
1190
|
+
);
|
|
1033
1191
|
const cliArgs = ["update", ...names, "--yes"];
|
|
1034
|
-
if (args.force) cliArgs.push("--force");
|
|
1035
|
-
if (args.overwriteLocal) cliArgs.push("--overwrite-local");
|
|
1192
|
+
if (args.force && replace.apply) cliArgs.push("--force");
|
|
1193
|
+
if (args.overwriteLocal && replace.apply) cliArgs.push("--overwrite-local");
|
|
1036
1194
|
if (args.merge) cliArgs.push("--merge");
|
|
1037
1195
|
const result = await runCli(cliArgs, { cwd });
|
|
1196
|
+
const stdout = result.stdout.trim();
|
|
1197
|
+
const files = parseUpdateFiles(stdout);
|
|
1198
|
+
const note = [
|
|
1199
|
+
`Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,
|
|
1200
|
+
replace.confirmation === "declined" ? "Replace was not confirmed. Conflicts and local-only edits were left in place." : ""
|
|
1201
|
+
].filter(Boolean).join(" ");
|
|
1038
1202
|
if (!result.ok) {
|
|
1039
1203
|
return failJson(`${CLI_BIN} update failed.`, {
|
|
1040
1204
|
cwd,
|
|
1041
1205
|
names,
|
|
1042
1206
|
exitCode: result.code,
|
|
1043
|
-
stdout
|
|
1207
|
+
stdout,
|
|
1044
1208
|
stderr: result.stderr.trim(),
|
|
1209
|
+
files,
|
|
1210
|
+
...replace.confirmation ? { confirmation: replace.confirmation } : {},
|
|
1045
1211
|
hint: "Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal."
|
|
1046
1212
|
});
|
|
1047
1213
|
}
|
|
@@ -1049,13 +1215,15 @@ async function updateComponents(args = {}) {
|
|
|
1049
1215
|
ok: true,
|
|
1050
1216
|
cwd,
|
|
1051
1217
|
names: names.length ? names : "all-tracked",
|
|
1052
|
-
force: Boolean(args.force),
|
|
1053
|
-
overwriteLocal: Boolean(args.overwriteLocal),
|
|
1218
|
+
force: Boolean(args.force && replace.apply),
|
|
1219
|
+
overwriteLocal: Boolean(args.overwriteLocal && replace.apply),
|
|
1054
1220
|
merge: Boolean(args.merge),
|
|
1055
1221
|
cli: [CLI_BIN, ...cliArgs].join(" "),
|
|
1056
|
-
stdout
|
|
1222
|
+
stdout,
|
|
1057
1223
|
stderr: result.stderr.trim() || void 0,
|
|
1058
|
-
|
|
1224
|
+
files,
|
|
1225
|
+
...replace.confirmation ? { confirmation: replace.confirmation } : {},
|
|
1226
|
+
note
|
|
1059
1227
|
});
|
|
1060
1228
|
} catch (err) {
|
|
1061
1229
|
return failJson(err.message || String(err));
|
|
@@ -1083,17 +1251,20 @@ function createMcpServer(options = {}) {
|
|
|
1083
1251
|
"add_components",
|
|
1084
1252
|
{
|
|
1085
1253
|
title: "Add Ply components",
|
|
1086
|
-
description: `Install registry components by shelling to \`${CLI_BIN} add --yes\`. --yes leaves an existing component in place; pass overwrite to replace it. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json.`,
|
|
1254
|
+
description: `Install registry components by shelling to \`${CLI_BIN} add --yes\`. --yes leaves an existing component in place; pass overwrite to replace it. Hosts that can ask confirm that overwrite first. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json. structuredContent includes missingPackages and installCommand.`,
|
|
1087
1255
|
inputSchema: addComponentsInput,
|
|
1256
|
+
outputSchema: addOutput,
|
|
1088
1257
|
annotations: writeAnnotations
|
|
1089
1258
|
},
|
|
1090
|
-
async (args) => addComponents(args
|
|
1259
|
+
async (args) => addComponents(args, {
|
|
1260
|
+
confirmReplace: (message) => confirmReplace(server, message)
|
|
1261
|
+
})
|
|
1091
1262
|
);
|
|
1092
1263
|
server.registerTool(
|
|
1093
1264
|
"init_project",
|
|
1094
1265
|
{
|
|
1095
1266
|
title: "Initialize Ply in a project",
|
|
1096
|
-
description: `Run \`${CLI_BIN} init --yes\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Always non-interactive.`,
|
|
1267
|
+
description: `Run \`${CLI_BIN} init --yes\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Writes the design skill to .cursor/skills and .agents/skills when those files are missing. Pass refreshEditorKit to replace an existing editor kit. Always non-interactive.`,
|
|
1097
1268
|
inputSchema: initProjectInput,
|
|
1098
1269
|
annotations: writeAnnotations
|
|
1099
1270
|
},
|
|
@@ -1103,8 +1274,9 @@ function createMcpServer(options = {}) {
|
|
|
1103
1274
|
"doctor",
|
|
1104
1275
|
{
|
|
1105
1276
|
title: "Verify Ply project setup",
|
|
1106
|
-
description: `Run \`${CLI_BIN} doctor\` (read-only). Returns isError when the CLI exits non-zero.`,
|
|
1277
|
+
description: `Run \`${CLI_BIN} doctor\` (read-only). structuredContent.checks lists each \u2714/\u26A0/\u2716 line. Returns isError when the CLI exits non-zero.`,
|
|
1107
1278
|
inputSchema: doctorInput,
|
|
1279
|
+
outputSchema: doctorOutput,
|
|
1108
1280
|
annotations: readOnlyAnnotations
|
|
1109
1281
|
},
|
|
1110
1282
|
async (args) => doctor(args)
|
|
@@ -1123,11 +1295,14 @@ function createMcpServer(options = {}) {
|
|
|
1123
1295
|
"update_components",
|
|
1124
1296
|
{
|
|
1125
1297
|
title: "Update installed Ply components",
|
|
1126
|
-
description: `Run \`${CLI_BIN} update --yes\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal.`,
|
|
1298
|
+
description: `Run \`${CLI_BIN} update --yes\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal. Hosts that can ask confirm force and overwriteLocal before those flags replace files. structuredContent.files is one result per file line.`,
|
|
1127
1299
|
inputSchema: updateComponentsInput,
|
|
1300
|
+
outputSchema: updateOutput,
|
|
1128
1301
|
annotations: writeAnnotations
|
|
1129
1302
|
},
|
|
1130
|
-
async (args) => updateComponents(args
|
|
1303
|
+
async (args) => updateComponents(args, {
|
|
1304
|
+
confirmReplace: (message) => confirmReplace(server, message)
|
|
1305
|
+
})
|
|
1131
1306
|
);
|
|
1132
1307
|
}
|
|
1133
1308
|
return server;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/catalog.ts","../src/resources.ts","../src/registry.ts","../src/utf8.ts","../src/tools/get-component.ts","../src/brand.ts","../src/install-hint.ts","../src/result.ts","../src/tools/list-components.ts","../src/tools/search-components.ts","../src/aliases.ts","../package.json","../src/version.ts","../src/tools/add-components.ts","../src/cli.ts","../src/tools/diff-components.ts","../src/tools/doctor.ts","../src/tools/init-project.ts","../src/tools/update-components.ts","../src/server.ts","../src/http.ts","../src/auth-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * ply-ui-mcp — MCP server wrapping the Ply registry + CLI.\n *\n * Default: stdio (Cursor, Claude Code/Desktop, Kimi, VS Code, Windsurf).\n * `--http`: Streamable HTTP for ChatGPT / Gemini chat apps and remote MCP URLs.\n * Hosted HTTP should use `--read-only` so catalog tools work without a local project.\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { startHttpServer } from './http';\nimport { MCP_PACKAGE } from './brand';\n\nfunction parseArgs(argv: string[]): {\n http: boolean;\n readOnly: boolean;\n port: number;\n host: string;\n} {\n let http =\n argv.includes('--http') ||\n process.env.PLY_MCP_HTTP === '1' ||\n process.env.BASE_UI_MCP_HTTP === '1';\n let readOnly =\n argv.includes('--read-only') ||\n process.env.PLY_MCP_READ_ONLY === '1' ||\n process.env.BASE_UI_MCP_READ_ONLY === '1';\n let port = Number(process.env.PORT || process.env.PLY_MCP_PORT || process.env.BASE_UI_MCP_PORT || 3334);\n let host = process.env.PLY_MCP_HOST || process.env.BASE_UI_MCP_HOST || (http ? '127.0.0.1' : '127.0.0.1');\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === '--port' && argv[i + 1]) {\n port = Number(argv[++i]);\n } else if (arg?.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length));\n } else if (arg === '--host' && argv[i + 1]) {\n host = argv[++i]!;\n } else if (arg?.startsWith('--host=')) {\n host = arg.slice('--host='.length);\n }\n }\n if (!Number.isFinite(port) || port <= 0) port = 3334;\n return { http, readOnly, port, host };\n}\n\nasync function main() {\n const opts = parseArgs(process.argv.slice(2));\n if (opts.http) {\n startHttpServer({\n host: opts.host,\n port: opts.port,\n readOnly: opts.readOnly,\n authToken:\n process.env.PLY_MCP_AUTH_TOKEN?.trim() ||\n process.env.BASE_UI_MCP_AUTH_TOKEN?.trim() ||\n undefined,\n });\n return;\n }\n\n const server = createMcpServer({ mutating: true });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`${MCP_PACKAGE} v${PACKAGE_VERSION} ready on stdio`);\n}\n\nmain().catch((err) => {\n console.error(`${MCP_PACKAGE} failed to start:`, err);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { registerResources } from './resources';\nimport { getComponent, getComponentInput } from './tools/get-component';\nimport { listComponents, listComponentsInput } from './tools/list-components';\nimport { searchComponents, searchComponentsInput } from './tools/search-components';\nimport { PACKAGE_VERSION } from './version';\nimport { CLI_NPX, MCP_SERVER_NAME } from './brand';\n\n/** ChatGPT treats tools as writes unless readOnlyHint is set. */\nconst catalogAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/** Catalog-only server: safe to bundle on Cloudflare Workers (no child_process). */\nexport function createCatalogMcpServer(): McpServer {\n const server = new McpServer({\n name: MCP_SERVER_NAME,\n version: PACKAGE_VERSION,\n });\n\n server.registerTool(\n 'list_components',\n {\n title: 'List Ply components',\n description:\n `List components from the Ply registry. Filter by tier (free|pro|all), category, or name substring. Does not install anything. To copy a component into a project, tell the user to run ${CLI_NPX} add <name>.`,\n inputSchema: listComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => listComponents(args)\n );\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component details',\n description:\n `Get registry metadata for one component (deps, category, file list). Free source only when includeSource=true. Pro source is never streamed via MCP. Does not install; returns installCommand (${CLI_NPX} add <name>).`,\n inputSchema: getComponentInput,\n annotations: catalogAnnotations,\n },\n async (args) => getComponent(args)\n );\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search Ply components',\n description:\n `Fuzzy / token search over registry component names (e.g. \"dialog\", \"sheet\", \"carousel\"). Does not install anything. Prefer this before guessing names, then give the user ${CLI_NPX} add <name> (or local stdio add_components).`,\n inputSchema: searchComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => searchComponents(args)\n );\n\n registerResources(server);\n return server;\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n fetchText,\n isSafeItemName,\n} from './registry';\nimport { utf8ByteLength } from './utf8';\n\nexport function registerResources(server: McpServer) {\n server.registerResource(\n 'registry-index',\n 'ply-ui://registry/index',\n {\n title: 'Registry index',\n description: 'Public Ply registry index (names, tiers, categories, description, usage, keywords, deps)',\n mimeType: 'application/json',\n },\n async (uri) => {\n const index = await fetchIndex();\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(index, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n 'docs-llms',\n 'ply-ui://docs/llms',\n {\n title: 'llms.txt',\n description:\n 'Agent-oriented product overview (keep fetching this URL even when MCP is available)',\n mimeType: 'text/plain',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/llms.txt`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/plain', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-catalog',\n 'ply-ui://docs/catalog',\n {\n title: 'AI component catalog',\n description: 'docs/ai/components.md — detailed component reference for agents',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/components.md`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-cursor-rules',\n 'ply-ui://docs/cursor-rules',\n {\n title: 'Cursor / Windsurf project rules',\n description:\n 'Save as .cursor/rules/ply-ui.mdc (or .windsurf/rules/ply-ui.md). Teaches assistants to write standalone zoneless Angular 22 with Ply without running MCP.',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.mdc`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-snippets',\n 'ply-ui://docs/snippets',\n {\n title: 'VS Code / Cursor snippets',\n description:\n 'Save as .vscode/ply-ui.code-snippets. Prefixes like ply-card expand usage markup after CLI install.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.code-snippets`);\n return {\n contents: [{ uri: uri.href, mimeType: 'application/json', text }],\n };\n }\n );\n\n server.registerResource(\n 'component',\n new ResourceTemplate('ply-ui://component/{name}', {\n list: undefined,\n }),\n {\n title: 'Component metadata',\n description:\n 'Registry metadata for one component. Free source files are listed without content; Pro never streams source via MCP in V1.',\n mimeType: 'application/json',\n },\n async (uri, vars) => {\n const name = String(vars.name || '');\n if (!isSafeItemName(name)) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Invalid name: ${name}` }),\n },\n ],\n };\n }\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Unknown component: ${name}` }),\n },\n ],\n };\n }\n\n if (entry.tier === 'pro') {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n ...entry,\n files: null,\n note: `Pro — metadata only. ${SITE_URL}/pricing`,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n const item = await fetchFreeItem(name);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n name: item.name,\n tier: item.tier,\n category: item.category,\n description: item.description,\n usage: item.usage,\n keywords: item.keywords,\n dependencies: item.dependencies,\n registryDependencies: item.registryDependencies,\n files: item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n })),\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n );\n}\n","/**\n * Thin registry client — mirrors packages/cli/src/registry.ts URLs/schemas\n * so the MCP server can return structured JSON without parsing CLI stdout.\n * Install/write side effects still go through ply-ui-cli (canonical path).\n */\nimport { z } from 'zod';\n\nexport const SITE_URL = 'https://ply-ui.com';\nexport const GITHUB_HUB_URL = 'https://github.com/ply-ui-ng/ply';\n\nconst env =\n typeof process !== 'undefined' && process.env ? process.env : ({} as Record<string, string | undefined>);\n\nfunction firstEnv(...names: string[]): string | undefined {\n for (const name of names) {\n const v = env[name]?.trim();\n if (v) return v;\n }\n}\n\nexport const FREE_REGISTRY_URL =\n firstEnv('PLY_REGISTRY_URL', 'BASE_UI_REGISTRY_URL') || `${SITE_URL}/registry`;\n\nexport const PRO_REGISTRY_URL =\n firstEnv('PLY_PRO_REGISTRY_URL', 'BASE_UI_PRO_REGISTRY_URL') ||\n 'https://pro.ply-ui.com/registry';\n\nconst registryFileSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const registryItemSchema = z.object({\n name: z.string(),\n tier: z.enum(['free', 'pro']),\n category: z\n .enum(['application', 'page-layout', 'block', 'widget', 'shell', 'component'])\n .optional()\n .default('component'),\n dependencies: z.array(z.string()).default([]),\n registryDependencies: z.array(z.string()).default([]),\n description: z.string().optional().default(''),\n usage: z.string().optional().default(''),\n keywords: z.array(z.string()).optional().default([]),\n files: z.array(registryFileSchema),\n type: z.string().optional(),\n license: z.enum(['MIT', 'Ply Pro']).optional(),\n});\n\nexport const registryIndexSchema = z.array(registryItemSchema.omit({ files: true }));\n\nexport type RegistryItem = z.infer<typeof registryItemSchema>;\nexport type RegistryIndexEntry = z.infer<typeof registryIndexSchema>[number];\n\nexport type Category = NonNullable<RegistryIndexEntry['category']>;\n\nexport function itemLicense(tier: 'free' | 'pro'): 'MIT' | 'Ply Pro' {\n return tier === 'pro' ? 'Ply Pro' : 'MIT';\n}\n\nexport function hubSourceUrl(name: string): string {\n return `${GITHUB_HUB_URL}/tree/main/components/${name}`;\n}\n\nexport function itemHaystack(\n item: Pick<RegistryIndexEntry, 'name' | 'description' | 'usage' | 'keywords'>\n): string {\n return [item.name, item.description, item.usage, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n\nexport function isSafeItemName(name: string): boolean {\n return /^[a-z0-9][a-z0-9-.]*$/i.test(name) && !name.includes('..');\n}\n\nasync function fetchJson(url: string, headers: Record<string, string> = {}): Promise<unknown> {\n let res: Response;\n try {\n res = await fetch(url, { headers });\n } catch (err: any) {\n throw new Error(\n `Network error while contacting the registry (${err.message}). Check your connection and try again.`\n );\n }\n if (res.status === 401 || res.status === 403) {\n throw new Error(\n `License rejected (HTTP ${res.status}). Check PLY_LICENSE_KEY, or see ${SITE_URL}/pricing.`\n );\n }\n if (res.status === 404) {\n const e: any = new Error('Not found');\n e.code = 'NOT_FOUND';\n throw e;\n }\n if (!res.ok) {\n throw new Error(`Registry request failed (HTTP ${res.status}) for ${url}.`);\n }\n return res.json();\n}\n\nexport async function fetchIndex(): Promise<RegistryIndexEntry[]> {\n const data = await fetchJson(`${FREE_REGISTRY_URL}/index.json`);\n return registryIndexSchema.parse(data);\n}\n\n/** Free registry item only — V1 never streams Pro source through MCP. */\nexport async function fetchFreeItem(name: string): Promise<RegistryItem> {\n if (!isSafeItemName(name)) {\n throw new Error(`Invalid component name: '${name}'.`);\n }\n const data = await fetchJson(`${FREE_REGISTRY_URL}/styles/default/${name}.json`);\n return registryItemSchema.parse(data);\n}\n\nexport async function fetchText(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err: any) {\n throw new Error(`Network error fetching ${url}: ${err.message}`);\n }\n if (!res.ok) {\n throw new Error(`Failed to fetch ${url} (HTTP ${res.status}).`);\n }\n return res.text();\n}\n\n/** Closest names to `query`, for search / suggestions. */\nexport function suggestNames(query: string, names: string[], limit = 8): string[] {\n const q = query.toLowerCase().trim();\n if (!q) return [];\n const scored = names\n .map((name) => {\n const n = name.toLowerCase();\n let score: number;\n if (n === q) score = 0;\n else if (n.startsWith(q) || q.startsWith(n)) score = 1;\n else if (n.includes(q) || q.includes(n)) score = 2;\n else score = 3 + levenshtein(q, n);\n return { name, score };\n })\n .filter((s) => s.score <= 6)\n .sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\n return scored.slice(0, limit).map((s) => s.name);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (!m) return n;\n if (!n) return m;\n let prev = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n const curr = [i];\n for (let j = 1; j <= n; j++) {\n curr[j] = Math.min(\n prev[j] + 1,\n curr[j - 1] + 1,\n prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n }\n prev = curr;\n }\n return prev[n];\n}\n","/** UTF-8 byte length without Node `Buffer` (Workers / browsers). */\nexport function utf8ByteLength(text: string): number {\n return new TextEncoder().encode(text).byteLength;\n}\n","import { z } from 'zod';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n hubSourceUrl,\n isSafeItemName,\n itemLicense,\n suggestNames,\n} from '../registry';\nimport { cliAddCommand, installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\nimport { utf8ByteLength } from '../utf8';\n\nexport const getComponentInput = {\n name: z.string().describe('Registry component name (e.g. button, card)'),\n includeSource: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, include free-tier source file contents. Pro source is never returned via MCP in V1.'\n ),\n};\n\nexport async function getComponent(args: { name: string; includeSource?: boolean }) {\n try {\n const name = args.name.trim();\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n const suggestions = suggestNames(\n name,\n index.map((i) => i.name)\n );\n return failJson(`Unknown component: '${name}'.`, {\n suggestions,\n listHint: 'Call list_components or search_components.',\n });\n }\n\n const base = {\n ok: true as const,\n name: entry.name,\n tier: entry.tier,\n license: entry.license || itemLicense(entry.tier),\n category: entry.category || 'component',\n description: entry.description || '',\n usage: entry.usage || '',\n keywords: entry.keywords || [],\n dependencies: entry.dependencies,\n registryDependencies: entry.registryDependencies,\n docsUrl: `${SITE_URL}/base-elements/${entry.name}/`,\n pricingUrl: `${SITE_URL}/pricing`,\n };\n\n if (entry.tier === 'pro') {\n return okJson({\n ...base,\n source: null,\n sourceUrl: null,\n installCommand: cliAddCommand(name),\n note: `Pro component — metadata only. ${installHint(name)} Pro install also needs PLY_LICENSE_KEY. Buy at ${SITE_URL}/pricing.`,\n });\n }\n\n const item = await fetchFreeItem(name);\n const files = item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n ...(args.includeSource ? { content: f.content } : {}),\n }));\n\n return okJson({\n ...base,\n files,\n includeSource: Boolean(args.includeSource),\n sourceUrl: hubSourceUrl(name),\n installCommand: cliAddCommand(name),\n note: args.includeSource\n ? `Free source included for reading. ${installHint(name)}`\n : `Source omitted by default. Pass includeSource=true to read free files here. ${installHint(name)}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Public npm / npx names for the Ply CLI and MCP. */\nexport const CLI_PACKAGE = 'ply-ui-cli';\nexport const CLI_BIN = 'ply-ui-cli';\nexport const CLI_NPX = `npx ${CLI_BIN}`;\nexport const MCP_PACKAGE = 'ply-ui-mcp';\nexport const MCP_NPX = `npx -y ${MCP_PACKAGE}`;\nexport const MCP_SERVER_NAME = 'ply';\n","import { CLI_NPX } from './brand';\n\n/** Copy-paste installer. Hosted catalog MCP cannot write files. */\nexport function cliAddCommand(name?: string): string {\n return name?.trim()\n ? `${CLI_NPX} add ${name.trim()}`\n : `${CLI_NPX} add <name>`;\n}\n\nexport function installHint(name?: string): string {\n return (\n `This catalog does not write files. Install in the project with \\`${cliAddCommand(name)}\\`. ` +\n 'Local stdio MCP (Cursor, Claude Code) can call add_components instead.'\n );\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\nexport function okJson(data: unknown): CallToolResult {\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n };\n}\n\nexport function failJson(\n message: string,\n extra: Record<string, unknown> = {}\n): CallToolResult {\n return {\n isError: true,\n content: [\n {\n type: 'text',\n text: JSON.stringify({ ok: false, error: message, ...extra }, null, 2),\n },\n ],\n };\n}\n","import { z } from 'zod';\nimport { fetchIndex, itemHaystack, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const listComponentsInput = {\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z\n .enum(CATEGORIES)\n .optional()\n .describe('Filter by registry category'),\n q: z\n .string()\n .optional()\n .describe('Substring filter on name, description, usage, or keywords (case-insensitive)'),\n};\n\nexport async function listComponents(args: {\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n q?: string;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const q = args.q?.trim().toLowerCase();\n\n let items = index;\n if (tier !== 'all') {\n items = items.filter((i) => i.tier === tier);\n }\n if (args.category) {\n items = items.filter((i) => (i.category || 'component') === args.category);\n }\n if (q) {\n items = items.filter((i) => itemHaystack(i).includes(q));\n }\n\n items = [...items].sort((a, b) => a.name.localeCompare(b.name));\n\n return okJson({\n ok: true,\n count: items.length,\n items: items.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n dependencies: i.dependencies,\n registryDependencies: i.registryDependencies,\n })),\n hint: `Use get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { canonicalComponentName } from '../aliases';\nimport { fetchIndex, itemHaystack, suggestNames, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const searchComponentsInput = {\n query: z\n .string()\n .min(1)\n .describe('Natural-language or substring query (e.g. \"dialog modal\", \"button\"). Matches name, description, usage, and keywords.'),\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z.enum(CATEGORIES).optional().describe('Filter by registry category'),\n limit: z.number().int().min(1).max(40).optional().default(12),\n};\n\nfunction tokenize(query: string): string[] {\n return query\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2);\n}\n\nexport async function searchComponents(args: {\n query: string;\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n limit?: number;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const limit = args.limit ?? 12;\n const rawQuery = args.query.trim();\n const canonical = canonicalComponentName(rawQuery);\n const variants = [...new Set([rawQuery, canonical].filter(Boolean))];\n\n let pool = index;\n if (tier !== 'all') {\n pool = pool.filter((i) => i.tier === tier);\n }\n if (args.category) {\n pool = pool.filter((i) => (i.category || 'component') === args.category);\n }\n\n const names = pool.map((i) => i.name);\n const byFuzzy = new Set(variants.flatMap((q) => suggestNames(q, names, limit)));\n\n const byTokens = pool.filter((i) => {\n const hay = itemHaystack(i);\n return variants.some((q) => {\n const tokens = tokenize(q);\n return tokens.length > 0 && tokens.every((t) => hay.includes(t));\n });\n });\n\n const ranked = [\n ...byTokens.sort((a, b) => a.name.localeCompare(b.name)),\n ...pool\n .filter((i) => byFuzzy.has(i.name) && !byTokens.some((t) => t.name === i.name))\n .sort(\n (a, b) =>\n [...byFuzzy].indexOf(a.name) - [...byFuzzy].indexOf(b.name)\n ),\n ].slice(0, limit);\n\n return okJson({\n ok: true,\n query: args.query,\n count: ranked.length,\n matches: ranked.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n registryDependencies: i.registryDependencies,\n })),\n hint: `Next: get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Keep in sync with packages/cli/src/aliases.ts */\nexport const COMPONENT_ALIASES: Record<string, string> = {\n sheet: 'drawer',\n 'side-sheet': 'drawer',\n gallery: 'slider',\n 'image-slider': 'slider',\n slideshow: 'slider',\n range: 'range-slider',\n 'slider-input': 'range-slider',\n 'input-slider': 'range-slider',\n 'base-list-item': 'ply-list-item',\n 'base-tab-icon': 'ply-tab-icon',\n 'base-group-button': 'ply-group-button',\n 'base-dropdown-menu-item': 'ply-dropdown-menu-item',\n 'base-context-menu-item': 'ply-context-menu-item',\n};\n\nexport function canonicalComponentName(name: string): string {\n const key = name.trim().toLowerCase();\n return COMPONENT_ALIASES[key] ?? name.trim();\n}\n","{\n \"name\": \"ply-ui-mcp\",\n \"version\": \"0.1.30\",\n \"description\": \"Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.\",\n \"type\": \"commonjs\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"ply-ui-mcp\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"angular\",\n \"tailwindcss\",\n \"ply\",\n \"ply-ui\",\n \"ply-ui-mcp\",\n \"cli\"\n ],\n \"author\": \"Lussos\",\n \"license\": \"MIT\",\n \"mcpName\": \"io.github.ply-ui-ng/ply-ui\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ply-ui-ng/ply.git\",\n \"directory\": \"packages/mcp\"\n },\n \"homepage\": \"https://ply-ui.com\",\n \"bugs\": {\n \"url\": \"https://github.com/ply-ui-ng/ply/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.32.1\",\n \"zod\": \"^4.6.2\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^26.5.1\",\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^7.0.2\",\n \"vitest\": \"^5.0.0\"\n },\n \"overrides\": {\n \"esbuild\": \"0.28.2\",\n \"fast-uri\": \"3.1.8\",\n \"proxy-addr\": \"2.0.8\",\n \"hono\": \"4.13.7\",\n \"qs\": \"6.16.0\"\n }\n}\n","import packageJson from '../package.json' with { type: 'json' };\n\n/** Bundled from packages/mcp/package.json by tsup and by the Workers deploy. */\nexport const PACKAGE_VERSION: string = packageJson.version;\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport {\n SITE_URL,\n fetchIndex,\n isSafeItemName,\n suggestNames,\n} from '../registry';\nimport { failJson, okJson } from '../result';\nimport { canonicalComponentName } from '../aliases';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const addComponentsInput = {\n names: z\n .array(z.string().min(1))\n .min(1)\n .describe('One or more registry component names to install (aliases like sheet → drawer are resolved)'),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)'\n ),\n overwrite: z\n .boolean()\n .optional()\n .default(false)\n .describe('Overwrite existing component folders (maps to CLI --overwrite)'),\n licenseKey: z\n .string()\n .optional()\n .describe(\n 'Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat.'\n ),\n};\n\n/**\n * Installs registry components via the CLI. Pro names require\n * `licenseKey` or `PLY_LICENSE_KEY` / `BASE_UI_LICENSE_KEY`.\n */\nexport async function addComponents(args: {\n names: string[];\n cwd?: string;\n overwrite?: boolean;\n licenseKey?: string;\n}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = [\n ...new Set(\n args.names\n .map((n) => canonicalComponentName(n.trim()))\n .filter(Boolean)\n ),\n ];\n\n if (!names.length) {\n return failJson('Provide at least one component name.');\n }\n\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const index = await fetchIndex();\n const byName = new Map(index.map((i) => [i.name, i]));\n const unknown: string[] = [];\n const pro: string[] = [];\n const free: string[] = [];\n\n for (const name of names) {\n const entry = byName.get(name);\n if (!entry) {\n unknown.push(name);\n continue;\n }\n if (entry.tier === 'pro') {\n pro.push(name);\n } else {\n free.push(name);\n }\n }\n\n if (unknown.length) {\n return failJson('Unknown component name(s).', {\n unknown,\n suggestions: unknown.flatMap((n) =>\n suggestNames(\n n,\n index.map((i) => i.name),\n 3\n )\n ),\n });\n }\n\n const licenseKey =\n args.licenseKey?.trim() ||\n process.env.PLY_LICENSE_KEY?.trim() ||\n process.env.BASE_UI_LICENSE_KEY?.trim() ||\n '';\n\n if (pro.length && !licenseKey) {\n return failJson(\n `Pro components need PLY_LICENSE_KEY (or licenseKey): ${pro.join(', ')}.`,\n {\n pro,\n pricingUrl: `${SITE_URL}/pricing`,\n note: 'Set PLY_LICENSE_KEY on the MCP server process (BASE_UI_LICENSE_KEY still works), then retry. Free components can still be added with this tool.',\n freeCandidates: free,\n }\n );\n }\n\n // Also reject if free items pull Pro registryDependencies (closure).\n const queue = [...free];\n const seen = new Set<string>();\n const proDeps: string[] = [];\n while (queue.length) {\n const name = queue.shift()!;\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = byName.get(name);\n if (!entry) continue;\n if (entry.tier === 'pro') {\n proDeps.push(name);\n continue;\n }\n queue.push(...entry.registryDependencies);\n }\n if (proDeps.length && !licenseKey) {\n return failJson(\n `Install blocked: free selection depends on Pro components: ${proDeps.join(', ')}.`,\n {\n proDependencies: proDeps,\n pricingUrl: `${SITE_URL}/pricing`,\n }\n );\n }\n\n const toInstall = [...free, ...pro];\n const cliArgs = ['add', ...toInstall, '--yes'];\n if (args.overwrite) cliArgs.push('--overwrite');\n\n const result = await runCli(cliArgs, {\n cwd,\n env: licenseKey\n ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey }\n : undefined,\n });\n if (!result.ok) {\n return failJson(`${CLI_BIN} add failed.`, {\n cwd,\n names: toInstall,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`,\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n installed: toInstall,\n cli: `${CLI_BIN} add --yes`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport { CLI_PACKAGE } from './brand';\n\n/**\n * Resolve the ply-ui-cli entrypoint.\n * Order: PLY_CLI_PATH → local monorepo dist → node_modules bin → npx.\n */\nexport function resolveCliEntrypoint(): { command: string; argsPrefix: string[] } {\n const envPath = process.env.PLY_CLI_PATH?.trim() || process.env.BASE_UI_CLI_PATH?.trim();\n if (envPath && fs.existsSync(envPath)) {\n return { command: process.execPath, argsPrefix: [envPath] };\n }\n\n const sibling = path.resolve(__dirname, '../../cli/dist/index.js');\n if (fs.existsSync(sibling)) {\n return { command: process.execPath, argsPrefix: [sibling] };\n }\n\n for (const pkg of [CLI_PACKAGE, 'base-ui-cli']) {\n try {\n const pkgJson = require.resolve(`${pkg}/package.json`);\n const bin = path.join(path.dirname(pkgJson), 'dist', 'index.js');\n if (fs.existsSync(bin)) {\n return { command: process.execPath, argsPrefix: [bin] };\n }\n } catch {\n // not installed as a dependency\n }\n }\n\n // npx.cmd is named directly so the child process never needs a shell — see\n // the spawn call below, which deliberately does not set `shell`.\n return { command: process.platform === 'win32' ? 'npx.cmd' : 'npx', argsPrefix: ['-y', CLI_PACKAGE] };\n}\n\nexport interface RunCliResult {\n ok: boolean;\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nexport function runCli(\n cliArgs: string[],\n options: { cwd: string; env?: NodeJS.ProcessEnv; timeoutMs?: number } = { cwd: process.cwd() }\n): Promise<RunCliResult> {\n const { command, argsPrefix } = resolveCliEntrypoint();\n const args = [...argsPrefix, ...cliArgs];\n const timeoutMs = options.timeoutMs ?? 120_000;\n\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: { ...process.env, ...options.env, FORCE_COLOR: '0' },\n });\n\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n child.kill('SIGTERM');\n resolve({\n ok: false,\n code: null,\n stdout,\n stderr: stderr + `\\nTimed out after ${timeoutMs}ms`,\n });\n }, timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: false, code: null, stdout, stderr: err.message });\n });\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: code === 0, code, stdout, stderr });\n });\n });\n}\n\n/** Project root for mutating tools (init/add). Prefer explicit cwd, else process cwd. */\nexport function resolveProjectCwd(cwd?: string): string {\n const root = cwd?.trim() || process.env.PLY_CWD?.trim() || process.env.BASE_UI_CWD?.trim() || process.cwd();\n return path.resolve(root);\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const diffComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n};\n\nexport async function diffComponents(args: { names?: string[]; cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = names.length ? ['diff', ...names] : ['diff'];\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} diff failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Project must be initialized and components tracked in ply-ui-lock.json.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n cli: names.length ? `${CLI_BIN} diff ${names.join(' ')}` : `${CLI_BIN} diff`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: 'Read-only. Use update_components to apply upstream changes.',\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const doctorInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only.'\n ),\n};\n\nexport async function doctor(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['doctor'], { cwd });\n const body = {\n cwd,\n cli: `${CLI_BIN} doctor`,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n };\n if (!result.ok) {\n return failJson(`${CLI_BIN} doctor reported problems.`, body);\n }\n return okJson({ ok: true, ...body });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const initProjectInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`).'\n ),\n};\n\nexport async function initProject(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['init', '--yes'], { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} init failed.`, {\n cwd,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `CLI remains the canonical installer: ${CLI_NPX} init --yes`,\n });\n }\n return okJson({\n ok: true,\n cwd,\n cli: `${CLI_BIN} init --yes`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const updateComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n force: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits.'\n ),\n overwriteLocal: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files.'\n ),\n merge: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins.'\n ),\n};\n\n/**\n * Always non-interactive (`update --yes`). Conflicts are skipped unless `force`.\n * Local-only edits are skipped unless `overwriteLocal`.\n */\nexport async function updateComponents(\n args: {\n names?: string[];\n cwd?: string;\n force?: boolean;\n overwriteLocal?: boolean;\n merge?: boolean;\n } = {}\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = ['update', ...names, '--yes'];\n if (args.force) cliArgs.push('--force');\n if (args.overwriteLocal) cliArgs.push('--overwrite-local');\n if (args.merge) cliArgs.push('--merge');\n\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} update failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n force: Boolean(args.force),\n overwriteLocal: Boolean(args.overwriteLocal),\n merge: Boolean(args.merge),\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createCatalogMcpServer } from './catalog';\nimport { addComponents, addComponentsInput } from './tools/add-components';\nimport { diffComponents, diffComponentsInput } from './tools/diff-components';\nimport { doctor, doctorInput } from './tools/doctor';\nimport { initProject, initProjectInput } from './tools/init-project';\nimport { updateComponents, updateComponentsInput } from './tools/update-components';\nimport { CLI_BIN } from './brand';\n\nexport { PACKAGE_VERSION } from './version';\n\nexport interface CreateMcpServerOptions {\n /** When false, mutating CLI tools are omitted (hosted catalog MCP). */\n mutating?: boolean;\n}\n\nexport function createMcpServer(options: CreateMcpServerOptions = {}): McpServer {\n const mutating = options.mutating !== false;\n const server = createCatalogMcpServer();\n\n const readOnlyAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n } as const;\n const writeAnnotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n } as const;\n\n if (mutating) {\n server.registerTool(\n 'add_components',\n {\n title: 'Add Ply components',\n description:\n `Install registry components by shelling to \\`${CLI_BIN} add --yes\\`. --yes leaves an existing component in place; pass overwrite to replace it. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json.`,\n inputSchema: addComponentsInput,\n annotations: writeAnnotations,\n },\n async (args) => addComponents(args)\n );\n\n server.registerTool(\n 'init_project',\n {\n title: 'Initialize Ply in a project',\n description:\n `Run \\`${CLI_BIN} init --yes\\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Always non-interactive.`,\n inputSchema: initProjectInput,\n annotations: writeAnnotations,\n },\n async (args) => initProject(args)\n );\n\n server.registerTool(\n 'doctor',\n {\n title: 'Verify Ply project setup',\n description:\n `Run \\`${CLI_BIN} doctor\\` (read-only). Returns isError when the CLI exits non-zero.`,\n inputSchema: doctorInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => doctor(args)\n );\n\n server.registerTool(\n 'diff_components',\n {\n title: 'Diff installed Ply components',\n description:\n `Run \\`${CLI_BIN} diff\\` against tracked components. Read-only. Omit names to check everything in ply-ui-lock.json.`,\n inputSchema: diffComponentsInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => diffComponents(args)\n );\n\n server.registerTool(\n 'update_components',\n {\n title: 'Update installed Ply components',\n description:\n `Run \\`${CLI_BIN} update --yes\\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal.`,\n inputSchema: updateComponentsInput,\n annotations: writeAnnotations,\n },\n async (args) => updateComponents(args)\n );\n }\n\n return server;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { MCP_PACKAGE } from './brand';\nimport { mcpProtectedResource, wwwAuthenticate } from './auth-metadata';\n\nexport interface HttpOptions {\n host: string;\n port: number;\n readOnly: boolean;\n authToken?: string;\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version'\n );\n}\n\nfunction unauthorized(res: ServerResponse, resourceMetadataUrl: string): void {\n setCors(res);\n res.writeHead(401, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': wwwAuthenticate(resourceMetadataUrl),\n });\n res.end(JSON.stringify({ error: 'Unauthorized' }));\n}\n\nfunction checkAuth(req: IncomingMessage, token?: string): boolean {\n if (!token) return true;\n const header = req.headers.authorization;\n return header === `Bearer ${token}`;\n}\n\nasync function readBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) return undefined;\n return JSON.parse(raw);\n}\n\n/**\n * Streamable HTTP MCP. ChatGPT / Gemini chat apps need a public HTTPS URL\n * pointing at `/mcp`. Mutating tools only work when this process can see\n * the consumer project (local `--http`, not a remote catalog host).\n */\nexport function startHttpServer(options: HttpOptions): ReturnType<typeof createServer> {\n const server = createServer(async (req, res) => {\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n\n if (req.method === 'OPTIONS') {\n setCors(res);\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n ok: true,\n name: MCP_PACKAGE,\n version: PACKAGE_VERSION,\n transport: 'streamable-http',\n mcp: '/mcp',\n mutating: !options.readOnly,\n })\n );\n return;\n }\n\n if (url.pathname === '/.well-known/oauth-protected-resource' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(\n JSON.stringify(\n mcpProtectedResource(new URL('/mcp', url.origin).href, Boolean(options.authToken))\n )\n );\n return;\n }\n\n if (url.pathname !== '/mcp') {\n setCors(res);\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found. MCP is POST/GET /mcp.' }));\n return;\n }\n\n if (!checkAuth(req, options.authToken)) {\n unauthorized(res, new URL('/.well-known/oauth-protected-resource', url.origin).href);\n return;\n }\n\n setCors(res);\n const mcp = createMcpServer({ mutating: !options.readOnly });\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await mcp.connect(transport);\n const parsedBody = req.method === 'POST' ? await readBody(req) : undefined;\n await transport.handleRequest(req, res, parsedBody);\n } catch (err) {\n console.error(`${MCP_PACKAGE} HTTP error:`, err);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n if (!res.writableEnded) {\n res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));\n }\n }\n });\n\n server.listen(options.port, options.host, () => {\n const addr = server.address();\n const port = typeof addr === 'object' && addr ? addr.port : options.port;\n console.error(\n `${MCP_PACKAGE} v${PACKAGE_VERSION} Streamable HTTP on http://${options.host}:${port}/mcp` +\n (options.readOnly ? ' (read-only catalog)' : '')\n );\n });\n return server;\n}\n","/** Canonical auth.md skill. Registration is not offered; see the file. */\nexport const AUTH_MD_URL = 'https://ply-ui.com/auth.md';\n\nexport interface ProtectedResourceMetadata {\n resource: string;\n resource_name: string;\n resource_documentation: string;\n resource_logo_uri: string;\n authorization_servers: string[];\n scopes_supported: string[];\n bearer_methods_supported: string[];\n}\n\n/** RFC 9728 metadata for one MCP origin. An empty authorization_servers list means registration is off. */\nexport function mcpProtectedResource(resource: string, bearer: boolean): ProtectedResourceMetadata {\n return {\n resource,\n resource_name: 'Ply MCP',\n resource_documentation: AUTH_MD_URL,\n resource_logo_uri: 'https://ply-ui.com/assets/pwa/apple-touch-icon.png',\n authorization_servers: [],\n scopes_supported: [],\n bearer_methods_supported: bearer ? ['header'] : [],\n };\n}\n\nexport function wwwAuthenticate(resourceMetadataUrl: string): string {\n return `Bearer resource_metadata=\"${resourceMetadataUrl}\"`;\n}\n"],"mappings":"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","names":["import_mcp","import_zod","import_zod","import_zod","CATEGORIES","import_zod","fs","path","import_zod","import_zod","import_zod","import_zod"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/catalog.ts","../src/resources.ts","../src/registry.ts","../src/utf8.ts","../src/tools/get-component.ts","../src/brand.ts","../src/install-hint.ts","../src/result.ts","../src/tools/list-components.ts","../src/tools/search-components.ts","../src/aliases.ts","../package.json","../src/version.ts","../src/elicit.ts","../src/tools/add-components.ts","../src/cli.ts","../src/cli-report.ts","../src/tools/diff-components.ts","../src/tools/doctor.ts","../src/tools/init-project.ts","../src/tools/update-components.ts","../src/server.ts","../src/http.ts","../src/auth-metadata.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * ply-ui-mcp — MCP server wrapping the Ply registry + CLI.\n *\n * Default: stdio (Cursor, Claude Code/Desktop, Kimi, VS Code, Windsurf).\n * `--http`: Streamable HTTP for ChatGPT / Gemini chat apps and remote MCP URLs.\n * Hosted HTTP should use `--read-only` so catalog tools work without a local project.\n */\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { startHttpServer } from './http';\nimport { MCP_PACKAGE } from './brand';\n\nfunction parseArgs(argv: string[]): {\n http: boolean;\n readOnly: boolean;\n port: number;\n host: string;\n} {\n let http =\n argv.includes('--http') ||\n process.env.PLY_MCP_HTTP === '1' ||\n process.env.BASE_UI_MCP_HTTP === '1';\n let readOnly =\n argv.includes('--read-only') ||\n process.env.PLY_MCP_READ_ONLY === '1' ||\n process.env.BASE_UI_MCP_READ_ONLY === '1';\n let port = Number(process.env.PORT || process.env.PLY_MCP_PORT || process.env.BASE_UI_MCP_PORT || 3334);\n let host = process.env.PLY_MCP_HOST || process.env.BASE_UI_MCP_HOST || (http ? '127.0.0.1' : '127.0.0.1');\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === '--port' && argv[i + 1]) {\n port = Number(argv[++i]);\n } else if (arg?.startsWith('--port=')) {\n port = Number(arg.slice('--port='.length));\n } else if (arg === '--host' && argv[i + 1]) {\n host = argv[++i]!;\n } else if (arg?.startsWith('--host=')) {\n host = arg.slice('--host='.length);\n }\n }\n if (!Number.isFinite(port) || port <= 0) port = 3334;\n return { http, readOnly, port, host };\n}\n\nasync function main() {\n const opts = parseArgs(process.argv.slice(2));\n if (opts.http) {\n startHttpServer({\n host: opts.host,\n port: opts.port,\n readOnly: opts.readOnly,\n authToken:\n process.env.PLY_MCP_AUTH_TOKEN?.trim() ||\n process.env.BASE_UI_MCP_AUTH_TOKEN?.trim() ||\n undefined,\n });\n return;\n }\n\n const server = createMcpServer({ mutating: true });\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(`${MCP_PACKAGE} v${PACKAGE_VERSION} ready on stdio`);\n}\n\nmain().catch((err) => {\n console.error(`${MCP_PACKAGE} failed to start:`, err);\n process.exit(1);\n});\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { registerResources } from './resources';\nimport { getComponent, getComponentInput } from './tools/get-component';\nimport { listComponents, listComponentsInput } from './tools/list-components';\nimport { searchComponents, searchComponentsInput } from './tools/search-components';\nimport { PACKAGE_VERSION } from './version';\nimport { CLI_NPX, MCP_SERVER_NAME } from './brand';\n\n/**\n * One instructions string for every Ply server. Hosted catalog and local\n * install share it. It is not a second llms.txt.\n */\nexport const SERVER_INSTRUCTIONS =\n 'Search the catalog before inventing a component name. The hosted catalog cannot write files. A local install is init_project, then add_components. When PLY_LICENSE_KEY is already set, leave it in the environment and out of the tool call.';\n\n/** ChatGPT treats tools as writes unless readOnlyHint is set. */\nconst catalogAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: true,\n} as const;\n\n/** Catalog-only server: safe to bundle on Cloudflare Workers (no child_process). */\nexport function createCatalogMcpServer(): McpServer {\n const server = new McpServer(\n {\n name: MCP_SERVER_NAME,\n version: PACKAGE_VERSION,\n },\n { instructions: SERVER_INSTRUCTIONS },\n );\n\n server.registerTool(\n 'list_components',\n {\n title: 'List Ply components',\n description:\n `List components from the Ply registry. Filter by tier (free|pro|all), category, or name substring. Does not install anything. To copy a component into a project, tell the user to run ${CLI_NPX} add <name>.`,\n inputSchema: listComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => listComponents(args)\n );\n\n server.registerTool(\n 'get_component',\n {\n title: 'Get component details',\n description:\n `Get registry metadata for one component (deps, category, file list). Free source only when includeSource=true. Pro source is never streamed via MCP. Does not install; returns installCommand (${CLI_NPX} add <name>).`,\n inputSchema: getComponentInput,\n annotations: catalogAnnotations,\n },\n async (args) => getComponent(args)\n );\n\n server.registerTool(\n 'search_components',\n {\n title: 'Search Ply components',\n description:\n `Fuzzy / token search over registry component names (e.g. \"dialog\", \"sheet\", \"carousel\"). Does not install anything. Prefer this before guessing names, then give the user ${CLI_NPX} add <name> (or local stdio add_components).`,\n inputSchema: searchComponentsInput,\n annotations: catalogAnnotations,\n },\n async (args) => searchComponents(args)\n );\n\n registerResources(server);\n return server;\n}\n","import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n fetchText,\n isSafeItemName,\n} from './registry';\nimport { utf8ByteLength } from './utf8';\n\nexport function registerResources(server: McpServer) {\n server.registerResource(\n 'registry-index',\n 'ply-ui://registry/index',\n {\n title: 'Registry index',\n description: 'Public Ply registry index (names, tiers, categories, description, usage, keywords, deps)',\n mimeType: 'application/json',\n },\n async (uri) => {\n const index = await fetchIndex();\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(index, null, 2),\n },\n ],\n };\n }\n );\n\n server.registerResource(\n 'docs-llms',\n 'ply-ui://docs/llms',\n {\n title: 'llms.txt',\n description:\n 'Agent-oriented product overview (keep fetching this URL even when MCP is available)',\n mimeType: 'text/plain',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/llms.txt`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/plain', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-catalog',\n 'ply-ui://docs/catalog',\n {\n title: 'AI component catalog',\n description: 'docs/ai/components.md — detailed component reference for agents',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/components.md`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-cursor-rules',\n 'ply-ui://docs/cursor-rules',\n {\n title: 'Cursor / Windsurf project rules',\n description:\n 'Save as .cursor/rules/ply-ui.mdc (or .windsurf/rules/ply-ui.md). Teaches assistants to write standalone zoneless Angular 22 with Ply without running MCP.',\n mimeType: 'text/markdown',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.mdc`);\n return {\n contents: [{ uri: uri.href, mimeType: 'text/markdown', text }],\n };\n }\n );\n\n server.registerResource(\n 'docs-snippets',\n 'ply-ui://docs/snippets',\n {\n title: 'VS Code / Cursor snippets',\n description:\n 'Save as .vscode/ply-ui.code-snippets. Prefixes like ply-card expand usage markup after CLI install.',\n mimeType: 'application/json',\n },\n async (uri) => {\n const text = await fetchText(`${SITE_URL}/docs/ai/ply-ui.code-snippets`);\n return {\n contents: [{ uri: uri.href, mimeType: 'application/json', text }],\n };\n }\n );\n\n server.registerResource(\n 'component',\n new ResourceTemplate('ply-ui://component/{name}', {\n list: undefined,\n }),\n {\n title: 'Component metadata',\n description:\n 'Registry metadata for one component. Free source files are listed without content; Pro never streams source via MCP in V1.',\n mimeType: 'application/json',\n },\n async (uri, vars) => {\n const name = String(vars.name || '');\n if (!isSafeItemName(name)) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Invalid name: ${name}` }),\n },\n ],\n };\n }\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify({ error: `Unknown component: ${name}` }),\n },\n ],\n };\n }\n\n if (entry.tier === 'pro') {\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n ...entry,\n files: null,\n note: `Pro — metadata only. ${SITE_URL}/pricing`,\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n\n const item = await fetchFreeItem(name);\n return {\n contents: [\n {\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(\n {\n name: item.name,\n tier: item.tier,\n category: item.category,\n description: item.description,\n usage: item.usage,\n keywords: item.keywords,\n dependencies: item.dependencies,\n registryDependencies: item.registryDependencies,\n files: item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n })),\n },\n null,\n 2\n ),\n },\n ],\n };\n }\n );\n}\n","/**\n * Thin registry client — mirrors packages/cli/src/registry.ts URLs/schemas\n * so the MCP server can return structured JSON without parsing CLI stdout.\n * Install/write side effects still go through ply-ui-cli (canonical path).\n */\nimport { z } from 'zod';\n\nexport const SITE_URL = 'https://ply-ui.com';\nexport const GITHUB_HUB_URL = 'https://github.com/ply-ui-ng/ply';\n\nconst env =\n typeof process !== 'undefined' && process.env ? process.env : ({} as Record<string, string | undefined>);\n\nfunction firstEnv(...names: string[]): string | undefined {\n for (const name of names) {\n const v = env[name]?.trim();\n if (v) return v;\n }\n}\n\nexport const FREE_REGISTRY_URL =\n firstEnv('PLY_REGISTRY_URL', 'BASE_UI_REGISTRY_URL') || `${SITE_URL}/registry`;\n\nexport const PRO_REGISTRY_URL =\n firstEnv('PLY_PRO_REGISTRY_URL', 'BASE_UI_PRO_REGISTRY_URL') ||\n 'https://pro.ply-ui.com/registry';\n\nconst registryFileSchema = z.object({\n name: z.string(),\n content: z.string(),\n});\n\nexport const registryItemSchema = z.object({\n name: z.string(),\n tier: z.enum(['free', 'pro']),\n category: z\n .enum(['application', 'page-layout', 'block', 'widget', 'shell', 'component'])\n .optional()\n .default('component'),\n dependencies: z.array(z.string()).default([]),\n registryDependencies: z.array(z.string()).default([]),\n description: z.string().optional().default(''),\n usage: z.string().optional().default(''),\n keywords: z.array(z.string()).optional().default([]),\n files: z.array(registryFileSchema),\n type: z.string().optional(),\n license: z.enum(['MIT', 'Ply Pro']).optional(),\n});\n\nexport const registryIndexSchema = z.array(registryItemSchema.omit({ files: true }));\n\nexport type RegistryItem = z.infer<typeof registryItemSchema>;\nexport type RegistryIndexEntry = z.infer<typeof registryIndexSchema>[number];\n\nexport type Category = NonNullable<RegistryIndexEntry['category']>;\n\nexport function itemLicense(tier: 'free' | 'pro'): 'MIT' | 'Ply Pro' {\n return tier === 'pro' ? 'Ply Pro' : 'MIT';\n}\n\nexport function hubSourceUrl(name: string): string {\n return `${GITHUB_HUB_URL}/tree/main/components/${name}`;\n}\n\nexport function itemHaystack(\n item: Pick<RegistryIndexEntry, 'name' | 'description' | 'usage' | 'keywords'>\n): string {\n return [item.name, item.description, item.usage, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n\nexport function isSafeItemName(name: string): boolean {\n return /^[a-z0-9][a-z0-9-.]*$/i.test(name) && !name.includes('..');\n}\n\nasync function fetchJson(url: string, headers: Record<string, string> = {}): Promise<unknown> {\n let res: Response;\n try {\n res = await fetch(url, { headers });\n } catch (err: any) {\n throw new Error(\n `Network error while contacting the registry (${err.message}). Check your connection and try again.`\n );\n }\n if (res.status === 401 || res.status === 403) {\n throw new Error(\n `License rejected (HTTP ${res.status}). Check PLY_LICENSE_KEY, or see ${SITE_URL}/pricing.`\n );\n }\n if (res.status === 404) {\n const e: any = new Error('Not found');\n e.code = 'NOT_FOUND';\n throw e;\n }\n if (!res.ok) {\n throw new Error(`Registry request failed (HTTP ${res.status}) for ${url}.`);\n }\n return res.json();\n}\n\nexport async function fetchIndex(): Promise<RegistryIndexEntry[]> {\n const data = await fetchJson(`${FREE_REGISTRY_URL}/index.json`);\n return registryIndexSchema.parse(data);\n}\n\n/** Free registry item only — V1 never streams Pro source through MCP. */\nexport async function fetchFreeItem(name: string): Promise<RegistryItem> {\n if (!isSafeItemName(name)) {\n throw new Error(`Invalid component name: '${name}'.`);\n }\n const data = await fetchJson(`${FREE_REGISTRY_URL}/styles/default/${name}.json`);\n return registryItemSchema.parse(data);\n}\n\nexport async function fetchText(url: string): Promise<string> {\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err: any) {\n throw new Error(`Network error fetching ${url}: ${err.message}`);\n }\n if (!res.ok) {\n throw new Error(`Failed to fetch ${url} (HTTP ${res.status}).`);\n }\n return res.text();\n}\n\n/** Closest names to `query`, for search / suggestions. */\nexport function suggestNames(query: string, names: string[], limit = 8): string[] {\n const q = query.toLowerCase().trim();\n if (!q) return [];\n const scored = names\n .map((name) => {\n const n = name.toLowerCase();\n let score: number;\n if (n === q) score = 0;\n else if (n.startsWith(q) || q.startsWith(n)) score = 1;\n else if (n.includes(q) || q.includes(n)) score = 2;\n else score = 3 + levenshtein(q, n);\n return { name, score };\n })\n .filter((s) => s.score <= 6)\n .sort((a, b) => a.score - b.score || a.name.localeCompare(b.name));\n return scored.slice(0, limit).map((s) => s.name);\n}\n\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n if (!m) return n;\n if (!n) return m;\n let prev = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n const curr = [i];\n for (let j = 1; j <= n; j++) {\n curr[j] = Math.min(\n prev[j] + 1,\n curr[j - 1] + 1,\n prev[j - 1] + (a[i - 1] === b[j - 1] ? 0 : 1)\n );\n }\n prev = curr;\n }\n return prev[n];\n}\n","/** UTF-8 byte length without Node `Buffer` (Workers / browsers). */\nexport function utf8ByteLength(text: string): number {\n return new TextEncoder().encode(text).byteLength;\n}\n","import { z } from 'zod';\nimport {\n SITE_URL,\n fetchFreeItem,\n fetchIndex,\n hubSourceUrl,\n isSafeItemName,\n itemLicense,\n suggestNames,\n} from '../registry';\nimport { cliAddCommand, installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\nimport { utf8ByteLength } from '../utf8';\n\nexport const getComponentInput = {\n name: z.string().describe('Registry component name (e.g. button, card)'),\n includeSource: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, include free-tier source file contents. Pro source is never returned via MCP in V1.'\n ),\n};\n\nexport async function getComponent(args: { name: string; includeSource?: boolean }) {\n try {\n const name = args.name.trim();\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n\n const index = await fetchIndex();\n const entry = index.find((i) => i.name === name);\n if (!entry) {\n const suggestions = suggestNames(\n name,\n index.map((i) => i.name)\n );\n return failJson(`Unknown component: '${name}'.`, {\n suggestions,\n listHint: 'Call list_components or search_components.',\n });\n }\n\n const base = {\n ok: true as const,\n name: entry.name,\n tier: entry.tier,\n license: entry.license || itemLicense(entry.tier),\n category: entry.category || 'component',\n description: entry.description || '',\n usage: entry.usage || '',\n keywords: entry.keywords || [],\n dependencies: entry.dependencies,\n registryDependencies: entry.registryDependencies,\n docsUrl: `${SITE_URL}/base-elements/${entry.name}/`,\n pricingUrl: `${SITE_URL}/pricing`,\n };\n\n if (entry.tier === 'pro') {\n return okJson({\n ...base,\n source: null,\n sourceUrl: null,\n installCommand: cliAddCommand(name),\n note: `Pro component — metadata only. ${installHint(name)} Pro install also needs PLY_LICENSE_KEY. Buy at ${SITE_URL}/pricing.`,\n });\n }\n\n const item = await fetchFreeItem(name);\n const files = item.files.map((f) => ({\n path: f.name,\n bytes: utf8ByteLength(f.content),\n ...(args.includeSource ? { content: f.content } : {}),\n }));\n\n return okJson({\n ...base,\n files,\n includeSource: Boolean(args.includeSource),\n sourceUrl: hubSourceUrl(name),\n installCommand: cliAddCommand(name),\n note: args.includeSource\n ? `Free source included for reading. ${installHint(name)}`\n : `Source omitted by default. Pass includeSource=true to read free files here. ${installHint(name)}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Public npm / npx names for the Ply CLI and MCP. */\nexport const CLI_PACKAGE = 'ply-ui-cli';\nexport const CLI_BIN = 'ply-ui-cli';\nexport const CLI_NPX = `npx ${CLI_BIN}`;\nexport const MCP_PACKAGE = 'ply-ui-mcp';\nexport const MCP_NPX = `npx -y ${MCP_PACKAGE}`;\nexport const MCP_SERVER_NAME = 'ply';\n","import { CLI_NPX } from './brand';\n\n/** Copy-paste installer. Hosted catalog MCP cannot write files. */\nexport function cliAddCommand(name?: string): string {\n return name?.trim()\n ? `${CLI_NPX} add ${name.trim()}`\n : `${CLI_NPX} add <name>`;\n}\n\nexport function installHint(name?: string): string {\n return (\n `This catalog does not write files. Install in the project with \\`${cliAddCommand(name)}\\`. ` +\n 'Local stdio MCP (Cursor, Claude Code) can call add_components instead.'\n );\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\n\nfunction asRecord(data: unknown): Record<string, unknown> | undefined {\n if (data && typeof data === 'object' && !Array.isArray(data)) {\n return data as Record<string, unknown>;\n }\n return undefined;\n}\n\nexport function okJson(data: unknown): CallToolResult {\n const structuredContent = asRecord(data);\n return {\n content: [{ type: 'text', text: JSON.stringify(data, null, 2) }],\n ...(structuredContent ? { structuredContent } : {}),\n };\n}\n\nexport function failJson(\n message: string,\n extra: Record<string, unknown> = {}\n): CallToolResult {\n const structuredContent = { ok: false, error: message, ...extra };\n return {\n isError: true,\n structuredContent,\n content: [\n {\n type: 'text',\n text: JSON.stringify(structuredContent, null, 2),\n },\n ],\n };\n}\n","import { z } from 'zod';\nimport { fetchIndex, itemHaystack, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const listComponentsInput = {\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z\n .enum(CATEGORIES)\n .optional()\n .describe('Filter by registry category'),\n q: z\n .string()\n .optional()\n .describe('Substring filter on name, description, usage, or keywords (case-insensitive)'),\n};\n\nexport async function listComponents(args: {\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n q?: string;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const q = args.q?.trim().toLowerCase();\n\n let items = index;\n if (tier !== 'all') {\n items = items.filter((i) => i.tier === tier);\n }\n if (args.category) {\n items = items.filter((i) => (i.category || 'component') === args.category);\n }\n if (q) {\n items = items.filter((i) => itemHaystack(i).includes(q));\n }\n\n items = [...items].sort((a, b) => a.name.localeCompare(b.name));\n\n return okJson({\n ok: true,\n count: items.length,\n items: items.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n dependencies: i.dependencies,\n registryDependencies: i.registryDependencies,\n })),\n hint: `Use get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { canonicalComponentName } from '../aliases';\nimport { fetchIndex, itemHaystack, suggestNames, itemLicense, type Category } from '../registry';\nimport { installHint } from '../install-hint';\nimport { failJson, okJson } from '../result';\n\nconst CATEGORIES = [\n 'application',\n 'page-layout',\n 'block',\n 'widget',\n 'shell',\n 'component',\n] as const satisfies readonly Category[];\n\nexport const searchComponentsInput = {\n query: z\n .string()\n .min(1)\n .describe('Natural-language or substring query (e.g. \"dialog modal\", \"button\"). Matches name, description, usage, and keywords.'),\n tier: z\n .enum(['free', 'pro', 'all'])\n .optional()\n .default('all')\n .describe('Filter by license tier'),\n category: z.enum(CATEGORIES).optional().describe('Filter by registry category'),\n limit: z.number().int().min(1).max(40).optional().default(12),\n};\n\nfunction tokenize(query: string): string[] {\n return query\n .toLowerCase()\n .split(/[^a-z0-9]+/i)\n .map((t) => t.trim())\n .filter((t) => t.length >= 2);\n}\n\nexport async function searchComponents(args: {\n query: string;\n tier?: 'free' | 'pro' | 'all';\n category?: Category;\n limit?: number;\n}) {\n try {\n const index = await fetchIndex();\n const tier = args.tier ?? 'all';\n const limit = args.limit ?? 12;\n const rawQuery = args.query.trim();\n const canonical = canonicalComponentName(rawQuery);\n const variants = [...new Set([rawQuery, canonical].filter(Boolean))];\n\n let pool = index;\n if (tier !== 'all') {\n pool = pool.filter((i) => i.tier === tier);\n }\n if (args.category) {\n pool = pool.filter((i) => (i.category || 'component') === args.category);\n }\n\n const names = pool.map((i) => i.name);\n const byFuzzy = new Set(variants.flatMap((q) => suggestNames(q, names, limit)));\n\n const byTokens = pool.filter((i) => {\n const hay = itemHaystack(i);\n return variants.some((q) => {\n const tokens = tokenize(q);\n return tokens.length > 0 && tokens.every((t) => hay.includes(t));\n });\n });\n\n const ranked = [\n ...byTokens.sort((a, b) => a.name.localeCompare(b.name)),\n ...pool\n .filter((i) => byFuzzy.has(i.name) && !byTokens.some((t) => t.name === i.name))\n .sort(\n (a, b) =>\n [...byFuzzy].indexOf(a.name) - [...byFuzzy].indexOf(b.name)\n ),\n ].slice(0, limit);\n\n return okJson({\n ok: true,\n query: args.query,\n count: ranked.length,\n matches: ranked.map((i) => ({\n name: i.name,\n tier: i.tier,\n license: i.license || itemLicense(i.tier),\n category: i.category || 'component',\n description: i.description || '',\n usage: i.usage || '',\n keywords: i.keywords || [],\n registryDependencies: i.registryDependencies,\n })),\n hint: `Next: get_component for details. ${installHint()}`,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","/** Keep in sync with packages/cli/src/aliases.ts */\nexport const COMPONENT_ALIASES: Record<string, string> = {\n sheet: 'drawer',\n 'side-sheet': 'drawer',\n gallery: 'slider',\n 'image-slider': 'slider',\n slideshow: 'slider',\n range: 'range-slider',\n 'slider-input': 'range-slider',\n 'input-slider': 'range-slider',\n 'base-list-item': 'ply-list-item',\n 'base-tab-icon': 'ply-tab-icon',\n 'base-group-button': 'ply-group-button',\n 'base-dropdown-menu-item': 'ply-dropdown-menu-item',\n 'base-context-menu-item': 'ply-context-menu-item',\n};\n\nexport function canonicalComponentName(name: string): string {\n const key = name.trim().toLowerCase();\n return COMPONENT_ALIASES[key] ?? name.trim();\n}\n","{\n \"name\": \"ply-ui-mcp\",\n \"version\": \"0.1.32\",\n \"description\": \"Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.\",\n \"type\": \"commonjs\",\n \"main\": \"dist/index.js\",\n \"bin\": {\n \"ply-ui-mcp\": \"dist/index.js\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"engines\": {\n \"node\": \">=18\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"start\": \"node dist/index.js\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"mcp\",\n \"model-context-protocol\",\n \"angular\",\n \"tailwindcss\",\n \"ply\",\n \"ply-ui\",\n \"ply-ui-mcp\",\n \"cli\"\n ],\n \"author\": \"Lussos\",\n \"license\": \"MIT\",\n \"mcpName\": \"io.github.ply-ui-ng/ply-ui\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ply-ui-ng/ply.git\",\n \"directory\": \"packages/mcp\"\n },\n \"homepage\": \"https://ply-ui.com\",\n \"bugs\": {\n \"url\": \"https://github.com/ply-ui-ng/ply/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.32.1\",\n \"zod\": \"^4.6.2\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^26.5.1\",\n \"tsup\": \"^9.0.0\",\n \"typescript\": \"^7.0.2\",\n \"vitest\": \"^5.0.0\"\n },\n \"overrides\": {\n \"esbuild\": \"0.28.2\",\n \"fast-uri\": \"3.1.8\",\n \"proxy-addr\": \"2.0.8\",\n \"hono\": \"4.13.13\",\n \"qs\": \"6.16.0\"\n }\n}\n","import packageJson from '../package.json' with { type: 'json' };\n\n/** Bundled from packages/mcp/package.json by tsup and by the Workers deploy. */\nexport const PACKAGE_VERSION: string = packageJson.version;\n","import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\n\nexport type ReplaceDecision = 'replace' | 'keep' | 'unsupported';\n\nexport interface ReplaceResolution {\n apply: boolean;\n confirmation?: 'accepted' | 'declined' | 'unsupported';\n}\n\n/**\n * Ask a host that supports form elicitation before an overwrite.\n * Hosts that cannot ask leave the explicit flag in place.\n */\nexport async function confirmReplace(server: McpServer, message: string): Promise<ReplaceDecision> {\n try {\n const result = await server.server.elicitInput({\n mode: 'form',\n message,\n requestedSchema: {\n type: 'object',\n properties: {\n replace: {\n type: 'boolean',\n title: 'Replace existing files',\n description: 'Overwrite the copies already in the project.',\n default: false,\n },\n },\n required: ['replace'],\n },\n });\n if (result.action === 'accept' && result.content?.replace === true) return 'replace';\n return 'keep';\n } catch (err) {\n const text = err instanceof Error ? err.message : String(err);\n if (text.includes('does not support form elicitation')) return 'unsupported';\n throw err;\n }\n}\n\nexport async function resolveReplace(\n requested: boolean,\n confirm: ((message: string) => Promise<ReplaceDecision>) | undefined,\n message: string,\n): Promise<ReplaceResolution> {\n if (!requested) return { apply: false };\n if (!confirm) return { apply: true };\n const decision = await confirm(message);\n if (decision === 'keep') return { apply: false, confirmation: 'declined' };\n if (decision === 'unsupported') return { apply: true, confirmation: 'unsupported' };\n return { apply: true, confirmation: 'accepted' };\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport {\n SITE_URL,\n fetchIndex,\n isSafeItemName,\n suggestNames,\n} from '../registry';\nimport { addOutput, parseAddReport } from '../cli-report';\nimport { resolveReplace, type ReplaceDecision } from '../elicit';\nimport { failJson, okJson } from '../result';\nimport { canonicalComponentName } from '../aliases';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport { addOutput };\n\nexport interface AddComponentsHooks {\n confirmReplace?: (message: string) => Promise<ReplaceDecision>;\n}\n\nexport const addComponentsInput = {\n names: z\n .array(z.string().min(1))\n .min(1)\n .describe('One or more registry component names to install (aliases like sheet → drawer are resolved)'),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD / BASE_UI_CWD)'\n ),\n overwrite: z\n .boolean()\n .optional()\n .default(false)\n .describe('Overwrite existing component folders (maps to CLI --overwrite)'),\n licenseKey: z\n .string()\n .optional()\n .describe(\n 'Ply Pro license. Prefer PLY_LICENSE_KEY (or BASE_UI_LICENSE_KEY) in the MCP server env instead of putting a key in chat.'\n ),\n};\n\n/**\n * Installs registry components via the CLI. Pro names require\n * `licenseKey` or `PLY_LICENSE_KEY` / `BASE_UI_LICENSE_KEY`.\n */\nexport async function addComponents(\n args: {\n names: string[];\n cwd?: string;\n overwrite?: boolean;\n licenseKey?: string;\n },\n hooks: AddComponentsHooks = {},\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = [\n ...new Set(\n args.names\n .map((n) => canonicalComponentName(n.trim()))\n .filter(Boolean)\n ),\n ];\n\n if (!names.length) {\n return failJson('Provide at least one component name.');\n }\n\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const index = await fetchIndex();\n const byName = new Map(index.map((i) => [i.name, i]));\n const unknown: string[] = [];\n const pro: string[] = [];\n const free: string[] = [];\n\n for (const name of names) {\n const entry = byName.get(name);\n if (!entry) {\n unknown.push(name);\n continue;\n }\n if (entry.tier === 'pro') {\n pro.push(name);\n } else {\n free.push(name);\n }\n }\n\n if (unknown.length) {\n return failJson('Unknown component name(s).', {\n unknown,\n suggestions: unknown.flatMap((n) =>\n suggestNames(\n n,\n index.map((i) => i.name),\n 3\n )\n ),\n });\n }\n\n const licenseKey =\n args.licenseKey?.trim() ||\n process.env.PLY_LICENSE_KEY?.trim() ||\n process.env.BASE_UI_LICENSE_KEY?.trim() ||\n '';\n\n if (pro.length && !licenseKey) {\n return failJson(\n `Pro components need PLY_LICENSE_KEY (or licenseKey): ${pro.join(', ')}.`,\n {\n pro,\n pricingUrl: `${SITE_URL}/pricing`,\n note: 'Set PLY_LICENSE_KEY on the MCP server process (BASE_UI_LICENSE_KEY still works), then retry. Free components can still be added with this tool.',\n freeCandidates: free,\n }\n );\n }\n\n // Also reject if free items pull Pro registryDependencies (closure).\n const queue = [...free];\n const seen = new Set<string>();\n const proDeps: string[] = [];\n while (queue.length) {\n const name = queue.shift()!;\n if (seen.has(name)) continue;\n seen.add(name);\n const entry = byName.get(name);\n if (!entry) continue;\n if (entry.tier === 'pro') {\n proDeps.push(name);\n continue;\n }\n queue.push(...entry.registryDependencies);\n }\n if (proDeps.length && !licenseKey) {\n return failJson(\n `Install blocked: free selection depends on Pro components: ${proDeps.join(', ')}.`,\n {\n proDependencies: proDeps,\n pricingUrl: `${SITE_URL}/pricing`,\n }\n );\n }\n\n const toInstall = [...free, ...pro];\n const replace = await resolveReplace(\n Boolean(args.overwrite),\n hooks.confirmReplace,\n `Replace existing files for ${toInstall.join(', ')}? This overwrites the copies already in the project.`,\n );\n const cliArgs = ['add', ...toInstall, '--yes'];\n if (replace.apply) cliArgs.push('--overwrite');\n\n const result = await runCli(cliArgs, {\n cwd,\n env: licenseKey\n ? { PLY_LICENSE_KEY: licenseKey, BASE_UI_LICENSE_KEY: licenseKey }\n : undefined,\n });\n const stdout = result.stdout.trim();\n const install = parseAddReport(stdout);\n const note = [\n `Files were written by ${CLI_BIN} (canonical installer). MCP does not replace the CLI.`,\n replace.confirmation === 'declined'\n ? 'Overwrite was not confirmed. Existing files were left in place.'\n : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (!result.ok) {\n return failJson(`${CLI_BIN} add failed.`, {\n cwd,\n names: toInstall,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim(),\n missingPackages: install.missingPackages,\n ...(install.installCommand ? { installCommand: install.installCommand } : {}),\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n hint: `Ensure the project was initialized (${CLI_NPX} init --yes). CLI remains the canonical install path.`,\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n installed: toInstall,\n cli: `${CLI_BIN} add --yes`,\n stdout,\n stderr: result.stderr.trim() || undefined,\n missingPackages: install.missingPackages,\n ...(install.installCommand ? { installCommand: install.installCommand } : {}),\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n note,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport { CLI_PACKAGE } from './brand';\n\n/**\n * Resolve the ply-ui-cli entrypoint.\n * Order: PLY_CLI_PATH → local monorepo dist → node_modules bin → npx.\n */\nexport function resolveCliEntrypoint(): { command: string; argsPrefix: string[] } {\n const envPath = process.env.PLY_CLI_PATH?.trim() || process.env.BASE_UI_CLI_PATH?.trim();\n if (envPath && fs.existsSync(envPath)) {\n return { command: process.execPath, argsPrefix: [envPath] };\n }\n\n const sibling = path.resolve(__dirname, '../../cli/dist/index.js');\n if (fs.existsSync(sibling)) {\n return { command: process.execPath, argsPrefix: [sibling] };\n }\n\n for (const pkg of [CLI_PACKAGE, 'base-ui-cli']) {\n try {\n const pkgJson = require.resolve(`${pkg}/package.json`);\n const bin = path.join(path.dirname(pkgJson), 'dist', 'index.js');\n if (fs.existsSync(bin)) {\n return { command: process.execPath, argsPrefix: [bin] };\n }\n } catch {\n // not installed as a dependency\n }\n }\n\n // npx.cmd is named directly so the child process never needs a shell — see\n // the spawn call below, which deliberately does not set `shell`.\n return { command: process.platform === 'win32' ? 'npx.cmd' : 'npx', argsPrefix: ['-y', CLI_PACKAGE] };\n}\n\nexport interface RunCliResult {\n ok: boolean;\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nexport function runCli(\n cliArgs: string[],\n options: { cwd: string; env?: NodeJS.ProcessEnv; timeoutMs?: number } = { cwd: process.cwd() }\n): Promise<RunCliResult> {\n const { command, argsPrefix } = resolveCliEntrypoint();\n const args = [...argsPrefix, ...cliArgs];\n const timeoutMs = options.timeoutMs ?? 120_000;\n\n return new Promise((resolve) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: { ...process.env, ...options.env, FORCE_COLOR: '0' },\n });\n\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const timer = setTimeout(() => {\n if (settled) return;\n settled = true;\n child.kill('SIGTERM');\n resolve({\n ok: false,\n code: null,\n stdout,\n stderr: stderr + `\\nTimed out after ${timeoutMs}ms`,\n });\n }, timeoutMs);\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (err) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: false, code: null, stdout, stderr: err.message });\n });\n child.on('close', (code) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve({ ok: code === 0, code, stdout, stderr });\n });\n });\n}\n\n/** Project root for mutating tools (init/add). Prefer explicit cwd, else process cwd. */\nexport function resolveProjectCwd(cwd?: string): string {\n const root = cwd?.trim() || process.env.PLY_CWD?.trim() || process.env.BASE_UI_CWD?.trim() || process.cwd();\n return path.resolve(root);\n}\n","import { z } from 'zod';\n\nexport interface DoctorCheck {\n name: string;\n status: 'ok' | 'warn' | 'error';\n message: string;\n}\n\nexport interface AddInstallReport {\n missingPackages: string[];\n installCommand?: string;\n}\n\nexport interface UpdateFileResult {\n path: string;\n action: 'updated' | 'added' | 'reverted' | 'kept' | 'merged' | 'merge-conflict' | 'saved-aside';\n detail?: string;\n}\n\nconst STATUS: Record<string, DoctorCheck['status']> = {\n '✔': 'ok',\n '⚠': 'warn',\n '✖': 'error',\n};\n\nconst FILE_ACTION: Record<string, UpdateFileResult['action']> = {\n '↑': 'updated',\n '+': 'added',\n '↓': 'reverted',\n '=': 'kept',\n '⋈': 'merged',\n '⚠': 'merge-conflict',\n '⇄': 'saved-aside',\n};\n\nexport const doctorOutput = z.looseObject({\n ok: z.boolean(),\n checks: z.array(\n z.looseObject({\n name: z.string(),\n status: z.enum(['ok', 'warn', 'error']),\n message: z.string(),\n }),\n ),\n});\n\nexport const addOutput = z.looseObject({\n ok: z.boolean(),\n missingPackages: z.array(z.string()),\n installCommand: z.string().optional(),\n});\n\nexport const updateOutput = z.looseObject({\n ok: z.boolean(),\n files: z.array(\n z.looseObject({\n path: z.string(),\n action: z.enum(['updated', 'added', 'reverted', 'kept', 'merged', 'merge-conflict', 'saved-aside']),\n detail: z.string().optional(),\n }),\n ),\n});\n\nfunction plain(text: string): string {\n return text.replace(/\\u001b\\[[0-9;]*m/g, '').replace(/\\r\\n/g, '\\n');\n}\n\n/** Doctor prints `✔|⚠|✖ Name: message` on stdout. The summary line is ignored. */\nexport function parseDoctorChecks(stdout: string): DoctorCheck[] {\n const checks: DoctorCheck[] = [];\n for (const line of plain(stdout).split('\\n')) {\n const match = line.match(/^([✔⚠✖])\\s+([^:]+):\\s*(.*)$/);\n if (!match) continue;\n const status = STATUS[match[1]];\n if (!status) continue;\n checks.push({ name: match[2].trim(), status, message: match[3].trim() });\n }\n return checks;\n}\n\n/** Add prints the package-manager command instead of running it. */\nexport function parseAddReport(stdout: string): AddInstallReport {\n const match = plain(stdout).match(/Install missing npm dependenc(?:y|ies):\\n\\s+(.+)/);\n if (!match) return { missingPackages: [] };\n const installCommand = match[1].trim();\n const packages = installCommand.match(/^(?:npm install|pnpm add|yarn add|bun add)\\s+(.+)$/);\n return {\n installCommand,\n missingPackages: packages ? packages[1].split(/\\s+/).filter(Boolean) : [],\n };\n}\n\n/** Update prints one indented symbol line per file it touched or skipped. */\nexport function parseUpdateFiles(stdout: string): UpdateFileResult[] {\n const files: UpdateFileResult[] = [];\n for (const line of plain(stdout).split('\\n')) {\n const match = line.match(/^\\s*([↑+↓=⋈⚠⇄])\\s+(\\S+)(?:\\s+\\((.*)\\))?\\s*$/);\n if (!match) continue;\n const action = FILE_ACTION[match[1]];\n if (!action) continue;\n const detail = match[3]?.trim();\n files.push(detail ? { path: match[2], action, detail } : { path: match[2], action });\n }\n return files;\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport const diffComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to diff. Omit or pass [] to check every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n};\n\nexport async function diffComponents(args: { names?: string[]; cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const cliArgs = names.length ? ['diff', ...names] : ['diff'];\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} diff failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: 'Project must be initialized and components tracked in ply-ui-lock.json.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n cli: names.length ? `${CLI_BIN} diff ${names.join(' ')}` : `${CLI_BIN} diff`,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n note: 'Read-only. Use update_components to apply upstream changes.',\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { parseDoctorChecks, doctorOutput } from '../cli-report';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport { doctorOutput };\n\nexport const doctorInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD). Read-only.'\n ),\n};\n\nexport async function doctor(args: { cwd?: string } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const result = await runCli(['doctor'], { cwd });\n const stdout = result.stdout.trim();\n const body = {\n cwd,\n cli: `${CLI_BIN} doctor`,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim() || undefined,\n checks: parseDoctorChecks(stdout),\n };\n if (!result.ok) {\n return failJson(`${CLI_BIN} doctor reported problems.`, body);\n }\n return okJson({ ok: true, ...body });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN, CLI_NPX } from '../brand';\n\nexport const initProjectInput = {\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root to initialize (defaults to MCP process cwd / PLY_CWD). Always non-interactive (`init --yes`).'\n ),\n refreshEditorKit: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Replace an editor kit that is already there (Cursor rule, snippets, and the design skill in .cursor/skills and .agents/skills). Maps to `init --refresh-editor-kit`.'\n ),\n};\n\nexport async function initProject(args: { cwd?: string; refreshEditorKit?: boolean } = {}) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const cliArgs = ['init', '--yes'];\n if (args.refreshEditorKit) cliArgs.push('--refresh-editor-kit');\n const result = await runCli(cliArgs, { cwd });\n if (!result.ok) {\n return failJson(`${CLI_BIN} init failed.`, {\n cwd,\n exitCode: result.code,\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim(),\n hint: `CLI remains the canonical installer: ${CLI_NPX} init --yes`,\n });\n }\n return okJson({\n ok: true,\n cwd,\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout: result.stdout.trim(),\n stderr: result.stderr.trim() || undefined,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { z } from 'zod';\nimport { resolveProjectCwd, runCli } from '../cli';\nimport { isSafeItemName } from '../registry';\nimport { parseUpdateFiles, updateOutput } from '../cli-report';\nimport { resolveReplace, type ReplaceDecision } from '../elicit';\nimport { failJson, okJson } from '../result';\nimport { CLI_BIN } from '../brand';\n\nexport { updateOutput };\n\nexport interface UpdateComponentsHooks {\n confirmReplace?: (message: string) => Promise<ReplaceDecision>;\n}\n\nexport const updateComponentsInput = {\n names: z\n .array(z.string().min(1))\n .optional()\n .describe(\n 'Tracked component names to update. Omit or pass [] to update every component in ply-ui-lock.json.'\n ),\n cwd: z\n .string()\n .optional()\n .describe(\n 'Project root containing ply-ui.json (defaults to MCP process cwd / PLY_CWD)'\n ),\n force: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict (both local and upstream changed), take the upstream version. Does not revert local-only edits.'\n ),\n overwriteLocal: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'Also revert files you edited that upstream did not change (`--overwrite-local`). Default skips those files.'\n ),\n merge: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'On conflict, apply a 3-way merge using the installed snapshot (`--merge`). force still wins.'\n ),\n};\n\n/**\n * Always non-interactive (`update --yes`). Conflicts are skipped unless `force`.\n * Local-only edits are skipped unless `overwriteLocal`.\n */\nexport async function updateComponents(\n args: {\n names?: string[];\n cwd?: string;\n force?: boolean;\n overwriteLocal?: boolean;\n merge?: boolean;\n } = {},\n hooks: UpdateComponentsHooks = {},\n) {\n try {\n const cwd = resolveProjectCwd(args.cwd);\n const names = (args.names ?? []).map((n) => n.trim()).filter(Boolean);\n for (const name of names) {\n if (!isSafeItemName(name)) {\n return failJson(`Invalid component name: '${name}'.`);\n }\n }\n\n const target = names.length ? names.join(', ') : 'tracked components';\n const replace = await resolveReplace(\n Boolean(args.force || args.overwriteLocal),\n hooks.confirmReplace,\n `Replace local files while updating ${target}? This overwrites copies already in the project.`,\n );\n const cliArgs = ['update', ...names, '--yes'];\n if (args.force && replace.apply) cliArgs.push('--force');\n if (args.overwriteLocal && replace.apply) cliArgs.push('--overwrite-local');\n if (args.merge) cliArgs.push('--merge');\n\n const result = await runCli(cliArgs, { cwd });\n const stdout = result.stdout.trim();\n const files = parseUpdateFiles(stdout);\n const note = [\n `Files were written by ${CLI_BIN} (canonical updater). MCP does not replace the CLI.`,\n replace.confirmation === 'declined'\n ? 'Replace was not confirmed. Conflicts and local-only edits were left in place.'\n : '',\n ]\n .filter(Boolean)\n .join(' ');\n if (!result.ok) {\n return failJson(`${CLI_BIN} update failed.`, {\n cwd,\n names,\n exitCode: result.code,\n stdout,\n stderr: result.stderr.trim(),\n files,\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n hint: 'Run diff_components first. Conflicts need --force; local-only edits need overwriteLocal.',\n });\n }\n\n return okJson({\n ok: true,\n cwd,\n names: names.length ? names : 'all-tracked',\n force: Boolean(args.force && replace.apply),\n overwriteLocal: Boolean(args.overwriteLocal && replace.apply),\n merge: Boolean(args.merge),\n cli: [CLI_BIN, ...cliArgs].join(' '),\n stdout,\n stderr: result.stderr.trim() || undefined,\n files,\n ...(replace.confirmation ? { confirmation: replace.confirmation } : {}),\n note,\n });\n } catch (err: any) {\n return failJson(err.message || String(err));\n }\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createCatalogMcpServer } from './catalog';\nimport { confirmReplace } from './elicit';\nimport { addComponents, addComponentsInput, addOutput } from './tools/add-components';\nimport { diffComponents, diffComponentsInput } from './tools/diff-components';\nimport { doctor, doctorInput, doctorOutput } from './tools/doctor';\nimport { initProject, initProjectInput } from './tools/init-project';\nimport { updateComponents, updateComponentsInput, updateOutput } from './tools/update-components';\nimport { CLI_BIN } from './brand';\n\nexport { PACKAGE_VERSION } from './version';\n\nexport interface CreateMcpServerOptions {\n /** When false, mutating CLI tools are omitted (hosted catalog MCP). */\n mutating?: boolean;\n}\n\nexport function createMcpServer(options: CreateMcpServerOptions = {}): McpServer {\n const mutating = options.mutating !== false;\n const server = createCatalogMcpServer();\n\n const readOnlyAnnotations = {\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n } as const;\n const writeAnnotations = {\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n } as const;\n\n if (mutating) {\n server.registerTool(\n 'add_components',\n {\n title: 'Add Ply components',\n description:\n `Install registry components by shelling to \\`${CLI_BIN} add --yes\\`. --yes leaves an existing component in place; pass overwrite to replace it. Hosts that can ask confirm that overwrite first. Pro names require PLY_LICENSE_KEY (or licenseKey). Project must already have ply-ui.json. structuredContent includes missingPackages and installCommand.`,\n inputSchema: addComponentsInput,\n outputSchema: addOutput,\n annotations: writeAnnotations,\n },\n async (args) =>\n addComponents(args, {\n confirmReplace: (message) => confirmReplace(server, message),\n })\n );\n\n server.registerTool(\n 'init_project',\n {\n title: 'Initialize Ply in a project',\n description:\n `Run \\`${CLI_BIN} init --yes\\` in the target directory. Writes ply-ui.json, ply-ui.css, and icon sprites only when those files are missing, discovers the stylesheet already listed in angular.json, and inserts @source when it is absent. Writes the design skill to .cursor/skills and .agents/skills when those files are missing. Pass refreshEditorKit to replace an existing editor kit. Always non-interactive.`,\n inputSchema: initProjectInput,\n annotations: writeAnnotations,\n },\n async (args) => initProject(args)\n );\n\n server.registerTool(\n 'doctor',\n {\n title: 'Verify Ply project setup',\n description:\n `Run \\`${CLI_BIN} doctor\\` (read-only). structuredContent.checks lists each ✔/⚠/✖ line. Returns isError when the CLI exits non-zero.`,\n inputSchema: doctorInput,\n outputSchema: doctorOutput,\n annotations: readOnlyAnnotations,\n },\n async (args) => doctor(args)\n );\n\n server.registerTool(\n 'diff_components',\n {\n title: 'Diff installed Ply components',\n description:\n `Run \\`${CLI_BIN} diff\\` against tracked components. Read-only. Omit names to check everything in ply-ui-lock.json.`,\n inputSchema: diffComponentsInput,\n annotations: readOnlyAnnotations,\n },\n async (args) => diffComponents(args)\n );\n\n server.registerTool(\n 'update_components',\n {\n title: 'Update installed Ply components',\n description:\n `Run \\`${CLI_BIN} update --yes\\`. Untouched files take upstream. Conflicts stay local and the CLI exits non-zero unless force or merge. Local-only edits skip unless overwriteLocal. Hosts that can ask confirm force and overwriteLocal before those flags replace files. structuredContent.files is one result per file line.`,\n inputSchema: updateComponentsInput,\n outputSchema: updateOutput,\n annotations: writeAnnotations,\n },\n async (args) =>\n updateComponents(args, {\n confirmReplace: (message) => confirmReplace(server, message),\n })\n );\n }\n\n return server;\n}\n","import { createServer, type IncomingMessage, type ServerResponse } from 'node:http';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { createMcpServer, PACKAGE_VERSION } from './server';\nimport { MCP_PACKAGE } from './brand';\nimport { mcpProtectedResource, wwwAuthenticate } from './auth-metadata';\n\nexport interface HttpOptions {\n host: string;\n port: number;\n readOnly: boolean;\n authToken?: string;\n}\n\nfunction setCors(res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');\n res.setHeader(\n 'Access-Control-Allow-Headers',\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version'\n );\n}\n\nfunction unauthorized(res: ServerResponse, resourceMetadataUrl: string): void {\n setCors(res);\n res.writeHead(401, {\n 'Content-Type': 'application/json',\n 'WWW-Authenticate': wwwAuthenticate(resourceMetadataUrl),\n });\n res.end(JSON.stringify({ error: 'Unauthorized' }));\n}\n\nfunction checkAuth(req: IncomingMessage, token?: string): boolean {\n if (!token) return true;\n const header = req.headers.authorization;\n return header === `Bearer ${token}`;\n}\n\nasync function readBody(req: IncomingMessage): Promise<unknown> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8').trim();\n if (!raw) return undefined;\n return JSON.parse(raw);\n}\n\n/**\n * Streamable HTTP MCP. ChatGPT / Gemini chat apps need a public HTTPS URL\n * pointing at `/mcp`. Mutating tools only work when this process can see\n * the consumer project (local `--http`, not a remote catalog host).\n */\nexport function startHttpServer(options: HttpOptions): ReturnType<typeof createServer> {\n const server = createServer(async (req, res) => {\n try {\n const url = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);\n\n if (req.method === 'OPTIONS') {\n setCors(res);\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (url.pathname === '/' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json' });\n res.end(\n JSON.stringify({\n ok: true,\n name: MCP_PACKAGE,\n version: PACKAGE_VERSION,\n transport: 'streamable-http',\n mcp: '/mcp',\n mutating: !options.readOnly,\n })\n );\n return;\n }\n\n if (url.pathname === '/.well-known/oauth-protected-resource' && req.method === 'GET') {\n setCors(res);\n res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });\n res.end(\n JSON.stringify(\n mcpProtectedResource(new URL('/mcp', url.origin).href, Boolean(options.authToken))\n )\n );\n return;\n }\n\n if (url.pathname !== '/mcp') {\n setCors(res);\n res.writeHead(404, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify({ error: 'Not found. MCP is POST/GET /mcp.' }));\n return;\n }\n\n if (!checkAuth(req, options.authToken)) {\n unauthorized(res, new URL('/.well-known/oauth-protected-resource', url.origin).href);\n return;\n }\n\n setCors(res);\n const mcp = createMcpServer({ mutating: !options.readOnly });\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n });\n await mcp.connect(transport);\n const parsedBody = req.method === 'POST' ? await readBody(req) : undefined;\n await transport.handleRequest(req, res, parsedBody);\n } catch (err) {\n console.error(`${MCP_PACKAGE} HTTP error:`, err);\n if (!res.headersSent) {\n res.writeHead(500, { 'Content-Type': 'application/json' });\n }\n if (!res.writableEnded) {\n res.end(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));\n }\n }\n });\n\n server.listen(options.port, options.host, () => {\n const addr = server.address();\n const port = typeof addr === 'object' && addr ? addr.port : options.port;\n console.error(\n `${MCP_PACKAGE} v${PACKAGE_VERSION} Streamable HTTP on http://${options.host}:${port}/mcp` +\n (options.readOnly ? ' (read-only catalog)' : '')\n );\n });\n return server;\n}\n","/** Canonical auth.md skill. Registration is not offered; see the file. */\nexport const AUTH_MD_URL = 'https://ply-ui.com/auth.md';\n\nexport interface ProtectedResourceMetadata {\n resource: string;\n resource_name: string;\n resource_documentation: string;\n resource_logo_uri: string;\n authorization_servers: string[];\n scopes_supported: string[];\n bearer_methods_supported: string[];\n}\n\n/** RFC 9728 metadata for one MCP origin. An empty authorization_servers list means registration is off. */\nexport function mcpProtectedResource(resource: string, bearer: boolean): ProtectedResourceMetadata {\n return {\n resource,\n resource_name: 'Ply MCP',\n resource_documentation: AUTH_MD_URL,\n resource_logo_uri: 'https://ply-ui.com/assets/pwa/apple-touch-icon.png',\n authorization_servers: [],\n scopes_supported: [],\n bearer_methods_supported: bearer ? ['header'] : [],\n };\n}\n\nexport function wwwAuthenticate(resourceMetadataUrl: string): string {\n return `Bearer resource_metadata=\"${resourceMetadataUrl}\"`;\n}\n"],"mappings":"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","names":["import_mcp","import_zod","import_zod","import_zod","CATEGORIES","import_zod","fs","path","import_zod","import_zod","import_zod","import_zod","import_zod"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ply-ui-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
4
4
|
"description": "Ply MCP server — stdio or Streamable HTTP (--http). List, search, init, doctor, diff, update, and add Angular + Tailwind components (Pro with PLY_LICENSE_KEY). Not MUI Base UI.",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"esbuild": "0.28.2",
|
|
63
63
|
"fast-uri": "3.1.8",
|
|
64
64
|
"proxy-addr": "2.0.8",
|
|
65
|
-
"hono": "4.13.
|
|
65
|
+
"hono": "4.13.13",
|
|
66
66
|
"qs": "6.16.0"
|
|
67
67
|
}
|
|
68
68
|
}
|