compendium-mcp 0.1.1 → 0.1.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/README.md +136 -44
- package/package.json +10 -8
package/README.md
CHANGED
|
@@ -1,32 +1,88 @@
|
|
|
1
1
|
# Compendium
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="assets/logo.svg" alt="Compendium" width="420" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
3
7
|
MCP server that **minimizes LLM token usage** by compressing, summarizing, filtering, and chunk-referencing large context before it reaches the model.
|
|
4
8
|
|
|
5
9
|
Built in Rust with the official [`rmcp`](https://crates.io/crates/rmcp) SDK.
|
|
6
10
|
|
|
7
|
-
##
|
|
11
|
+
## Quick start (Cursor)
|
|
12
|
+
|
|
13
|
+
You need **Node.js 18+**. Compendium itself arrives via npm — no Rust install required.
|
|
14
|
+
|
|
15
|
+
### 1. Add the MCP server
|
|
16
|
+
|
|
17
|
+
Open Cursor MCP settings (`~/.cursor/mcp.json` or the project `.cursor/mcp.json`) and add:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"mcpServers": {
|
|
22
|
+
"compendium": {
|
|
23
|
+
"command": "npx",
|
|
24
|
+
"args": ["-y", "compendium-mcp"]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Restart MCP / reload Cursor. You should see one tool named **`compendium`**.
|
|
31
|
+
|
|
32
|
+
That alone is enough: filter, compress, summarize, cache, and BM25 actions all work **without** a local model (fast heuristics).
|
|
8
33
|
|
|
9
|
-
|
|
34
|
+
### 2. (Optional) Smarter summaries with Ollama
|
|
35
|
+
|
|
36
|
+
Want better `summarize_smart` / `filter_relevant`? Run a small model on your machine and point Compendium at it.
|
|
37
|
+
|
|
38
|
+
1. Install [Ollama](https://ollama.com/) and start it (default: `http://127.0.0.1:11434`).
|
|
39
|
+
2. Pull a chat model, for example:
|
|
10
40
|
|
|
11
41
|
```bash
|
|
12
|
-
|
|
13
|
-
# or:
|
|
42
|
+
ollama pull qwen:latest
|
|
43
|
+
# or a smaller one: ollama pull qwen2.5:3b
|
|
14
44
|
```
|
|
15
45
|
|
|
16
|
-
**
|
|
46
|
+
3. Extend the MCP `env` block (URL must stay on **localhost** — Compendium blocks remote hosts on purpose):
|
|
17
47
|
|
|
18
48
|
```json
|
|
19
49
|
{
|
|
20
50
|
"mcpServers": {
|
|
21
51
|
"compendium": {
|
|
22
52
|
"command": "npx",
|
|
23
|
-
"args": ["-y", "compendium-mcp"]
|
|
53
|
+
"args": ["-y", "compendium-mcp"],
|
|
54
|
+
"env": {
|
|
55
|
+
"COMPENDIUM_LOCAL_LLM_URL": "http://127.0.0.1:11434/v1",
|
|
56
|
+
"COMPENDIUM_LOCAL_LLM_MODEL": "qwen:latest"
|
|
57
|
+
}
|
|
24
58
|
}
|
|
25
59
|
}
|
|
26
60
|
}
|
|
27
61
|
```
|
|
28
62
|
|
|
29
|
-
|
|
63
|
+
4. Reload MCP, then ask the agent to call `compendium` with `action: "summarize_smart"`.
|
|
64
|
+
In the result, `"backend": "local_llm"` means Ollama answered; `"heuristic"` means it fell back (Ollama down, wrong model name, or URL missing).
|
|
65
|
+
|
|
66
|
+
**Notes**
|
|
67
|
+
|
|
68
|
+
- Package name on npm is **`compendium-mcp`** (`compendium` was already taken). The CLI binary name is still `compendium`.
|
|
69
|
+
- First Ollama reply can be slow while the model loads; later calls are faster.
|
|
70
|
+
- Other local OpenAI-compatible servers work the same way (e.g. Lemonade `http://127.0.0.1:13305/api/v1`). See [Environment](#environment).
|
|
71
|
+
|
|
72
|
+
Smoke-check from a terminal (any folder **except** this git repo root is fine):
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx -y compendium-mcp --help
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Binary packaging details for maintainers: [npm/DISTRIBUTION.md](npm/DISTRIBUTION.md).
|
|
79
|
+
|
|
80
|
+
## Community
|
|
81
|
+
|
|
82
|
+
- [Contributing](CONTRIBUTING.md)
|
|
83
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
84
|
+
- [Security policy](SECURITY.md)
|
|
85
|
+
- [Support](SUPPORT.md)
|
|
30
86
|
|
|
31
87
|
## Transports
|
|
32
88
|
|
|
@@ -59,11 +115,32 @@ Single MCP tool: **`compendium`**. Choose the operation with `action`:
|
|
|
59
115
|
| `cache_invalidate` | Drop one key or clear cache | `key?` |
|
|
60
116
|
| `sanitize` | Redact secrets + neutralize IPI phrases | `text`, `sanitize?` |
|
|
61
117
|
| `rerank` | BM25-rank candidates / chunks for a query | `query`, `items` or `text` or chunk `map`, `rerank?` |
|
|
118
|
+
| `brief` | Scan a workspace; pack a structured starter briefing + cache key | `query`, `brief?` (`root`, caps), optional `text` hint |
|
|
119
|
+
| `catalog` | Short action (+ playbook) ads; prefer before guessing | _(none)_ |
|
|
120
|
+
| `help` | Usage notes for one action (default **compressed**; `force: true` → full) | `id`, `force?` |
|
|
121
|
+
| `playbooks` | List bundled token-hygiene playbook ads | _(none)_ |
|
|
122
|
+
| `playbook` | Load one playbook body (sanitized) | `id` |
|
|
123
|
+
| `pack` | Zip text/files into a size-capped archive (cache and/or base64) | `text` or `items`, `pack?` |
|
|
124
|
+
| `unpack` | Unpack zip with caps → chunks (**never runs scripts**) | `key` or base64 `text`, `pack?` |
|
|
125
|
+
|
|
126
|
+
### Progressive disclosure (skills)
|
|
127
|
+
|
|
128
|
+
Tool description/instructions stay thin. Discover details on demand:
|
|
129
|
+
|
|
130
|
+
- **Tool bridge:** `action=catalog` → `action=help` with `id`, or `playbooks` → `playbook`
|
|
131
|
+
- **MCP resources:** `resources/list` / `resources/read` on:
|
|
132
|
+
- `cmp://skill/index` — JSON index of actions + playbooks
|
|
133
|
+
- `cmp://skill/action/{name}` — full action help (markdown)
|
|
134
|
+
- `cmp://skill/playbook/{id}` — playbook body
|
|
135
|
+
|
|
136
|
+
Bundled playbooks live under [`playbooks/`](playbooks/). Override/extend with `COMPENDIUM_PLAYBOOKS_DIR` (same `id` wins). Archives honor `COMPENDIUM_ARCHIVE_MAX_BYTES` / `_UNCOMPRESSED` / `_FILES` (defaults 2 MiB / 4 MiB / 50).
|
|
62
137
|
|
|
63
138
|
Optional on most text actions: `sanitize_input: true` scrubs before processing. Soft payloads under `COMPENDIUM_SIGNAL_MIN_CHARS` (default 1000) bypass `compress` / `summarize` / `summarize_smart` unless `force: true`.
|
|
64
139
|
|
|
65
140
|
`filter` accepts optional `query` (top-level or `filter.query`) for BM25 line keep. `prune_history` supports `prune.strategy: "afm"` (Critical / Thematic / Distant tiers; distant blob cached for `cache_get`).
|
|
66
141
|
|
|
142
|
+
`brief` walks `brief.root` (default: process cwd) with `.gitignore` / `.ignore`, BM25-ranks paths/chunks, window-reads oversized files (not head-truncate), and returns a structured `briefing`: **Task / Status / Evidence / Caveats / Sources / Read next**, plus `cache_key`. Status uses a local SLM when `COMPENDIUM_LOCAL_LLM_URL` is set (`backend: local_llm`); otherwise heuristic bullets. Caveats flag truncated files and docs older than selected code. **Read next** includes source paths plus suggested `cmp://skill/playbook/…` / action URIs. Optional `COMPENDIUM_BRIEF_ROOT` restricts allowed roots. Briefings are sanitized by default.
|
|
143
|
+
|
|
67
144
|
Example:
|
|
68
145
|
|
|
69
146
|
```json
|
|
@@ -79,14 +156,13 @@ Response envelope: `{ "ok": true, "action": "filter", "result_json": "{...}" }`.
|
|
|
79
156
|
## Project layout
|
|
80
157
|
|
|
81
158
|
```
|
|
82
|
-
|
|
83
|
-
npm/ # platform packages + distribution docs
|
|
84
|
-
.github/workflows/ # release cross-compile + npm publish
|
|
159
|
+
assets/ # brand mark (SVG/PNG); baked into MCP icons via data URI
|
|
85
160
|
src/
|
|
86
161
|
main.rs # CLI: stdio | http
|
|
87
162
|
lib.rs
|
|
163
|
+
brand.rs # SEP-973 icons for serverInfo + tool
|
|
88
164
|
config.rs # COMPENDIUM_* env config
|
|
89
|
-
server.rs # MCP tool handlers (rmcp
|
|
165
|
+
server.rs # MCP tool + resources handlers (rmcp)
|
|
90
166
|
http.rs # Streamable HTTP/SSE (feature = "http")
|
|
91
167
|
pipeline/
|
|
92
168
|
tokens.rs # heuristic or tiktoken BPE (feature = "real-tokens")
|
|
@@ -97,12 +173,16 @@ src/
|
|
|
97
173
|
local_llm.rs # OpenAI-compatible local SLM client
|
|
98
174
|
chunk.rs # chunk + resolve
|
|
99
175
|
cache.rs # session key/value cache
|
|
176
|
+
catalog.rs # action ads + help (progressive disclosure)
|
|
177
|
+
playbook.rs # bundled / dir playbooks
|
|
178
|
+
pack.rs # zip pack/unpack with size caps
|
|
100
179
|
stats.rs # session savings counters
|
|
101
180
|
prune.rs # conversation history pruning
|
|
102
181
|
output.rs # domain-aware compress_output
|
|
182
|
+
playbooks/ # embedded skill-md playbooks
|
|
103
183
|
tests/
|
|
104
184
|
integration.rs
|
|
105
|
-
e2e_smoke.rs # spawns binary, MCP handshake,
|
|
185
|
+
e2e_smoke.rs # spawns binary, MCP handshake, tools + resources
|
|
106
186
|
```
|
|
107
187
|
|
|
108
188
|
## Build
|
|
@@ -123,27 +203,27 @@ cargo build --release --features real-tokens,http
|
|
|
123
203
|
|
|
124
204
|
Binary: `target/release/compendium`
|
|
125
205
|
|
|
126
|
-
## Configure (
|
|
206
|
+
## Configure (advanced)
|
|
207
|
+
|
|
208
|
+
The [Quick start](#quick-start-cursor) config is enough for most people. Extra options:
|
|
209
|
+
|
|
210
|
+
### Claude Desktop
|
|
211
|
+
|
|
212
|
+
Same `command` / `args` / `env` as Cursor, in Claude’s MCP config file.
|
|
127
213
|
|
|
128
|
-
###
|
|
214
|
+
### Optional tuning env
|
|
129
215
|
|
|
130
216
|
```json
|
|
131
|
-
{
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"RUST_LOG": "compendium=info",
|
|
138
|
-
"COMPENDIUM_DEFAULT_MAX_TOKENS": "2048",
|
|
139
|
-
"COMPENDIUM_TOKENIZER": "cl100k_base"
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
217
|
+
"env": {
|
|
218
|
+
"RUST_LOG": "compendium=info",
|
|
219
|
+
"COMPENDIUM_DEFAULT_MAX_TOKENS": "2048",
|
|
220
|
+
"COMPENDIUM_TOKENIZER": "cl100k_base",
|
|
221
|
+
"COMPENDIUM_LOCAL_LLM_URL": "http://127.0.0.1:11434/v1",
|
|
222
|
+
"COMPENDIUM_LOCAL_LLM_MODEL": "qwen:latest"
|
|
143
223
|
}
|
|
144
224
|
```
|
|
145
225
|
|
|
146
|
-
|
|
226
|
+
### Local Cargo binary (developers)
|
|
147
227
|
|
|
148
228
|
```json
|
|
149
229
|
{
|
|
@@ -152,9 +232,7 @@ Or point at a local release binary:
|
|
|
152
232
|
"command": "/absolute/path/to/Compendium/target/release/compendium",
|
|
153
233
|
"env": {
|
|
154
234
|
"RUST_LOG": "compendium=info",
|
|
155
|
-
"COMPENDIUM_DEFAULT_MAX_TOKENS": "2048"
|
|
156
|
-
"COMPENDIUM_CHARS_PER_TOKEN": "4.0",
|
|
157
|
-
"COMPENDIUM_TOKENIZER": "cl100k_base"
|
|
235
|
+
"COMPENDIUM_DEFAULT_MAX_TOKENS": "2048"
|
|
158
236
|
}
|
|
159
237
|
}
|
|
160
238
|
}
|
|
@@ -181,10 +259,16 @@ Point an MCP streamable-HTTP client at that URL (e.g. `StreamableHttpClientTrans
|
|
|
181
259
|
| `COMPENDIUM_SIMILARITY_THRESHOLD` | `0.85` | Jaccard line-dedupe threshold |
|
|
182
260
|
| `COMPENDIUM_HTTP_BIND` | `127.0.0.1:8788` | Default HTTP listen address |
|
|
183
261
|
| `COMPENDIUM_LOCAL_LLM_URL` | _(unset)_ | OpenAI-compatible base URL (e.g. `http://127.0.0.1:11434/v1` or `http://127.0.0.1:13305/api/v1`). Enables smart actions. |
|
|
184
|
-
| `COMPENDIUM_LOCAL_LLM_MODEL` | `Qwen3-4B-GGUF` | Model id
|
|
262
|
+
| `COMPENDIUM_LOCAL_LLM_MODEL` | `Qwen3-4B-GGUF` | Model id on that server (Ollama: e.g. `qwen:latest`) |
|
|
185
263
|
| `COMPENDIUM_LOCAL_LLM_API_KEY` | _(unset)_ | Optional bearer token for locked loopback servers |
|
|
186
264
|
| `COMPENDIUM_LOCAL_LLM_TIMEOUT_SECS` | `120` | HTTP timeout (first model load can be slow) |
|
|
187
265
|
| `COMPENDIUM_SIGNAL_MIN_CHARS` | `1000` | Bypass compress/summarize below this length (`0` disables) |
|
|
266
|
+
| `COMPENDIUM_BRIEF_ROOT` | _(unset)_ | When set, `action=brief` may only scan roots under this canonical path |
|
|
267
|
+
| `COMPENDIUM_PLAYBOOKS_DIR` | _(unset)_ | Extra/override playbook `*.md` directory (same `id` replaces embedded) |
|
|
268
|
+
| `COMPENDIUM_ARCHIVE_MAX_BYTES` | `2097152` | Max compressed archive size for pack/unpack |
|
|
269
|
+
| `COMPENDIUM_ARCHIVE_MAX_UNCOMPRESSED` | `4194304` | Max total uncompressed bytes for pack/unpack |
|
|
270
|
+
| `COMPENDIUM_ARCHIVE_MAX_FILES` | `50` | Max files per archive |
|
|
271
|
+
| `COMPENDIUM_SKILL_TTL_MS` | `300000` | Soft TTL (ms) on skill `resources/read` responses |
|
|
188
272
|
| `RUST_LOG` | `compendium=info` | Logs on **stderr** only |
|
|
189
273
|
|
|
190
274
|
## Example tool calls
|
|
@@ -250,26 +334,34 @@ Prefer the returned `index_text` in the model context; pull individual chunk con
|
|
|
250
334
|
|
|
251
335
|
Without `COMPENDIUM_LOCAL_LLM_URL`, `summarize_smart` / `filter_relevant` automatically use heuristics and set `backend: "heuristic"` plus `fallback_reason` in the result.
|
|
252
336
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
Smart actions call a **loopback-only** OpenAI-compatible chat endpoint — never a cloud API. `COMPENDIUM_LOCAL_LLM_URL` must be `127.0.0.1`, `::1`, or `localhost` (SSRF guard). Requests use `temperature=0` and `seed=0` for stable outputs. Point Compendium at Ollama, Lemonade, or llama.cpp:
|
|
337
|
+
**Pack a workspace briefing for a fresh agent turn**
|
|
256
338
|
|
|
257
339
|
```json
|
|
258
340
|
{
|
|
259
|
-
"
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
}
|
|
341
|
+
"action": "brief",
|
|
342
|
+
"query": "fix the OAuth refresh token path",
|
|
343
|
+
"brief": {
|
|
344
|
+
"root": "/path/to/repo",
|
|
345
|
+
"max_files": 40,
|
|
346
|
+
"top_k_chunks": 12,
|
|
347
|
+
"max_brief_tokens": 2048
|
|
268
348
|
}
|
|
269
349
|
}
|
|
270
350
|
```
|
|
271
351
|
|
|
272
|
-
|
|
352
|
+
Start the new turn with the returned `briefing` (or `cache_get` the `cache_key`). The host should not paste the whole tree into the prompt first. Treat Status as a starter synthesis — verify Caveats and Read next before large edits.
|
|
353
|
+
|
|
354
|
+
## Local small language model
|
|
355
|
+
|
|
356
|
+
Follow [Quick start §2](#2-optional-smarter-summaries-with-ollama) for Ollama.
|
|
357
|
+
|
|
358
|
+
Rules of thumb:
|
|
359
|
+
|
|
360
|
+
- **Only loopback** URLs (`127.0.0.1`, `::1`, `localhost`) — no cloud endpoints.
|
|
361
|
+
- Without `COMPENDIUM_LOCAL_LLM_URL`, smart actions use heuristics and set `backend: "heuristic"`.
|
|
362
|
+
- Calls use `temperature=0` and `seed=0` for stable outputs.
|
|
363
|
+
- Lemonade example: `COMPENDIUM_LOCAL_LLM_URL=http://127.0.0.1:13305/api/v1` and `COMPENDIUM_LOCAL_LLM_MODEL=Qwen3-4B-GGUF`.
|
|
364
|
+
- llama.cpp OpenAI server: same pattern — set URL to its `/v1` base and the served model id.
|
|
273
365
|
|
|
274
366
|
## Develop / test
|
|
275
367
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compendium-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "MCP server that compresses, summarizes, and filters context to minimize LLM token usage",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
"node": ">=18"
|
|
25
25
|
},
|
|
26
26
|
"bin": {
|
|
27
|
-
"compendium": "bin/run.js"
|
|
27
|
+
"compendium": "bin/run.js",
|
|
28
|
+
"compendium-mcp": "bin/run.js"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"bin/",
|
|
@@ -33,14 +34,15 @@
|
|
|
33
34
|
"LICENSE"
|
|
34
35
|
],
|
|
35
36
|
"scripts": {
|
|
36
|
-
"prepack": "node npm/scripts/check-wrapper.js"
|
|
37
|
+
"prepack": "node npm/scripts/check-wrapper.js",
|
|
38
|
+
"prepare": "node npm/scripts/link-bins.js"
|
|
37
39
|
},
|
|
38
40
|
"optionalDependencies": {
|
|
39
|
-
"compendium-mcp-darwin-arm64": "0.1.
|
|
40
|
-
"compendium-mcp-darwin-x64": "0.1.
|
|
41
|
-
"compendium-mcp-linux-x64": "0.1.
|
|
42
|
-
"compendium-mcp-linux-arm64": "0.1.
|
|
43
|
-
"compendium-mcp-win32-x64": "0.1.
|
|
41
|
+
"compendium-mcp-darwin-arm64": "0.1.3",
|
|
42
|
+
"compendium-mcp-darwin-x64": "0.1.3",
|
|
43
|
+
"compendium-mcp-linux-x64": "0.1.3",
|
|
44
|
+
"compendium-mcp-linux-arm64": "0.1.3",
|
|
45
|
+
"compendium-mcp-win32-x64": "0.1.3"
|
|
44
46
|
},
|
|
45
47
|
"preferUnplugged": true
|
|
46
48
|
}
|