mcpill 1.5.0 → 1.7.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/CHANGELOG.md +10 -0
- package/README.md +18 -2
- package/dist/cli.js +99 -10
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.7.0
|
|
4
|
+
|
|
5
|
+
- `mcpill run` is now side-effect-free by default — stopping the process disconnects the server; no Claude config is written
|
|
6
|
+
- `mcpill run --register` retains the old persistent behavior: registers the server entry in Claude config so Claude manages the process
|
|
7
|
+
- `mcpill unregister` removes the server entry from `.claude/settings.json`, `~/.claude.json`, and Claude Desktop config
|
|
8
|
+
|
|
9
|
+
## 1.6.0
|
|
10
|
+
|
|
11
|
+
- `HELLO-MCP.md` template (scaffolded by `mcpill init`) now includes a commented-out `## Hook:` section stub with inline field explanations for all four Claude Code event types
|
|
12
|
+
|
|
3
13
|
## 1.5.0
|
|
4
14
|
|
|
5
15
|
- `mcpill init` scaffolds `.mcpill/server/hooks/` with a commented `example-hook.md` stub covering all four Claude Code event types (`PreToolUse`, `PostToolUse`, `PreCompact`, `Stop`)
|
package/README.md
CHANGED
|
@@ -20,7 +20,8 @@ Describe your server in plain English, let Claude generate the source files.
|
|
|
20
20
|
mcpill init # scaffolds PILL.md + example source files
|
|
21
21
|
# fill PILL.md # describe your server: tools, resources, prompts
|
|
22
22
|
# tell Claude: "Build this PILL.md" # agent generates source files + runs compile
|
|
23
|
-
mcpill run # start the server
|
|
23
|
+
mcpill run # start the server (transient — stops when you do)
|
|
24
|
+
mcpill run --register # or: register so Claude manages it persistently
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
`PILL.md` embeds the agent instructions — Claude knows exactly what to generate and how.
|
|
@@ -31,7 +32,7 @@ mcpill run # start the server
|
|
|
31
32
|
mcpill init # scaffolds server.md + tools/ + prompts/
|
|
32
33
|
# edit source files # tools/*.md, prompts/*.md, server.md
|
|
33
34
|
mcpill compile # compile source → .{name}/ pill artifact
|
|
34
|
-
mcpill run # start the server
|
|
35
|
+
mcpill run # start the server (transient — stops when you do)
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
---
|
|
@@ -49,6 +50,7 @@ Scaffolds a new project in the current directory:
|
|
|
49
50
|
- `.mcpill/server/hooks/example-hook.md` — stub hook file (see file for format; all fields commented out by default)
|
|
50
51
|
- `.mcpill/HELLO-MCP.md` — ready-to-run example (copy into `PILL.md` to try it)
|
|
51
52
|
- `.claude/commands/create-pill.md` — `/create-pill` slash command; say `/create-pill` in Claude Code to start the guided pill-creation workflow
|
|
53
|
+
- `README.md` — quickstart guide covering project layout and tool-editing workflow
|
|
52
54
|
- `package.json` — `{ type: "module", dependencies: { mcpill-runtime } }` — deps are installed automatically by `mcpill compile` and `mcpill validate`
|
|
53
55
|
|
|
54
56
|
### `mcpill compile`
|
|
@@ -88,8 +90,22 @@ Starts the MCP server from the pill artifact.
|
|
|
88
90
|
```bash
|
|
89
91
|
mcpill run # stdio (default)
|
|
90
92
|
mcpill run --transport http --port 3333
|
|
93
|
+
mcpill run --register # also write server entry to Claude config
|
|
91
94
|
```
|
|
92
95
|
|
|
96
|
+
`--register` is opt-in. Without it, running the server has no side effects on Claude's configuration — stopping the process fully disconnects it.
|
|
97
|
+
|
|
98
|
+
### `mcpill unregister`
|
|
99
|
+
|
|
100
|
+
Removes the server entry from all Claude config files — the inverse of `mcpill run --register`.
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
mcpill unregister
|
|
104
|
+
mcpill unregister --dir <path>
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Removes from `.claude/settings.json` (project scope), `~/.claude.json` (user scope), and the Claude Desktop config. Prints what was removed, or reports if the server was not registered.
|
|
108
|
+
|
|
93
109
|
### `mcpill pack`
|
|
94
110
|
|
|
95
111
|
Prepares the pill for npm distribution:
|
package/dist/cli.js
CHANGED
|
@@ -273,6 +273,24 @@ description: Ask the server to introduce itself.
|
|
|
273
273
|
behavior: |
|
|
274
274
|
A prompt (no args) with a single user message:
|
|
275
275
|
"Introduce yourself \u2014 what is hello-mcp and what can it do?"
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
<!-- Add a ## Hook: section to run a shell command when Claude Code fires an event.
|
|
280
|
+
Run: mcpill compile after editing to apply changes to .claude/settings.json.
|
|
281
|
+
Remove comment markers to activate.
|
|
282
|
+
|
|
283
|
+
trigger \u2014 event that fires the hook: PreToolUse | PostToolUse | PreCompact | Stop
|
|
284
|
+
matcher \u2014 regex matched against tool name (PreToolUse/PostToolUse only); blank = all tools
|
|
285
|
+
command \u2014 shell command; stdout shown to Claude; exit!=0 blocks (PreToolUse)
|
|
286
|
+
|
|
287
|
+
## Hook: example-hook
|
|
288
|
+
|
|
289
|
+
trigger: PreToolUse
|
|
290
|
+
matcher: .*
|
|
291
|
+
command: echo "example hook \u2014 replace this command"
|
|
292
|
+
|
|
293
|
+
-->
|
|
276
294
|
`;
|
|
277
295
|
var SERVER_MD_TEMPLATE = `## Config
|
|
278
296
|
name: my-server
|
|
@@ -1139,15 +1157,17 @@ async function runServer(opts) {
|
|
|
1139
1157
|
resolver: async () => content
|
|
1140
1158
|
});
|
|
1141
1159
|
}
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1160
|
+
if (opts.register) {
|
|
1161
|
+
applySetup(name, tools.map((t) => t.name), {
|
|
1162
|
+
projectPath: baseDir,
|
|
1163
|
+
permissions: "restrictive",
|
|
1164
|
+
register: true,
|
|
1165
|
+
cmdOverride: {
|
|
1166
|
+
command: "mcpill",
|
|
1167
|
+
args: ["run", "--dir", baseDir]
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1151
1171
|
try {
|
|
1152
1172
|
await server.start();
|
|
1153
1173
|
} catch (err) {
|
|
@@ -1541,6 +1561,72 @@ async function runPublish(dir, access) {
|
|
|
1541
1561
|
}
|
|
1542
1562
|
}
|
|
1543
1563
|
|
|
1564
|
+
// src/commands/unregister.ts
|
|
1565
|
+
import path10 from "path";
|
|
1566
|
+
import fs8 from "fs";
|
|
1567
|
+
import os from "os";
|
|
1568
|
+
function patchJson(filePath, patcher) {
|
|
1569
|
+
if (!fs8.existsSync(filePath)) return false;
|
|
1570
|
+
try {
|
|
1571
|
+
const obj = JSON.parse(fs8.readFileSync(filePath, "utf-8"));
|
|
1572
|
+
patcher(obj);
|
|
1573
|
+
fs8.writeFileSync(filePath, JSON.stringify(obj, null, 2) + "\n", "utf-8");
|
|
1574
|
+
return true;
|
|
1575
|
+
} catch {
|
|
1576
|
+
return false;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
function desktopConfigPaths() {
|
|
1580
|
+
const home = os.homedir();
|
|
1581
|
+
if (process.platform === "win32") {
|
|
1582
|
+
const appData = process.env.APPDATA ?? path10.join(home, "AppData", "Roaming");
|
|
1583
|
+
return [path10.join(appData, "Claude", "claude_desktop_config.json")];
|
|
1584
|
+
}
|
|
1585
|
+
return [path10.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json")];
|
|
1586
|
+
}
|
|
1587
|
+
async function runUnregister(opts) {
|
|
1588
|
+
const baseDir = path10.resolve(opts.dir ?? process.cwd());
|
|
1589
|
+
const mcpillDir = path10.join(baseDir, ".mcpill", "server");
|
|
1590
|
+
const config = await loadConfig(mcpillDir);
|
|
1591
|
+
const { name } = config;
|
|
1592
|
+
let removed = 0;
|
|
1593
|
+
const settingsPath = path10.join(baseDir, ".claude", "settings.json");
|
|
1594
|
+
const removedProject = patchJson(settingsPath, (obj) => {
|
|
1595
|
+
const servers = obj.mcpServers;
|
|
1596
|
+
if (servers && name in servers) {
|
|
1597
|
+
delete servers[name];
|
|
1598
|
+
removed++;
|
|
1599
|
+
}
|
|
1600
|
+
});
|
|
1601
|
+
if (removedProject) process.stderr.write(`removed "${name}" from .claude/settings.json
|
|
1602
|
+
`);
|
|
1603
|
+
const claudeJsonPath = path10.join(os.homedir(), ".claude.json");
|
|
1604
|
+
const removedUser = patchJson(claudeJsonPath, (obj) => {
|
|
1605
|
+
const servers = obj.mcpServers;
|
|
1606
|
+
if (servers && name in servers) {
|
|
1607
|
+
delete servers[name];
|
|
1608
|
+
removed++;
|
|
1609
|
+
}
|
|
1610
|
+
});
|
|
1611
|
+
if (removedUser) process.stderr.write(`removed "${name}" from ~/.claude.json
|
|
1612
|
+
`);
|
|
1613
|
+
for (const configPath of desktopConfigPaths()) {
|
|
1614
|
+
const removedDesktop = patchJson(configPath, (obj) => {
|
|
1615
|
+
const servers = obj.mcpServers;
|
|
1616
|
+
if (servers && name in servers) {
|
|
1617
|
+
delete servers[name];
|
|
1618
|
+
removed++;
|
|
1619
|
+
}
|
|
1620
|
+
});
|
|
1621
|
+
if (removedDesktop) process.stderr.write(`removed "${name}" from Claude Desktop config
|
|
1622
|
+
`);
|
|
1623
|
+
}
|
|
1624
|
+
if (removed === 0) {
|
|
1625
|
+
process.stderr.write(`"${name}" was not registered \u2014 nothing to remove
|
|
1626
|
+
`);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1544
1630
|
// src/cli.ts
|
|
1545
1631
|
var pkgDir = dirname(fileURLToPath(import.meta.url));
|
|
1546
1632
|
var pkg = JSON.parse(
|
|
@@ -1551,7 +1637,7 @@ program.name("mcpill").version(pkg.version);
|
|
|
1551
1637
|
program.command("init").description("Scaffold a new .mcpill/ directory").option("--dir <path>", "Target directory").action(async (opts) => {
|
|
1552
1638
|
await runInit(opts);
|
|
1553
1639
|
});
|
|
1554
|
-
program.command("run").description("Start the MCP server").option("--transport <
|
|
1640
|
+
program.command("run").description("Start the MCP server").option("--transport <type>", "Transport: stdio (default) or http").option("--port <n>", "Port number (HTTP only)", parseInt).option("--dir <path>", "Project root containing .mcpill/").option("--register", "Write server entry to Claude config so Claude manages the process").action(
|
|
1555
1641
|
async (opts) => {
|
|
1556
1642
|
await runServer(opts);
|
|
1557
1643
|
}
|
|
@@ -1563,6 +1649,9 @@ program.command("validate").description("Validate .mcpill/ configuration").optio
|
|
|
1563
1649
|
program.command("compile").description("Compile server.md \u2194 .mcpill/ files").option("--dir <path>", "Directory containing server.md and .mcpill/").option("--to-md", "Reverse: generate server.md from .mcpill/ files").option("--strict", "Error on missing tool handlers instead of generating stubs").option("--no-hooks", "Skip writing the PreToolUse hook to .claude/settings.json").action(async (opts) => {
|
|
1564
1650
|
await runCompile({ ...opts, noHooks: opts.hooks === false });
|
|
1565
1651
|
});
|
|
1652
|
+
program.command("unregister").description("Remove server entry from Claude config (undo mcpill run --register)").option("--dir <path>", "Project root containing .mcpill/").action(async (opts) => {
|
|
1653
|
+
await runUnregister(opts);
|
|
1654
|
+
});
|
|
1566
1655
|
program.command("pack").description("Prepare pill for npm distribution").option("--dir <path>", "pill project root", ".").action(({ dir }) => runPack(dir));
|
|
1567
1656
|
program.command("publish").description("Pack and publish pill to npm").option("--dir <path>", "pill project root", ".").option("--access <level>", "npm access level", "public").action(({ dir, access }) => runPublish(dir, access));
|
|
1568
1657
|
program.parseAsync(process.argv).catch((err) => {
|