Files
claude-skills/skills/using-markitdown/SKILL.md
vitya 9f54068de0 feat: migrate 12 personal skills + add build/install scripts
- skills/: editable sources for all 12 personal skills (caveman family,
  find-skills, project-bootstrap, task-status-wiki, using-context7,
  using-markitdown, wiki-maintainer, compress)
- dist/: built .skill archives, committed (cross-machine deploy without
  needing zip on the target)
- scripts/build.sh + build.ps1: zip skills/<name>/ into dist/<name>.skill;
  Windows fallback uses .NET ZipArchive (PS 5.1 Compress-Archive writes
  backslashes that break extraction on *nix)
- scripts/install.sh: copy skills/<name>/ into ~/.claude/skills/<name>/
  ($CLAUDE_SKILLS_DIR overrides target)
- .wiki/source/repo-layout.md, build-notes.md: design + gotchas
- .gitignore: keep dist/ tracked

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 10:42:33 +03:00

5.7 KiB

name, description
name description
using-markitdown Use when capturing external content into a markdown-based knowledge base, wiki `raw/` directory, or any pipeline that must preserve the source's full text — for web pages, PDFs, DOCX/PPTX/XLSX, EPUB, CSV/JSON/XML, ZIP archives, images (with OCR/EXIF), audio (with transcription), or YouTube URLs. Also use when WebFetch returned an LLM-summarized version but the raw content is what's needed.

using-markitdown

Convert almost any URI to plain markdown using Microsoft's markitdown MCP server. Returns raw textual content, not an LLM summary.

Tool

mcp__markitdown__convert_to_markdown(uri: string) → markdown string

uri accepts: http://, https://, file://, data:.

Local files — Docker-mount caveat (READ FIRST)

The markitdown MCP usually runs in a Docker container with a single host directory bind-mounted. The container does not see your full host filesystem. file:// URIs must point to the in-container path, not the host path.

  1. Open ~/.claude.json and find mcpServers.markitdown.args. Look for the -v flag — e.g. -v C:\Users\vitya:/workdir means host C:\Users\vitya is mounted at /workdir inside the container.
  2. Translate the host path to the container path before forming the URI.
  3. Forward slashes only inside the container path.

Example. Host file at C:\Users\vitya\modular\heart-and-mask\.wiki\raw\foo.html with mount C:\Users\vitya:/workdir:

file:///workdir/modular/heart-and-mask/.wiki/raw/foo.html

Symptom of getting this wrong: [Errno 2] No such file or directory: '/c:/Users/...' — the container literally tried to open the host-shaped path. The fix is path translation, not URL encoding.

If the file falls outside the mount: either copy it into the mounted tree, or extend the mount in ~/.claude.json (a Claude restart is required for MCP changes to take effect — MCP servers are spawned at session start).

Filenames. Non-ASCII filenames (Cyrillic, etc.) inside file:// URIs are flaky across the URL-encode → urllib → Docker → host-FS chain. Rename to Latin kebab-case before calling markitdown.

When to use

  • Filling a wiki's raw/ directory from a URL or local PDF/DOCX.
  • Datasheets, papers, blog posts, GitHub READMEs, Obsidian Web Clipper outputs, KiCad netlist exports — anything where the source text matters and lossy summarization would break later ingest steps.
  • Any time the next step is "save the source verbatim before summarizing".

When NOT to use

  • You only need a summary or an answer about a page → use WebFetch (cheaper, runs through a small model, returns prose).
  • The URI is GitHub/PR/issue/release content → use gh CLI (richer metadata, structured output).
  • The URI is private/authenticated (GDocs, Confluence, Jira, Slack, Notion, share.google/* sign-in walls) → markitdown receives the public-facing fallback page (sign-in screen, cookie banner) and returns that as markdown. Verify the result is real content before saving.
  • The URI is a browser-rendered web page the user is already viewing → ask the user to capture it via Obsidian Web Clipper (browser extension, runs Readability extraction client-side) and drop the resulting .md into raw/. Web Clipper output is dramatically cleaner than markitdown's HTML pass — no nav chrome, no sidebar history, no cookie banners — plus it carries YAML frontmatter (title / source URL / date) out of the box. Reserves markitdown for things browsers can't easily save (PDF, DOCX, PPTX, XLSX, EPUB, file:// resources). Note: rename the resulting file to Latin kebab-case before ingest (Web Clipper preserves the page <title> verbatim, often non-ASCII).

Pattern: ingest a remote source into a wiki

1. mcp__markitdown__convert_to_markdown(uri="https://example.com/foo.pdf")
2. Inspect the head of the result. If it looks like a sign-in/cookie/consent page, abort — ask the user for an alternative (manual save, paste, authenticated MCP).
3. Write the result to .wiki/raw/<slug>.md (kebab-case, Latin only).
4. Register the new file in .wiki/raw/README.md.
5. Hand off to the wiki ingest workflow (creates sources/<slug>.md summary + entity/concept updates).

Common gotchas

Symptom Cause Fix
Output is a Google/Microsoft sign-in page in some random language URI behind auth wall Ask user to export the content manually (Save as PDF, copy-paste) and put it in raw/
Output is mostly nav/cookie banner text Site is JS-rendered or anti-bot Try the cached or print URL; or ask user for HTML export
Output lacks images / diagrams Markdown is text-only by design Save the original asset separately under raw/assets/; reference it from the sources/ summary
Tool not available in session MCP server not loaded Confirm mcp__markitdown__convert_to_markdown appears via ToolSearch; load with select:mcp__markitdown__convert_to_markdown
Huge output (book-length) Whole document converted in one call Save raw, then summarize from the saved file — do not hold the entire markdown in working context

Quick contrast with WebFetch and Web Clipper

markitdown WebFetch Obsidian Web Clipper
Returns raw markdown of the source LLM answer about the source Readability-extracted markdown with YAML frontmatter
Use for PDF / DOCX / non-browser-friendly one-shot Q&A any browser-viewable web page
Auth-aware no no yes (uses the user's logged-in browser session)
Chrome / nav stripped partial (still verbose) n/a (model picks signal) yes (clean)
Handles PDFs / DOCX yes text-only HTML extraction no (web pages only)
Who triggers it Claude Claude the user (manual click)