Skip to main content
Glama
README.md
# kaeru

**Verified conversions — every one actually run, not just claimed.**
Your files are never uploaded to convert them.
One tool your AI agents and you both use.

![kaeru converting a confidential .docx to Markdown, entirely on the local machine](https://raw.githubusercontent.com/NOGUCHILin/kaeru/main/docs/kaeru-ui-en.gif)

*A contract that cannot leave the building, turned into something an agent can read.
Note the **Tool** and **Command** lines: that is the binary on your machine, and the exact
command it ran. Nothing to take on faith.*

```bash
npx @noguchilin/kaeru --doctor     # what can this machine convert?
```

## Verified, not claimed

Every conversion listed below was **actually run, one by one, on real machines** — and the
output was re-opened with a second tool to prove it isn't empty. The test suite ships with
the code, so you can re-run the count yourself.

| OS | Conversions offered | Actually passed | Tools installed |
|---|---|---|---|
| **macOS 26** | 4,779 | **4,753 / 4,753** | all |
| **Windows 11** | 4,062 | **3,708 / 3,952** | ImageMagick, pandoc |
| **Debian (Linux)** | 3,426 | **3,218 / 3,329** | ImageMagick, pandoc |

*The macOS row was re-run on 2026-08-25. The Windows and Debian rows are from
2026-08-18 on real machines that did not have poppler installed, so they predate
`pdf>txt` — install poppler there and each gains one more.*

```bash
npm test        # re-run every combination on your machine
npm run list    # print the conversion table (this is what the numbers count)
```

Numbers differ per machine **on purpose** — see below.

## The table adapts to your machine

kaeru doesn't bundle converters. It finds the ones you already have — and asks each one
what *its version* actually supports. **A conversion that can't work is never offered.**

```
$ npx @noguchilin/kaeru --doctor
This machine can do: 4,062 conversions

Tools:
  ✓ magick      C:\Program Files\ImageMagick-7.1.2-Q16-HDRI\magick.EXE
  ✗ ffmpeg      not found
  ...

Install these to unlock more:
  ffmpeg      +468 conversions   winget install Gyan.FFmpeg
```

Nothing installed? Nothing breaks — you get 0 conversions and a list of one-line installs.

## Three doors, one engine

| Door | For | Start it |
|---|---|---|
| **Command line** | you, right now | `npx @noguchilin/kaeru photo.png --to jpg` |
| **MCP server** | your AI agents | add one line to `.mcp.json` |
| **Local web page** | you, with a file picker | `npm run ui` → http://127.0.0.1:19921 |

All three call the same code, so an agent and a human can never disagree about what's possible.
An option that would do nothing is refused rather than ignored — `--max` on `docx>pdf` comes
back with what that conversion *does* accept — and the web page only shows a field once the
engine says the chosen target accepts it.

### For agents (MCP)

```json
{ "mcpServers": { "kaeru": { "command": "npx", "args": ["-y", "@noguchilin/kaeru"] } } }
```

One tool, `convert`. Ask for something impossible and it replies with what *is* possible
from that input — or which tool to install.

### For humans, from the shell

```bash
npx @noguchilin/kaeru photo.png --to jpg
npx @noguchilin/kaeru report.pdf --to pdf --output smaller.pdf   # same format = compress
npx @noguchilin/kaeru a.pdf b.pdf --to pdf --output merged.pdf   # PDFs merge
npx @noguchilin/kaeru contract.pdf --to txt                      # text out of a PDF
npx @noguchilin/kaeru a.png b.png --to png --output tall.png     # images stack
npx @noguchilin/kaeru a.png b.png c.png d.png --to png --columns 2 --output grid.png
npx @noguchilin/kaeru shot.png --to png --max 800 --output small.png  # longest side ≤ 800
```

It prints the path it wrote and exits. Run it with no arguments and it becomes the MCP
server instead — that is how your agent starts it.

### For humans, from a page

`npm run ui` opens a single page on `127.0.0.1` only. Drop a file, pick a target, save the
result. **It does not stay running** — Ctrl-C and it's gone. No Docker, no daemon, no account.

## What it converts

Images · video · audio · documents (md, html, tex, docx, odt, epub, and ~30 more) · Office
and spreadsheets · PDF · 3D models · Parquet.

PDFs can be **merged, split, compressed, rasterised, and read as text**. Images, audio and
PDFs can be **shrunk without changing format**. `--max N` bounds an image's longest side —
it only ever shrinks, so a small image is returned untouched rather than blown up. Pass
several images and they are **joined into one** (`--columns` sets how many per row). Pass a
URL to pull from video sites.

**A scanned PDF has no text to give.** `--to txt` on one does not hand you an empty file
and call it a conversion — it tells you the pages are images, and points you at `--to png`.
That is the same rule as the headline: a result you can't verify isn't offered.

CJK encodings are detected automatically (a Shift_JIS CSV from Excel just works).

## Every result comes with its receipt

```
Converted: csv>xlsx
Output:    /path/to/data.xlsx
Tool:      soffice
Command:   soffice --headless --convert-to xlsx --outdir /tmp/... /path/to/data.csv
Took:      3,512 ms
```

You can always see which program touched your file, and repeat it by hand.

## Install the converters

kaeru calls these; install the ones you need (or none, and add them later).

<details>
<summary><b>macOS</b></summary>

```bash
brew install imagemagick ffmpeg pandoc weasyprint qpdf poppler img2pdf yt-dlp assimp duckdb ghostscript
brew install --cask libreoffice
```
</details>

<details>
<summary><b>Windows</b></summary>

```powershell
winget install ImageMagick.ImageMagick Gyan.FFmpeg JohnMacFarlane.Pandoc QPDF.QPDF `
  oschwartz10612.Poppler yt-dlp.yt-dlp Assimp.Assimp DuckDB.cli `
  ArtifexSoftware.GhostScript TheDocumentFoundation.LibreOffice
pip install weasyprint img2pdf
```
</details>

<details>
<summary><b>Linux (apt)</b></summary>

```bash
sudo apt install imagemagick ffmpeg pandoc qpdf poppler-utils img2pdf yt-dlp assimp-utils ghostscript libreoffice
pip install weasyprint
```
</details>

## Privacy and security

- Files are processed by local programs. **kaeru makes no network requests** (except when you
  explicitly pass a video-site URL — that path downloads, by definition).
- **What kaeru does not control: what you do with the result.** If your agent then *reads* the
  converted file, its contents go to whatever model provider that agent uses. kaeru governs the
  conversion, not the reading. For a file that must never reach a model, convert it and open it
  yourself in the local web page (`npm run ui`) instead of handing it to an agent.
- The web page binds to `127.0.0.1`, rejects non-localhost `Host` headers, and hands results
  back by an unguessable id.
- **Existing files are never overwritten** unless you ask for it.
- **No telemetry. Ever.** Not anonymous, not opt-out — none.

Three independent models reviewed the source on 2026-08-18; every exploitable finding was
fixed the same day. **One known risk is not fixed: converting untrusted HTML or SVG can embed
local files in the output.** Details, severities and mitigations: [SECURITY.md](SECURITY.md).

## Tests

| Command | What it checks |
|---|---|
| `npm test` | every listed conversion actually runs, output re-opens |
| `node test/quality.mjs` | images round-trip pixel-for-pixel; text survives |
| `node test/fidelity.mjs` | documents keep headings, tables, lists, emphasis |
| `node test/languages.mjs` | 12 writing systems keep their characters |
| `node test/platforms.mjs` | tool lookup is correct for macOS / Windows / Linux |

Known gaps are written down, not hidden — see `docs/`.

## Support

Issues are welcome. **This is a one-person project: no response time is promised.**
For a bundled installer or a support contract, see the bottom of this file.

## License

MIT. The converters it calls have their own licenses.

---

**Need this installed for a team, or with a support contract?** Open an issue titled
`commercial` and I'll get back to you.

TDQS

A4.6/5.0

Scored across 1 tool

Disambiguation5/5

ツールが convert のみで、他のツールと混同する余地がまったくない。単一ツールのためエージェントが選択を誤る可能性はない。

Naming Consistency5/5

ツール名が convert という明確な動詞で統一されており、命名の不整合や混在が存在しない。単一ツールでも分かりやすい命名と言える。

Tool Count4/5

ツールは1つだけだが、ファイル変換というサーバーの目的に対して convert が広範な形式と操作をカバーしており、実用上は十分に機能する。数は少ないが、無意味に分割せず1つに集約した設計は妥当。

Completeness5/5

画像・動画・音声・文書・PDF・3Dモデル・Parquet など主要な変換対象を網羅し、PDF結合や画像連結、動画URL取り込み、上書き制御などの必要な操作も備えている。変換ドメインにおける大きな欠落は見当たらない。

Maintenance

ActivityMaintained
ResponsivenessNo issues