mcp-context-optimizer 0.1.7 → 0.1.9
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 +163 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/cli.d.ts +10 -0
- package/dist/mcp/cli.d.ts.map +1 -1
- package/dist/mcp/cli.js +141 -6
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/server.d.ts +5 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +65 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/store.d.ts +22 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +62 -0
- package/dist/store.js.map +1 -1
- package/dist/token-presets.d.ts +25 -0
- package/dist/token-presets.d.ts.map +1 -0
- package/dist/token-presets.js +33 -0
- package/dist/token-presets.js.map +1 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# mcp-context-optimizer
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
and an MCP server. No cloud services, no AI models, no API keys, no telemetry.
|
|
3
|
+
Keep critical context within token limits for AI coding agents — without losing errors, decisions, or file references.
|
|
5
4
|
|
|
6
5
|
`mcp-context-optimizer` takes the raw exhaust of a coding session (conversation
|
|
7
6
|
messages, tool outputs, errors, stack traces, file snapshots, git diffs, test
|
|
@@ -66,6 +65,87 @@ console.log(result.stats); // estimated input/output tokens + reduction rati
|
|
|
66
65
|
|
|
67
66
|
Identical inputs and configuration always produce byte-identical outputs.
|
|
68
67
|
|
|
68
|
+
## Quick start (CLI, no MCP client needed)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# Build a compact context from a records file
|
|
72
|
+
npx mcp-context-optimizer build --task "Fix auth" --records session.json
|
|
73
|
+
|
|
74
|
+
# Pipe records from stdin
|
|
75
|
+
cat session.json | npx mcp-context-optimizer build --task "Fix auth" --stdin
|
|
76
|
+
|
|
77
|
+
# Write the result to a file
|
|
78
|
+
npx mcp-context-optimizer build --task "Fix auth" --records session.json --output context.txt
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Before / after
|
|
82
|
+
|
|
83
|
+
A typical debugging session is full of repeated tool outputs, chit-chat, and
|
|
84
|
+
stale context. Here is what happens with a realistic session:
|
|
85
|
+
|
|
86
|
+
**Before** — raw session dump (4992 tokens, over budget):
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
# Task: Stop the duplicate-charge bug in src/billing/charge.ts
|
|
90
|
+
|
|
91
|
+
message #1 (user): Customers get charged twice when retrying; the duplicate
|
|
92
|
+
originates in src/billing/charge.ts
|
|
93
|
+
message #2 (assistant): Chattering about hypothesis 0: maybe the cache, maybe
|
|
94
|
+
the clock, maybe the moon phase. Let us look at more logs.
|
|
95
|
+
... (40 lines of chattering)
|
|
96
|
+
message #42 (assistant): Chattering about hypothesis 39: maybe the cache...
|
|
97
|
+
tool_call #43: npm test -- billing
|
|
98
|
+
RUN v2.1.0
|
|
99
|
+
❯ src/billing/charge.test.ts (1 test)
|
|
100
|
+
× duplicate charge
|
|
101
|
+
→ DuplicateKeyError: duplicate key value violates unique constraint
|
|
102
|
+
Test Files 1 failed (1)
|
|
103
|
+
... (8 identical copies of the same test output)
|
|
104
|
+
error #52: DuplicateKeyError: duplicate key value violates unique constraint
|
|
105
|
+
at chargeOnce (src/billing/charge.ts:88:11)
|
|
106
|
+
decision #53: Idempotency keys must be generated per logical order, not per
|
|
107
|
+
retry attempt
|
|
108
|
+
file #54: src/billing/charge.ts
|
|
109
|
+
export async function chargeOnce(order, retry) {
|
|
110
|
+
const key = `ord-${order.id}-retry-${retry.attempt}`;
|
|
111
|
+
return stripe.charges.create({ amount: order.total, idempotencyKey: key });
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**After** — optimized context (328 tokens, 93% reduction, all required facts retained):
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
# Task
|
|
119
|
+
|
|
120
|
+
Stop the duplicate-charge bug in src/billing/charge.ts
|
|
121
|
+
|
|
122
|
+
## Errors
|
|
123
|
+
- [error] DuplicateKeyError: duplicate key value violates unique constraint
|
|
124
|
+
"charges_idempotency_key_key"
|
|
125
|
+
src/billing/charge.ts:88:11 [source: fr_a1b2c3 | record r52]
|
|
126
|
+
|
|
127
|
+
## Decisions
|
|
128
|
+
- [decision] Idempotency keys must be generated per logical order, not per retry
|
|
129
|
+
attempt [source: fr_d4e5f6 | record r53]
|
|
130
|
+
|
|
131
|
+
## Files
|
|
132
|
+
- [file] src/billing/charge.ts
|
|
133
|
+
export async function chargeOnce(order, retry) {
|
|
134
|
+
const key = `ord-${order.id}-retry-${retry.attempt}`;
|
|
135
|
+
return stripe.charges.create({ amount: order.total, idempotencyKey: key });
|
|
136
|
+
} [source: fr_g7h8i9 | record r54]
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
**What was dropped:** 40 lines of chattering, 7 duplicate test runs, noise notes.
|
|
140
|
+
**What was kept:** the error, the accepted decision, the relevant file — all with
|
|
141
|
+
source references so you can trace every line back to its origin.
|
|
142
|
+
|
|
143
|
+
Run the benchmark yourself:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
npm run bench
|
|
147
|
+
```
|
|
148
|
+
|
|
69
149
|
## How it works: the pipeline
|
|
70
150
|
|
|
71
151
|
Each stage is a separate, unit-tested, pure function:
|
|
@@ -140,9 +220,29 @@ MCP tool availability does **not** automatically intercept or rewrite model
|
|
|
140
220
|
requests. A compatible client must explicitly call these tools (e.g. the agent
|
|
141
221
|
decides to call `build_context` before answering a task). Automatic context
|
|
142
222
|
replacement would require a native integration inside the coding agent
|
|
143
|
-
(hooking its prompt assembly).
|
|
144
|
-
|
|
145
|
-
|
|
223
|
+
(hooking its prompt assembly).
|
|
224
|
+
|
|
225
|
+
### Persistence (opt-in)
|
|
226
|
+
|
|
227
|
+
By default the store is **in-memory per process lifetime** — restarting the
|
|
228
|
+
server starts from an empty store. To keep records across restarts, pass
|
|
229
|
+
`--persist <path>` to the CLI or set `persistPath` in `McpAdapterOptions`:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
mcp-ctx-optimizer --persist ~/.cache/mcp-context-optimizer/context.json
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
import { createContextOptimizerServer } from 'mcp-context-optimizer/mcp';
|
|
237
|
+
|
|
238
|
+
const server = createContextOptimizerServer({
|
|
239
|
+
persistPath: './context-store.json',
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Records are written to a local JSON file; no network access is used. The file
|
|
244
|
+
stays on the local machine. Implement the `ContextStore` interface for custom
|
|
245
|
+
backends (e.g. SQLite).
|
|
146
246
|
|
|
147
247
|
## Privacy & local operation
|
|
148
248
|
|
|
@@ -168,6 +268,30 @@ const optimizer = new ContextOptimizer({
|
|
|
168
268
|
});
|
|
169
269
|
```
|
|
170
270
|
|
|
271
|
+
### Built-in tokenizer presets
|
|
272
|
+
|
|
273
|
+
For convenience, the SDK ships with presets tuned for popular model families:
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { ContextOptimizer, claudeEstimator, gpt4Estimator } from 'mcp-context-optimizer';
|
|
277
|
+
|
|
278
|
+
const optimizer = new ContextOptimizer({
|
|
279
|
+
tokenBudget: 12_000,
|
|
280
|
+
tokenEstimator: claudeEstimator, // ~3 chars/token, tuned for Claude
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
// Or look up a preset by name:
|
|
284
|
+
import { getPreset } from 'mcp-context-optimizer';
|
|
285
|
+
const est = getPreset('claude-3');
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
| Preset | Heuristic | Best for |
|
|
289
|
+
| ------------ | --------------- | -------------------------------- |
|
|
290
|
+
| `default` | `ceil(chars / 4)` | Default; good for prose-heavy |
|
|
291
|
+
| `claude-3` | `ceil(chars / 3)` | Claude code/context; denser tokens |
|
|
292
|
+
| `gpt-4` | `ceil(chars / 4)` | GPT-4 family |
|
|
293
|
+
| `mistral` | `ceil(chars / 4)` | Mistral family |
|
|
294
|
+
|
|
171
295
|
## Benchmarks
|
|
172
296
|
|
|
173
297
|
A reproducible benchmark suite compares three strategies across 9 coding-session
|
|
@@ -363,6 +487,37 @@ Add to `~/.continue/config.json`:
|
|
|
363
487
|
}
|
|
364
488
|
```
|
|
365
489
|
|
|
490
|
+
## MCP registries
|
|
491
|
+
|
|
492
|
+
The package is listed in MCP registries for one-click installation:
|
|
493
|
+
|
|
494
|
+
| Registry | How to add |
|
|
495
|
+
|---|---|
|
|
496
|
+
| **Smithery** | See [`smithery.yaml`](smithery.yaml). The server is configured with `--persist` so records survive restarts. |
|
|
497
|
+
| **Glama** | Add server via Glama dashboard: command `npx mcp-ctx-optimizer`, transport `stdio`. |
|
|
498
|
+
| **MCP.so** | Add server via MCP.so dashboard: command `npx mcp-ctx-optimizer`, transport `stdio`. |
|
|
499
|
+
|
|
500
|
+
**Smithery example** — add to your Smithery client config:
|
|
501
|
+
|
|
502
|
+
```json
|
|
503
|
+
{
|
|
504
|
+
"mcpServers": {
|
|
505
|
+
"context-optimizer": {
|
|
506
|
+
"command": "npx",
|
|
507
|
+
"args": [
|
|
508
|
+
"mcp-ctx-optimizer",
|
|
509
|
+
"--persist",
|
|
510
|
+
"~/.cache/mcp-context-optimizer/context.json"
|
|
511
|
+
]
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
**Claude Code hooks** — see [`claude-code-hooks.json`](claude-code-hooks.json). Register it in Claude Code settings to automatically call `build_context` on every user prompt (reduces the explicit-invocation friction).
|
|
518
|
+
|
|
519
|
+
**Claude Desktop** — see [`claude-desktop-config.json`](claude-desktop-config.json). Add to your Claude Desktop `claude_desktop_config.json`.
|
|
520
|
+
|
|
366
521
|
**Important:** MCP tool availability does not automatically intercept model
|
|
367
522
|
requests. The client/agent must explicitly call these tools (e.g. call
|
|
368
523
|
`build_context` before answering). Automatic context replacement requires a
|
|
@@ -370,5 +525,7 @@ native integration inside the coding agent.
|
|
|
370
525
|
|
|
371
526
|
The MCP server stores data **in memory per process lifetime** — restarting the
|
|
372
527
|
server starts from an empty store. Re-ingest records or implement your own
|
|
373
|
-
`ContextStore` (see `src/store.ts`) for persistence.
|
|
528
|
+
`ContextStore` (see `src/store.ts`) for persistence. Use `--persist` for
|
|
529
|
+
built-in file persistence.
|
|
530
|
+
|
|
374
531
|
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { ContextOptimizer, PIPELINE_VERSION } from './optimizer.js';
|
|
8
8
|
export { defaultTokenEstimator, createTokenEstimator, sha256, shortHash, } from './tokens.js';
|
|
9
|
+
export { claudeEstimator, gpt4Estimator, mistralEstimator, TOKENIZER_PRESETS, getPreset, } from './token-presets.js';
|
|
9
10
|
export { DEFAULT_WEIGHTS, DECISION_RECENCY_FLOOR, tokenize, scoreStage } from './score.js';
|
|
10
11
|
export { renderContext, sourceTag, type RenderOptions } from './render.js';
|
|
11
12
|
export { selectStage, fragmentCost, truncateText } from './select.js';
|
|
@@ -13,7 +14,7 @@ export { compactStage, compactFragment, compactCode, compactStackTrace, compactT
|
|
|
13
14
|
export { dedupeStage, containmentSimilarity } from './dedupe.js';
|
|
14
15
|
export { extractStage, extractSignals, extractPaths, extractSymbols, extractStackFrames, extractRequirements, } from './extract.js';
|
|
15
16
|
export { normalizeStage, collectRecords, recordToFragment, normalizeText, collapseRepeatedLines, stableStringify, validateRecord, } from './normalize.js';
|
|
16
|
-
export { InMemoryContextStore, filterByFile, filterDecisions, filterErrors } from './store.js';
|
|
17
|
+
export { InMemoryContextStore, FileContextStore, filterByFile, filterDecisions, filterErrors } from './store.js';
|
|
17
18
|
export type { ContextStore } from './store.js';
|
|
18
19
|
export type { BuildContextInput, BudgetConflict, BudgetSummary, DecisionRecord, DecisionStatus, DiffRecord, ErrorRecord, ExtractedError, ExtractedPath, ExtractedRequirement, ExtractedSignals, ExtractedSymbol, FileRecord, FileState, Fragment, FragmentMeta, InputRecord, MessageRecord, MessageRole, MergeReason, NoteRecord, OmittedFragment, OmissionReason, OptimizerOptions, OptimizedContext, OptimizationReport, OutcomeInfo, Provenance, RecordBase, RecordKind, RelevanceScore, ScoringWeights, ScoreComponent, SelectedFragment, SelectionReason, SourceRef, TestFailure, TestResultRecord, TokenEstimator, ToolCallRecord, Warning, WarningCode, } from './types.js';
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,EACN,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACtM,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,EACN,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACtM,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACjH,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,YAAY,EACV,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,UAAU,EACV,UAAU,EACV,UAAU,EACV,cAAc,EACd,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,OAAO,EACP,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { ContextOptimizer, PIPELINE_VERSION } from './optimizer.js';
|
|
8
8
|
export { defaultTokenEstimator, createTokenEstimator, sha256, shortHash, } from './tokens.js';
|
|
9
|
+
export { claudeEstimator, gpt4Estimator, mistralEstimator, TOKENIZER_PRESETS, getPreset, } from './token-presets.js';
|
|
9
10
|
export { DEFAULT_WEIGHTS, DECISION_RECENCY_FLOOR, tokenize, scoreStage } from './score.js';
|
|
10
11
|
export { renderContext, sourceTag } from './render.js';
|
|
11
12
|
export { selectStage, fragmentCost, truncateText } from './select.js';
|
|
@@ -13,5 +14,5 @@ export { compactStage, compactFragment, compactCode, compactStackTrace, compactT
|
|
|
13
14
|
export { dedupeStage, containmentSimilarity } from './dedupe.js';
|
|
14
15
|
export { extractStage, extractSignals, extractPaths, extractSymbols, extractStackFrames, extractRequirements, } from './extract.js';
|
|
15
16
|
export { normalizeStage, collectRecords, recordToFragment, normalizeText, collapseRepeatedLines, stableStringify, validateRecord, } from './normalize.js';
|
|
16
|
-
export { InMemoryContextStore, filterByFile, filterDecisions, filterErrors } from './store.js';
|
|
17
|
+
export { InMemoryContextStore, FileContextStore, filterByFile, filterDecisions, filterErrors } from './store.js';
|
|
17
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,EACN,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,uBAAuB,EAA2C,MAAM,cAAc,CAAC;AACtM,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,EACN,SAAS,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,SAAS,GACV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC3F,OAAO,EAAE,aAAa,EAAE,SAAS,EAAsB,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,uBAAuB,EAA2C,MAAM,cAAc,CAAC;AACtM,OAAO,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,YAAY,EACZ,cAAc,EACd,YAAY,EACZ,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,qBAAqB,EACrB,eAAe,EACf,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/mcp/cli.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI entry for the mcp-context-optimizer.
|
|
4
|
+
*
|
|
5
|
+
* MCP server mode (default):
|
|
6
|
+
* mcp-ctx-optimizer [--persist <path>]
|
|
7
|
+
*
|
|
8
|
+
* Standalone build mode:
|
|
9
|
+
* mcp-ctx-optimizer build --task "Fix auth" --records session.json
|
|
10
|
+
* cat session.json | mcp-ctx-optimizer build --task "Fix auth" --stdin
|
|
11
|
+
*/
|
|
2
12
|
export {};
|
|
3
13
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/mcp/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}
|
package/dist/mcp/cli.js
CHANGED
|
@@ -1,12 +1,147 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* CLI entry for the mcp-context-optimizer
|
|
3
|
+
* CLI entry for the mcp-context-optimizer.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* MCP server mode (default):
|
|
6
|
+
* mcp-ctx-optimizer [--persist <path>]
|
|
7
|
+
*
|
|
8
|
+
* Standalone build mode:
|
|
9
|
+
* mcp-ctx-optimizer build --task "Fix auth" --records session.json
|
|
10
|
+
* cat session.json | mcp-ctx-optimizer build --task "Fix auth" --stdin
|
|
9
11
|
*/
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
13
|
import { startContextOptimizerStdio } from './server.js';
|
|
11
|
-
|
|
14
|
+
import { ContextOptimizer } from '../optimizer.js';
|
|
15
|
+
function printHelp() {
|
|
16
|
+
console.error(`mcp-context-optimizer CLI
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
mcp-ctx-optimizer [--persist <path>] Start MCP server over stdio
|
|
20
|
+
mcp-ctx-optimizer build [options] Build compact context for a task
|
|
21
|
+
|
|
22
|
+
build options:
|
|
23
|
+
--task <text> Task description (required)
|
|
24
|
+
--records <file> JSON file with records array
|
|
25
|
+
--stdin Read records JSON from stdin
|
|
26
|
+
--token-budget <n> Token budget (default 12000)
|
|
27
|
+
--query <text> Additional relevance query
|
|
28
|
+
--output <file> Write context to file (default: stdout)
|
|
29
|
+
|
|
30
|
+
Examples:
|
|
31
|
+
mcp-ctx-optimizer build --task "Fix auth" --records session.json
|
|
32
|
+
cat session.json | mcp-ctx-optimizer build --task "Fix auth" --stdin
|
|
33
|
+
`);
|
|
34
|
+
}
|
|
35
|
+
function parseBuildArgs(argv) {
|
|
36
|
+
const args = {};
|
|
37
|
+
for (let i = 0; i < argv.length; i++) {
|
|
38
|
+
const arg = argv[i];
|
|
39
|
+
if (arg === '--task')
|
|
40
|
+
args.task = argv[++i];
|
|
41
|
+
else if (arg === '--records')
|
|
42
|
+
args.records = argv[++i];
|
|
43
|
+
else if (arg === '--stdin')
|
|
44
|
+
args.stdin = true;
|
|
45
|
+
else if (arg === '--token-budget')
|
|
46
|
+
args.tokenBudget = argv[++i];
|
|
47
|
+
else if (arg === '--query')
|
|
48
|
+
args.query = argv[++i];
|
|
49
|
+
else if (arg === '--output')
|
|
50
|
+
args.output = argv[++i];
|
|
51
|
+
else if (arg === '--help' || arg === '-h')
|
|
52
|
+
args.task = 'help';
|
|
53
|
+
}
|
|
54
|
+
return args;
|
|
55
|
+
}
|
|
56
|
+
async function readRecordsFromStdin() {
|
|
57
|
+
const chunks = [];
|
|
58
|
+
for await (const chunk of process.stdin)
|
|
59
|
+
chunks.push(chunk);
|
|
60
|
+
const raw = Buffer.concat(chunks).toString('utf8');
|
|
61
|
+
const parsed = JSON.parse(raw);
|
|
62
|
+
return Array.isArray(parsed) ? parsed : parsed.records ?? [];
|
|
63
|
+
}
|
|
64
|
+
async function runBuild(args) {
|
|
65
|
+
if (args.task === 'help') {
|
|
66
|
+
printHelp();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (!args.task) {
|
|
70
|
+
console.error('Error: --task is required');
|
|
71
|
+
printHelp();
|
|
72
|
+
process.exitCode = 1;
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Load records
|
|
76
|
+
let records = [];
|
|
77
|
+
if (args.records) {
|
|
78
|
+
if (!existsSync(args.records)) {
|
|
79
|
+
console.error(`Error: records file not found: ${args.records}`);
|
|
80
|
+
process.exitCode = 1;
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
const raw = JSON.parse(readFileSync(args.records, 'utf8'));
|
|
85
|
+
records = Array.isArray(raw) ? raw : raw.records ?? [];
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
console.error(`Error: failed to parse records file: ${err.message}`);
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else if (args.stdin) {
|
|
94
|
+
try {
|
|
95
|
+
records = await readRecordsFromStdin();
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.error(`Error: failed to parse stdin: ${err.message}`);
|
|
99
|
+
process.exitCode = 1;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const optimizer = new ContextOptimizer({
|
|
104
|
+
tokenBudget: args.tokenBudget ? Number(args.tokenBudget) : undefined,
|
|
105
|
+
});
|
|
106
|
+
const result = optimizer.buildContextSync({
|
|
107
|
+
task: args.task,
|
|
108
|
+
records,
|
|
109
|
+
...(args.query ? { query: args.query } : {}),
|
|
110
|
+
...(args.tokenBudget ? { tokenBudget: Number(args.tokenBudget) } : {}),
|
|
111
|
+
});
|
|
112
|
+
// Output
|
|
113
|
+
if (args.output) {
|
|
114
|
+
writeFileSync(args.output, result.context, 'utf8');
|
|
115
|
+
console.error(`Context written to ${args.output}`);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
process.stdout.write(result.context);
|
|
119
|
+
}
|
|
120
|
+
process.stderr.write(`[mcp-context-optimizer] ${result.stats.estimatedInputTokens} -> ${result.stats.estimatedOutputTokens} tokens (${(result.stats.reductionRatio * 100).toFixed(0)}% reduction)\n`);
|
|
121
|
+
}
|
|
122
|
+
function parseMcpArgs(argv) {
|
|
123
|
+
const args = {};
|
|
124
|
+
for (let i = 0; i < argv.length; i++) {
|
|
125
|
+
const arg = argv[i];
|
|
126
|
+
if (arg === '--persist')
|
|
127
|
+
args.persist = argv[++i];
|
|
128
|
+
}
|
|
129
|
+
return args;
|
|
130
|
+
}
|
|
131
|
+
function main() {
|
|
132
|
+
const rawArgs = process.argv.slice(2);
|
|
133
|
+
if (rawArgs.length > 0 && rawArgs[0] === 'build') {
|
|
134
|
+
const buildArgs = parseBuildArgs(rawArgs.slice(1));
|
|
135
|
+
runBuild(buildArgs).catch((err) => {
|
|
136
|
+
console.error(err);
|
|
137
|
+
process.exitCode = 1;
|
|
138
|
+
});
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const mcpArgs = parseMcpArgs(rawArgs);
|
|
142
|
+
startContextOptimizerStdio({
|
|
143
|
+
...(mcpArgs.persist ? { persistPath: mcpArgs.persist } : {}),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
main();
|
|
12
147
|
//# sourceMappingURL=cli.js.map
|
package/dist/mcp/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":";AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/mcp/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ export declare const SERVER_INSTRUCTIONS = "Deterministic, local-first context o
|
|
|
6
6
|
export interface McpAdapterOptions {
|
|
7
7
|
/** Store backing the server. Defaults to a fresh in-memory store. */
|
|
8
8
|
store?: ContextStore;
|
|
9
|
+
/**
|
|
10
|
+
* When set, records are persisted to this local JSON file and restored on
|
|
11
|
+
* restart. The file stays on the local machine; no network access is used.
|
|
12
|
+
*/
|
|
13
|
+
persistPath?: string;
|
|
9
14
|
/** Optimizer configuration (token budget, weights, ...). */
|
|
10
15
|
optimizer?: OptimizerOptions;
|
|
11
16
|
serverInfo?: {
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAOzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAA+B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAyBjF,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,yOAEgE,CAAC;AAEjG,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAOD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,iBAAsB,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAOzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAA+B,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAyBjF,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,yOAEgE,CAAC;AAEjG,MAAM,WAAW,iBAAiB;IAChC,qEAAqE;IACrE,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,UAAU,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAOD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,iBAAsB,GAAG,SAAS,CAqQvF;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,iBAAsB,GAAG,IAAI,CAKhF"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -3,7 +3,7 @@ import { serveStdio } from '@modelcontextprotocol/server/stdio';
|
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
import { ContextOptimizer } from '../optimizer.js';
|
|
5
5
|
import { validateRecord } from '../normalize.js';
|
|
6
|
-
import { InMemoryContextStore, filterByFile, filterDecisions, filterErrors } from '../store.js';
|
|
6
|
+
import { FileContextStore, InMemoryContextStore, filterByFile, filterDecisions, filterErrors } from '../store.js';
|
|
7
7
|
/**
|
|
8
8
|
* MCP adapter exposing the mcp-context-optimizer core over the Model Context
|
|
9
9
|
* Protocol. Optional: the core SDK never imports this module; only clients
|
|
@@ -39,7 +39,7 @@ function jsonResult(data) {
|
|
|
39
39
|
* wires one (use {@link startContextOptimizerStdio} for stdio).
|
|
40
40
|
*/
|
|
41
41
|
export function createContextOptimizerServer(options = {}) {
|
|
42
|
-
const store = options.store ?? new InMemoryContextStore();
|
|
42
|
+
const store = options.store ?? (options.persistPath ? new FileContextStore(options.persistPath) : new InMemoryContextStore());
|
|
43
43
|
const optimizer = new ContextOptimizer(options.optimizer ?? {});
|
|
44
44
|
const server = new McpServer({
|
|
45
45
|
name: options.serverInfo?.name ?? 'mcp-context-optimizer',
|
|
@@ -186,6 +186,69 @@ export function createContextOptimizerServer(options = {}) {
|
|
|
186
186
|
report: result.report,
|
|
187
187
|
});
|
|
188
188
|
});
|
|
189
|
+
// MCP prompts: discoverable via prompts/list and invocable as slash commands.
|
|
190
|
+
server.registerPrompt('optimize-context', {
|
|
191
|
+
title: 'Optimize Context',
|
|
192
|
+
description: 'Build a compact, task-specific context from stored records. Use before answering a task to keep only relevant facts within the token budget.',
|
|
193
|
+
argsSchema: z.object({
|
|
194
|
+
task: z.string().min(1).describe('The current task description.'),
|
|
195
|
+
query: z.string().optional().describe('Additional relevance terms.'),
|
|
196
|
+
tokenBudget: z.number().int().min(1).optional().describe('Override the server token budget.'),
|
|
197
|
+
}),
|
|
198
|
+
}, async ({ task, query, tokenBudget }) => {
|
|
199
|
+
const all = store.all();
|
|
200
|
+
const result = optimizer.buildContextSync({
|
|
201
|
+
task,
|
|
202
|
+
...(query ? { query } : {}),
|
|
203
|
+
records: all,
|
|
204
|
+
...(tokenBudget ? { tokenBudget } : {}),
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
messages: [
|
|
208
|
+
{
|
|
209
|
+
role: 'user',
|
|
210
|
+
content: {
|
|
211
|
+
type: 'text',
|
|
212
|
+
text: `${result.context}\n\n[Optimization report: ${result.stats.estimatedInputTokens} -> ${result.stats.estimatedOutputTokens} tokens, ${(result.stats.reductionRatio * 100).toFixed(0)}% reduction. ${result.sources.length} sources retained, ${result.omitted.length} omitted.]`,
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
server.registerPrompt('summarize-errors', {
|
|
219
|
+
title: 'Summarize Errors',
|
|
220
|
+
description: 'Retrieve recorded errors and failed attempts, optionally ranked by a query. Use when debugging to see what has failed so far.',
|
|
221
|
+
argsSchema: z.object({
|
|
222
|
+
query: z.string().optional().describe('Optional relevance query; omit for all errors.'),
|
|
223
|
+
}),
|
|
224
|
+
}, async ({ query }) => {
|
|
225
|
+
const errors = store.getErrors ? store.getErrors() : filterErrors(store.all());
|
|
226
|
+
if (!query || errors.length === 0) {
|
|
227
|
+
return {
|
|
228
|
+
messages: [
|
|
229
|
+
{
|
|
230
|
+
role: 'user',
|
|
231
|
+
content: {
|
|
232
|
+
type: 'text',
|
|
233
|
+
text: `${errors.length} error(s) recorded.\n\n${errors.map((e) => `- [${e.kind}] ${'message' in e ? e.message : JSON.stringify(e).slice(0, 200)}`).join('\n')}`,
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
const hits = optimizer.search({ query, records: errors });
|
|
240
|
+
return {
|
|
241
|
+
messages: [
|
|
242
|
+
{
|
|
243
|
+
role: 'user',
|
|
244
|
+
content: {
|
|
245
|
+
type: 'text',
|
|
246
|
+
text: `${hits.length} relevant error(s) for "${query}":\n\n${hits.map((h) => `- ${h.fragment.text}`).join('\n\n')}`,
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
};
|
|
251
|
+
});
|
|
189
252
|
return server;
|
|
190
253
|
}
|
|
191
254
|
/**
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAChE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIlH;;;;;;;;GAQG;AAEH,MAAM,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QACX,SAAS;QACT,WAAW;QACX,OAAO;QACP,MAAM;QACN,MAAM;QACN,aAAa;QACb,UAAU;QACV,MAAM;KACP,CAAC;CACH,CAAC,CAAC;AAEH,yEAAyE;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG;;gGAE6D,CAAC;AAejG,2DAA2D;AAC3D,SAAS,UAAU,CAAC,IAAa;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,UAA6B,EAAE;IAC1E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IAC9H,MAAM,SAAS,GAAG,IAAI,gBAAgB,CAAC,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,OAAO,CAAC,UAAU,EAAE,IAAI,IAAI,uBAAuB;QACzD,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,IAAI,OAAO;KAChD,CAAC,CAAC;IAEH,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,8MAA8M;QAChN,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,YAAY,CAAC;iBACnB,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,4EAA4E,CAAC;SAC1F,CAAC;KACH,EACD,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;QACpB,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAA6C,EAAE,CAAC;QAC9D,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,GAA6B,CAAC,CAAC;YAC5D,IAAI,KAAK,EAAE,CAAC;gBACV,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,KAAK,CAAC,GAAG,CAAC,CAAC,GAA6B,CAAC,CAAC,CAAC;YAC3C,QAAQ,CAAC,IAAI,CAAE,GAAuB,CAAC,EAAE,IAAI,IAAI,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,OAAO,UAAU,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,WAAW,EACT,qKAAqK;QACvK,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6CAA6C,CAAC;YAChF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YACpG,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,YAAY,CAAC;iBACnB,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;SACjF,CAAC;KACH,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QAClC,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,CAAE,OAAoC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QACpF,OAAO,UAAU,CAAC;YAChB,KAAK;YACL,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACrB,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU;gBACjC,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,WAAW,EACT,8GAA8G;QAChH,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;KAC1B,EACD,KAAK,IAAI,EAAE;QACT,MAAM,SAAS,GAAqB,KAAK,CAAC,YAAY,EAAE,EAAE,IAAI,eAAe,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC3F,OAAO,UAAU,CAAC;YAChB,KAAK,EAAE,SAAS,CAAC,MAAM;YACvB,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;gBAChC,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,IAAI;gBAC9B,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,IAAI;aACjC,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,qBAAqB,EACrB;QACE,WAAW,EACT,sJAAsJ;QACxJ,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;YACvF,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;SACnD,CAAC;KACH,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,EAAE,EAAE,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAChE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,UAAU,CAAC;gBAChB,KAAK,EAAE,MAAM,CAAC,MAAM;gBACpB,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;aACnE,CAAC,CAAC;QACL,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC;YAC5B,KAAK;YACL,OAAO,EAAE,MAAM;YACf,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5B,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;YAChB,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvB,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE;gBACjB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU;gBACjC,KAAK,EAAE,CAAC,CAAC,KAAK;aACf,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,WAAW,EACT,4HAA4H;QAC9H,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;SACjF,CAAC;KACH,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACjB,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;QAC3E,OAAO,UAAU,CAAC;YAChB,IAAI;YACJ,KAAK,EAAE,OAAO,CAAC,MAAM;YACrB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;SACrE,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,eAAe,EACf;QACE,WAAW,EACT,mSAAmS;QACrS,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YACjE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;YAC7F,OAAO,EAAE,CAAC;iBACP,KAAK,CAAC,YAAY,CAAC;iBACnB,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;SACjF,CAAC;KACH,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE,EAAE;QAC9C,MAAM,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,EAAE,EAAE,GAAG,CAAE,OAAoC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC;YACxC,IAAI;YACJ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,GAAG;YACZ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,OAAO,UAAU,CAAC;YAChB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAClC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE;gBACjB,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ;gBAC7B,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI;gBACrB,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK;gBACzC,eAAe,EAAE,CAAC,CAAC,eAAe;gBAClC,KAAK,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,IAAI,IAAI;aAC5C,CAAC,CAAC;YACH,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,MAAM,EAAE,MAAM,CAAC,MAAM;SACtB,CAAC,CAAC;IACL,CAAC,CACF,CAAC;IAEF,8EAA8E;IAC9E,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,8IAA8I;QAChJ,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;YACnB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YACjE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,6BAA6B,CAAC;YACpE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;SAC9F,CAAC;KACH,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE;QACrC,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,SAAS,CAAC,gBAAgB,CAAC;YACxC,IAAI;YACJ,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,GAAG;YACZ,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,6BAA6B,MAAM,CAAC,KAAK,CAAC,oBAAoB,OAAO,MAAM,CAAC,KAAK,CAAC,qBAAqB,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,MAAM,CAAC,OAAO,CAAC,MAAM,sBAAsB,MAAM,CAAC,OAAO,CAAC,MAAM,YAAY;qBACrR;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,cAAc,CACnB,kBAAkB,EAClB;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,+HAA+H;QACjI,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC;YACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;SACxF,CAAC;KACH,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QAClB,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC/E,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,0BAA0B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;yBAChK;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAe;oBACrB,OAAO,EAAE;wBACP,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,2BAA2B,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;qBACpH;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,UAA6B,EAAE;IACxE,UAAU,CAAC,GAAG,EAAE,CAAC,4BAA4B,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,OAAO,CAAC,KAAK,CACX,0FAA0F,CAC3F,CAAC;AACJ,CAAC"}
|
package/dist/store.d.ts
CHANGED
|
@@ -41,4 +41,26 @@ export declare class InMemoryContextStore implements ContextStore {
|
|
|
41
41
|
/** Records associated with a file path (exact or suffix match). */
|
|
42
42
|
getByFile(path: string): InputRecord[];
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* File-backed context store. Records are written to a local JSON file on
|
|
46
|
+
* every `add()` and read back on construction. No network access, no
|
|
47
|
+
* telemetry — the file stays on the local machine.
|
|
48
|
+
*
|
|
49
|
+
* This is an opt-in persistence layer for the MCP server: pass a `persistPath`
|
|
50
|
+
* to keep records across server restarts. The default store remains
|
|
51
|
+
* in-memory only (see {@link InMemoryContextStore}).
|
|
52
|
+
*/
|
|
53
|
+
export declare class FileContextStore implements ContextStore {
|
|
54
|
+
private readonly filePath;
|
|
55
|
+
private readonly records;
|
|
56
|
+
constructor(filePath: string);
|
|
57
|
+
private load;
|
|
58
|
+
private flush;
|
|
59
|
+
add(records: InputRecord[]): void;
|
|
60
|
+
all(): InputRecord[];
|
|
61
|
+
clear(): void;
|
|
62
|
+
getDecisions(): DecisionRecord[];
|
|
63
|
+
getErrors(): InputRecord[];
|
|
64
|
+
getByFile(path: string): InputRecord[];
|
|
65
|
+
}
|
|
44
66
|
//# sourceMappingURL=store.d.ts.map
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAClC,6CAA6C;IAC7C,GAAG,IAAI,WAAW,EAAE,CAAC;IACrB,0BAA0B;IAC1B,KAAK,IAAI,IAAI,CAAC;IACd,oEAAoE;IACpE,YAAY,CAAC,IAAI,cAAc,EAAE,CAAC;IAClC,oFAAoF;IACpF,SAAS,CAAC,IAAI,WAAW,EAAE,CAAC;IAC5B,mFAAmF;IACnF,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAAC;CACzC;AAED,gFAAgF;AAChF,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,cAAc,EAAE,CAExE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAOlE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAiBhF;AAED;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,YAAY;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAE7C,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IAKjC,GAAG,IAAI,WAAW,EAAE;IAIpB,KAAK,IAAI,IAAI;IAIb,yDAAyD;IACzD,YAAY,IAAI,cAAc,EAAE;IAIhC,yDAAyD;IACzD,SAAS,IAAI,WAAW,EAAE;IAI1B,mEAAmE;IACnE,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE;CAGvC;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAE5B,QAAQ,EAAE,MAAM;IAK5B,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,KAAK;IASb,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,IAAI;IAMjC,GAAG,IAAI,WAAW,EAAE;IAIpB,KAAK,IAAI,IAAI;IAKb,YAAY,IAAI,cAAc,EAAE;IAIhC,SAAS,IAAI,WAAW,EAAE;IAI1B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE;CAGvC"}
|
package/dist/store.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
1
3
|
import { normalizeStage } from './normalize.js';
|
|
2
4
|
/** Filter helpers used when a store does not implement the optional queries. */
|
|
3
5
|
export function filterDecisions(records) {
|
|
@@ -56,4 +58,64 @@ export class InMemoryContextStore {
|
|
|
56
58
|
return filterByFile(this.records, path);
|
|
57
59
|
}
|
|
58
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* File-backed context store. Records are written to a local JSON file on
|
|
63
|
+
* every `add()` and read back on construction. No network access, no
|
|
64
|
+
* telemetry — the file stays on the local machine.
|
|
65
|
+
*
|
|
66
|
+
* This is an opt-in persistence layer for the MCP server: pass a `persistPath`
|
|
67
|
+
* to keep records across server restarts. The default store remains
|
|
68
|
+
* in-memory only (see {@link InMemoryContextStore}).
|
|
69
|
+
*/
|
|
70
|
+
export class FileContextStore {
|
|
71
|
+
filePath;
|
|
72
|
+
records;
|
|
73
|
+
constructor(filePath) {
|
|
74
|
+
this.filePath = resolve(filePath);
|
|
75
|
+
this.records = this.load();
|
|
76
|
+
}
|
|
77
|
+
load() {
|
|
78
|
+
try {
|
|
79
|
+
const raw = readFileSync(this.filePath, 'utf8');
|
|
80
|
+
const parsed = JSON.parse(raw);
|
|
81
|
+
if (!Array.isArray(parsed))
|
|
82
|
+
return [];
|
|
83
|
+
const { records } = normalizeStage(parsed);
|
|
84
|
+
return records;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
flush() {
|
|
91
|
+
try {
|
|
92
|
+
mkdirSync(dirname(this.filePath), { recursive: true });
|
|
93
|
+
writeFileSync(this.filePath, JSON.stringify(this.records, null, 2), 'utf8');
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Persistence is best-effort; never throw from the store.
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
add(records) {
|
|
100
|
+
const { records: valid } = normalizeStage(records);
|
|
101
|
+
this.records.push(...valid);
|
|
102
|
+
this.flush();
|
|
103
|
+
}
|
|
104
|
+
all() {
|
|
105
|
+
return [...this.records];
|
|
106
|
+
}
|
|
107
|
+
clear() {
|
|
108
|
+
this.records.length = 0;
|
|
109
|
+
this.flush();
|
|
110
|
+
}
|
|
111
|
+
getDecisions() {
|
|
112
|
+
return filterDecisions(this.records);
|
|
113
|
+
}
|
|
114
|
+
getErrors() {
|
|
115
|
+
return filterErrors(this.records);
|
|
116
|
+
}
|
|
117
|
+
getByFile(path) {
|
|
118
|
+
return filterByFile(this.records, path);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
59
121
|
//# sourceMappingURL=store.js.map
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional tokenizer presets for popular model families.
|
|
3
|
+
*
|
|
4
|
+
* These are heuristics tuned for common model tokenizers. For exact counts,
|
|
5
|
+
* plug in a real tokenizer (e.g. tiktoken) via {@link createTokenEstimator}.
|
|
6
|
+
*
|
|
7
|
+
* | Preset | Heuristic | Best for |
|
|
8
|
+
* | ---------- | --------------- | -------------------------------- |
|
|
9
|
+
* | chars/4 | ceil(chars / 4) | Default; good for prose-heavy |
|
|
10
|
+
* | claude-3 | ceil(chars / 3) | Claude code/context; denser tokens |
|
|
11
|
+
* | gpt-4 | ceil(chars / 4) | GPT-4; similar to default |
|
|
12
|
+
* | mistral | ceil(chars / 4) | Mistral; similar to default |
|
|
13
|
+
*/
|
|
14
|
+
import type { TokenEstimator } from './types.js';
|
|
15
|
+
/** Claude models produce denser tokens on code; ~3 chars/token. */
|
|
16
|
+
export declare const claudeEstimator: TokenEstimator;
|
|
17
|
+
/** GPT-4 family; ~4 chars/token, same as the built-in default. */
|
|
18
|
+
export declare const gpt4Estimator: TokenEstimator;
|
|
19
|
+
/** Mistral family; ~4 chars/token. */
|
|
20
|
+
export declare const mistralEstimator: TokenEstimator;
|
|
21
|
+
/** Registry of named presets. */
|
|
22
|
+
export declare const TOKENIZER_PRESETS: Record<string, TokenEstimator>;
|
|
23
|
+
/** Look up a preset by name; returns undefined if not found. */
|
|
24
|
+
export declare function getPreset(name: string): TokenEstimator | undefined;
|
|
25
|
+
//# sourceMappingURL=token-presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-presets.d.ts","sourceRoot":"","sources":["../src/token-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,mEAAmE;AACnE,eAAO,MAAM,eAAe,EAAE,cAG7B,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,aAAa,EAAE,cAG3B,CAAC;AAEF,sCAAsC;AACtC,eAAO,MAAM,gBAAgB,EAAE,cAG9B,CAAC;AAEF,iCAAiC;AACjC,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAM5D,CAAC;AAEF,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAElE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Optional tokenizer presets for popular model families.
|
|
3
|
+
*
|
|
4
|
+
* These are heuristics tuned for common model tokenizers. For exact counts,
|
|
5
|
+
* plug in a real tokenizer (e.g. tiktoken) via {@link createTokenEstimator}.
|
|
6
|
+
*
|
|
7
|
+
* | Preset | Heuristic | Best for |
|
|
8
|
+
* | ---------- | --------------- | -------------------------------- |
|
|
9
|
+
* | chars/4 | ceil(chars / 4) | Default; good for prose-heavy |
|
|
10
|
+
* | claude-3 | ceil(chars / 3) | Claude code/context; denser tokens |
|
|
11
|
+
* | gpt-4 | ceil(chars / 4) | GPT-4; similar to default |
|
|
12
|
+
* | mistral | ceil(chars / 4) | Mistral; similar to default |
|
|
13
|
+
*/
|
|
14
|
+
import { createTokenEstimator } from './tokens.js';
|
|
15
|
+
/** Claude models produce denser tokens on code; ~3 chars/token. */
|
|
16
|
+
export const claudeEstimator = createTokenEstimator('claude-3/chars-3', (text) => Math.ceil(text.length / 3));
|
|
17
|
+
/** GPT-4 family; ~4 chars/token, same as the built-in default. */
|
|
18
|
+
export const gpt4Estimator = createTokenEstimator('gpt-4/chars-4', (text) => Math.ceil(text.length / 4));
|
|
19
|
+
/** Mistral family; ~4 chars/token. */
|
|
20
|
+
export const mistralEstimator = createTokenEstimator('mistral/chars-4', (text) => Math.ceil(text.length / 4));
|
|
21
|
+
/** Registry of named presets. */
|
|
22
|
+
export const TOKENIZER_PRESETS = {
|
|
23
|
+
'claude-3': claudeEstimator,
|
|
24
|
+
'gpt-4': gpt4Estimator,
|
|
25
|
+
'gpt-4o': gpt4Estimator,
|
|
26
|
+
'mistral': mistralEstimator,
|
|
27
|
+
default: createTokenEstimator('chars/4', (text) => Math.ceil(text.length / 4)),
|
|
28
|
+
};
|
|
29
|
+
/** Look up a preset by name; returns undefined if not found. */
|
|
30
|
+
export function getPreset(name) {
|
|
31
|
+
return TOKENIZER_PRESETS[name];
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=token-presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-presets.js","sourceRoot":"","sources":["../src/token-presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGnD,mEAAmE;AACnE,MAAM,CAAC,MAAM,eAAe,GAAmB,oBAAoB,CACjE,kBAAkB,EAClB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CACrC,CAAC;AAEF,kEAAkE;AAClE,MAAM,CAAC,MAAM,aAAa,GAAmB,oBAAoB,CAC/D,eAAe,EACf,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CACrC,CAAC;AAEF,sCAAsC;AACtC,MAAM,CAAC,MAAM,gBAAgB,GAAmB,oBAAoB,CAClE,iBAAiB,EACjB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CACrC,CAAC;AAEF,iCAAiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAmC;IAC/D,UAAU,EAAE,eAAe;IAC3B,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,aAAa;IACvB,SAAS,EAAE,gBAAgB;IAC3B,OAAO,EAAE,oBAAoB,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;CAC/E,CAAC;AAEF,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-context-optimizer",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "Keep critical context within token limits for AI coding agents. Deterministic, local-first context optimization SDK and MCP server.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mcp",
|
|
7
7
|
"model-context-protocol",
|
|
8
8
|
"ai-agents",
|
|
9
9
|
"context-management",
|
|
10
10
|
"context-optimization",
|
|
11
|
+
"token-budget",
|
|
11
12
|
"llm",
|
|
12
13
|
"claude",
|
|
13
14
|
"cursor",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"bench": "tsx benchmarks/run.ts",
|
|
73
74
|
"bench:write": "tsx benchmarks/run.ts --write",
|
|
74
75
|
"mcp:start": "node dist/mcp/cli.js",
|
|
75
|
-
"prepublishOnly": "npm run typecheck && npm run build && npm run lint && npm test"
|
|
76
|
+
"prepublishOnly": "npm run typecheck && npm run build && npm run lint && npm run test"
|
|
76
77
|
},
|
|
77
78
|
"devDependencies": {
|
|
78
79
|
"@eslint/js": "^9.39.5",
|
|
@@ -88,4 +89,4 @@
|
|
|
88
89
|
"@modelcontextprotocol/server": "^2.3.1",
|
|
89
90
|
"zod": "^4.3.0"
|
|
90
91
|
}
|
|
91
|
-
}
|
|
92
|
+
}
|