apple-books-mcp
π―SkillInstallation
npx skills add vladmdgolam/agent-skills --skill apple-books-mcpRun it in a terminal; it asks which AI coding tools to install it for (Claude Code, Codex, Cursor and more).
Uses skills.sh Β· Node.js 22.20+
After installing
Ask for related work and the agent uses it on its own, or call it yourself.
/apple-books-mcpInstall by hand
Copy the whole skill folder from GitHub to the place below. Copying only SKILL.md can leave out files the skill uses.
Open the skill folder β- This project
.claude/skills/apple-books-mcp/ - All projects
~/.claude/skills/apple-books-mcp/
These paths are for Claude Code. For other tools, the command above puts it in the right place.
SKILL.md
View on GitHub βExtracts highlights, annotations, and book data from Apple Books via MCP. Use when: user asks to export book highlights, extract annotations with colors, search highlights across books, create highlight summaries, or match books from a reading list against their Apple Books library. Covers efficient batch color extraction (5 calls instead of 150+), annotation-to-book matching, and markdown export patterns.
Apple Books MCP
MCP server: vgnshiyer/apple-books-mcp
Install: npx -y @anthropic-ai/claude-code mcp add apple-books -- uvx apple-books-mcp
Tools Reference
| Tool | Purpose |
|---|---|
list_all_books | List all books (ID, title, author) |
get_book_annotations | All annotations for a book by ID. No color data. |
describe_annotation | Full details for one annotation including color |
get_highlights_by_color | All highlights of one color across entire library |
search_highlighted_text | Search annotations by highlighted text |
search_notes | Search by user-written notes |
list_all_annotations | All annotations across all books |
list_all_collections | List collections |
get_collection_books | Books in a collection |
describe_book / describe_collection | Details by ID |
recent_annotations | Recently created annotations |
full_text_search | Full text search across books |
Critical: Color Extraction Strategy
get_book_annotations does NOT return colors. describe_annotation returns colors but one at a time β 150+ calls for a single book.
Solution: Call get_highlights_by_color once per color (5 total calls), then cross-reference annotation IDs programmatically.
Available colors: PINK, BLUE, YELLOW, GREEN, PURPLE
Underlines: color = null, is_underline = 1
Build the Color Map
import json, glob
# After calling get_highlights_by_color for PINK, BLUE, YELLOW, GREEN, PURPLE
# Results save to files when they exceed token limits
ann_color = {}
colors = ["PINK", "BLUE", "YELLOW", "GREEN", "PURPLE"]
for color_file, color in zip(sorted(glob.glob("path/to/results/*.txt")), colors):
with open(color_file, 'r') as f:
data = json.load(f)
current_id = None
for line in data.get("text", "").split("\n"):
line = line.strip()
if line.startswith("ID: "):
current_id = line.split("ID: ")[1].strip()
elif line.startswith("Selected text: ") and current_id:
selected = line[len("Selected text: "):]
if selected and selected != "None":
ann_color[current_id] = color
# Look up: ann_color.get(str(annotation_id), None) # None = underline
Workflow: Extract Highlights for a Book List
Step 1: Match Books
Call list_all_books and match against user's list. Tips:
- Books may appear under translated titles (e.g., Russian editions)
- PDFs often have garbled or filename-based titles
- Use partial/fuzzy matching β "Vignelli Canon" may appear as just "canon"
- Same book may exist in multiple editions (different IDs)
Step 2: Get Annotations per Book
get_book_annotations(book_id="531")
Returns: ID, selected_text, representative_text, note, chapter, location, modification date. Filter out entries where selected_text is None (empty bookmarks).
Step 3: Get Colors (Batch)
get_highlights_by_color(color="PINK")
get_highlights_by_color(color="BLUE")
get_highlights_by_color(color="YELLOW")
get_highlights_by_color(color="GREEN")
get_highlights_by_color(color="PURPLE")
Results are large (100k-400k chars). Use Python to parse.
Step 4: Export to Markdown
color_emoji = {
"PINK": "π©·", "BLUE": "π΅", "YELLOW": "π‘",
"GREEN": "π’", "PURPLE": "π£",
}
lines = [f"# {title}", f"**{author}**", "", "---", ""]
for ann_id, text in annotations:
color = ann_color.get(str(ann_id), None)
tag = color_emoji.get(color, "γ°οΈ") # γ°οΈ for underlines
lines.append(f"{tag} {text}")
lines.append("")
Annotation Data Structure
From describe_annotation:
{
"id": 2133,
"selected_text": "be impeccable with your word",
"representative_text": "The first agreement is to be impeccable...",
"note": null,
"is_underline": 0,
"style": 4,
"color": "PINK",
"chapter": null,
"location": "epubcfi(/6/12[c005]!/4/10,/1:26,/2/1:28)"
}
Style-to-Color Mapping
| Style | Color |
|---|---|
| 0 | Underline (no color) |
| 1 | Green |
| 2 | Blue |
| 3 | Yellow |
| 4 | Pink |
| 5 | Purple |
Examples
Example 1: Export All Highlights from a Reading List
User says: "Extract highlights from the books in my reading list"
- Read the user's list (file, note, etc.) to get book titles
list_all_booksβ match titles to IDs- For each matched book:
get_book_annotations(book_id=ID)β collect annotation IDs + text get_highlights_by_colorx5 β build color map- Python script combines annotations + colors β writes .md files per book
Example 2: Search for a Quote Across All Books
User says: "Find where I highlighted something about shadow work"
search_highlighted_text(text="shadow")β returns matching annotations with book context- If color needed:
describe_annotation(annotation_id=ID)for the few results
Example 3: Get All Pink Highlights
User says: "Show me all my pink highlights"
get_highlights_by_color(color="PINK")β all pink highlights across library- Group by book title for readability
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
list_all_books empty | Apple Books never opened | Open Apple Books app once |
| No annotations for a book | Book was read but not highlighted | Expected behavior |
describe_annotation color is null | It's an underline | Check is_underline field |
| Color results too large | Many highlights in library | Results auto-save to file; parse with Python |
| Book title doesn't match | Different edition/translation | Try author name or partial title |
selected_text is None | Bookmark, not a highlight | Filter these out |
More from this repository6
Helps an AI assistant work with Blender, the 3D app, through Blender MCP. It can inspect scenes, run Python scripts, and export 3D models for websites while keeping materials and file sizes in check.
Cinema 4D MCP expert skill for extracting scene data, writing C4D Python scripts, and controlling Cinema 4D through MCP tools, covering MoGraph extraction, animation baking, Redshift availability, and known error fixes.
Skill
Skill
Skill
Skill