kindle-export
Skill0 starsChanged 3 months agoMITView on GitHub
Converts a Markdown or HTML document to a reflowable EPUB3 and sends it to a Kindle via Send to Kindle email. PDFs are passed through untouched. Use when the user asks to read a document on their Kindle, e-reader, or "send this to Kindle".
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- nicolas-diez/personal-osedited, first seen Nov 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- nicolas-diez/personal-os★ 493% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 2 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 44
Resolve the source file: Use the path given as argument.
- Very specific: line 47
Ask for explicit confirmation before sending: Only then re-run with --send --yes.
- Very specific: line 65
No front-matter title → infer from the first # H1 (or <title>/<h1> for HTML), falling back to the filename.
- Distinctive: line 66
No author → send with no author: Never invent authorship.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Kindle Export
Purpose
Get a Claude-generated document onto a Kindle in one command.
Send to Kindle does not accept .md, so conversion is mandatory. The source file stays the source of truth; the EPUB is a derived artifact.
Scope (v1)
| Input | Behavior |
.md, .markdown | Convert to reflowable EPUB3 (pandoc) |
.html, .htm | Convert to reflowable EPUB3 (pandoc) |
.pdf | Pass through untouched. Amazon accepts native PDF, and PDF→EPUB is the most fragile conversion there is. Warn the user it arrives without reflow. |
.epub | Pass through untouched. It is already the target format; reconverting only adds a lossy round trip. Lets you send an EPUB built elsewhere. |
| anything else | Refuse with a clear message |
Deliberately not in scope: OCR, PDF reconstruction, EPUBCheck, MathML, Mermaid rendering, cover generation, typography CSS, compression, chunking. Amazon re-typesets the EPUB on ingest, so elaborate CSS is wasted work.
Artifact contract
Same contract as md-to-html-artifact:
- The source file is the source of truth.
- The EPUB goes to an
artifacts/folder beside the source file. - The artifact is updated in place, never versioned (
doc-v2.epub,doc-final.epubare wrong).
project/notes/
├── prep-entrevista.md
└── artifacts/
└── prep-entrevista.epubRequired behavior
- Resolve the source file. Use the path given as argument. If none, prefer the file the user just mentioned; if several are equally plausible, ask instead of converting all.
- Convert by running the script (never hand-roll the EPUB).
- Show the report and the recipient address.
- Ask for explicit confirmation before sending. Only then re-run with
--send --yes. - Never claim delivery. Send to Kindle returns no acknowledgement. The honest statement is "se envió", never "llegó".
Commands
# 1. Convert only (writes artifacts/<name>.epub, sends nothing)
python3 <skill-dir>/kindle_export.py path/to/document.md
# 2. Convert and send, after the user confirms the recipient
python3 <skill-dir>/kindle_export.py path/to/document.md --send --yes--lang sets the EPUB language (default es).
Metadata rules
- Title and author come from the YAML front matter when present.
- No front-matter title → infer from the first
# H1(or<title>/<h1>for HTML), falling back to the filename. - No author → send with no author. Never invent authorship.
Kindle-safe pass (minimal, on purpose)
Semantic emojis render poorly on e-ink, so a small map replaces them with words:
| Emoji | Replacement |
| ✅ | OK |
| ❌ | No |
| ⚠️ | Aviso |
| 📌 | Nota |
| 💡 | Idea |
| ⭐ | Destacado |
Extend it with an emoji_map.json beside the script. Keep it small.
Position decides the treatment. An emoji that opens a Markdown heading is decoration, not
content — substituting a word there corrupts the title and the TOC (## ⭐ Outputs would become
"Destacado Outputs"). So: leading emoji in a heading → deleted; emoji anywhere else → replaced
via the map. Deletions are never silent — the report lists every heading emoji removed. A heading
made up of only an emoji is left to the map instead, so it never ends up empty.
Text arrows (→), em dashes and × are content, not decoration: the pass leaves them alone.
Hard rule, enforced in code: the pass must never alter á é í ó ú ü ñ Á É Í Ó Ú Ü Ñ ¿ ¡. The script counts these characters before and after and aborts if any count changes. Do not weaken this check.
Hard rules (in code, not in the prompt)
- Size ceiling is 25 MB on the built message, not on the file. Gmail — not Amazon — is the binding limit. Above it Gmail swaps the attachment for a Drive link, Amazon receives a mail with no attachment, and it fails silently. The script measures the encoded message and refuses to send. It also warns above ~18 MB of raw attachment, since base64 adds ~37%.
- The App Password comes from the macOS Keychain (service
kindle-export, account = the sender address), withKINDLE_SMTP_PASSWORDas a fallback for non-macOS. The two addresses —KINDLE_EMAIL,KINDLE_SENDER_EMAIL— come from the environment. Never write a password, app password, or token into any file, and never ask the user to paste one into the chat. - If a credential does land in the conversation, say so plainly and tell the user to revoke it at https://myaccount.google.com/apppasswords before anything else. Do not use it, do not echo it, do not store it. Have the user run the send from their own terminal instead.
- Sending requires
--send; without a TTY it also requires--yes. Converting never sends. - Gmail rejects the account password — only an App Password works. The script's auth error explains how to generate one.
Report
The script prints a short terminal report: source, conversion, title, artifact path, size, emojis replaced, send status. Relay it as-is. Do not write a summary .md file.
Setup
One-time setup (approving the sender address with Amazon, generating the App Password, exporting the variables) is documented in README.md. The skill does not automate it — Amazon's approval list is manual by design.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

