mcpill 1.2.2 → 1.2.3
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/CHANGELOG.md +7 -0
- package/README.md +5 -6
- package/dist/cli.js +37 -36
- package/package.json +1 -1
- package/src/commands/compile.ts +16 -1
- package/src/commands/init.ts +21 -37
- package/src/loaders/tools.ts +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.2.3
|
|
4
|
+
|
|
5
|
+
- `mcpill init` now scaffolds a `package.json` with `type: module` and `mcpill-runtime` as the only dependency; prints `Run: npm install` rather than auto-installing
|
|
6
|
+
- `mcpill run` and `mcpill validate` now catch missing `mcpill-runtime` import errors and surface an actionable message
|
|
7
|
+
- Removed stale `echo`/`greet` tool examples from the default scaffold; replaced with a single `my-tool` placeholder — examples moved to `pill-user-guide.md`
|
|
8
|
+
- `mcpill compile` parses `PILL.md` `## Server` block and lets it win over `server.md` for `name`/`transport`; both files coexist with different roles — `server.md` is editable directly, `PILL.md` is the intent-level spec for the agent
|
|
9
|
+
|
|
3
10
|
## 1.2.2
|
|
4
11
|
|
|
5
12
|
- Fix: bump mcpster dependency to `^0.3.0` — `0.2.x` did not export `applySetup`, causing a crash on `mcpill --version` after global install
|
package/README.md
CHANGED
|
@@ -42,13 +42,12 @@ mcpill run # start the server
|
|
|
42
42
|
|
|
43
43
|
Scaffolds a new project in the current directory:
|
|
44
44
|
|
|
45
|
-
- `README.md` — quickstart guide for the scaffolded project
|
|
46
45
|
- `PILL.md` — intent-level spec; fill this and hand to Claude to generate source files
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
- `package.json` —
|
|
46
|
+
- `.mcpill/pill-agent-guide.md` — agent instructions read by Claude when building from `PILL.md`
|
|
47
|
+
- `.mcpill/server.md` — server config + resources
|
|
48
|
+
- `.mcpill/server/prompts/greeting.md` — example prompt
|
|
49
|
+
- `.mcpill/HELLO-MCP.md` — ready-to-run example (copy into `PILL.md` to try it)
|
|
50
|
+
- `package.json` — `{ type: "module", dependencies: { mcpill-runtime } }` — run `npm install`
|
|
52
51
|
|
|
53
52
|
### `mcpill compile`
|
|
54
53
|
|
package/dist/cli.js
CHANGED
|
@@ -127,25 +127,14 @@ transport: stdio
|
|
|
127
127
|
|
|
128
128
|
---
|
|
129
129
|
|
|
130
|
-
## Tool:
|
|
130
|
+
## Tool: my-tool
|
|
131
131
|
|
|
132
|
-
description:
|
|
132
|
+
description: Describe what this tool does.
|
|
133
133
|
inputs:
|
|
134
|
-
-
|
|
135
|
-
output:
|
|
134
|
+
- param (string): A parameter.
|
|
135
|
+
output: What the tool returns.
|
|
136
136
|
behavior: |
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
---
|
|
140
|
-
|
|
141
|
-
## Tool: greet
|
|
142
|
-
|
|
143
|
-
description: Generate a personalised greeting.
|
|
144
|
-
inputs:
|
|
145
|
-
- name (string): The name of the person to greet.
|
|
146
|
-
output: A greeting string addressed to the given name.
|
|
147
|
-
behavior: |
|
|
148
|
-
Return "Hello, {name}!" as a text response.
|
|
137
|
+
Describe the logic here. Claude will implement it.
|
|
149
138
|
|
|
150
139
|
---
|
|
151
140
|
|
|
@@ -234,22 +223,6 @@ name: Status
|
|
|
234
223
|
---
|
|
235
224
|
The server is running.
|
|
236
225
|
`;
|
|
237
|
-
var ECHO_TOOL_MD = `# echo
|
|
238
|
-
|
|
239
|
-
Echo a message back
|
|
240
|
-
|
|
241
|
-
## Parameters
|
|
242
|
-
|
|
243
|
-
- message (string): The message to echo
|
|
244
|
-
|
|
245
|
-
## Handler
|
|
246
|
-
|
|
247
|
-
\`\`\`js
|
|
248
|
-
async ({ message }) => {
|
|
249
|
-
return { content: [{ type: "text", text: message }] };
|
|
250
|
-
}
|
|
251
|
-
\`\`\`
|
|
252
|
-
`;
|
|
253
226
|
var GREETING_PROMPT_MD = `# greeting
|
|
254
227
|
|
|
255
228
|
Generate a greeting
|
|
@@ -298,7 +271,7 @@ ${projectName}/
|
|
|
298
271
|
\u2514\u2500\u2500 server/
|
|
299
272
|
\u251C\u2500\u2500 mcpill.config.json \u2190 compiled config
|
|
300
273
|
\u251C\u2500\u2500 tools/ \u2190 one .md file per tool
|
|
301
|
-
\u2502 \u2514\u2500\u2500
|
|
274
|
+
\u2502 \u2514\u2500\u2500 my-tool.md
|
|
302
275
|
\u2514\u2500\u2500 prompts/ \u2190 one .md file per prompt (optional)
|
|
303
276
|
\u2514\u2500\u2500 greeting.md
|
|
304
277
|
\`\`\`
|
|
@@ -341,7 +314,6 @@ async function runInit(opts) {
|
|
|
341
314
|
fs.mkdirSync(path.join(serverDir, "prompts"), { recursive: true });
|
|
342
315
|
const serverMd = SERVER_MD_TEMPLATE.replace("name: my-server", `name: ${projectName}`);
|
|
343
316
|
fs.writeFileSync(path.join(mcpillDir, "server.md"), serverMd);
|
|
344
|
-
fs.writeFileSync(path.join(serverDir, "tools", "echo.md"), ECHO_TOOL_MD);
|
|
345
317
|
fs.writeFileSync(path.join(serverDir, "prompts", "greeting.md"), GREETING_PROMPT_MD);
|
|
346
318
|
fs.writeFileSync(
|
|
347
319
|
path.join(serverDir, "mcpill.config.json"),
|
|
@@ -351,15 +323,27 @@ async function runInit(opts) {
|
|
|
351
323
|
fs.writeFileSync(path.join(mcpillDir, "pill-user-guide.md"), makePillUserGuideMd(projectName));
|
|
352
324
|
fs.writeFileSync(path.join(mcpillDir, "HELLO-MCP.md"), HELLO_MCP_MD);
|
|
353
325
|
fs.writeFileSync(path.join(targetDir, "PILL.md"), makePillMd(projectName));
|
|
326
|
+
const pkgJsonPath = path.join(targetDir, "package.json");
|
|
327
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
328
|
+
const pkg2 = {
|
|
329
|
+
name: projectName,
|
|
330
|
+
version: "0.1.0",
|
|
331
|
+
type: "module",
|
|
332
|
+
dependencies: {
|
|
333
|
+
"mcpill-runtime": "latest"
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg2, null, 2) + "\n");
|
|
337
|
+
}
|
|
354
338
|
console.log('\u2713 PILL.md \u2190 describe your server, then tell Claude: "Build this PILL.md"');
|
|
339
|
+
console.log("\u2713 package.json \u2190 Run: npm install");
|
|
355
340
|
console.log("\u2713 .mcpill/HELLO-MCP.md \u2190 copy into PILL.md to see a working example instantly");
|
|
356
341
|
console.log("\u2713 .mcpill/server.md \u2190 or edit source files directly");
|
|
357
|
-
console.log("\u2713 .mcpill/server/tools/echo.md");
|
|
358
342
|
console.log("\u2713 .mcpill/server/prompts/greeting.md");
|
|
359
343
|
console.log("\u2713 .mcpill/pill-agent-guide.md \u2190 agent instructions (read by Claude)");
|
|
360
344
|
console.log("\u2713 .mcpill/pill-user-guide.md \u2190 start here");
|
|
361
345
|
console.log("");
|
|
362
|
-
console.log("
|
|
346
|
+
console.log("Next: npm install && mcpill compile && mcpill run");
|
|
363
347
|
}
|
|
364
348
|
|
|
365
349
|
// src/commands/run.ts
|
|
@@ -397,6 +381,11 @@ async function loadTools(mcpillDir) {
|
|
|
397
381
|
mod = await import(pathToFileURL(toolsPath).href);
|
|
398
382
|
} catch (err) {
|
|
399
383
|
const msg = err instanceof Error ? err.message : String(err);
|
|
384
|
+
if (msg.includes("mcpill-runtime")) {
|
|
385
|
+
throw new Error(
|
|
386
|
+
"tools.js failed to load: mcpill-runtime not found.\nRun: npm install mcpill-runtime"
|
|
387
|
+
);
|
|
388
|
+
}
|
|
400
389
|
throw new Error(`tools.js failed to load: ${msg}`);
|
|
401
390
|
}
|
|
402
391
|
const tools = mod.default;
|
|
@@ -1083,6 +1072,18 @@ async function runCompile(opts) {
|
|
|
1083
1072
|
const toolsJsPath = join3(serverDir, "tools.js");
|
|
1084
1073
|
const existing = existsSync(toolsJsPath) ? extractHandlers(readFileSync2(toolsJsPath, "utf-8")) : /* @__PURE__ */ new Map();
|
|
1085
1074
|
const { doc: mergedDoc, stubbed } = mergeHandlers(doc, existing);
|
|
1075
|
+
const pillMdPath = join3(baseDir, "PILL.md");
|
|
1076
|
+
if (existsSync(pillMdPath)) {
|
|
1077
|
+
const pillContent = readFileSync2(pillMdPath, "utf-8");
|
|
1078
|
+
const serverSection = ("\n" + pillContent).split("\n## ").find((s) => s.startsWith("Server\n"));
|
|
1079
|
+
if (serverSection) {
|
|
1080
|
+
const kv = parseKvBlock(serverSection.slice("Server\n".length));
|
|
1081
|
+
if (kv["name"]) mergedDoc.config.name = kv["name"];
|
|
1082
|
+
if (kv["transport"] === "stdio" || kv["transport"] === "http") {
|
|
1083
|
+
mergedDoc.config.transport = kv["transport"];
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1086
1087
|
if (opts.strict && stubbed.length > 0) {
|
|
1087
1088
|
throw new Error("Missing handlers for: " + stubbed.join(", "));
|
|
1088
1089
|
}
|
package/package.json
CHANGED
package/src/commands/compile.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolve, join } from 'path';
|
|
2
2
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
|
|
3
3
|
import { pathToFileURL } from 'url';
|
|
4
|
-
import { parseServerDir } from '../compiler/parse.js';
|
|
4
|
+
import { parseServerDir, parseKvBlock } from '../compiler/parse.js';
|
|
5
5
|
import { serializeServerDir } from '../compiler/serialize.js';
|
|
6
6
|
import { extractHandlers, mergeHandlers } from '../compiler/merge-tools.js';
|
|
7
7
|
import { loadConfig } from '../loaders/config.js';
|
|
@@ -134,6 +134,21 @@ export async function runCompile(opts: {
|
|
|
134
134
|
|
|
135
135
|
const { doc: mergedDoc, stubbed } = mergeHandlers(doc, existing);
|
|
136
136
|
|
|
137
|
+
// If PILL.md declares a name/transport in its ## Server section, let it win
|
|
138
|
+
// over whatever server.md still has (catches cases where the agent forgets to update server.md).
|
|
139
|
+
const pillMdPath = join(baseDir, 'PILL.md');
|
|
140
|
+
if (existsSync(pillMdPath)) {
|
|
141
|
+
const pillContent = readFileSync(pillMdPath, 'utf-8');
|
|
142
|
+
const serverSection = ('\n' + pillContent).split('\n## ').find((s) => s.startsWith('Server\n'));
|
|
143
|
+
if (serverSection) {
|
|
144
|
+
const kv = parseKvBlock(serverSection.slice('Server\n'.length));
|
|
145
|
+
if (kv['name']) mergedDoc.config.name = kv['name'];
|
|
146
|
+
if (kv['transport'] === 'stdio' || kv['transport'] === 'http') {
|
|
147
|
+
mergedDoc.config.transport = kv['transport'];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
137
152
|
if (opts.strict && stubbed.length > 0) {
|
|
138
153
|
throw new Error('Missing handlers for: ' + stubbed.join(', '));
|
|
139
154
|
}
|
package/src/commands/init.ts
CHANGED
|
@@ -120,25 +120,14 @@ transport: stdio
|
|
|
120
120
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
|
-
## Tool:
|
|
124
|
-
|
|
125
|
-
description: Echo a message back to the caller.
|
|
126
|
-
inputs:
|
|
127
|
-
- message (string): The message to echo.
|
|
128
|
-
output: The same message, echoed back as text.
|
|
129
|
-
behavior: |
|
|
130
|
-
Return the message input unchanged.
|
|
131
|
-
|
|
132
|
-
---
|
|
123
|
+
## Tool: my-tool
|
|
133
124
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
description: Generate a personalised greeting.
|
|
125
|
+
description: Describe what this tool does.
|
|
137
126
|
inputs:
|
|
138
|
-
-
|
|
139
|
-
output:
|
|
127
|
+
- param (string): A parameter.
|
|
128
|
+
output: What the tool returns.
|
|
140
129
|
behavior: |
|
|
141
|
-
|
|
130
|
+
Describe the logic here. Claude will implement it.
|
|
142
131
|
|
|
143
132
|
---
|
|
144
133
|
|
|
@@ -232,23 +221,6 @@ name: Status
|
|
|
232
221
|
The server is running.
|
|
233
222
|
`;
|
|
234
223
|
|
|
235
|
-
const ECHO_TOOL_MD = `# echo
|
|
236
|
-
|
|
237
|
-
Echo a message back
|
|
238
|
-
|
|
239
|
-
## Parameters
|
|
240
|
-
|
|
241
|
-
- message (string): The message to echo
|
|
242
|
-
|
|
243
|
-
## Handler
|
|
244
|
-
|
|
245
|
-
\`\`\`js
|
|
246
|
-
async ({ message }) => {
|
|
247
|
-
return { content: [{ type: "text", text: message }] };
|
|
248
|
-
}
|
|
249
|
-
\`\`\`
|
|
250
|
-
`;
|
|
251
|
-
|
|
252
224
|
const GREETING_PROMPT_MD = `# greeting
|
|
253
225
|
|
|
254
226
|
Generate a greeting
|
|
@@ -298,7 +270,7 @@ ${projectName}/
|
|
|
298
270
|
└── server/
|
|
299
271
|
├── mcpill.config.json ← compiled config
|
|
300
272
|
├── tools/ ← one .md file per tool
|
|
301
|
-
│ └──
|
|
273
|
+
│ └── my-tool.md
|
|
302
274
|
└── prompts/ ← one .md file per prompt (optional)
|
|
303
275
|
└── greeting.md
|
|
304
276
|
\`\`\`
|
|
@@ -345,7 +317,6 @@ export async function runInit(opts: { dir?: string }): Promise<void> {
|
|
|
345
317
|
|
|
346
318
|
const serverMd = SERVER_MD_TEMPLATE.replace("name: my-server", `name: ${projectName}`);
|
|
347
319
|
fs.writeFileSync(path.join(mcpillDir, "server.md"), serverMd);
|
|
348
|
-
fs.writeFileSync(path.join(serverDir, "tools", "echo.md"), ECHO_TOOL_MD);
|
|
349
320
|
fs.writeFileSync(path.join(serverDir, "prompts", "greeting.md"), GREETING_PROMPT_MD);
|
|
350
321
|
fs.writeFileSync(
|
|
351
322
|
path.join(serverDir, "mcpill.config.json"),
|
|
@@ -357,13 +328,26 @@ export async function runInit(opts: { dir?: string }): Promise<void> {
|
|
|
357
328
|
|
|
358
329
|
fs.writeFileSync(path.join(targetDir, "PILL.md"), makePillMd(projectName));
|
|
359
330
|
|
|
331
|
+
const pkgJsonPath = path.join(targetDir, "package.json");
|
|
332
|
+
if (!fs.existsSync(pkgJsonPath)) {
|
|
333
|
+
const pkg = {
|
|
334
|
+
name: projectName,
|
|
335
|
+
version: "0.1.0",
|
|
336
|
+
type: "module",
|
|
337
|
+
dependencies: {
|
|
338
|
+
"mcpill-runtime": "latest",
|
|
339
|
+
},
|
|
340
|
+
};
|
|
341
|
+
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkg, null, 2) + "\n");
|
|
342
|
+
}
|
|
343
|
+
|
|
360
344
|
console.log("✓ PILL.md ← describe your server, then tell Claude: \"Build this PILL.md\"");
|
|
345
|
+
console.log("✓ package.json ← Run: npm install");
|
|
361
346
|
console.log("✓ .mcpill/HELLO-MCP.md ← copy into PILL.md to see a working example instantly");
|
|
362
347
|
console.log("✓ .mcpill/server.md ← or edit source files directly");
|
|
363
|
-
console.log("✓ .mcpill/server/tools/echo.md");
|
|
364
348
|
console.log("✓ .mcpill/server/prompts/greeting.md");
|
|
365
349
|
console.log("✓ .mcpill/pill-agent-guide.md ← agent instructions (read by Claude)");
|
|
366
350
|
console.log("✓ .mcpill/pill-user-guide.md ← start here");
|
|
367
351
|
console.log("");
|
|
368
|
-
console.log("
|
|
352
|
+
console.log("Next: npm install && mcpill compile && mcpill run");
|
|
369
353
|
}
|
package/src/loaders/tools.ts
CHANGED
|
@@ -16,6 +16,11 @@ export async function loadTools(mcpillDir: string): Promise<RawToolDef[]> {
|
|
|
16
16
|
mod = await import(pathToFileURL(toolsPath).href);
|
|
17
17
|
} catch (err) {
|
|
18
18
|
const msg = err instanceof Error ? err.message : String(err);
|
|
19
|
+
if (msg.includes("mcpill-runtime")) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
"tools.js failed to load: mcpill-runtime not found.\nRun: npm install mcpill-runtime"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
19
24
|
throw new Error(`tools.js failed to load: ${msg}`);
|
|
20
25
|
}
|
|
21
26
|
|