promptgraph-mcp 2.9.8 → 2.9.10
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 +235 -205
- package/index.js +9 -1
- package/marketplace.js +14 -2
- package/package.json +1 -1
- package/platform.js +6 -3
package/README.md
CHANGED
|
@@ -1,205 +1,235 @@
|
|
|
1
|
-
# PromptGraph
|
|
2
|
-
|
|
3
|
-
**Semantic skill router and marketplace for Claude Code.**
|
|
4
|
-
|
|
5
|
-
Instead of loading every `.md` skill into
|
|
6
|
-
|
|
7
|
-
[](https://www.npmjs.com/package/promptgraph-mcp)
|
|
8
|
-
[](LICENSE)
|
|
9
|
-
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
##
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
##
|
|
107
|
-
|
|
108
|
-
```bash
|
|
109
|
-
pg
|
|
110
|
-
pg
|
|
111
|
-
pg
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
pg marketplace
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
pg
|
|
129
|
-
pg
|
|
130
|
-
pg
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
Claude
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
---
|
|
191
|
-
|
|
192
|
-
##
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
1
|
+
# PromptGraph
|
|
2
|
+
|
|
3
|
+
**Semantic skill router and marketplace for Claude Code and OpenCode.**
|
|
4
|
+
|
|
5
|
+
Instead of loading every `.md` skill into context, Claude calls `pg_search` and loads only the skill it needs — saving 20k+ tokens per session.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/promptgraph-mcp)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
**Requirements:** Node.js 18+ — [nodejs.org](https://nodejs.org)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g promptgraph-mcp@latest
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Check version:
|
|
21
|
+
```bash
|
|
22
|
+
pg --version
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Update to latest:
|
|
26
|
+
```bash
|
|
27
|
+
pg update
|
|
28
|
+
# or
|
|
29
|
+
npm install -g promptgraph-mcp@latest
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Uninstall:
|
|
33
|
+
```bash
|
|
34
|
+
npm uninstall -g promptgraph-mcp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## Quick Start
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm install -g promptgraph-mcp@latest
|
|
43
|
+
pg init
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`pg init` auto-detects your installed editor, downloads the embedding model (~23 MB, once), indexes your skills, and writes the config automatically.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Setup
|
|
51
|
+
|
|
52
|
+
### Claude Code
|
|
53
|
+
|
|
54
|
+
**Option 1 — auto (recommended):**
|
|
55
|
+
```bash
|
|
56
|
+
pg init
|
|
57
|
+
# or
|
|
58
|
+
pg setup claude-code
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Option 2 — manual.** Add to `~/.claude/settings.json`:
|
|
62
|
+
```json
|
|
63
|
+
{
|
|
64
|
+
"mcpServers": {
|
|
65
|
+
"promptgraph": {
|
|
66
|
+
"command": "npx",
|
|
67
|
+
"args": ["promptgraph-mcp"]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Option 3 — official plugin:**
|
|
74
|
+
```
|
|
75
|
+
/plugin install promptgraph@claude-community
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### OpenCode
|
|
79
|
+
|
|
80
|
+
**Option 1 — auto (recommended):**
|
|
81
|
+
```bash
|
|
82
|
+
pg init
|
|
83
|
+
# or
|
|
84
|
+
pg setup opencode
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Option 2 — manual.** Add to `~/.config/opencode/opencode.json`:
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"plugin": ["promptgraph-mcp/plugin"]
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Other clients
|
|
95
|
+
|
|
96
|
+
| Client | Command |
|
|
97
|
+
|---|---|
|
|
98
|
+
| Claude Desktop | `pg setup claude-desktop` |
|
|
99
|
+
| Cursor | `pg setup cursor` |
|
|
100
|
+
| Windsurf | `pg setup windsurf` |
|
|
101
|
+
| Cline | `pg setup cline` |
|
|
102
|
+
| OpenAI Codex CLI | `pg setup codex` |
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Install skill bundles
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
pg install engineering-best-practices
|
|
110
|
+
pg install pg-000001
|
|
111
|
+
pg install "LLM Prompts"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Or browse interactively:
|
|
115
|
+
```bash
|
|
116
|
+
pg marketplace
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## CLI
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
pg init # first-time setup (auto-detects editor)
|
|
125
|
+
pg setup <platform> # register MCP in a specific editor
|
|
126
|
+
pg install <name> # install a bundle by name, code, or id
|
|
127
|
+
pg marketplace # browse + search + install (interactive TUI)
|
|
128
|
+
pg status # show indexed sources, repos, installed bundles
|
|
129
|
+
pg reindex # full reindex (semantic + keyword)
|
|
130
|
+
pg reindex --fast # keyword-only reindex (~30 s)
|
|
131
|
+
pg search "deploy" # search from terminal
|
|
132
|
+
pg import owner/repo # import any GitHub repo of .md skills
|
|
133
|
+
pg bundle update # update all installed bundles
|
|
134
|
+
pg validate my-skill.md # validate before publishing
|
|
135
|
+
pg doctor # clean orphaned DB rows
|
|
136
|
+
pg update # update to latest version
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## How it works
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
pg_search("refactor without breaking tests")
|
|
145
|
+
→ embed query (BGE-Small-EN, 384-dim)
|
|
146
|
+
→ HNSW ANN index — topK×4 candidates
|
|
147
|
+
→ BM25 FTS5 — topK×4 candidates
|
|
148
|
+
→ hybrid merge (cosine + BM25, adaptive weights)
|
|
149
|
+
→ term-overlap reranker (TF + header-position boost)
|
|
150
|
+
→ return topK skill paths + snippets
|
|
151
|
+
→ Claude reads only the files it needs
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Index:** SQLite + Float32 BLOB embeddings + HNSW. No external vector DB, no API key, no cloud.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Marketplace
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
pg marketplace # 🛠 Engineering 💻 Coding 🤖 AI 🔒 Security 🎨 Creative
|
|
162
|
+
pg marketplace bundles # curated GitHub repos as skill bundles
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Bundles** clone a GitHub repo and index only the skill files — auto-detects `skills/`, `commands/`, `prompts/` subdirectory.
|
|
166
|
+
|
|
167
|
+
**Publish your skill** — open an issue on [promptgraph-registry](https://github.com/NeiP4n/promptgraph-registry) with label `skill-submission`. The bot validates, commits, and closes automatically.
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
## MCP Tools
|
|
172
|
+
|
|
173
|
+
Claude uses these automatically when the server is running:
|
|
174
|
+
|
|
175
|
+
| Tool | Description |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `pg_search` | Semantic search by task description |
|
|
178
|
+
| `pg_list` | List all indexed skills |
|
|
179
|
+
| `pg_context` | Full skill details + callers/callees |
|
|
180
|
+
| `pg_callers` | Which skills reference this one |
|
|
181
|
+
| `pg_callees` | Which skills this one calls |
|
|
182
|
+
| `pg_impact` | What breaks if this skill changes |
|
|
183
|
+
| `pg_marketplace_browse` | Browse community registry |
|
|
184
|
+
| `pg_marketplace_install` | Install a skill by code or name |
|
|
185
|
+
| `pg_bundle_browse` | Browse skill bundles |
|
|
186
|
+
| `pg_bundle_install` | Install a bundle |
|
|
187
|
+
| `pg_top_rated` | Highest-rated skills |
|
|
188
|
+
| `pg_rate` | Rate a skill after use |
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Environment Variables
|
|
193
|
+
|
|
194
|
+
| Variable | Default | Description |
|
|
195
|
+
|---|---|---|
|
|
196
|
+
| `PG_VECTOR_STORE` | `hnsw` | `hnsw` (ANN) or `flat` (brute-force cosine) |
|
|
197
|
+
| `PG_RERANKER` | `1` | Term-overlap reranker — set `0` to disable |
|
|
198
|
+
| `PG_MAX_CHUNKS` | `8` | Max semantic chunks per skill file |
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Skill filtering
|
|
203
|
+
|
|
204
|
+
When importing a GitHub repo, PromptGraph:
|
|
205
|
+
1. Looks for a dedicated subdir (`skills/`, `commands/`, `prompts/`, `agents/`, etc.) — indexes only that if found
|
|
206
|
+
2. Falls back to repo root with a content quality filter: min 150 chars, 2+ headers, code blocks or bullets required, skips readme/changelog/license
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Benchmarks
|
|
211
|
+
|
|
212
|
+
| Operation | Result |
|
|
213
|
+
|---|---|
|
|
214
|
+
| 88 new skills (cold ONNX) | **49.5 s** |
|
|
215
|
+
| 88 skills (unchanged, hash match) | **< 1 s** |
|
|
216
|
+
| `pg reindex --fast` (3000 files) | **~30 s** |
|
|
217
|
+
| Semantic search (HNSW) | **< 50 ms** |
|
|
218
|
+
| Model size (BGE-Small-EN-v1.5, one-time) | **23 MB** |
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Requirements
|
|
223
|
+
|
|
224
|
+
- Node.js 18+
|
|
225
|
+
- Claude Code, OpenCode, Cursor, Windsurf, Cline, or any MCP-compatible client
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Related
|
|
230
|
+
|
|
231
|
+
- 📋 [promptgraph-registry](https://github.com/NeiP4n/promptgraph-registry) — community skill registry
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
*Built with [Claude Code](https://claude.com/claude-code).*
|
package/index.js
CHANGED
|
@@ -18,7 +18,7 @@ const args = process.argv.slice(2);
|
|
|
18
18
|
const rawBin = process.argv[1]?.split(/[\\/]/).pop()?.replace(/\.js$/, '');
|
|
19
19
|
const bin = (rawBin && rawBin !== 'index') ? rawBin : 'pg';
|
|
20
20
|
|
|
21
|
-
const KNOWN_COMMANDS = new Set(['init', 'reindex', 'update', 'import', 'install', 'setup', 'validate', 'marketplace', 'doctor', 'search', 'help', '--help', '-h', 'bundle', 'status', 'train']);
|
|
21
|
+
const KNOWN_COMMANDS = new Set(['init', 'reindex', 'update', 'import', 'install', 'setup', 'validate', 'marketplace', 'doctor', 'search', 'help', '--help', '-h', '--version', '-v', 'version', 'bundle', 'status', 'train']);
|
|
22
22
|
|
|
23
23
|
function showHelp() {
|
|
24
24
|
console.log(
|
|
@@ -57,6 +57,14 @@ if (args[0] === 'help' || args[0] === '--help' || args[0] === '-h') {
|
|
|
57
57
|
process.exit(0);
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// Version flag
|
|
61
|
+
if (args[0] === '--version' || args[0] === '-v' || args[0] === 'version') {
|
|
62
|
+
const { createRequire } = await import('module');
|
|
63
|
+
const _pkg = createRequire(import.meta.url)('./package.json');
|
|
64
|
+
console.log(_pkg.version);
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}
|
|
67
|
+
|
|
60
68
|
// No args: if launched from an interactive terminal, show help.
|
|
61
69
|
// If stdin is a pipe (i.e. an MCP client like Claude), fall through and
|
|
62
70
|
// start the server — NEVER print to stdout here, it corrupts JSON-RPC.
|
package/marketplace.js
CHANGED
|
@@ -359,9 +359,21 @@ async function _findBundle(bundleId) {
|
|
|
359
359
|
const text = await fetchText(REGISTRY_URL);
|
|
360
360
|
const registry = JSON.parse(text);
|
|
361
361
|
const q = String(bundleId).trim().toLowerCase();
|
|
362
|
+
const valid = (registry.bundles || []).filter(b => validateRegistryEntry(b).ok);
|
|
362
363
|
const validSkills = (registry.skills || []).filter(s => validateRegistryEntry(s).ok);
|
|
363
|
-
|
|
364
|
-
|
|
364
|
+
// 1. Exact match (code, id, name)
|
|
365
|
+
let bundle = valid.find(b =>
|
|
366
|
+
(b.code || codeFor(b.id)).toLowerCase() === q ||
|
|
367
|
+
b.id?.toLowerCase() === q ||
|
|
368
|
+
b.name?.toLowerCase() === q
|
|
369
|
+
);
|
|
370
|
+
// 2. Partial name/id match (starts with)
|
|
371
|
+
if (!bundle) bundle = valid.find(b =>
|
|
372
|
+
b.name?.toLowerCase().startsWith(q) || b.id?.toLowerCase().startsWith(q)
|
|
373
|
+
);
|
|
374
|
+
// 3. Contains match
|
|
375
|
+
if (!bundle) bundle = valid.find(b =>
|
|
376
|
+
b.name?.toLowerCase().includes(q) || b.id?.toLowerCase().includes(q)
|
|
365
377
|
);
|
|
366
378
|
if (!bundle) return { error: `No bundle matching "${bundleId}"` };
|
|
367
379
|
return { bundle, validSkills };
|
package/package.json
CHANGED
package/platform.js
CHANGED
|
@@ -88,12 +88,15 @@ export function detectPlatforms() {
|
|
|
88
88
|
|
|
89
89
|
function isBinaryInstalled(bin) {
|
|
90
90
|
try {
|
|
91
|
-
const
|
|
92
|
-
|
|
91
|
+
const cmd = process.platform === 'win32' ? 'where' : 'which';
|
|
92
|
+
const r = spawnSync(cmd, [bin], { encoding: 'utf8', timeout: 3000, stdio: 'pipe' });
|
|
93
|
+
return r.status === 0 && r.stdout.trim().length > 0;
|
|
93
94
|
} catch { return false; }
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
function isOpenCodeInstalled() {
|
|
97
|
+
function isOpenCodeInstalled() {
|
|
98
|
+
return isBinaryInstalled('opencode') || isBinaryInstalled('OpenCode');
|
|
99
|
+
}
|
|
97
100
|
function isClaudeCodeInstalled() { return isBinaryInstalled('claude'); }
|
|
98
101
|
|
|
99
102
|
function getOpenCodeConfig() {
|