context-distill
Description
context-distill is an MCP server that compresses noisy command output into precise, actionable summaries for LLM workflows. Use distill_batch for large logs and distill_watch for cycle-to-cycle deltas. Built with Go, Cobra, Viper, and DI for reliable local and provider-backed…
About
context-distill is an MCP server that compresses noisy command output into precise, actionable summaries for LLM workflows. Use distill_batch for large logs and distill_watch for cycle-to-cycle deltas. Built with Go, Cobra, Viper, and DI for reliable local and provider-backed distillation.
Details
- Author
- jcastilloa
- Categories
- Productivity, AI
Jump to
Quick install example (Claude Code, project-level)
mkdir -p .claude/skills/context-distill cp SKILL.md .claude/skills/context-distill/SKILL.md
Quick install example (all agents, global)
for agent in .claude .codex .opencode .cursor; do mkdir -p ~/"$agent"/skills/context-distill cp SKILL.md ~/"$agent"/skills/context-distill/SKILL.md done
The CLI commands provide the same capabilities as the MCP tools (distillation + code retrieval) but are invoked directly from the shell. Use them in local scripts, CI pipelines, or with agent runtimes that execute shell commands instead of MCP tools.
# 1. Pipe (preferred) echo "data" | context-distill distill_batch --question "..." # 2. Explicit flag context-distill distill_batch --question "..." --input "data" # 3. Explicit stdin marker echo "data" | context-distill distill_batch --question "..." --input -
Distills one raw output payload using an explicit question contract.
go test ./... 2>&1 | context-distill distill_batch --question "Did all tests pass? Return only PASS or FAIL."
Distills MCP results in either of these modes:
- You already have a raw MCP payload and pass it with--output.
- You wantcontext-distillto call an MCP tool first and then distill the result.
context-distill distill_mcp_output \ --tool-name "list_items" \ --question "Return only item names, one per line." \ --output '<mcp payload>'
context-distill distill_mcp_output \ --server-command "/absolute/path/to/mcp-server" \ --server-arg "--transport" \ --server-arg "stdio" \ --tool-name "get_status" \ --tool-arguments '{"scope":"production"}' \ --question "Return only status and version as JSON."
- You must provide either
--outputor a server invocation (--server-command+--tool-name).
context-distill distill_watch \ --question "Return only newly failing services, one per line." \ --previous-cycle "$(cat /tmp/health.prev)" \ --current-cycle "$(cat /tmp/health.curr)"
Searches repository code locally and distills compact matches according to--question.
context-distill search_code \ --query "distill_watch" \ --mode symbol \ --question "Return definitions first, then usages, as file:line."
- CLI syntax uses flags. Use--query,--mode,--question,--max-results,--context-lines.
- Do not use shell arguments likesearch_code mode=text query="..." max_results=5(that format is not valid CLI syntax).
- For--mode path, treat--queryas a path fragment (for example,.go), and use--scopefor glob filters.
- CLI commands and MCP tools share the same underlying use cases and validation rules.
- Invalid/missing inputs return a non-zero exit code.
- Output is written to standard output exactly as produced by the selected use case.
context-distill --transport stdio # or without building: go run ./cmd/server --transport stdio
After building or installing the binary, register it in your MCP client to use the tool interface.
Terminal UI (recommended for first-time setup)
context-distill --config-ui # or without building: go run ./cmd/server --config-ui
- Providers that require an API key block save until one is entered.
- OpenAI-compatible providers require abase_url.
- Provider aliases are normalized automatically (e.g.OpenAI Compatible→openai-compatible,dmr→docker-model-runner).
Persisted config path:~/.config/context-distill/config.yaml
Save preserves existing YAML sections (service,openai, etc.) and updates only the relevantdistillfields.
You can also edit the config file directly.
- ~/.config/<service>/config.yaml
- ./config.yaml
service: transport: stdio openai: provider_name: openai api_key: sk-xxxx base_url: https://api.openai.com/v1 model: gpt-4o-mini timeout: 30s max_retries: 3 supports_system_role: true supports_json_mode: true distill: provider_name: ollama base_url: http://127.0.0.1:11434 model: qwen3.5:2b timeout: 90s max_retries: 0 thinking: false
Note:service.versionis injected at build time from binary metadata and does not need to be set manually.
The quality of distillation/search output depends on thequestioncontract — whether invoked via Skill, CLI, or MCP. Be explicit aboutwhatyou want andin what format.
A Go tool thatdistills command output and retrieves code contextbefore it reaches a paid LLM. Available as aSkill(recommended), astandalone CLI, and anMCP server. Inspired by thedistillCLI and built with hexagonal architecture, dependency injection, and TDD.
context-distillexposes four operations accessible inthree ways:
All three modes share the same underlying use cases, validation rules, and output behavior. Only the invocation method differs.
- LLM provider configuration via YAML and environment variables.
- An interactive terminal UI for first-time setup (--config-ui).
- Support for Ollama and any OpenAI-compatible provider.
Skill mode works because modern coding agents (Codex, Claude Code, Cursor, Aider, OpenCode…) already know how to read project documentation and execute shell commands. ASKILL.mdfile teaches the agentwhento distill or retrieve code context andhowto call the CLI — no protocol integration needed.
- Triple interface— Skill file for zero-config agent adoption + CLI for direct shell use + MCP tools for protocol-native clients.
- Four core operations—distill_batch,distill_mcp_output,distill_watch, andsearch_code.
- Hexagonal architecture—distill/domain,distill/application,platform/.
- Dependency injectionviasarulabs/di.
- Config managementwithviper+.env.
- Provider-specific validationat config time.
- Interactive setup UI(--config-ui).
- Unit, integration, and optional live tests.
If you prefer not to compile, you can install a prebuilt binary from GitHub Releases (see below).
The binary is placed at./bin/context-distill.
make install # installs to ~/.local/bin/context-distill
Option B: Prebuilt binary (no build required)
# Latest release curl -fsSL https://raw.githubusercontent.com/jcastilloa/context-distill/master/scripts/install.sh | sh # Specific version curl -fsSL https://raw.githubusercontent.com/jcastilloa/context-distill/master/scripts/install.sh | VERSION=vX.Y.Z sh
# Latest release iwr https://raw.githubusercontent.com/jcastilloa/context-distill/master/scripts/install.ps1 -UseBasicParsing | iex # Specific version $env:VERSION='vX.Y.Z'; iwr https://raw.githubusercontent.com/jcastilloa/context-distill/master/scripts/install.ps1 -UseBasicParsing | iex
echo "PASS: TestA, PASS: TestB, FAIL: TestC - expected 4 got 5" | context-distill distill_batch --question "Did tests pass? Return only PASS or FAIL. If FAIL, list failing test names."
context-distill distill_watch --question "What changed? Return one short sentence." --previous-cycle "services: api=OK, db=OK, cache=OK" --current-cycle "services: api=OK, db=FAIL, cache=OK"
context-distill distill_mcp_output \ --tool-name "list_items" \ --question "Return only item names, one per line." \ --output '[{"type":"text","text":"[{\"id\":\"a1\",\"name\":\"Alpha\"},{\"id\":\"b2\",\"name\":\"Beta\"}]"}]'
context-distill distill_mcp_output \ --server-command "/absolute/path/to/mcp-server" \ --server-arg "--transport" \ --server-arg "stdio" \ --tool-name "get_status" \ --tool-arguments '{"scope":"production"}' \ --question "Return only status and version as JSON."
context-distill search_code --query "provider_name" --mode text --question "Return only file:line, one per line."
If commands return expected compact answers, setup is ready.
CopySKILL.mdinto the appropriate agent skills directory (seeSkill Setup). Your agent will read it automatically and start distilling.
Use the subcommands directly in scripts or agent shell calls:
# Pipe (preferred) echo "data" | context-distill distill_batch --question "..." # Explicit flag context-distill distill_batch --question "..." --input "data" # Explicit stdin marker echo "data" | context-distill distill_batch --question "..." --input - # MCP payload distillation context-distill distill_mcp_output --tool-name "list_items" --question "Return only item names." --output '<mcp payload>' # MCP call + distillation in one step context-distill distill_mcp_output --server-command "/absolute/path/to/mcp-server" --server-arg "--transport" --server-arg "stdio" --tool-name "get_status" --tool-arguments '{"scope":"production"}' --question "Return only status and version as JSON." # Code retrieval context-distill search_code --query "LoadDistillConfig" --mode symbol --question "Return likely definitions first as file:line, one per line."
Then register the server in your MCP client (seeMCP Client Registration).
The canonical installable skill now lives inSKILL.md.
That file is the clearest place to learn the behavior and the easiest file to copy into an agent skills directory.
The skill now covers four concrete workflows:
- Distill long command output withdistill_batch.
- Distill raw MCP payloads you already have withdistill_mcp_output --output.
- Call an MCP tool and distill the result in one step withdistill_mcp_output --server-command.
- Locate code before opening many files withsearch_code.
Additional ready-to-copy templates live here:
- CLI AGENTS template
- MCP AGENTS template
- Strict CI AGENTS template
InstallSKILL.mdat project level, global level, or both:
Project-level(recommended for teams): every agent working on the repo picks it up automatically.
Global(recommended for personal use): available in every project without per-repo setup.
Quick install example (Claude Code, project-level)
mkdir -p .claude/skills/context-distill cp SKILL.md .claude/skills/context-distill/SKILL.md
Quick install example (all agents, global)
for agent in .claude .codex .opencode .cursor; do mkdir -p ~/"$agent"/skills/context-distill cp SKILL.md ~/"$agent"/skills/context-distill/SKILL.md done
The CLI commands provide the same capabilities as the MCP tools (distillation + code retrieval) but are invoked directly from the shell. Use them in local scripts, CI pipelines, or with agent runtimes that execute shell commands instead of MCP tools.
# 1. Pipe (preferred) echo "data" | context-distill distill_batch --question "..." # 2. Explicit flag context-distill distill_batch --question "..." --input "data" # 3. Explicit stdin marker echo "data" | context-distill distill_batch --question "..." --input -
Distills one raw output payload using an explicit question contract.
go test ./... 2>&1 | context-distill distill_batch --question "Did all tests pass? Return only PASS or FAIL."
Distills MCP results in either of these modes:
- You already have a raw MCP payload and pass it with--output.
- You wantcontext-distillto call an MCP tool first and then distill the result.
context-distill distill_mcp_output \ --tool-name "list_items" \ --question "Return only item names, one per line." \ --output '<mcp payload>'
context-distill distill_mcp_output \ --server-command "/absolute/path/to/mcp-server" \ --server-arg "--transport" \ --server-arg "stdio" \ --tool-name "get_status" \ --tool-arguments '{"scope":"production"}' \ --question "Return only status and version as JSON."
You must provide either--outputor a server invocation (--server-command+--tool-name).
Distills only the relevant delta between two snapshots.
context-distill distill_watch \ --question "Return only newly failing services, one per line." \ --previous-cycle "$(cat /tmp/health.prev)" \ --current-cycle "$(cat /tmp/health.curr)"
Searches repository code locally and distills compact matches according to--question.
context-distill search_code \ --query "distill_watch" \ --mode symbol \ --question "Return definitions first, then usages, as file:line."
- CLI syntax uses flags. Use--query,--mode,--question,--max-results,--context-lines.
- Do not use shell arguments likesearch_code mode=text query="..." max_results=5(that format is not valid CLI syntax).
- For--mode path, treat--queryas a path fragment (for example,.go), and use--scopefor glob filters.
- CLI commands and MCP tools share the same underlying use cases and validation rules.
- Invalid/missing inputs return a non-zero exit code.
- Output is written to standard output exactly as produced by the selected use case.
context-distill --transport stdio # or without building: go run ./cmd/server --transport stdio
After building or installing the binary, register it in your MCP client to use the tool interface.
JSON-based clients (Claude Desktop, Cursor, etc.)
{ "mcpServers": { "context-distill": { "command": "/absolute/path/to/context-distill", "args": ["--transport", "stdio"] } } }
[mcp_servers.context-distill] command = "/absolute/path/to/context-distill" args = ["--transport", "stdio"] startup_timeout_sec = 20.0
[mcp_servers.context-distill] command = "/home/<your-user>/.local/bin/context-distill" args = ["--transport", "stdio"] startup_timeout_sec = 20.0
codex mcp add context-distill -- /absolute/path/to/context-distill --transport stdio
codex mcp list codex mcp get context-distill
Restart your Codex session so it picks up the new server.
- Location→Current projectorGlobal.
- Name→context-distill.
- Type→local.
- Command→/absolute/path/to/context-distill --transport stdio.
If the server is not connected yet, restart your OpenCode session.
OpenCode — manual config (opencode.json)
{ "$schema": "https://opencode.ai/config.json", "mcp": { "context-distill": { "type": "local", "command": ["/absolute/path/to/context-distill", "--transport", "stdio"], "enabled": true } } }
- Always use anabsolutebinary path.
- Always usestdiotransport.
- If the server does not appear, runcodex mcp list --jsonto inspect the resolved config.
The MCP tools expose the same capabilities as the CLI commands (distillation + code retrieval), but are consumed by MCP-compatible clients over thestdiotransport.
Returns a short, focused answer toquestion.
Returns a short summary of relevant changes, or a no-change message when nothing meaningful differs.
Returns compact output controlled byquestion, after local repository retrieval.
- This section documents MCP tool payload fields (snake_case), not shell flags.
- CLI equivalents are--query,--mode,--question,--scope,--max-results,--context-lines.
Terminal UI (recommended for first-time setup)
context-distill --config-ui # or without building: go run ./cmd/server --config-ui
- Providers that require an API key block save until one is entered.
- OpenAI-compatible providers require abase_url.
- Provider aliases are normalized automatically (e.g.OpenAI Compatible→openai-compatible,dmr→docker-model-runner).
Persisted config path:~/.config/context-distill/config.yaml
Save preserves existing YAML sections (service,openai, etc.) and updates only the relevantdistillfields.
You can also edit the config file directly.
- ~/.config/<service>/config.yaml
- ./config.yaml
service: transport: stdio openai: provider_name: openai api_key: sk-xxxx base_url: https://api.openai.com/v1 model: gpt-4o-mini timeout: 30s max_retries: 3 supports_system_role: true supports_json_mode: true distill: provider_name: ollama base_url: http://127.0.0.1:11434 model: qwen3.5:2b timeout: 90s max_retries: 0 thinking: false
Note:service.versionis injected at build time from binary metadata and does not need to be set manually.
The quality of distillation/search output depends on thequestioncontract — whether invoked via Skill, CLI, or MCP. Be explicit aboutwhatyou want andin what format.
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.

