read_file tool automatically converts common document formats to readable text, so the agent can inspect a PDF or spreadsheet the same way it reads source code.
Supported formats
* The optional converter is the
firecrawl-anydoc package, installed lazily where installs are permitted (security.allow_lazy_installs in config.yaml). Without it, the three stdlib formats still work; other formats fall back to the binary-file guard.
SQLite files render as a schema overview rather than a dump: each table’s CREATE statement, row count and first five rows, plus the list of indexes, views and triggers. The database is opened read-only (mode=ro&immutable=1, so a live database another process holds open is still readable without locks); for anything beyond the preview, query it from the terminal with sqlite3. A .db that is not SQLite (the magic bytes do not match) is refused with the real reason. Mibyan’s own read denylist applies before extraction, so protected stores under mibyan_HOME stay unreadable.
read_file also flags unresolved git merge conflicts: when the returned range contains balanced <<<<<<< / >>>>>>> marker lines, the result carries conflict_blocks: N and a hint to resolve them before editing around them. A lone marker inside a string or a test fixture is not counted.
Conversion output is Markdown, paginated through read_file’s normal offset/limit window. East Asian phonetic guides (XLSX rPh, DOCX ruby text) annotate cell or run text and are not part of the extracted value: a cell holding 東京 with the guide トウキョウ reads as 東京. Documents over 50 MB are refused to keep tool turns bounded.
Notebook cell outputs longer than 20,000 characters are truncated; the truncation marker carries a jq command that names the notebook’s full, shell-quoted path so the omitted output can be pulled from the original file.
Extraction works with remote terminal backends (Docker, Modal, SSH): the file’s bytes are transferred across the backend boundary and converted host-side, so a document inside a sandbox reads the same as a local one.
Scanned PDFs: the coverage warning
PDF conversion reads the text layer only. Pages that are scanned images — common in legal documents, resale packages, signed contracts, faxes — contain no text layer and silently convert to nothing. The telltale signature is section headers with empty bodies. When a meaningful share of pages yields no text (over 20% of the document, or 10+ pages absolute),read_file prepends a warning to the extraction. Each unreadable gap is labeled with the last text extracted before it — usually a section divider — so the agent can target only the gaps it actually needs instead of OCRing the whole document:
- A few pages — render + vision. Convert the pages to images and read them with the vision tool:
Then inspect each image with
vision_analyze. Zero extra dependencies (poppler is required for the detection itself). - Many pages — OCR. The
ocr-and-documentsskill covers bulk OCR with marker-pdf (90+ languages, handles equations and tables; ~3-5 GB install).
pdftotext for per-page text counts. If poppler is not installed, extraction still works — the coverage check is silently skipped.

