--- 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 # → markdown to stdout markitdown -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.