apple-books-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_all_collectionsA | List all collections in my Apple Books library. Output is one row
per collection: Args: limit: Max collections to return (1–500, default 200). offset: Collections to skip, for paging. |
| get_collection_booksA | List the books in a collection as lean rows: Args: collection_id: The collection's numeric ID. |
| describe_collectionB | Describe a specific collection in detail — title, details text, and the books contained in it. Args: collection_id: The collection's numeric ID. |
| search_collections_by_titleA | Search for collections by title (substring match). Output is one
row per match: Args: title: The title to search for. |
| create_collectionA | Create a new collection in the user's Apple Books library. Requires write access and Books to be quit; a backup is taken automatically. Args: title: Name for the new collection. details: Optional description. |
| rename_collectionA | Rename a user-created collection (built-in collections are refused). Requires write access and Books to be quit. Args: collection_id: The collection's numeric ID. new_title: The new name. |
| delete_collectionA | Delete a user-created collection (built-in collections are refused). The books inside are NOT deleted — only the collection. Requires write access and Books to be quit. Args: collection_id: The collection's numeric ID. |
| add_book_to_collectionC | Add a book to a collection (user-created collections and "Want to Read"). Idempotent. Requires write access and Books to be quit. Args: collection_id: The collection's numeric ID. book_id: The book's numeric ID. |
| remove_book_from_collectionA | Remove a book from a collection (the book stays in the library). Idempotent. Requires write access and Books to be quit. Args: collection_id: The collection's numeric ID. book_id: The book's numeric ID. |
| list_all_booksA | List all books in my Apple Books library. Output is one row per
book: Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging; a footer names the next offset when there are more. |
| describe_bookA | Describe a specific book in detail — metadata (title, author, genre,
page count), reading status (progress, last opened, finished date),
and annotation count. Also whether the chapter tools can read its
text ( Args: book_id: The book's numeric ID. |
| search_booksA | Search for books whose title or author contains Args: query: Text to find in the title or the author's name. limit: Max books to return (1–500, default 200). offset: Books to skip, for paging; a footer names the next offset when there are more. |
| search_books_by_titleA | Search for books by title (substring match, ignoring case, accents
and quote/dash style). Output is one row per match: Args: title: The title to search for. limit: Max books to return (1–500, default 200). offset: Books to skip, for paging; a footer names the next offset when there are more. |
| get_books_by_genreA | Get books whose genre matches the given string (substring match).
Output is one row per match: Args: genre: The genre to search for (e.g. "Romance", "Philosophy"). limit: Max books to return (1–500, default 200). offset: Books to skip, for paging. |
| get_books_in_progressA | Get books currently being read (progress > 0% and < 100%). Output
per row: Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging. |
| get_finished_booksA | Get books that have been finished. Output per row: Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging. |
| get_unstarted_booksA | Get books that haven't been started yet (0% progress). Output per
row: Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging. |
| get_recently_read_booksA | Get the most recently read books, newest first (by when each was
last opened or read, whichever is later).
Output per row: Args: limit: Max books to return (1–500, default 10). offset: Books to skip, for paging. |
| list_all_annotationsA | Browse all annotations grouped by book, most recent first. Rows:
Args: limit: Max annotations to return (1–500, default 50). offset: Annotations to skip, for paging; a footer names the next offset when there are more. |
| list_annotationsA | List annotations within a specific book in reading order (their
position in the book). Rows are lean —
Args: book_id: The book's numeric ID. limit: Max annotations to return (1–500, default 50). offset: Annotations to skip, for paging; a footer names the next offset when there are more. |
| get_highlights_by_colorA | Browse highlights of a particular color, grouped by book. Output is one row per highlight: Args:
color: |
| search_notesA | Search user notes (not highlights) by substring, grouped by book.
Output shows the highlighted passage on the primary row and the
matching note on a second line prefixed with Args:
note: Substring to find inside note bodies.
limit: Max annotations to return (1–500, default 50).
offset: Annotations to skip, for paging.
order_by: |
| search_annotationsA | Search across every annotation field — selected (highlighted) text,
the surrounding paragraph, and the user's note body. Grouped by
book; a row's note, if any, is on a second line prefixed with
Args:
text: Substring to match anywhere in an annotation.
limit: Max annotations to return (1–500, default 50).
offset: Annotations to skip, for paging.
order_by: |
| recent_annotationsA | Most recent annotations, newest first. Flat rows with the creation time (the server's local time zone) and book name inline so Claude can see chronology across books at a glance. Row format:: Args: limit: Max annotations to return (1–500, default 10). offset: Annotations to skip, for paging. |
| describe_annotationA | Describe a specific annotation in detail — text, note, book (with
an Args: annotation_id: The annotation's numeric ID. |
| get_annotation_contextA | Return the passage around a specific highlight — the text before
and after, with the highlight itself wrapped in Works for non-DRM EPUBs downloaded to this Mac; fails with a clear message for DRM-protected books, iCloud-only books, or older annotations that lack the chapter hint. Args: annotation_id: The annotation's numeric ID. chars_before: Chars of context before the highlight (0–5000). Default 500. chars_after: Chars of context after the highlight (0–5000). Default 500. |
| get_annotations_by_date_rangeA | Annotations created within a date range, newest first by default. Flat rows with the creation time and book name inline. Dates and times are in the Mac's local time zone, named in the header. Row format:: Args:
after: Only include annotations created on or after this date
(YYYY-MM-DD, or YYYY-MM-DDTHH:MM).
before: Only include annotations created on or before this
date (YYYY-MM-DD covers the whole day, or YYYY-MM-DDTHH:MM).
limit: Max annotations to return (1–500, default 50).
offset: Annotations to skip, for paging.
order_by: |
| list_book_chaptersA | List the table of contents for a book — chapter titles, order, and nesting depth. Only works for non-DRM EPUBs that have been downloaded to this Mac. Args:
book_id: The book's numeric ID (from |
| get_chapter_contentA | Return the plain-text content of a chapter, paginated by default
to protect the context window. Get Default Every response ends with a footer like one of:: Args:
book_id: The book's numeric ID.
chapter_id: Chapter identifier, the 1-based chapter order as a
string (e.g. |
| get_current_reading_positionA | Return where the user last left off reading a book — chapter
title and chapter_id, no text — and an Works for non-DRM EPUBs downloaded to this Mac. If Apple Books hasn't recorded a position, falls back to inferring from the user's most recent highlight (labeled as such in the output). Args: book_id: The book's numeric ID. |
| get_library_statsA | Get a summary of your Apple Books library with reading stats. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| weekly_digest | Summarize what I've read and highlighted in the past week. |
| library_snapshot | A reflection on my whole reading life — what I've read, what I'm reading, what's stuck. |
| revisit_book | Revisit your notes and highlights from a specific book. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| Currently Reading | A short pointer (a few hundred chars) to the in-progress book you opened most recently: its title, author, book id, reading progress and an Open in Books link, the chapter you left off on (title and chapter_id, or inferred from your latest highlight when Books hasn't recorded a position; or why its text can't be read), and how many highlights it has. It holds no chapter text and no highlight text; Claude fetches those on demand with get_chapter_content, list_annotations and get_annotation_context. |
TDQS
Scored across 31 tools
Most tools target distinct resources or actions (collections, books, annotations, chapters), and descriptions clarify differences like search_books vs search_books_by_title or list_annotations vs list_all_annotations. However, several listing/searching tools for the same resource overlap somewhat, requiring careful reading to pick the right one.
Names are predominantly snake_case with a clear verb_noun structure (list_, get_, describe_, search_, create_, rename_, delete_, add_, remove_). Minor inconsistencies include 'recent_annotations' lacking a verb prefix and filtered book lists using 'get_' while full lists use 'list_', but the overall pattern is readable.
31 tools is heavy for the domain; many could be consolidated (e.g., the four reading-status book filters, the multiple book search tools, the several annotation listing tools). While the domain is complex, the rubric flags 25+ as too many, and several tools feel redundant.
Read coverage is extensive (books, collections, annotations, chapters, stats), but there are notable gaps in write operations: no tools to create/update/delete annotations or notes, no book metadata editing, no reading progress updates, and no ability to add/remove books from the library. Collection CRUD exists, suggesting write support is intended, so these gaps limit full lifecycle coverage.