Skip to main content
Glama
Koderkup

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 server
  • Node.js >= 20, ESM only.

  • The MCP adapter is optional: it lives behind the mcp-context-optimizer/mcp export 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 ratio

Identical 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.txt

Before / 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 bench

How it works: the pipeline

Each stage is a separate, unit-tested, pure function:

Stage

Module

What it does

1. Normalize & classify

normalize.ts

Validates records, assigns deterministic ids, normalizes line endings, collapses pathological repeated log lines (never file contents/diffs), keeps original data untouched.

2. Deduplicate

dedupe.ts

(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

extract.ts

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

score.ts

Weighted, explainable scoring (see below). Recency uses the max timestamp in the data — never Date.now() — and has a floor for constraints/decisions so old but binding decisions stay important.

5. Budget-aware selection

select.ts

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 (BUDGET_CONFLICT), never silently discarded.

6. Render & report

render.ts

Fixed-order sections; every fragment gets a [source: fr_xxx | record rN | path] tag. Machine-readable metadata stays separate from the rendered text.

Scoring weights (defaults, all configurable)

Signal

Weight

Meaning

lexicalOverlap

3

IDF-weighted overlap between task/query tokens and fragment tokens.

identifierMatch

4

Fragment mentions file paths/symbols that appear in the task (full path 1.0, basename 0.6, symbol 0.8).

errorRelevance

3

Fragment is an error/failing test that matches the task identifiers.

constraint

5

Fragment states a requirement, constraint or accepted decision.

failedAttempt

2

Fragment documents a failed attempt or unresolved problem.

recency

1.5

Exponential decay, half-life 7 days; floored at 0.7 for constraints/decisions.

role

1

user/system 1.0 > assistant 0.6 > tool 0.4.

redundancyPenalty

2

Negative: trigram containment against earlier-ranked fragments.

callerPriority

1

Explicit priority hint on a record (default 0.5).

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

ingest_records

Add structured records to the server's in-memory store.

search_context

Rank fragments for a query with score breakdowns and provenance.

get_decisions

Retrieve recorded technical decisions and constraints.

get_relevant_errors

Retrieve errors, failed attempts, failing tests (optionally ranked).

get_file_history

Retrieve snapshots/diffs/errors associated with a file path.

build_context

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.js

Cursor / 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.json
import { 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: fetch is 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 ContextStore interface 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

ceil(chars / 4)

Default; good for prose-heavy

claude-3

ceil(chars / 3)

Claude code/context; denser tokens

gpt-4

ceil(chars / 4)

GPT-4 family

mistral

ceil(chars / 4)

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.json

Latest 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 (src/index.ts exports)

Stable

Minor version bump

Rendered context text format

Stable

Minor version bump

OptimizationReport JSON shape

Stable

Minor version bump

PIPELINE_VERSION constant

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.js

Then 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 smithery.yaml. The server is configured with --persist so records survive restarts.

Glama

Add server via Glama dashboard: command npx mcp-context-optimizer, transport stdio.

MCP.so

Add server via MCP.so dashboard: command npx mcp-context-optimizer, transport stdio.

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 tools
build_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.

NameRequiredDescriptionDefault
taskYesThe current task description.
queryNoAdditional relevance terms.
recordsNoOptional inline records to include in addition to stored records.
tokenBudgetNoOverride the server token budget.

TDQS

B3.2/5.0
Behavior3/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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).

NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
pathYesFile path (absolute, relative, or basename).

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
limitNo
queryNoOptional relevance query; omit for all errors.

TDQS

B3.2/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

NameRequiredDescriptionDefault
recordsYesArray of records; each must have a "kind" field plus kind-specific fields.

TDQS

A3.7/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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).

NameRequiredDescriptionDefault
limitNoMax fragments to return (default 10).
queryYesNatural-language query or task description.
recordsNoOptional records to search inline, in addition to stored records.

TDQS

A3.8/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines3/5

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.

  1. 6 tool updatesv0.1.9
    • First observedbuild_context
    • First observedget_decisions
    • First observedget_file_history
    • First observedget_relevant_errors
    • First observedingest_records
    • First observedsearch_context

TDQS

A3.7/5.0

Scored across 6 tools

Disambiguation4/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • F
    license
    A
    quality
    A
    maintenance
    Deterministic 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.
    9
    39 PyPI
    9
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    A 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.
    325
    MIT