Replace all mcp__markitdown__convert_to_markdown invocations with the native `markitdown <path|url>` CLI (v0.1.6, on PATH). Outputs to stdout or `-o <file>`; sees the full host filesystem, so the Docker bind-mount caveat (host→container file:// translation, [Errno 2] /c:/Users/...) is gone and that whole section is removed. Updated the ingest pattern (-o straight into .wiki/raw/), gotchas table (command-not-found → check `markitdown --version`), and contrast table header (CLI, not MCP). Description triggers unchanged. PATCH bump 1.0.0→1.0.1; dist artifact rebuilt. Decommissioned the Docker MCP containers: no container is named `markitdown-mcp` (the server spawns anonymous ones from markitdown-mcp:latest, 3 had piled up); removed all by image ancestor. Left mcpServers.markitdown in ~/.claude.json untouched (out of scope) — flagged as a follow-up in the concept page. Wiki: concepts/using-markitdown-cli-migration.md + index + log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
59 lines
2.5 KiB
Markdown
59 lines
2.5 KiB
Markdown
---
|
||
title: using-markitdown — MCP → CLI migration
|
||
type: concept
|
||
updated: 2026-06-09
|
||
---
|
||
|
||
# using-markitdown — MCP → CLI migration
|
||
|
||
`using-markitdown` v1.0.0 → v1.0.1 (PATCH). Rewrote the skill from the Docker-based
|
||
`mcp__markitdown__convert_to_markdown` MCP tool to the native `markitdown` CLI (v0.1.6,
|
||
on `PATH`).
|
||
|
||
## Why
|
||
|
||
The MCP path ran markitdown inside a Docker container with a single host directory
|
||
bind-mounted (`-v C:\Users\vitya:/workdir`). That forced a brittle host→container path
|
||
translation for every local file (`file:///workdir/...`), and the failure mode
|
||
(`[Errno 2] No such file or directory: '/c:/Users/...'`) was a recurring foot-gun. The
|
||
container also could not see files outside its one mount.
|
||
|
||
The CLI is a normal local process: it sees the full host filesystem, takes a plain path
|
||
or URL as its positional arg, and writes markdown to stdout (or to a file with `-o`). No
|
||
mount, no path rewriting, no `file://` URIs. The whole "Docker-mount caveat (READ FIRST)"
|
||
section of the skill became dead weight and was removed.
|
||
|
||
## CLI contract
|
||
|
||
```
|
||
markitdown <path|url> # → markdown to stdout
|
||
markitdown <path|url> -o out.md # → write to a file
|
||
cat file.pdf | markitdown -x pdf # → stdin + format hint
|
||
```
|
||
|
||
Verified on this machine: `markitdown 0.1.6`; URL fetch (`markitdown https://example.com`)
|
||
and stdout conversion both work.
|
||
|
||
## Container cleanup gotcha
|
||
|
||
The task asked to run `docker stop markitdown-mcp && docker rm markitdown-mcp`. There was
|
||
**no container named `markitdown-mcp`** — the MCP server spawns a fresh anonymously-named
|
||
container from the `markitdown-mcp:latest` image per session, and three had piled up
|
||
(`sharp_jones`, `boring_goldberg`, `admiring_kowalevski`, ages 47s–28h). The correct
|
||
decommission is by image ancestor, not by name:
|
||
|
||
```
|
||
docker rm -f $(docker ps -aq --filter "ancestor=markitdown-mcp:latest")
|
||
```
|
||
|
||
(Stopping them races with the server's own `--rm` cleanup, briefly leaving "Dead"
|
||
containers that finish removing themselves — re-checking the filter confirms none remain.)
|
||
|
||
## Out of scope / follow-up
|
||
|
||
The `markitdown` **MCP server registration** in `~/.claude.json` was left untouched (the
|
||
task scoped only the running container, and editing user-global config is cross-cutting).
|
||
While that entry remains, a new container will respawn on the next session that loads the
|
||
MCP. A full decommission would deregister `mcpServers.markitdown` from `~/.claude.json` —
|
||
recommended as a separate, explicitly-confirmed step.
|