qbsm-init 0.1.0 → 0.2.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 +29 -7
- package/dist/init.js +30 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,44 +1,66 @@
|
|
|
1
1
|
# qbsm-init
|
|
2
2
|
|
|
3
|
-
One-shot CLI that wires **qb-skill-manager** (skills auto-extraction for Claude Code) into any project. After running this, Claude Code in that project can call the qbsm MCP server (
|
|
3
|
+
One-shot CLI that wires **qb-skill-manager** (skills auto-extraction for Claude Code) into any project. After running this, Claude Code in that project can call the qbsm MCP server (Streamable HTTP, hosted on Fly.io) to record skills demonstrated in the conversation.
|
|
4
4
|
|
|
5
5
|
## Quick start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
# 1. Sign up + issue an API token at https://
|
|
8
|
+
# 1. Sign up + issue an API token at https://qbsm.fly.dev/settings/tokens
|
|
9
9
|
# 2. Run qbsm-init in your project directory:
|
|
10
10
|
npx qbsm-init --api-key qbsm_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
That writes three files in your project (all merged idempotently if they already exist):
|
|
14
14
|
|
|
15
|
-
- `.mcp.json` — registers `qbsm` as a remote
|
|
15
|
+
- `.mcp.json` — registers `qbsm` as a remote Streamable HTTP MCP server
|
|
16
16
|
- `CLAUDE.md` — appends a guidance section so Claude Code knows when to call the tools
|
|
17
17
|
- `.claude/settings.json` — hooks that nudge the agent to call `register_skill` after package installs
|
|
18
18
|
|
|
19
19
|
Then start a Claude Code session as usual; the `qbsm` server appears in `claude mcp list`.
|
|
20
20
|
|
|
21
|
+
## What changed in 0.2.0
|
|
22
|
+
|
|
23
|
+
- Default transport switched from **SSE** (`type: "sse"`) to **Streamable HTTP** (`type: "http"`). Streamable HTTP is the current MCP spec (2025-03-26), is stateless per request, and runs on multi-machine / HA hosts. Add `--legacy-sse` to keep the old behavior if your Claude Code client does not yet support `type: "http"`.
|
|
24
|
+
- Default `--server-url` updated to `https://qbsm.fly.dev` (Fly.io app rename).
|
|
25
|
+
|
|
21
26
|
## Options
|
|
22
27
|
|
|
23
28
|
| Flag | Description |
|
|
24
29
|
|------|-------------|
|
|
25
|
-
| `--api-key <key>` | Required (or interactive prompt). Get at `https://
|
|
26
|
-
| `--server-url <url>` | Override server (default `https://
|
|
30
|
+
| `--api-key <key>` | Required (or interactive prompt). Get at `https://qbsm.fly.dev/settings/tokens` |
|
|
31
|
+
| `--server-url <url>` | Override server (default `https://qbsm.fly.dev`) |
|
|
27
32
|
| `-y, --yes` | Non-interactive mode; `--api-key` becomes required |
|
|
28
33
|
| `--no-hooks` | Skip `.claude/settings.json` hook registration |
|
|
29
34
|
| `--overwrite` | Replace existing `<qbsm:start>…<qbsm:end>` section in CLAUDE.md |
|
|
35
|
+
| `--legacy-sse` | Generate the older `type: "sse"` + `/api/mcp/sse` config |
|
|
30
36
|
| `-h, --help` | Show help |
|
|
31
37
|
|
|
32
38
|
Positional `[target-path]` (default `.`) lets you point at a sibling directory.
|
|
33
39
|
|
|
34
40
|
## Generated `.mcp.json` entry
|
|
35
41
|
|
|
42
|
+
**Default (Streamable HTTP):**
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"mcpServers": {
|
|
47
|
+
"qbsm": {
|
|
48
|
+
"type": "http",
|
|
49
|
+
"url": "https://qbsm.fly.dev/api/mcp",
|
|
50
|
+
"headers": { "x-api-key": "qbsm_..." }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**With `--legacy-sse`:**
|
|
57
|
+
|
|
36
58
|
```json
|
|
37
59
|
{
|
|
38
60
|
"mcpServers": {
|
|
39
61
|
"qbsm": {
|
|
40
62
|
"type": "sse",
|
|
41
|
-
"url": "https://
|
|
63
|
+
"url": "https://qbsm.fly.dev/api/mcp/sse",
|
|
42
64
|
"headers": { "x-api-key": "qbsm_..." }
|
|
43
65
|
}
|
|
44
66
|
}
|
|
@@ -58,4 +80,4 @@ Positional `[target-path]` (default `.`) lets you point at a sibling directory.
|
|
|
58
80
|
|
|
59
81
|
## Tokens
|
|
60
82
|
|
|
61
|
-
If a token is leaked, revoke it at `https://
|
|
83
|
+
If a token is leaked, revoke it at `https://qbsm.fly.dev/settings/tokens` and re-run `qbsm-init --api-key <new>` to overwrite `.mcp.json`.
|
package/dist/init.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, } from "node:fs";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { createInterface } from "node:readline";
|
|
5
|
-
const DEFAULT_SERVER_URL = "https://
|
|
5
|
+
const DEFAULT_SERVER_URL = "https://qbsm.fly.dev";
|
|
6
6
|
const SERVER_KEY = "qbsm";
|
|
7
7
|
const CLAUDE_MD_SECTION_START = "<!-- qbsm:start -->";
|
|
8
8
|
const CLAUDE_MD_SECTION_END = "<!-- qbsm:end -->";
|
|
@@ -14,6 +14,7 @@ function parseArgs(argv) {
|
|
|
14
14
|
yes: false,
|
|
15
15
|
noHooks: false,
|
|
16
16
|
overwrite: false,
|
|
17
|
+
legacySse: false,
|
|
17
18
|
};
|
|
18
19
|
for (let i = 0; i < args.length; i++) {
|
|
19
20
|
const a = args[i];
|
|
@@ -30,6 +31,9 @@ function parseArgs(argv) {
|
|
|
30
31
|
else if (a === "--overwrite") {
|
|
31
32
|
flags.overwrite = true;
|
|
32
33
|
}
|
|
34
|
+
else if (a === "--legacy-sse") {
|
|
35
|
+
flags.legacySse = true;
|
|
36
|
+
}
|
|
33
37
|
else if (a === "--api-key") {
|
|
34
38
|
flags.apiKey = args[++i];
|
|
35
39
|
}
|
|
@@ -55,10 +59,15 @@ Options:
|
|
|
55
59
|
-y, --yes Skip all prompts; use defaults
|
|
56
60
|
--no-hooks Skip .claude/settings.json hooks registration
|
|
57
61
|
--overwrite Overwrite .mcp.json / CLAUDE.md section if present
|
|
62
|
+
--legacy-sse Generate legacy SSE config (type: "sse" + /api/mcp/sse)
|
|
63
|
+
instead of Streamable HTTP. Use only if your Claude Code
|
|
64
|
+
client does not yet support type: "http".
|
|
58
65
|
-h, --help Show this help
|
|
59
66
|
|
|
60
67
|
What it does (idempotent merge):
|
|
61
|
-
- .mcp.json adds an "${SERVER_KEY}" entry pointing to the
|
|
68
|
+
- .mcp.json adds an "${SERVER_KEY}" entry pointing to the Streamable
|
|
69
|
+
HTTP endpoint (POST /api/mcp). Use --legacy-sse for the
|
|
70
|
+
old SSE transport.
|
|
62
71
|
- CLAUDE.md appends a guidance section between qbsm:start/end markers
|
|
63
72
|
- .claude/settings.json
|
|
64
73
|
registers PostToolUse (npm/pip/go/cargo install detector)
|
|
@@ -93,20 +102,25 @@ function readJson(path) {
|
|
|
93
102
|
function writeJson(path, value, mode = 0o644) {
|
|
94
103
|
writeFileSync(path, JSON.stringify(value, null, 2) + "\n", { mode });
|
|
95
104
|
}
|
|
96
|
-
function writeMcpJson(target, apiKey, serverUrl,
|
|
105
|
+
function writeMcpJson(target, apiKey, serverUrl, legacySse) {
|
|
97
106
|
const path = join(target, ".mcp.json");
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
const base = serverUrl.replace(/\/$/, "");
|
|
108
|
+
const entry = legacySse
|
|
109
|
+
? {
|
|
110
|
+
type: "sse",
|
|
111
|
+
url: `${base}/api/mcp/sse`,
|
|
112
|
+
headers: { "x-api-key": apiKey },
|
|
113
|
+
}
|
|
114
|
+
: {
|
|
115
|
+
type: "http",
|
|
116
|
+
url: `${base}/api/mcp`,
|
|
117
|
+
headers: { "x-api-key": apiKey },
|
|
118
|
+
};
|
|
119
|
+
const config = readJson(path) ?? {};
|
|
104
120
|
const servers = (config.mcpServers && typeof config.mcpServers === "object"
|
|
105
121
|
? config.mcpServers
|
|
106
122
|
: {});
|
|
107
|
-
|
|
108
|
-
// upsert: replace existing qbsm entry (always — overwrite flag is for non-qbsm collisions)
|
|
109
|
-
}
|
|
123
|
+
// Always upsert the qbsm entry (overwrite flag is reserved for CLAUDE.md section replacement).
|
|
110
124
|
servers[SERVER_KEY] = entry;
|
|
111
125
|
config.mcpServers = servers;
|
|
112
126
|
writeJson(path, config);
|
|
@@ -199,8 +213,8 @@ async function main() {
|
|
|
199
213
|
console.error("✗ API key must start with 'qbsm_'");
|
|
200
214
|
process.exit(1);
|
|
201
215
|
}
|
|
202
|
-
const mcpPath = writeMcpJson(target, apiKey, flags.serverUrl, flags.
|
|
203
|
-
console.log(`✓ .mcp.json ${mcpPath}`);
|
|
216
|
+
const mcpPath = writeMcpJson(target, apiKey, flags.serverUrl, flags.legacySse);
|
|
217
|
+
console.log(`✓ .mcp.json ${mcpPath} (${flags.legacySse ? "sse" : "http"})`);
|
|
204
218
|
const claude = writeClaudeMd(target, flags.overwrite);
|
|
205
219
|
console.log(`✓ CLAUDE.md ${claude.path} (${claude.action})`);
|
|
206
220
|
if (flags.noHooks) {
|
|
@@ -210,9 +224,10 @@ async function main() {
|
|
|
210
224
|
const settings = writeClaudeSettings(target);
|
|
211
225
|
console.log(`✓ .claude/settings.json ${settings.path} (${settings.action})`);
|
|
212
226
|
}
|
|
227
|
+
const endpointPath = flags.legacySse ? "/api/mcp/sse" : "/api/mcp";
|
|
213
228
|
console.log(`
|
|
214
229
|
Done. Start a Claude Code session in ${target} and the qbsm MCP server will be
|
|
215
|
-
reachable at ${flags.serverUrl}
|
|
230
|
+
reachable at ${flags.serverUrl}${endpointPath} with your API key.
|
|
216
231
|
|
|
217
232
|
To verify quickly:
|
|
218
233
|
cd ${target} && claude mcp list # should include "qbsm"
|