mcp-context-optimizer
mcp-context-optimizer
Keep critical context within token limits for AI coding agents — without losing errors, decisions, or file references.
mcp-context-optimizer takes the raw exhaust of a coding session (conversation
messages, tool outputs, errors, stack traces, file snapshots, git diffs, test
results, recorded decisions) and produces a compact, task-specific context
that keeps the facts needed to solve the task — with full provenance for every
retained fragment and a reproducible report of what was kept, merged, and
omitted, and why.
It is not a truncation or summarization utility. The value comes from:
deterministic normalization and classification,
exact + conservative near-duplicate detection,
structured extraction (paths, symbols, stack frames, test failures, requirements),
explainable, weighted relevance scoring,
budget-aware selection that never silently drops mandatory facts,
evidence-preserving rendering with source references for every fragment.
Effectiveness is demonstrated by a reproducible benchmark suite (see Benchmarks) — not by claims.
Install
npm install mcp-context-optimizer # core SDK (zero runtime deps)
npm install @modelcontextprotocol/server zod # only for the MCP serverNode.js >= 20, ESM only.
The MCP adapter is optional: it lives behind the
mcp-context-optimizer/mcpexport and its dependencies are optional peer dependencies. The core SDK never imports the MCP SDK, never opens sockets, and never writes to disk.
Related MCP server: Smart Context MCP
Quick start (SDK)
import { ContextOptimizer } from 'mcp-context-optimizer';
const optimizer = new ContextOptimizer({ tokenBudget: 12_000 });
const result = await optimizer.buildContext({
task: 'Fix authentication after an access policy change',
messages: [
{ role: 'user', text: 'Login fails with 401 after the policy change in src/auth/policy.ts' },
],
files: [
{ path: 'src/auth/policy.ts', content: 'export function checkPolicy(user) { /* ... */ }' },
],
errors: [
{ message: 'Error: 401 Unauthorized\n at checkPolicy (src/auth/policy.ts:2:10)' },
],
decisions: [
{ text: 'Policy checks must stay server-side only', status: 'accepted' },
],
});
console.log(result.context); // rendered, compact context
console.log(result.sources); // selected fragments + provenance + score breakdowns
console.log(result.omitted); // dropped fragments + reasons
console.log(result.report); // reproducible machine-readable report
console.log(result.stats); // estimated input/output tokens + reduction ratioIdentical inputs and configuration always produce byte-identical outputs.
Quick start (CLI, no MCP client needed)
# Build a compact context from a records file
npx mcp-context-optimizer build --task "Fix auth" --records session.json
# Pipe records from stdin
cat session.json | npx mcp-context-optimizer build --task "Fix auth" --stdin
# Write the result to a file
npx mcp-context-optimizer build --task "Fix auth" --records session.json --output context.txtBefore / after
A typical debugging session is full of repeated tool outputs, chit-chat, and stale context. Here is what happens with a realistic session:
Before — raw session dump (4992 tokens, over budget):
# Task: Stop the duplicate-charge bug in src/billing/charge.ts
message #1 (user): Customers get charged twice when retrying; the duplicate
originates in src/billing/charge.ts
message #2 (assistant): Chattering about hypothesis 0: maybe the cache, maybe
the clock, maybe the moon phase. Let us look at more logs.
... (40 lines of chattering)
message #42 (assistant): Chattering about hypothesis 39: maybe the cache...
tool_call #43: npm test -- billing
RUN v2.1.0
❯ src/billing/charge.test.ts (1 test)
× duplicate charge
→ DuplicateKeyError: duplicate key value violates unique constraint
Test Files 1 failed (1)
... (8 identical copies of the same test output)
error #52: DuplicateKeyError: duplicate key value violates unique constraint
at chargeOnce (src/billing/charge.ts:88:11)
decision #53: Idempotency keys must be generated per logical order, not per
retry attempt
file #54: src/billing/charge.ts
export async function chargeOnce(order, retry) {
const key = `ord-${order.id}-retry-${retry.attempt}`;
return stripe.charges.create({ amount: order.total, idempotencyKey: key });
}After — optimized context (328 tokens, 93% reduction, all required facts retained):
# Task
Stop the duplicate-charge bug in src/billing/charge.ts
## Errors
- [error] DuplicateKeyError: duplicate key value violates unique constraint
"charges_idempotency_key_key"
src/billing/charge.ts:88:11 [source: fr_a1b2c3 | record r52]
## Decisions
- [decision] Idempotency keys must be generated per logical order, not per retry
attempt [source: fr_d4e5f6 | record r53]
## Files
- [file] src/billing/charge.ts
export async function chargeOnce(order, retry) {
const key = `ord-${order.id}-retry-${retry.attempt}`;
return stripe.charges.create({ amount: order.total, idempotencyKey: key });
} [source: fr_g7h8i9 | record r54]What was dropped: 40 lines of chattering, 7 duplicate test runs, noise notes. What was kept: the error, the accepted decision, the relevant file — all with source references so you can trace every line back to its origin.
Run the benchmark yourself:
npm run benchHow it works: the pipeline
Each stage is a separate, unit-tested, pure function:
Stage | Module | What it does |
1. Normalize & classify |
| Validates records, assigns deterministic ids, normalizes line endings, collapses pathological repeated log lines (never file contents/diffs), keeps original data untouched. |
2. Deduplicate |
| (a) exact duplicates via sha256; (b) repeated tool/test runs — keeps the latest run in full and preserves prior runs' exit codes/timestamps as a compact history line; (c) conservative near-duplicates via trigram containment (same kind only; files/diffs only same path; never on error-type similarity alone). Every merge is explained in the report. |
3. Structured extraction |
| File paths (unix + windows), code symbols (regex families per language, conservative), Node/Python stack frames, error signatures, test failures, explicit requirements ("must", "do not", ...), evidence-based outcomes (exit codes, markers). Never infers success from an attempt. |
4. Relevance scoring |
| Weighted, explainable scoring (see below). Recency uses the max timestamp in the data — never |
5. Budget-aware selection |
| Groups fragments by record (structured records are never split), includes mandatory fragments first, then fills remaining budget greedily by score/token density with deterministic tie-breaking. If mandatory content exceeds the budget, it is still included and the conflict is reported ( |
6. Render & report |
| Fixed-order sections; every fragment gets a |
Scoring weights (defaults, all configurable)
Signal | Weight | Meaning |
| 3 | IDF-weighted overlap between task/query tokens and fragment tokens. |
| 4 | Fragment mentions file paths/symbols that appear in the task (full path 1.0, basename 0.6, symbol 0.8). |
| 3 | Fragment is an error/failing test that matches the task identifiers. |
| 5 | Fragment states a requirement, constraint or accepted decision. |
| 2 | Fragment documents a failed attempt or unresolved problem. |
| 1.5 | Exponential decay, half-life 7 days; floored at 0.7 for constraints/decisions. |
| 1 | user/system 1.0 > assistant 0.6 > tool 0.4. |
| 2 | Negative: trigram containment against earlier-ranked fragments. |
| 1 | Explicit |
Every fragment's score.components exposes value, weight and contribution per
signal so selection is fully auditable.
MCP server (optional)
The adapter speaks the Model Context Protocol over stdio using the official
TypeScript SDK (@modelcontextprotocol/server v2). It exposes:
Tool | Purpose |
| Add structured records to the server's in-memory store. |
| Rank fragments for a query with score breakdowns and provenance. |
| Retrieve recorded technical decisions and constraints. |
| Retrieve errors, failed attempts, failing tests (optionally ranked). |
| Retrieve snapshots/diffs/errors associated with a file path. |
| Build a compact context under a token budget; returns context + sources + omissions + report. |
Client configuration
Claude Code:
claude mcp add mcp-context-optimizer -- node /absolute/path/to/mcp-context-optimizer/dist/mcp/cli.jsCursor / Claude Desktop / any MCP client (mcp.json):
{
"mcpServers": {
"mcp-context-optimizer": {
"command": "node",
"args": ["/absolute/path/to/mcp-context-optimizer/dist/mcp/cli.js"]
}
}
}During development, run it directly from source with npx tsx src/mcp/cli.ts,
or inspect it locally with npx @modelcontextprotocol/inspector node dist/mcp/cli.js.
Important limitation
MCP tool availability does not automatically intercept or rewrite model
requests. A compatible client must explicitly call these tools (e.g. the agent
decides to call build_context before answering a task). Automatic context
replacement would require a native integration inside the coding agent
(hooking its prompt assembly).
Persistence (opt-in)
By default the store is in-memory per process lifetime — restarting the
server starts from an empty store. To keep records across restarts, pass
--persist <path> to the CLI or set persistPath in McpAdapterOptions:
mcp-context-optimizer --persist ~/.cache/mcp-context-optimizer/context.jsonimport { createContextOptimizerServer } from 'mcp-context-optimizer/mcp';
const server = createContextOptimizerServer({
persistPath: './context-store.json',
});Records are written to a local JSON file; no network access is used. The file
stays on the local machine. Implement the ContextStore interface for custom
backends (e.g. SQLite).
Privacy & local operation
No network requests, ever. (Tested:
fetchis stubbed to throw in the test suite.)No API keys, no external AI models, no telemetry or analytics.
No source files are read or written; the SDK only sees data you pass in.
The default store is in-memory; implementing the
ContextStoreinterface is the explicit opt-in path if you want local persistence (e.g. a JSON file) — the SDK itself never writes to disk.
The default estimator is a character heuristic (ceil(chars / 4)). It is an
estimate: real tokenizers vary by a factor of 1.5–3× on code and unicode. The
report labels the estimator used (report.tokens.estimator) and emits a
TOKEN_ESTIMATE_ONLY warning. For exact counts, plug in your own tokenizer:
import { ContextOptimizer, createTokenEstimator } from 'mcp-context-optimizer';
const optimizer = new ContextOptimizer({
tokenBudget: 12_000,
tokenEstimator: createTokenEstimator('my-tok', (text) => myTokenizer.encode(text).length),
});Built-in tokenizer presets
For convenience, the SDK ships with presets tuned for popular model families:
import { ContextOptimizer, claudeEstimator, gpt4Estimator } from 'mcp-context-optimizer';
const optimizer = new ContextOptimizer({
tokenBudget: 12_000,
tokenEstimator: claudeEstimator, // ~3 chars/token, tuned for Claude
});
// Or look up a preset by name:
import { getPreset } from 'mcp-context-optimizer';
const est = getPreset('claude-3');Preset | Heuristic | Best for |
|
| Default; good for prose-heavy |
|
| Claude code/context; denser tokens |
|
| GPT-4 family |
|
| Mistral family |
Benchmarks
A reproducible benchmark suite compares three strategies across 9 coding-session scenarios:
Baseline A — original, unoptimized context (raw).
Baseline B — exact deduplication + head truncation to budget.
Candidate C —
ContextOptimizer(this package).
Metrics: context size reduction, required-fact retention, retrieval precision/recall, budget compliance, and source-attribution integrity. Latency and memory are machine-local measurements.
Running benchmarks
npm run bench # run all scenarios and print a comparison table
npm run bench -- --write # also write results to benchmarks/results/latest.jsonLatest results
scenario strategy tok-in tok-out reduct facts prec rec budget attrib ms
------------------------------------------------------------------------------------
repeated-tool-outputs A_raw 829 829 0% 100% 30% 100% ok - 0.0
repeated-tool-outputs B_dedupe_truncate 829 829 0% 100% 30% 100% ok - 0.0
repeated-tool-outputs C_optimizer 829 187 77% 100% 100% 100% ok 100% 1.3
long-debugging-session A_raw 4992 4992 0% 100% 5% 100% OVER - 0.0
long-debugging-session B_dedupe_truncate 4992 2481 50% 67% 5% 50% ok - 0.0
long-debugging-session C_optimizer 4992 328 93% 100% 80% 100% ok 100% 4.6
errors-and-stack-traces A_raw 300 300 0% 100% 60% 100% ok - 0.0
errors-and-stack-traces B_dedupe_truncate 300 300 0% 100% 60% 100% ok - 0.0
errors-and-stack-traces C_optimizer 300 295 2% 100% 60% 100% ok 100% 0.6
previous-failed-attempts A_raw 260 260 0% 100% 80% 100% ok - 0.0
previous-failed-attempts B_dedupe_truncate 260 260 0% 100% 80% 100% ok - 0.0
previous-failed-attempts C_optimizer 260 243 7% 100% 80% 100% ok 100% 0.7
decisions-and-constraints A_raw 306 306 0% 100% 50% 100% ok - 0.0
decisions-and-constraints B_dedupe_truncate 306 306 0% 100% 50% 100% ok - 0.0
decisions-and-constraints C_optimizer 306 250 18% 100% 60% 100% ok 100% 0.8
multi-file-dependencies A_raw 424 424 0% 100% 71% 100% ok - 0.0
multi-file-dependencies B_dedupe_truncate 424 424 0% 100% 71% 100% ok - 0.0
multi-file-dependencies C_optimizer 424 431 -2% 100% 71% 100% ok 100% 1.1
stale-information A_raw 248 248 0% 100% 40% 100% ok - 0.0
stale-information B_dedupe_truncate 248 248 0% 100% 40% 100% ok - 0.0
stale-information C_optimizer 248 197 21% 100% 50% 100% ok 100% 0.5
tight-budget A_raw 2089 2089 0% 100% 40% 100% OVER - 0.0
tight-budget B_dedupe_truncate 2089 98 95% 100% 100% 100% ok - 0.0
tight-budget C_optimizer 2089 159 92% 100% 50% 100% ok 100% 2.6
impossible-budget A_raw 79 79 0% 100% 50% 100% OVER - 0.0
impossible-budget B_dedupe_truncate 79 44 44% 100% 100% 100% ok - 0.0
impossible-budget C_optimizer 79 58 27% 100% 50% 100% ok 100% 0.1
=== Aggregate (Candidate C) ===
required facts fully retained in every scenario: YES
budget compliance: 9/9 scenarios within budget
attribution integrity (all source tags resolve): YES
avg reduction: C=42% B=21%
avg retrieval precision(C)=71% recall(C)=100%Candidate C retains 100% of required facts in all 9 scenarios, stays within budget, and achieves 42% average reduction (vs 21% for simple dedupe+truncation). On tight budgets it preserves mandatory constraints while Baseline B loses them.
Testing
npm test # run unit + integration tests (vitest)
npm run test:watch # watch mode during development
npm run typecheck # TypeScript type checking
npm run lint # ESLint + formatting checks
npm run build # compile to dist/See test/ for the test suite covering: deterministic output, duplicate handling,
similar-but-non-identical errors, required-fact preservation, source-reference
integrity, stable ranking, empty/malformed input, impossible budgets, MCP tool
validation, and local-only operation (no network).
Custom tokenizers
By default, token counts use the chars/4 heuristic (deterministic, zero dependencies).
For production use with a specific model, plug in a real tokenizer:
import { ContextOptimizer, type TokenEstimator } from 'mcp-context-optimizer';
import { encoding_for_model } from 'tiktoken'; // npm install tiktoken (optional dep)
const enc = encoding_for_model('gpt-4');
const tokenizer: TokenEstimator = {
name: 'tiktoken/gpt-4',
estimate: (text: string) => enc.encode(text).length,
};
const optimizer = new ContextOptimizer({
tokenBudget: 12_000,
tokenEstimator: tokenizer,
});The estimate function must be deterministic — the same string must always
return the same number. This keeps buildContext output byte-identical for
identical inputs, which is required for caching and reproducibility.
See src/tokens.ts for the TokenEstimator interface and the built-in
defaultTokenEstimator / createTokenEstimator helpers.
Versioning & SemVer
mcp-context-optimizer follows SemVer.
Component | Stability | Breaking change policy |
Public TypeScript API ( | Stable | Minor version bump |
Rendered context text format | Stable | Minor version bump |
| Stable | Minor version bump |
| Internal | Patch may change if output format changes |
MCP tool names / arguments | Stable | Minor version bump |
Scoring weight defaults | Internal | Patch may change (re-optimize after upgrade) |
PIPELINE_VERSION is incremented whenever the pipeline changes in a way that
affects output (e.g. new compaction stage, new scoring signal). It is part of
the config hash so that cached results are invalidated automatically.
Current version: 0.1.x — pre-1.0. Breaking changes may land in minor releases
until 1.0.0. After 1.0.0, breaking changes require a major version bump.
Comparison with alternatives
Approach | Deterministic | Local-only | Zero deps | Structured signals | Budget control | Provenance |
mcp-context-optimizer | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Paths/symbols/stacks/errors | ✅ Hard budget + mandatory | ✅ Every fragment tagged |
LLM summarization (external API) | ❌ No | ❌ No | ❌ No | ⚠️ Partial | ⚠️ Soft / best-effort | ❌ None |
Simple truncation (head/tail) | ✅ Yes | ✅ Yes | ✅ Yes | ❌ None | ✅ Yes | ❌ None |
Semantic chunking (embeddings) | ⚠️ Model-dependent | ❌ Usually remote | ❌ Heavy deps | ❌ None | ⚠️ Soft | ❌ None |
RAG / vector retrieval | ⚠️ Approximate | ❌ Usually remote | ❌ Heavy deps | ❌ None | ✅ Yes | ⚠️ Source docs only |
Key differences:
No model calls. Most "context optimizers" are just wrappers around another LLM that summarizes your context — expensive, slow, non-deterministic, and sends your code to a third party. This package does everything locally with pure functions.
Structured, not blind. It extracts file paths, symbols, stack frames, test failures, and explicit requirements before scoring, so a 200-line stack trace is reduced to its relevant frames rather than chopped at an arbitrary line.
Mandatory facts are never silently dropped. If required content exceeds the budget, the conflict is reported (
BUDGET_CONFLICT) instead of silently losing evidence.Full audit trail. Every retained fragment carries a
[source: ...]tag, and the machine-readable report lists every merge, omission, and score component.
MCP client integration examples
Claude Code
claude mcp add mcp-context-optimizer -- node /absolute/path/to/dist/mcp/cli.jsThen in Claude Code, the agent can call build_context, search_context,
get_decisions, get_relevant_errors, get_file_history, and
ingest_records directly.
Cursor / Claude Desktop (mcp.json)
{
"mcpServers": {
"mcp-context-optimizer": {
"command": "node",
"args": ["/absolute/path/to/mcp-context-optimizer/dist/mcp/cli.js"]
}
}
}Continue.dev
Add to ~/.continue/config.json:
{
"mcpServers": {
"mcp-context-optimizer": {
"command": "node",
"args": ["/absolute/path/to/mcp-context-optimizer/dist/mcp/cli.js"]
}
}
}MCP registries
The package is listed in MCP registries for one-click installation:
Registry | How to add |
Smithery | See |
Glama | Add server via Glama dashboard: command |
MCP.so | Add server via MCP.so dashboard: command |
Smithery example — add to your Smithery client config:
{
"mcpServers": {
"context-optimizer": {
"command": "npx",
"args": [
"mcp-context-optimizer",
"--persist",
"~/.cache/mcp-context-optimizer/context.json"
]
}
}
}Claude Code hooks — see claude-code-hooks.json. Register it in Claude Code settings to automatically call build_context on every user prompt (reduces the explicit-invocation friction).
Claude Desktop — see claude-desktop-config.json. Add to your Claude Desktop claude_desktop_config.json.
Important: MCP tool availability does not automatically intercept model
requests. The client/agent must explicitly call these tools (e.g. call
build_context before answering). Automatic context replacement requires a
native integration inside the coding agent.
The MCP server stores data in memory per process lifetime — restarting the
server starts from an empty store. Re-ingest records or implement your own
ContextStore (see src/store.ts) for persistence. Use --persist for
built-in file persistence.
Available Tools
6 toolsbuild_contextB
Construct a compact, task-specific context under a token budget. Combines stored records with any inline records; returns the rendered context plus provenance, omissions and a reproducible optimization report. Token counts are estimates unless a custom estimator is configured server-side.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | The current task description. | |
| query | No | Additional relevance terms. | |
| records | No | Optional inline records to include in addition to stored records. | |
| tokenBudget | No | Override the server token budget. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does valuable work by disclosing the return payload (rendered context, provenance, omissions, reproducible optimization report) and a real caveat that token counts are estimates unless a server-side estimator is configured. It does not say whether stored records are modified, whether the call is side-effect free, or what happens when the budget cannot be met.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose and then the output contract. No filler, though the second sentence packs provenance, omissions, report, and the estimation caveat into one dense clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter, schema-rich tool with no output schema, the description does explain what comes back, which is the main gap it needed to fill. It is still incomplete on routing versus siblings and on failure behavior when the budget is exceeded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all four parameters are already documented, and the baseline is 3. The description adds framing for tokenBudget ('under a token budget') and clarifies that records merge with stored records, but adds no syntax, defaults, or interaction detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb+resource ('Construct a compact, task-specific context') and states the mechanism ('combines stored records with any inline records'). It implicitly separates itself from ingest_records and search_context by being the composition/rendering step, though it never names those siblings directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance: nothing says to call build_context before search_context or instead of it, and no preconditions or exclusions are stated. The agent must infer from the name and from 'task-specific' that this is the final assembly step.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_decisionsA
Retrieve previously recorded technical decisions and constraints (accepted, proposed, superseded, rejected).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full disclosure burden. It does convey read-only retrieval and the four status categories in scope, but says nothing about result volume, ordering, scoping, or auth. Since the tool takes zero parameters, it presumably returns everything unfiltered, which the description never states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence, front-loaded with the verb and resource, with the status list attached compactly. Nothing is redundant and nothing needs to be moved earlier.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple zero-parameter read tool this is close to sufficient, but with no output schema the description should hint at what a decision record looks like (id, status, rationale) or whether all statuses come back together. As written, an agent knows the topic but not the shape or size of the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is no parameter semantics to add and the baseline of 4 applies. The parenthetical about statuses describes returned data rather than inputs, which is still useful orientation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Retrieve previously recorded technical decisions and constraints" gives a specific verb (retrieve) and resource (decisions/constraints), and the parenthetical enumerates the status values returned. It does not name or contrast with any sibling such as search_context or get_file_history, so an agent must infer the boundary itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied by "previously recorded" — the agent gathers this is for looking up already-captured decisions rather than creating new ones. There is no explicit when-to-use, no exclusion, and no pointer to alternatives like search_context when a keyword lookup is wanted.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_file_historyA
Retrieve context associated with a particular file: file snapshots, diffs, errors and test failures pointing at that path.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path (absolute, relative, or basename). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It implies a read-only retrieval and lists the kinds of context returned, but it does not disclose scope limits such as time range, pagination, permissions, or whether results are exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no redundant wording. It states the action and the main categories of returned context efficiently.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter retrieval tool with no output schema, the description gives a useful list of returned content categories but does not clarify result scope, ordering, or limits. It is adequate but leaves meaningful behavioral details unspecified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already fully documents the single 'path' parameter, including that it may be absolute, relative, or a basename. The description adds only that context is associated with the file path, so baseline 3 is appropriate given 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Retrieve') and resource ('context associated with a particular file') and enumerates the content types returned: snapshots, diffs, errors, and test failures. It is clear what the tool does, but it does not explicitly distinguish itself from siblings such as search_context or get_relevant_errors.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'particular file' implies file-scoped usage, but there is no explicit guidance on when to choose this tool over search_context or get_relevant_errors. No exclusions or alternative-routing instructions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_relevant_errorsB
Retrieve related errors, failed attempts and diagnostic information (error records, failed tool calls, failing tests). Optionally ranked by a query.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| query | No | Optional relevance query; omit for all errors. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It never states that this is a read-only operation, what permissions are needed, whether results are paginated or bounded (the limit cap of 100 is only in the schema), or what ordering applies when no query is given. The enumeration of returned content types is the only behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the retrieval scope front-loaded and the query behavior second. No filler, though the parenthetical list is slightly redundant with the first clause.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter read tool with no output schema, the description covers what is returned and how query affects ordering, but leaves the meaning of 'related' (relative to what context?) and default ordering unspecified — a gap an agent would notice when calling without a query.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% and the description adds meaning the schema does not: that supplying a query changes the result into a relevance ranking, rather than merely filtering. It says nothing about the limit parameter or its cap, leaving that to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb ('Retrieve') and concrete resources ('related errors, failed attempts and diagnostic information'), further clarified by the parenthetical list of error records, failed tool calls, and failing tests. It does not distinguish itself from siblings like get_decisions or search_context, and 'related' is left undefined, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Optionally ranked by a query' implies the two modes (unranked fetch vs. ranked search) but never says when to prefer this tool over search_context or the other siblings, nor any exclusions. Usage must be inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
ingest_recordsA
Add structured records (messages, tool calls, errors, files, diffs, test results, decisions, notes) to the local in-memory context store. Records are validated; malformed entries are reported and skipped.
| Name | Required | Description | Default |
|---|---|---|---|
| records | Yes | Array of records; each must have a "kind" field plus kind-specific fields. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does add real behavioral content: the store is "local" and "in-memory" (so writes are ephemeral), records are validated, and malformed entries are reported and skipped rather than aborting the call. It stops short of stating idempotency, duplicate handling, or size limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, and the payload kinds and validation behavior are front-loaded so an agent can decide and call after one read.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the most important unknowns for a mutation tool (ephemeral store, partial-failure semantics), but with no output schema it never says what a successful call returns or what the malformed-entry report looks like. For a one-parameter tool this is adequate but leaves a real gap around the response.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and there is a single parameter, so the schema already explains the array and the required "kind" field. The description's kind list restates the enum rather than adding syntax or per-kind field requirements.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"Add structured records ... to the local in-memory context store" gives a specific verb plus resource and enumerates the eight record kinds, which maps directly onto the schema enum. It never names the retrieval siblings (build_context, search_context), but the write-vs-read split is obvious enough from the wording.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use statement, no mention of ordering relative to build_context, and no guidance on batching versus repeated calls. Usage is only implied by the fact that it is the sole write-side tool among read/retrieval siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_contextA
Retrieve fragments relevant to a query, ranked by the explainable relevance model. Returns fragments with score breakdowns and provenance (never modifies sources).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max fragments to return (default 10). | |
| query | Yes | Natural-language query or task description. | |
| records | No | Optional records to search inline, in addition to stored records. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations supplied, the description carries the full burden and does meaningful work: it explicitly guarantees the operation never modifies sources (a read-only safety claim) and discloses that results carry score breakdowns and provenance. It stops short of describing the scope of stored records searched, freshness, or result-count behavior beyond what the schema's limit field already states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler, with the core action and the strongest behavioral guarantee ("never modifies sources") front-loaded. Every clause adds information an agent can act on.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a three-parameter read tool with no output schema, the definition covers action, ranking model, return contents, and safety. The remaining gap is routing: an agent given five retrieval-oriented siblings lacks the sentence that would tell it when this is the right choice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so query, limit, and the inline `records` array are already documented in structured form. The description adds nothing about parameter interaction — notably that `records` supplements rather than replaces stored records, which the schema only hints at — so it stays at the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Names a specific verb and resource ("Retrieve fragments relevant to a query") and adds the distinguishing trait that results are ranked by an explainable relevance model. It does not, however, contrast itself with the retrieval siblings (get_decisions, get_relevant_errors, build_context), so an agent must infer that this is the generic cross-kind search.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: the phrasing suggests a free-form relevance search over stored context, in contrast to the more targeted sibling lookups. There is no explicit when-to-use statement, no condition favoring this over build_context, and no guidance on when the inline `records` mode is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.9- First observed
build_context - First observed
get_decisions - First observed
get_file_history - First observed
get_relevant_errors - First observed
ingest_records - First observed
search_context
TDQS
Scored across 6 tools
The write tool (ingest_records) and composition tool (build_context) are clearly distinct from the retrieval tools. The four retrieval tools are mostly separable by scope (general query, decisions, errors, file history), though search_context can overlap with the specialized getters when queries target decisions or errors.
All six names follow a consistent snake_case verb_noun pattern: ingest_records, search_context, get_decisions, get_relevant_errors, get_file_history, build_context. The verbs vary by operation but remain predictable and readable.
Six tools is well-scoped for a context optimizer: one ingestion path, several targeted retrieval views, and one context-builder. Each tool has a clear role and the set avoids unnecessary surface area.
The core lifecycle is covered: ingest records, retrieve by query/category/file, and build budgeted context with provenance. Minor gaps exist around record management, such as updating, deleting, clearing, or listing stored records, which could matter for long-running in-memory use.
Maintenance
Related MCP Connectors
Compress coding-agent context ~64%. Hosted Neural Keep MCP for Cursor/Claude/Codex.
Universal memory for AI agents and tools. Save, organize and search context anywhere.
Shared memory for coding agents. Stop re-explaining your codebase every session.
The context platform for AI agents: code search, team decisions, and grounded project context.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceDeterministic context compression for MCP agents, reducing token usage via 11 tools for prompts, history, shell output, file deltas, and code navigation without ML or GPU.9MIT
- AlicenseNot gradedqualityBmaintenanceReduces token consumption for AI coding agents by 50-70% through intelligent code context filtering, Git delta tracking, and local SQLite/Tree-sitter indexing.167 npmMIT
- FlicenseAqualityAmaintenanceDeterministic repository context packing for AI coding agents: selects, compresses, and budgets only the files a task needs. Measured 83% fewer input tokens at the same task coverage, fully local, no LLM in the loop.939 PyPI9-
- AlicenseNot gradedqualityDmaintenanceA task-aware context compression layer for Agent workflows, RAG pipelines, and AI Coding assistants, reducing noisy logs, retrieval chunks, and code context into high-signal LLM inputs via CLI, Python SDK, and MCP.325MIT