Distill
Convert docx, xlsx, and pdf to markdown or plain text — no external dependencies
The Problem
LLMs work with text. Documents don't. Word files, spreadsheets, and PDFs are binary formats that no LLM can read directly — you need a conversion step before the model can touch the content.
Most conversion tools require installed libraries, cloud accounts, or proprietary APIs with usage limits. Building that into every workflow that handles documents is repetitive, fragile, and slow to set up.
About Distill
Distill is a stateless document converter written in pure Go. Drop a file in, get text back. No database, no queue, no credentials, no state. It handles docx, xlsx, and pdf and outputs either Markdown or plain text.
There are two ways to use it: a web UI for one-off conversions, and an HTTP API for programmatic access. A Streamable HTTP MCP endpoint lets LLMs call the converter as a tool — so Claude Code, Cursor, or any MCP client can convert a document without leaving the conversation.
Because Distill is pure Go with no C bindings or runtime dependencies, it runs anywhere: a single binary on Linux, or a Docker container in a private network. Self-host it inside your own infrastructure with no external calls required.
Key Features
Three formats
DOCX preserves headings, lists, tables, and inline formatting as Markdown. XLSX converts rows and columns with sheet selection. PDF extracts text in reading order.
MCP tool use
An MCP endpoint at /mcp exposes a convert tool and a list_sheets tool. LLMs call them natively without shell escapes or curl commands.
Stateless
Every request is self-contained. No files are written to disk, no sessions, no cleanup. Scale horizontally or run as a single container — behavior is identical either way.
Zero dependencies
Pure Go implementation. No libreoffice, no pdfium, no Python, no Node. The binary is self-contained and runs on any Linux host with no setup beyond copying the file.
MCP Integration
Distill's MCP endpoint lets any compatible LLM convert documents as a native tool call. Two deployment modes are available: a hosted HTTP endpoint, or a local stdio binary via Docker.
Claude Code (HTTP)
claude mcp add --transport http distill https://<your-distill-host>/mcp
Stdio via Docker (reads local files directly)
{
"mcpServers": {
"distill": {
"command": "docker",
"args": ["run", "--rm", "-i", "carefuldream/distill", "/distill-mcp"]
}
}
}The stdio mode reads files from your local filesystem directly. The HTTP mode returns a curl command for the LLM to run instead.
Available tools
convertConvert a docx, xlsx, or pdf file to markdown or plain text. Takes a file path and optional format and sheet name.list_sheetsList sheet names in an XLSX file before converting, so the LLM can pick the right one.HTTP API
/convert?format=mdMultipart form upload. Set format to md or text. Add sheet=SheetName for XLSX files with multiple sheets. Returns {"content": "..."}.
curl -F '[email protected]' 'https://<your-distill-host>/convert?format=md'
/sheetsReturns the list of sheet names in an XLSX file. Returns {"sheets": [...]}.
curl -F '[email protected]' https://<your-distill-host>/sheets
Technical Stack
- •Go — single stateless binary, no runtime dependencies
- •DOCX: pure Go OOXML parser with structure-aware Markdown output
- •XLSX: pure Go spreadsheet reader with multi-sheet support
- •PDF: pure Go text extraction in reading order
- •MCP: Streamable HTTP (JSON-RPC 2.0) and stdio transports
- •Deployed on Kubernetes — scales to zero between requests
Have a project like this one?
We'd be glad to talk through your goals, your constraints, and whether we're the right team for the work.
