@modootoday/pmcp 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/{chunk-JOQTOVTJ.js → chunk-5TX2IAVD.js} +17 -18
- package/dist/chunk-6TSHDCUY.js +1238 -0
- package/dist/{chunk-X4LYYULW.js → chunk-FXBLBKP6.js} +2 -2
- package/dist/cli.js +301 -29
- package/dist/http.js +1 -1
- package/dist/index.d.ts +126 -1
- package/dist/index.js +21 -3
- package/dist/stdio.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-PUGLIJYM.js +0 -193
package/README.md
CHANGED
|
@@ -70,6 +70,49 @@ Paths resolve against the file's directory. Keys are `roots`, `scopes`,
|
|
|
70
70
|
the same meaning; an unknown key is an error. A flag replaces the file's list
|
|
71
71
|
of its kind. `--config <file>` names another file and `--no-config` ignores it.
|
|
72
72
|
|
|
73
|
+
## Native files for each agent tool
|
|
74
|
+
|
|
75
|
+
`pmcp project` writes what Claude Code, Codex, Gemini CLI, Grok Build and
|
|
76
|
+
Antigravity read natively, from cross-tool sources under `.agents/`
|
|
77
|
+
(`skills/<name>/SKILL.md`, `agents/<name>/agent.md`, `rules/*.md`) and the rest
|
|
78
|
+
of `pmcp.toml`:
|
|
79
|
+
|
|
80
|
+
```toml
|
|
81
|
+
[targets]
|
|
82
|
+
tools = ["claude", "codex", "gemini", "grok", "antigravity"]
|
|
83
|
+
|
|
84
|
+
[skills.deploy]
|
|
85
|
+
invocation = "user" # the person starts it; the model is not offered it
|
|
86
|
+
|
|
87
|
+
[agents.reviewer.claude]
|
|
88
|
+
tools = "Read, Grep" # fields one tool reads stay out of agent.md
|
|
89
|
+
|
|
90
|
+
[rules.packages]
|
|
91
|
+
file = ".agent/rules/PACKAGE.RULE.md" # each package's path-scoped rule
|
|
92
|
+
strip = ["apps"] # dropped from derived link names
|
|
93
|
+
|
|
94
|
+
[mcp.skills]
|
|
95
|
+
command = "node"
|
|
96
|
+
args = ["${PROJECT_ROOT}/node_modules/@modootoday/pmcp/dist/cli.js", "serve"]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
```sh
|
|
100
|
+
pmcp project # write
|
|
101
|
+
pmcp project --check # exit 2 on drift, stale or undeclared outputs
|
|
102
|
+
pmcp project add <name> # copy a catalog skill or agent into .agents/
|
|
103
|
+
pmcp project remove <name>
|
|
104
|
+
pmcp doctor # ask each installed tool what it loads
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Rules go to `.claude/rules/<dir>/`, never the top level, because Grok Build
|
|
108
|
+
loads top-level `.claude/rules/*.md` in every session regardless of `paths:`.
|
|
109
|
+
A server that names `${PROJECT_ROOT}` is launched through `sh`, which finds
|
|
110
|
+
`pmcp.toml` at spawn time, so the generated files hold no machine's path.
|
|
111
|
+
`pmcp.lock` records what was written; a file pmcp did not write is never
|
|
112
|
+
overwritten. `doctor` calls no model: it reads `claude mcp list`,
|
|
113
|
+
`codex mcp list`, `gemini skills list`, `gemini mcp list` and
|
|
114
|
+
`grok inspect --json`, and skips a tool that is not installed.
|
|
115
|
+
|
|
73
116
|
## Package skills
|
|
74
117
|
|
|
75
118
|
Skills are discovered by filename, including `skills/`, `.agents/skills/`,
|
|
@@ -1009,6 +1009,10 @@ var readOnly = {
|
|
|
1009
1009
|
idempotentHint: true,
|
|
1010
1010
|
openWorldHint: false
|
|
1011
1011
|
};
|
|
1012
|
+
var readOnlyTool = (title) => ({
|
|
1013
|
+
title,
|
|
1014
|
+
annotations: { ...readOnly, title }
|
|
1015
|
+
});
|
|
1012
1016
|
var kindInput = z2.enum(["skill", "agent", "hook", "mcp", "any"]).optional().describe(
|
|
1013
1017
|
"skill (default), agent, hook, mcp, or any. Commands are skills; agents, hooks and MCP servers are installed with pmcp add rather than read."
|
|
1014
1018
|
);
|
|
@@ -1019,22 +1023,21 @@ function registerSkillTools(server, tools) {
|
|
|
1019
1023
|
server.registerTool(
|
|
1020
1024
|
"skill_catalog",
|
|
1021
1025
|
{
|
|
1022
|
-
|
|
1026
|
+
...readOnlyTool("List skills"),
|
|
1023
1027
|
description: "Every skill the installed packages and marketplaces ship, grouped by package or plugin, with names, one-line descriptions and tier, and no bodies. Paged by group. Use it to see what exists, or when skill_find returns nothing. Pass kind to list agents, hooks or MCP servers instead.",
|
|
1024
1028
|
inputSchema: z2.object({
|
|
1025
1029
|
page: z2.number().int().min(1).optional(),
|
|
1026
1030
|
pageSize: z2.number().int().min(1).max(20).optional(),
|
|
1027
1031
|
tier: z2.enum(["open", "free", "paid", "internal"]).optional(),
|
|
1028
1032
|
kind: kindInput
|
|
1029
|
-
})
|
|
1030
|
-
annotations: readOnly
|
|
1033
|
+
})
|
|
1031
1034
|
},
|
|
1032
1035
|
async (request) => asText(tools.catalog(request))
|
|
1033
1036
|
);
|
|
1034
1037
|
server.registerTool(
|
|
1035
1038
|
"skill_find",
|
|
1036
1039
|
{
|
|
1037
|
-
|
|
1040
|
+
...readOnlyTool("Find skills"),
|
|
1038
1041
|
description: "Ranked skill names for an intent. Describe the problem in a full sentence in English rather than a keyword: a single word matches far worse, and the ranking is over descriptions. Returns names only -- read one with skill_call.",
|
|
1039
1042
|
inputSchema: z2.object({
|
|
1040
1043
|
intent: z2.string().min(1).max(256).describe("What you are trying to do, as an English sentence."),
|
|
@@ -1047,20 +1050,18 @@ function registerSkillTools(server, tools) {
|
|
|
1047
1050
|
domain: z2.string().optional(),
|
|
1048
1051
|
medium: z2.string().optional()
|
|
1049
1052
|
}).optional().describe("Exact-match filters over the catalog before ranking.")
|
|
1050
|
-
})
|
|
1051
|
-
annotations: readOnly
|
|
1053
|
+
})
|
|
1052
1054
|
},
|
|
1053
1055
|
async ({ intent, limit, filters }) => asText(await tools.find(intent, limit, filters))
|
|
1054
1056
|
);
|
|
1055
1057
|
server.registerTool(
|
|
1056
1058
|
"skill_describe",
|
|
1057
1059
|
{
|
|
1058
|
-
|
|
1060
|
+
...readOnlyTool("Describe a skill"),
|
|
1059
1061
|
description: "Frontmatter, metadata (tier, level, requirements, licence, approval), and the files the skill carries with sizes and sha256, without any body. Use it to decide between candidates before skill_call.",
|
|
1060
1062
|
inputSchema: z2.object({
|
|
1061
1063
|
name: z2.string().min(1).describe("The skill name skill_find or skill_catalog returned.")
|
|
1062
|
-
})
|
|
1063
|
-
annotations: readOnly
|
|
1064
|
+
})
|
|
1064
1065
|
},
|
|
1065
1066
|
async ({ name }) => {
|
|
1066
1067
|
const described = tools.describe(name);
|
|
@@ -1080,15 +1081,14 @@ function registerSkillTools(server, tools) {
|
|
|
1080
1081
|
server.registerTool(
|
|
1081
1082
|
"skill_read",
|
|
1082
1083
|
{
|
|
1083
|
-
|
|
1084
|
-
description: "A reference or script file inside one skill's directory, as text, with its sha256. Read only when the skill body points at the file. Scripts are returned, never run. Files over 256 KiB and paths outside the skill are refused.",
|
|
1084
|
+
...readOnlyTool("Read a skill file"),
|
|
1085
|
+
description: "A reference or script file inside one skill's directory in this catalog, as text, with its sha256. It reads only files the catalog ships and calls no external API; path is relative to the skill, as skill_describe lists it (layout: https://pmcp.build). Read only when the skill body points at the file. Scripts are returned, never run. Files over 256 KiB and paths outside the skill are refused.",
|
|
1085
1086
|
inputSchema: z2.object({
|
|
1086
1087
|
name: z2.string().min(1),
|
|
1087
1088
|
path: z2.string().min(1).optional().describe(
|
|
1088
1089
|
"Path relative to the skill directory, as skill_describe lists it. Defaults to SKILL.md."
|
|
1089
1090
|
)
|
|
1090
|
-
})
|
|
1091
|
-
annotations: readOnly
|
|
1091
|
+
})
|
|
1092
1092
|
},
|
|
1093
1093
|
async ({ name, path }) => {
|
|
1094
1094
|
const result = tools.read(name, path);
|
|
@@ -1105,12 +1105,11 @@ function registerSkillTools(server, tools) {
|
|
|
1105
1105
|
server.registerTool(
|
|
1106
1106
|
"skill_call",
|
|
1107
1107
|
{
|
|
1108
|
-
|
|
1108
|
+
...readOnlyTool("Read a skill"),
|
|
1109
1109
|
description: "The body of a single skill, by the name skill_find or skill_catalog returned. This is the only call that costs a document.",
|
|
1110
1110
|
inputSchema: z2.object({
|
|
1111
1111
|
name: z2.string().min(1).describe("The skill name, as <package>/<slug>.")
|
|
1112
|
-
})
|
|
1113
|
-
annotations: readOnly
|
|
1112
|
+
})
|
|
1114
1113
|
},
|
|
1115
1114
|
async ({ name }) => {
|
|
1116
1115
|
const found = tools.call(name);
|
|
@@ -1130,7 +1129,7 @@ function registerSkillTools(server, tools) {
|
|
|
1130
1129
|
return server;
|
|
1131
1130
|
}
|
|
1132
1131
|
function createSkillServer(options) {
|
|
1133
|
-
const server = new McpServer({ name: SERVER_NAME, version: "0.
|
|
1132
|
+
const server = new McpServer({ name: SERVER_NAME, version: "0.6.0" });
|
|
1134
1133
|
const tools = createSkillTools(options);
|
|
1135
1134
|
registerSkillsExtension(server, tools.skills);
|
|
1136
1135
|
return registerSkillTools(server, tools);
|
|
@@ -1168,4 +1167,4 @@ export {
|
|
|
1168
1167
|
registerSkillTools,
|
|
1169
1168
|
createSkillServer
|
|
1170
1169
|
};
|
|
1171
|
-
//# sourceMappingURL=chunk-
|
|
1170
|
+
//# sourceMappingURL=chunk-5TX2IAVD.js.map
|