DistillDistill

Changelog

Distill release history — shipped versions, corrections, and new Claude Code integration points.

Changelog

This page summarises the published distill-mcp npm releases. The full commit-level history lives in CHANGELOG.md at the repository root; each release's PRD captures the story-by-story motivation.

v0.10.1 — 2026-04-22

Patch release. No contract change, no API change, no migration. Two bug fixes surfaced right after v0.10.0 shipped.

Fixes

  • code_execute — crash on code without a return statement. User code that only called console.log(...) without returning a value crashed the tool: JSON.stringify(undefined) returns undefined (not a string), which broke the downstream countTokens call. A guard at src/sandbox/executor.ts:152-153 now coerces the undefined case to an empty string before serialisation. Pure side-effect scripts work again.
  • smart_file_readasync async in TypeScript skeletons. The skeleton renderer unconditionally prepended async to asynchronous functions without checking whether the captured signature already contained it, producing output like async async function fetchData(...). The render line at src/tools/smart-file-read.ts:395-414 now tests for a pre-existing \basync\b token before adding the modifier.

Tests and coverage

1,203 passing tests (1 skipped) across 46 files. mcp-server coverage: Lines 72.13% · Branches 58.62% · Functions 73.46% · Statements 71.32%. v0.9.2 floors remain respected with headroom.

v0.10.0 — 2026-04-22

Correctness + native-integration release. No change to the three tools' contracts (auto_optimize, smart_file_read, code_execute). No change to the sandbox, the AST parsers, or the compression algorithms. First release published to npm since v0.8.1 — it consolidates the previously-draft v0.9.1 and v0.9.2 work into one shipped version.

Documentation corrections

Every claim in CLAUDE.md is now pinned to a claude-code/<path>:<line> citation so re-verification against a moving upstream is a single grep.

  • The MCP tool-result persistence threshold is 25 000 tokens (DEFAULT_MAX_MCP_OUTPUT_TOKENS), not "50 000 chars". The length/4 heuristic gate at mcpValidation.ts:151-163 short-circuits at ~12 500 estimated tokens (≈ 50K chars).
  • The autocompact formula reserves min(maxOutputTokens, 20_000) tokens — for Haiku (max_output = 4 096) that yields a trigger ~16K tokens higher than a hardcoded 20K would suggest.
  • A "Claude Code Mechanics — Verified Citations" appendix collects eleven mechanisms (alwaysLoad / searchHint / outputSchema / MCP persistence / autocompact / structuredContent drop / PreCompact hook / MCP prompts / custom agent loading / readOnlyHint / MCP skills), each with a one-line re-verification script.

Code aligned with Claude Code

  • structuredContent is no longer emitted on the MCP wire. Claude Code parks it in mcpMeta, and mcpMeta is explicitly excluded from the Anthropic-API blocks — the model never saw the field.
  • The searchHints map in server.ts is removed. The hint is rendered only for deferred tools via ToolSearch, and Distill's three tools declare alwaysLoad: true — the hint was unreachable by construction.
  • annotations.readOnlyHint: true is now declared on smart_file_read and auto_optimize. Claude Code maps that hint to isConcurrencySafe(), enabling parallel dispatch alongside other read-only tools on multi-tool turns.

PreCompact hook (opt-in)

  • [DISTILL:COMPRESSED ratio=X.XX method=<name>] marker contract. Opt-in envelope enabled via DISTILL_COMPRESSED_MARKERS=1. Thresholds: auto_optimize savings ≥ 30%; smart_file_read < 50% of source size in skeleton/extract/search modes; code_execute's ctx.compress.* helpers under the same rule. Collision handled via [DISTILL-USER-TEXT:COMPRESSED …] escape tokens.
  • packages/mcp-server/scripts/precompact-hook.sh — shipped POSIX hook that emits the "preserve verbatim" instruction Claude Code merges into newCustomInstructions. Exits 0 on every input shape (malformed JSON, unexpected events) so it can never block compaction.
  • distill-mcp setup --install-precompact-hook — idempotent, atomic (tempfile + rename), with --dry-run, --uninstall-precompact-hook, and --user-dir=<path> for tests. Aborts cleanly on a malformed ~/.claude/settings.json with a line/column pointer.

MCP slash commands

Three prompts registered via prompts/list, available as zero-argument slash commands:

  • /mcp__distill-mcp__compress-session — surveys recent tool results and runs auto_optimize on the largest.
  • /mcp__distill-mcp__analyze-tokens — estimates session token usage and identifies the three heaviest contributors.
  • /mcp__distill-mcp__forget-large-results — surfaces disk-persisted tool results (> 25K tokens) and proposes candidates for re-compression.

Full documentation on the Slash commands page.

distill-compressor custom subagent

  • Agent markdown template shipped at packages/mcp-server/assets/agents/distill-compressor.md — read-only toolset (Read, Grep, Glob, Bash + auto_optimize + smart_file_read), code_execute explicitly in disallowedTools, requiredMcpServers: [distill-mcp].
  • distill-mcp setup --install-agent — atomic copy to ~/.claude/agents/ (mode 0644, parent 0755). Idempotent; supports --dry-run, --uninstall-agent, and a diff preview when the target file exists and differs (--force required to overwrite).

MCP skills — NO-GO

The spike at docs/spikes/mcp-skills-exposure.md settled it: on today's shipped Claude Code binary an external MCP server cannot produce commands with loadedFrom === 'mcp'. The loader is gated behind a bundle-time feature('MCP_SKILLS') flag compiled to false in the public build, and the skills/mcpSkills.ts producer module is absent from the open-source tree. The spike report lists the four upstream preconditions that would flip the decision to GO and three strings-based tripwires to re-check whenever Claude Code bumps versions. v0.11 will not include MCP skills.

Migration notes

No migration required. The three tools' signatures and output shapes are unchanged. The marker contract, the PreCompact hook, the slash commands, and the custom agent are all opt-in — existing v0.8.x / v0.9.x integrators keep vanilla behaviour.

Before v0.10.0

Earlier releases have long-form notes under docs/releases/; from v0.9.0 onward the canonical source is CHANGELOG.md.

On this page