compendium-mcp 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Compendium contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,295 @@
1
+ # Compendium
2
+
3
+ MCP server that **minimizes LLM token usage** by compressing, summarizing, filtering, and chunk-referencing large context before it reaches the model.
4
+
5
+ Built in Rust with the official [`rmcp`](https://crates.io/crates/rmcp) SDK.
6
+
7
+ ## Install via npm / npx
8
+
9
+ Package name: **`compendium-mcp`** (the npm name `compendium` is taken). CLI bin: `compendium`.
10
+
11
+ ```bash
12
+ npx -y compendium-mcp --help
13
+ # or: npm install -g compendium-mcp
14
+ ```
15
+
16
+ **Cursor / Claude Desktop**
17
+
18
+ ```json
19
+ {
20
+ "mcpServers": {
21
+ "compendium": {
22
+ "command": "npx",
23
+ "args": ["-y", "compendium-mcp"]
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ Distribution uses **optional platform packages** (`compendium-mcp-darwin-arm64`, …) with a **GitHub Releases download fallback**. See [npm/DISTRIBUTION.md](npm/DISTRIBUTION.md) for local testing, CI release, and publishing.
30
+
31
+ ## Transports
32
+
33
+ | Mode | Command | Notes |
34
+ |------|---------|-------|
35
+ | **stdio** (default) | `compendium` / `compendium stdio` | Cursor / Claude Desktop |
36
+ | **Streamable HTTP/SSE** | `compendium http [BIND]` | Requires `--features http`. Endpoint: `http://{bind}/mcp` |
37
+
38
+ Default HTTP bind: `127.0.0.1:8788` (override with arg or `COMPENDIUM_HTTP_BIND`).
39
+
40
+ ## Tools
41
+
42
+ Single MCP tool: **`compendium`**. Choose the operation with `action`:
43
+
44
+ | `action` | Purpose | Main fields |
45
+ |----------|---------|-------------|
46
+ | `filter` | Strip ANSI, boilerplate, whitespace; densify JSON; keep/drop regexes | `text`, `filter` |
47
+ | `compress` | Dense representation of text/code/logs | `text`, `compress` |
48
+ | `compress_output` | Domain-aware stdout/stderr scrub (git, cargo, npm, docker, …) | `text`, `output` |
49
+ | `summarize` | Hierarchical summary (conversation / file tree / outline) | `text`, `summarize` |
50
+ | `summarize_smart` | Local-SLM dense summary (heuristic fallback if unset/fails) | `text`, `smart?`, `summarize?` |
51
+ | `filter_relevant` | Query-aware keep of relevant lines (local SLM + heuristic fallback) | `text`, `query`, `smart?` |
52
+ | `prune_history` | Drop filler / compress older chat turns | `text` or `messages`, `prune` |
53
+ | `chunk` | Split into `cmp://` chunks (session-cached) | `text`, `chunk` |
54
+ | `resolve` | Fetch chunk content by id | `id` (+ optional `map` / `text`) |
55
+ | `count_tokens` | Measure tokens | `text` |
56
+ | `stats` | Session savings + latency/bypass/backend telemetry | `reset?` |
57
+ | `cache_store` | Park bulky payload outside the prompt | `text`, `cache` |
58
+ | `cache_get` | Retrieve by key | `key` |
59
+ | `cache_invalidate` | Drop one key or clear cache | `key?` |
60
+ | `sanitize` | Redact secrets + neutralize IPI phrases | `text`, `sanitize?` |
61
+ | `rerank` | BM25-rank candidates / chunks for a query | `query`, `items` or `text` or chunk `map`, `rerank?` |
62
+
63
+ 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
+
65
+ `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
+
67
+ Example:
68
+
69
+ ```json
70
+ {
71
+ "action": "filter",
72
+ "text": "…noisy log…",
73
+ "filter": { "strip_ansi": true, "keep_patterns": ["ERROR|WARN"] }
74
+ }
75
+ ```
76
+
77
+ Response envelope: `{ "ok": true, "action": "filter", "result_json": "{...}" }`. Parse `result_json` as JSON for the action-specific payload.
78
+
79
+ ## Project layout
80
+
81
+ ```
82
+ package.json / bin/run.js # npm wrapper for npx compendium-mcp
83
+ npm/ # platform packages + distribution docs
84
+ .github/workflows/ # release cross-compile + npm publish
85
+ src/
86
+ main.rs # CLI: stdio | http
87
+ lib.rs
88
+ config.rs # COMPENDIUM_* env config
89
+ server.rs # MCP tool handlers (rmcp macros)
90
+ http.rs # Streamable HTTP/SSE (feature = "http")
91
+ pipeline/
92
+ tokens.rs # heuristic or tiktoken BPE (feature = "real-tokens")
93
+ filter.rs
94
+ compress.rs
95
+ summarize.rs
96
+ smart.rs # summarize_smart + filter_relevant
97
+ local_llm.rs # OpenAI-compatible local SLM client
98
+ chunk.rs # chunk + resolve
99
+ cache.rs # session key/value cache
100
+ stats.rs # session savings counters
101
+ prune.rs # conversation history pruning
102
+ output.rs # domain-aware compress_output
103
+ tests/
104
+ integration.rs
105
+ e2e_smoke.rs # spawns binary, MCP handshake, all tools
106
+ ```
107
+
108
+ ## Build
109
+
110
+ ```bash
111
+ # Default: heuristic tokens + stdio only
112
+ cargo build --release
113
+
114
+ # Exact BPE token counts (tiktoken-rs)
115
+ cargo build --release --features real-tokens
116
+
117
+ # Streamable HTTP transport
118
+ cargo build --release --features http
119
+
120
+ # Everything
121
+ cargo build --release --features real-tokens,http
122
+ ```
123
+
124
+ Binary: `target/release/compendium`
125
+
126
+ ## Configure (Cursor / Claude Desktop)
127
+
128
+ ### Cursor (`~/.cursor/mcp.json` or project `.cursor/mcp.json`)
129
+
130
+ ```json
131
+ {
132
+ "mcpServers": {
133
+ "compendium": {
134
+ "command": "npx",
135
+ "args": ["-y", "compendium-mcp"],
136
+ "env": {
137
+ "RUST_LOG": "compendium=info",
138
+ "COMPENDIUM_DEFAULT_MAX_TOKENS": "2048",
139
+ "COMPENDIUM_TOKENIZER": "cl100k_base"
140
+ }
141
+ }
142
+ }
143
+ }
144
+ ```
145
+
146
+ Or point at a local release binary:
147
+
148
+ ```json
149
+ {
150
+ "mcpServers": {
151
+ "compendium": {
152
+ "command": "/absolute/path/to/Compendium/target/release/compendium",
153
+ "env": {
154
+ "RUST_LOG": "compendium=info",
155
+ "COMPENDIUM_DEFAULT_MAX_TOKENS": "2048",
156
+ "COMPENDIUM_CHARS_PER_TOKEN": "4.0",
157
+ "COMPENDIUM_TOKENIZER": "cl100k_base"
158
+ }
159
+ }
160
+ }
161
+ }
162
+ ```
163
+
164
+ ### Remote / sidecar (HTTP)
165
+
166
+ ```bash
167
+ cargo run --features http -- http 127.0.0.1:8788
168
+ # MCP endpoint: http://127.0.0.1:8788/mcp
169
+ ```
170
+
171
+ Point an MCP streamable-HTTP client at that URL (e.g. `StreamableHttpClientTransport::from_uri`).
172
+
173
+ ## Environment
174
+
175
+ | Variable | Default | Meaning |
176
+ |----------|---------|---------|
177
+ | `COMPENDIUM_CHARS_PER_TOKEN` | `4.0` | Heuristic chars÷tokens (ignored with `real-tokens`) |
178
+ | `COMPENDIUM_TOKENIZER` | `cl100k_base` | BPE encoding: `cl100k_base` or `o200k_base` (`real-tokens`) |
179
+ | `COMPENDIUM_DEFAULT_MAX_TOKENS` | `2048` | Soft cap for compress |
180
+ | `COMPENDIUM_MAX_BLANK_LINES` | `1` | Blank-line collapse limit |
181
+ | `COMPENDIUM_SIMILARITY_THRESHOLD` | `0.85` | Jaccard line-dedupe threshold |
182
+ | `COMPENDIUM_HTTP_BIND` | `127.0.0.1:8788` | Default HTTP listen address |
183
+ | `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 accepted by the local server |
185
+ | `COMPENDIUM_LOCAL_LLM_API_KEY` | _(unset)_ | Optional bearer token for locked loopback servers |
186
+ | `COMPENDIUM_LOCAL_LLM_TIMEOUT_SECS` | `120` | HTTP timeout (first model load can be slow) |
187
+ | `COMPENDIUM_SIGNAL_MIN_CHARS` | `1000` | Bypass compress/summarize below this length (`0` disables) |
188
+ | `RUST_LOG` | `compendium=info` | Logs on **stderr** only |
189
+
190
+ ## Example tool calls
191
+
192
+ **Filter noisy terminal output**
193
+
194
+ ```json
195
+ {
196
+ "name": "compendium_filter",
197
+ "arguments": {
198
+ "text": "\u001b[31mERROR\u001b[0m boom\n\n\nINFO ok",
199
+ "options": {
200
+ "strip_ansi": true,
201
+ "keep_patterns": ["ERROR|WARN"]
202
+ }
203
+ }
204
+ }
205
+ ```
206
+
207
+ **Compress a large log**
208
+
209
+ ```json
210
+ {
211
+ "name": "compendium_compress",
212
+ "arguments": {
213
+ "text": "...",
214
+ "options": {
215
+ "content_type": "log",
216
+ "max_tokens": 512
217
+ }
218
+ }
219
+ }
220
+ ```
221
+
222
+ **Chunk a document into references**
223
+
224
+ ```json
225
+ {
226
+ "name": "compendium_chunk",
227
+ "arguments": {
228
+ "text": "... huge file ...",
229
+ "options": {
230
+ "source": "file:///path/to/doc.md",
231
+ "chunk_tokens": 400,
232
+ "overlap_tokens": 40
233
+ }
234
+ }
235
+ }
236
+ ```
237
+
238
+ Prefer the returned `index_text` in the model context; pull individual chunk contents by id only when needed.
239
+
240
+ **Query-aware filter (local SLM or heuristic fallback)**
241
+
242
+ ```json
243
+ {
244
+ "action": "filter_relevant",
245
+ "text": "... noisy cargo/test log ...",
246
+ "query": "why did the auth tests fail",
247
+ "smart": { "max_tokens": 512, "fallback": true }
248
+ }
249
+ ```
250
+
251
+ Without `COMPENDIUM_LOCAL_LLM_URL`, `summarize_smart` / `filter_relevant` automatically use heuristics and set `backend: "heuristic"` plus `fallback_reason` in the result.
252
+
253
+ ## Local small language model
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:
256
+
257
+ ```json
258
+ {
259
+ "mcpServers": {
260
+ "compendium": {
261
+ "command": "npx",
262
+ "args": ["-y", "compendium-mcp"],
263
+ "env": {
264
+ "COMPENDIUM_LOCAL_LLM_URL": "http://127.0.0.1:11434/v1",
265
+ "COMPENDIUM_LOCAL_LLM_MODEL": "qwen2.5:3b"
266
+ }
267
+ }
268
+ }
269
+ }
270
+ ```
271
+
272
+ Lemonade example: `COMPENDIUM_LOCAL_LLM_URL=http://127.0.0.1:13305/api/v1` and `COMPENDIUM_LOCAL_LLM_MODEL=Qwen3-4B-GGUF`.
273
+
274
+ ## Develop / test
275
+
276
+ ```bash
277
+ cargo test
278
+ cargo test --features real-tokens
279
+ cargo test --features http --test http_smoke
280
+ cargo test --test e2e_smoke
281
+ cargo run --features http -- http 127.0.0.1:8788
282
+ ```
283
+
284
+ `e2e_smoke` spawns `CARGO_BIN_EXE_compendium`, completes the MCP initialize handshake over stdio, lists tools, then calls gateway actions. `http_smoke` (requires `--features http`) exercises streamable HTTP in-process.
285
+
286
+ ## Design notes
287
+
288
+ - **Deterministic by default** — heuristic pipeline needs no network; smart actions only call a configured **local** OpenAI-compatible URL and fall back to heuristics when unset or failing.
289
+ - **Token backends** — fast heuristic by default; opt into exact BPE with `real-tokens`.
290
+ - **Zero stdout pollution** (stdio mode) — tracing goes to stderr so JSON-RPC framing stays clean.
291
+ - **Release profile** — LTO + stripped binary for low footprint.
292
+
293
+ ## License
294
+
295
+ MIT
package/bin/run.js ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * Compendium MCP dispatcher.
6
+ *
7
+ * Resolves the native binary and exec's it with inherited stdio so Cursor /
8
+ * Claude Desktop / `npx compendium-mcp` talk JSON-RPC over stdin/stdout.
9
+ *
10
+ * Resolution order:
11
+ * 1. COMPENDIUM_BINARY env
12
+ * 2. Dev build: <repo>/target/release|debug/compendium(.exe)
13
+ * 3. optionalDependency platform package (compendium-mcp-<platform>)
14
+ * 4. Cached GitHub Release download (~/.cache/compendium-mcp/<version>/)
15
+ */
16
+
17
+ const { spawn } = require('child_process');
18
+ const fs = require('fs');
19
+ const https = require('https');
20
+ const http = require('http');
21
+ const path = require('path');
22
+ const { pipeline } = require('stream/promises');
23
+ const { createWriteStream } = require('fs');
24
+
25
+ const {
26
+ packageVersion,
27
+ githubRepo,
28
+ currentPlatform,
29
+ binaryName,
30
+ cacheDir,
31
+ platformKey,
32
+ } = require('../npm/lib/platform');
33
+
34
+ function existsExecutable(file) {
35
+ try {
36
+ fs.accessSync(file, fs.constants.F_OK);
37
+ // On Windows, X_OK is unreliable; presence is enough.
38
+ if (process.platform !== 'win32') {
39
+ fs.accessSync(file, fs.constants.X_OK);
40
+ }
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ function tryRequirePlatformBinary() {
48
+ const spec = currentPlatform();
49
+ try {
50
+ // optionalDependency installs next to this package when available.
51
+ const pkgRoot = path.dirname(require.resolve(`${spec.pkg}/package.json`));
52
+ const candidate = path.join(pkgRoot, 'bin', binaryName(spec));
53
+ if (existsExecutable(candidate)) return candidate;
54
+ } catch {
55
+ // optional dep missing — fall through
56
+ }
57
+ return null;
58
+ }
59
+
60
+ function tryDevBinary() {
61
+ const repoRoot = path.resolve(__dirname, '..');
62
+ const name = process.platform === 'win32' ? 'compendium.exe' : 'compendium';
63
+ const release = path.join(repoRoot, 'target', 'release', name);
64
+ const debug = path.join(repoRoot, 'target', 'debug', name);
65
+ if (existsExecutable(release)) return release;
66
+ if (existsExecutable(debug)) return debug;
67
+ return null;
68
+ }
69
+
70
+ function download(url, dest) {
71
+ return new Promise((resolve, reject) => {
72
+ const client = url.startsWith('https:') ? https : http;
73
+ const req = client.get(
74
+ url,
75
+ {
76
+ headers: {
77
+ 'User-Agent': `compendium-mcp/${packageVersion()}`,
78
+ Accept: 'application/octet-stream',
79
+ },
80
+ },
81
+ (res) => {
82
+ // Follow one redirect hop (GitHub release assets).
83
+ if (
84
+ res.statusCode >= 300 &&
85
+ res.statusCode < 400 &&
86
+ res.headers.location
87
+ ) {
88
+ res.resume();
89
+ download(res.headers.location, dest).then(resolve, reject);
90
+ return;
91
+ }
92
+ if (res.statusCode !== 200) {
93
+ res.resume();
94
+ reject(
95
+ new Error(
96
+ `Download failed (${res.statusCode}) for ${url}. ` +
97
+ `Ensure release assets exist for ${platformKey()}.`
98
+ )
99
+ );
100
+ return;
101
+ }
102
+ const tmp = `${dest}.partial`;
103
+ const out = createWriteStream(tmp);
104
+ pipeline(res, out)
105
+ .then(() => {
106
+ fs.renameSync(tmp, dest);
107
+ if (process.platform !== 'win32') {
108
+ fs.chmodSync(dest, 0o755);
109
+ }
110
+ resolve(dest);
111
+ })
112
+ .catch((err) => {
113
+ try {
114
+ fs.unlinkSync(tmp);
115
+ } catch {
116
+ /* ignore */
117
+ }
118
+ reject(err);
119
+ });
120
+ }
121
+ );
122
+ req.on('error', reject);
123
+ });
124
+ }
125
+
126
+ async function ensureDownloadedBinary() {
127
+ const spec = currentPlatform();
128
+ const version = packageVersion();
129
+ const dir = cacheDir(version);
130
+ fs.mkdirSync(dir, { recursive: true });
131
+ const dest = path.join(dir, binaryName(spec));
132
+ if (existsExecutable(dest)) return dest;
133
+
134
+ const repo = githubRepo();
135
+ const tag = `v${version}`;
136
+ const url = `https://github.com/${repo}/releases/download/${tag}/${spec.asset}`;
137
+
138
+ process.stderr.write(
139
+ `[compendium-mcp] Downloading ${spec.asset} (${tag})…\n`
140
+ );
141
+ await download(url, dest);
142
+ process.stderr.write(`[compendium-mcp] Cached at ${dest}\n`);
143
+ return dest;
144
+ }
145
+
146
+ async function resolveBinary() {
147
+ if (process.env.COMPENDIUM_BINARY) {
148
+ const forced = path.resolve(process.env.COMPENDIUM_BINARY);
149
+ if (!existsExecutable(forced)) {
150
+ throw new Error(`COMPENDIUM_BINARY not executable: ${forced}`);
151
+ }
152
+ return forced;
153
+ }
154
+
155
+ // Prefer a local Cargo build when developing from this repo so `cargo build
156
+ // --release` is picked up immediately (optional platform packages can lag).
157
+ const fromDev = tryDevBinary();
158
+ if (fromDev) return fromDev;
159
+
160
+ const fromOptional = tryRequirePlatformBinary();
161
+ if (fromOptional) return fromOptional;
162
+
163
+ return ensureDownloadedBinary();
164
+ }
165
+
166
+ async function main() {
167
+ let binary;
168
+ try {
169
+ binary = await resolveBinary();
170
+ } catch (err) {
171
+ process.stderr.write(`[compendium-mcp] ${err.message}\n`);
172
+ process.exit(1);
173
+ }
174
+
175
+ process.stderr.write(`[compendium-mcp] using ${binary}\n`);
176
+
177
+ const child = spawn(binary, process.argv.slice(2), {
178
+ stdio: 'inherit',
179
+ windowsHide: true,
180
+ });
181
+
182
+ child.on('error', (err) => {
183
+ process.stderr.write(`[compendium-mcp] failed to spawn ${binary}: ${err.message}\n`);
184
+ process.exit(1);
185
+ });
186
+
187
+ const forward = (signal) => {
188
+ if (!child.killed) child.kill(signal);
189
+ };
190
+ process.on('SIGINT', () => forward('SIGINT'));
191
+ process.on('SIGTERM', () => forward('SIGTERM'));
192
+
193
+ child.on('exit', (code, signal) => {
194
+ if (signal) {
195
+ process.exit(signal === 'SIGINT' ? 130 : 1);
196
+ }
197
+ process.exit(code ?? 1);
198
+ });
199
+ }
200
+
201
+ main();
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Shared platform → package / release-asset mapping for Compendium npm distribution.
5
+ *
6
+ * Distribution strategy (hybrid):
7
+ * 1. Prefer optionalDependency platform packages (esbuild-style) — offline, fast.
8
+ * 2. Fall back to downloading the matching GitHub Release asset into a local cache.
9
+ * 3. Dev override: COMPENDIUM_BINARY or ./target/release/compendium.
10
+ */
11
+
12
+ const os = require('os');
13
+ const path = require('path');
14
+
15
+ /** @typedef {{ pkg: string, asset: string, rustTarget: string }} PlatformSpec */
16
+
17
+ /** @type {Record<string, PlatformSpec>} */
18
+ const PLATFORMS = {
19
+ 'darwin-arm64': {
20
+ pkg: 'compendium-mcp-darwin-arm64',
21
+ asset: 'compendium-darwin-arm64',
22
+ rustTarget: 'aarch64-apple-darwin',
23
+ },
24
+ 'darwin-x64': {
25
+ pkg: 'compendium-mcp-darwin-x64',
26
+ asset: 'compendium-darwin-x64',
27
+ rustTarget: 'x86_64-apple-darwin',
28
+ },
29
+ 'linux-x64': {
30
+ pkg: 'compendium-mcp-linux-x64',
31
+ asset: 'compendium-linux-x64',
32
+ rustTarget: 'x86_64-unknown-linux-gnu',
33
+ },
34
+ 'linux-arm64': {
35
+ pkg: 'compendium-mcp-linux-arm64',
36
+ asset: 'compendium-linux-arm64',
37
+ rustTarget: 'aarch64-unknown-linux-gnu',
38
+ },
39
+ 'win32-x64': {
40
+ pkg: 'compendium-mcp-win32-x64',
41
+ asset: 'compendium-win32-x64.exe',
42
+ rustTarget: 'x86_64-pc-windows-msvc',
43
+ },
44
+ };
45
+
46
+ function packageVersion() {
47
+ // Keep in sync with root package.json / Cargo.toml at publish time.
48
+ return require('../../package.json').version;
49
+ }
50
+
51
+ function githubRepo() {
52
+ return (
53
+ process.env.COMPENDIUM_GITHUB_REPO ||
54
+ process.env.GITHUB_REPOSITORY ||
55
+ 'hocestnonsatis/Compendium'
56
+ );
57
+ }
58
+
59
+ /**
60
+ * Normalize Node's process.platform + process.arch into our key.
61
+ * @returns {string}
62
+ */
63
+ function platformKey() {
64
+ const platform = process.platform;
65
+ let arch = process.arch;
66
+ // Rosetta / rare aliases
67
+ if (arch === 'ia32') arch = 'x64';
68
+ return `${platform}-${arch}`;
69
+ }
70
+
71
+ /**
72
+ * @returns {PlatformSpec}
73
+ */
74
+ function currentPlatform() {
75
+ const key = platformKey();
76
+ const spec = PLATFORMS[key];
77
+ if (!spec) {
78
+ const supported = Object.keys(PLATFORMS).join(', ');
79
+ throw new Error(
80
+ `Unsupported platform "${key}". Supported: ${supported}.\n` +
81
+ `Set COMPENDIUM_BINARY to a local build, or open an issue for this target.`
82
+ );
83
+ }
84
+ return spec;
85
+ }
86
+
87
+ /**
88
+ * Binary filename inside a platform package / cache.
89
+ * @param {PlatformSpec} [spec]
90
+ */
91
+ function binaryName(spec = currentPlatform()) {
92
+ return process.platform === 'win32' ? 'compendium.exe' : 'compendium';
93
+ }
94
+
95
+ /**
96
+ * Cache directory for lazily downloaded binaries.
97
+ * @param {string} version
98
+ */
99
+ function cacheDir(version = packageVersion()) {
100
+ const base =
101
+ process.env.COMPENDIUM_CACHE_DIR ||
102
+ process.env.XDG_CACHE_HOME ||
103
+ path.join(os.homedir(), '.cache');
104
+ return path.join(base, 'compendium-mcp', version);
105
+ }
106
+
107
+ module.exports = {
108
+ PLATFORMS,
109
+ packageVersion,
110
+ githubRepo,
111
+ platformKey,
112
+ currentPlatform,
113
+ binaryName,
114
+ cacheDir,
115
+ };
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "compendium-mcp",
3
+ "version": "0.1.0",
4
+ "description": "MCP server that compresses, summarizes, and filters context to minimize LLM token usage",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "llm",
10
+ "tokens",
11
+ "compression",
12
+ "cursor",
13
+ "claude"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/hocestnonsatis/Compendium.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/hocestnonsatis/Compendium/issues"
21
+ },
22
+ "homepage": "https://github.com/hocestnonsatis/Compendium#readme",
23
+ "engines": {
24
+ "node": ">=18"
25
+ },
26
+ "bin": {
27
+ "compendium": "bin/run.js"
28
+ },
29
+ "files": [
30
+ "bin/",
31
+ "npm/lib/",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "scripts": {
36
+ "prepack": "node npm/scripts/check-wrapper.js"
37
+ },
38
+ "optionalDependencies": {
39
+ "compendium-mcp-darwin-arm64": "0.1.0",
40
+ "compendium-mcp-darwin-x64": "0.1.0",
41
+ "compendium-mcp-linux-x64": "0.1.0",
42
+ "compendium-mcp-linux-arm64": "0.1.0",
43
+ "compendium-mcp-win32-x64": "0.1.0"
44
+ },
45
+ "preferUnplugged": true
46
+ }