A folder-based multimodal document format and CLI for AI-native research
Project description
mmdoc
A folder-based multimodal document format so AI agents can search, read, and edit image-bearing docs with ordinary file tools.
The problem
Research is text + tables + images, but Markdown can only reference images, not hold
them — and AI agents are now the primary readers. Content trapped in a screenshot is
invisible to grep; an agent can't see a referenced image without extra steps; converting
a .docx or Google Doc to Markdown silently drops the images; and rich copy-paste from
Google Docs or Notion has nowhere to land, because terminals strip everything but plain
text. The worst case is catastrophic: a Markdown file with base64-inlined images, read as
text, burns ~200k tokens per image while the model still can't see the image.
mmdoc fixes this once, at write time: convert content into a plain folder shape, and the read side needs nothing special — forever, for every tool and every agent.
The format in 10 lines
An mmdoc is a directory: exactly 1 index.md (the document) plus N co-located
image files at the folder root, referenced by relative path with descriptive alt text.
district-analysis/
index.md ← exactly 1 entry file: YAML frontmatter + Markdown body
img-001.png ← N images (0 or more), referenced as
img-002.jpg 
The alt text is a greppable one-sentence summary — rg "budget allocation" matches
the reference line, and an agent opens the actual image file only when it needs visual
detail. grep, git, and every editor already work; no new tooling is required to read one.
Install
Via Homebrew (includes pandoc):
brew install hsurick/mmdoc/mmdoc
Or from PyPI (then install pandoc yourself):
uv tool install mmdoc # or: pip install mmdoc
brew install pandoc
Then wire up Claude Code (installs the agent skill + the CLAUDE.md read convention):
mmdoc setup
60-second demo
Copy a chunk of a Google Doc — text and images — then:
mmdoc paste notes/
The text lands in notes/index.md and the images land as real files
(notes/img-001.png, …) next to it. Or skip the clipboard entirely and pull a
link-shared Google Doc directly:
mmdoc fetch "https://docs.google.com/document/d/<id>/edit"
Commands
| Command | What it does |
|---|---|
mmdoc init <name> |
Scaffold a new, empty mmdoc folder with a templated index.md. |
mmdoc normalize <src> |
Convert a document (.docx or base64 Markdown) into an mmdoc folder. |
mmdoc paste <target> |
Land the system clipboard (rich text, image, or text) in an mmdoc — appends or creates. |
mmdoc clip |
Snapshot the clipboard into a numbered staging dir (reference as {clip:N}). |
mmdoc fetch <url> |
Download a link-shared Google Doc (no OAuth) and convert it into an mmdoc folder. |
mmdoc export <target> |
Export an mmdoc folder to a single shareable file (html, docx, or pdf). |
mmdoc validate <target> |
Check that a folder is a well-formed mmdoc; exit non-zero on errors. |
mmdoc setup |
Wire mmdoc into Claude Code: install the skill + CLAUDE.md read convention. |
Agent integration
mmdoc setup wires Claude Code in one shot: it installs the bundled workflow skill to
~/.claude/skills/mmdoc/ and maintains a marker-delimited read-convention block in
~/.claude/CLAUDE.md (idempotent; --dry-run supported).
The read convention itself is three lines:
index.mdholds the text; alt text is a summary — read the image file only when you need visual detail.- Convert before read: never read a
.docxor a base64-blob.mddirectly into context; runmmdoc normalizefirst. - After editing an mmdoc, run
mmdoc validate <folder>.
The format is agent-agnostic: paste the same convention into an AGENTS.md (or any
equivalent instruction file) and any agent with file tools can work with mmdocs.
Spec & design docs
- FORMAT.md — the normative format specification (v0.1).
- CLI.md — CLI architecture and command specs.
- OVERVIEW.md — the problem, goal, and build plan.
- NOTES.md — background reasoning and prior-art survey.
Status
v0.1. Clipboard commands (paste, clip) are macOS-only for now (Linux via
xclip/wl-paste planned). Roadmap:
normalizesupport for Notion.zipexports.normalizesupport for loose/messy folders.- DocLang (
.dclg/.dclx) importer — bridges Docling document-AI pipelines (and PDFs) into mmdoc. - TextBundle interop — import/export the existing
.textbundleformat.
License
Apache-2.0. See LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mmdoc-0.1.1.tar.gz.
File metadata
- Download URL: mmdoc-0.1.1.tar.gz
- Upload date:
- Size: 60.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30d6342c7d641eadeced8d8f8e3518a15327e7ad1177a13b61777dc8fbddb845
|
|
| MD5 |
0c4e0b414324fa849d56f5ead8a00976
|
|
| BLAKE2b-256 |
8119def54b8476061f23c1e9a162ba176c1a52c82dfd2fb12036d25e3755614b
|
File details
Details for the file mmdoc-0.1.1-py3-none-any.whl.
File metadata
- Download URL: mmdoc-0.1.1-py3-none-any.whl
- Upload date:
- Size: 26.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
259ccba387d9731290d7456522dc764ac0c87586f0d74152c2553dbc2952d8e2
|
|
| MD5 |
578c21253ad6ea9f676b0697011e1e82
|
|
| BLAKE2b-256 |
b49dd162b06c73f68ec67fa26031e97afd9f22a997c67de8a263e1d2bfd68d19
|