Skip to main content
Glama
vgnshiyer

apple-books-mcp

by vgnshiyer

Apple Books MCP

Model Context Protocol (MCP) server for Apple Books.

Website PyPI License: Apache 2.0 Buy Me A Coffee

At a glance

  • Pick up where you left off — Claude sees the book you're reading, your progress and the chapter you're on, and pulls that chapter's text (chapter_id="current") and your highlights when it needs them.

  • Find any book — by title or author, ignoring case, accents and curly quotes, with a link that opens it in Apple Books.

  • Expand on any highlight — get the surrounding paragraph explained in context, with the exact anchor you marked shown in «...».

  • Revisit a book — pull your highlights, cluster them by theme, and quote you back to yourself.

  • Reflect on your reading — patterns across books, recurring ideas in your highlights, what you're actually drawn to.

https://github.com/user-attachments/assets/77a5a29b-bfd7-4275-a4af-8d6c51a4527e

And much more!

Related MCP server: Co-Reading MCP

Available Tools

List and search tools return one page at a time: 50 annotations or 200 books by default, limit between 1 and 500, and offset for the next page. When there is more, the output says so and names the next offset.

How results work:

  • Ids are integers: every row starts with one, as in [175] Title by Author, to pass on as book_id, annotation_id or collection_id. A numeric string such as "175" is accepted too; true, false and fractions are not ids.

  • A failure (an unknown id, a book that isn't downloaded, a bad color) comes back as an MCP error (isError) whose message names what to do next, often another tool to call. An empty result ("No books matched …") is a normal answer, not an error.

  • Text taken from your books (chapter text, the passage around a highlight, a table of contents, a book's description) is wrapped in <book_text>…</book_text>. The server's instructions tell Claude that this text is untrusted data from the book, never instructions to follow.

  • Highlights from books you've removed from the library are kept by Apple Books. They are shown per removed book, as "Removed book (asset 3F2A1B2C…)", after the books still in your library.

Collections

Tool

Description

Parameters

list_all_collections

List all collections

limit?: int (default: 200), offset?: int

get_collection_books

Get all books in a collection

collection_id: int

describe_collection

Get details of a collection

collection_id: int

search_collections_by_title

Search for collections by title

title: str

Editing collections (opt-in)

Off by default. Enable by adding --enable-writes to the server args:

"args": ["apple-books-mcp", "--enable-writes"]

With the Claude Desktop extension, turn on Allow editing collections in the extension's settings instead.

Apple provides no automation API for collections, so these write directly to the library database — behind guard rails: every write refuses while Books is open, takes an automatic WAL-safe backup first (~/.py_apple_books/backups/), validates the schema and aborts on drift, and only touches user-created collections (plus "Want to Read" membership). Deleting a collection never deletes the books in it.

⚠️ If iCloud sync for collections is enabled, direct edits may not propagate to other devices and can be reverted by a cloud re-sync.

Tool

Description

Parameters

create_collection

Create a new collection

title: str, details?: str

rename_collection

Rename a user-created collection

collection_id: int, new_title: str

delete_collection

Delete a user-created collection (books untouched)

collection_id: int

add_book_to_collection

Add a book to a collection (idempotent)

collection_id: int, book_id: int

remove_book_from_collection

Remove a book from a collection (idempotent)

collection_id: int, book_id: int

Books

Tool

Description

Parameters

list_all_books

List all books

limit?: int (default: 200), offset?: int

search_books

Find books whose title or author contains the query, ignoring case, accents and quote/dash style

query: str, limit?: int (default: 200), offset?: int

search_books_by_title

Search for books by title (same matching, titles only)

title: str, limit?: int (default: 200), offset?: int

describe_book

Get details of a particular book (metadata, progress, annotation count, description), whether its text is readable (see below) and an "Open in Books" link

book_id: int

list_annotations

Annotations for a book in reading order (id + text + chapter per row, with your notes)

book_id: int, limit?: int (default: 50), offset?: int

get_books_by_genre

Get books by genre (substring match)

genre: str, limit?: int (default: 200), offset?: int

describe_book has a Readable text line saying whether the chapter tools can read the book, and if not why: yes (EPUB), a PDF, DRM-protected, not downloaded (in iCloud only, an Apple Books Store title, or never downloaded) or a missing file. It is worked out from the library's records and file metadata, without opening the book: reading a file that is only in iCloud would make macOS download it.

Open in Books links (ibooks://assetid/…) open the book in Apple Books. They appear in describe_book, describe_annotation, get_current_reading_position and the Currently Reading resource.

Reading Status

Tool

Description

Parameters

get_books_in_progress

Get books currently being read

limit?: int (default: 200), offset?: int

get_finished_books

Get books that have been finished

limit?: int (default: 200), offset?: int

get_unstarted_books

Get books not yet started

limit?: int (default: 200), offset?: int

get_recently_read_books

Get the most recently read books

limit?: int (default: 10), offset?: int

Annotations

Tool

Description

Parameters

list_all_annotations

Browse every annotation grouped by book, newest first, with your notes

limit?: int (default: 50), offset?: int

recent_annotations

Get most recent annotations (flat, with date + book per row)

limit?: int (default: 10), offset?: int

describe_annotation

Get full details of a single annotation, with the book's "Open in Books" link

annotation_id: int

get_annotation_context

Text window around a highlight (the paragraph it's in), with the highlight marked «...»

annotation_id: int, chars_before?: int (default: 500), chars_after?: int (default: 500)

get_highlights_by_color

Highlights of a particular color, grouped by book

color: yellow|green|blue|pink|purple, limit?: int (default: 50), offset?: int, order_by?: newest|oldest

search_notes

Search user notes (shows highlight + note inline)

note: str, limit?: int (default: 50), offset?: int, order_by?: newest|oldest

search_annotations

Search across highlights + notes + surrounding text (shows notes inline)

text: str, limit?: int (default: 50), offset?: int, order_by?: newest|oldest

get_annotations_by_date_range

Annotations within a date range, inclusive of the before day, local time (flat, with date + book per row)

after?: YYYY-MM-DD, before?: YYYY-MM-DD, limit?: int (default: 50), offset?: int, order_by?: newest|oldest

Library Stats

Tool

Description

Parameters

get_library_stats

Get library summary with reading stats

None

Book Content

Only works for non-DRM EPUBs downloaded to this Mac (imported books, Project Gutenberg, Standard Ebooks, etc.). Apple Books Store purchases are usually FairPlay-protected and return a clear error, and iCloud-only books a "not downloaded" hint; describe_book's "Readable text" line tells in advance.

Tool

Description

Parameters

list_book_chapters

Table of contents for a book (chapter titles, order, nesting)

book_id: int

get_chapter_content

Plain-text content of a chapter, with optional offset + max_chars slicing. chapter_id="current" (the default) reads the chapter you're on in Apple Books

book_id: int, chapter_id?: str (default: "current"), offset?: int, max_chars?: int

get_current_reading_position

The chapter the user last left off reading (via Apple Books' auto-bookmark CFI), with an "Open in Books" link

book_id: int

Available Resources

Attachable data objects accessible from Claude Desktop's resource picker.

Resource

URI

Description

Currently Reading

apple-books://currently-reading

A short pointer to the book you're reading right now (the most recently opened in-progress book): title, author, book id, progress, an "Open in Books" link, the chapter you left off on with its chapter id (for non-DRM EPUBs; otherwise why its text can't be read), and how many highlights you have in it. It carries no chapter text or highlights; Claude fetches those on demand with get_chapter_content and list_annotations. Attach to any conversation to focus Claude on your current read.

Available Prompts

One-click workflows, accessible from Claude Desktop's prompt picker.

Prompt

Description

Arguments

weekly_digest

Summarize what I've read and highlighted in the past week

days?: int (default: 7)

library_snapshot

A reflection on my whole reading life

None

revisit_book

Revisit your notes and highlights from a specific book

book_title: str

Installation

Requirements

  • macOS, with Apple Books opened at least once (it creates the library the server reads).

  • Python 3.10 or newer. uvx and the Claude Desktop extension provide one if needed.

  • Installed with the server: mcp >= 1.12 (< 2) and py-apple-books >= 1.10 (< 2).

uvx runs apple-books-mcp without a separate install step.

brew install uv  # for macos
uvx apple-books-mcp --version

The first run downloads about 14 MB of dependencies and can take up to a minute, which is close to how long Claude waits for a server to start. Running the command above once in Terminal warms uv's cache before you add the server to Claude. --version prints the apple-books-mcp, mcp and py-apple-books versions uvx resolved.

Then add the server to Claude with the JSON config or the Claude Code command below.

Claude Desktop extension (.mcpb)

Claude Desktop can also install apple-books-mcp as an extension, without editing its config: download apple-books-mcp-<version>.mcpb from the latest GitHub release, double-click it (or open Settings → Extensions → Install Extension… and pick the file), and click Install. Desktop installs uv and the locked dependencies itself. Allow editing collections in the extension's settings does the same as --enable-writes.

On organization-managed Claude (Team/Enterprise), admins can limit Desktop Extensions to an allowlist or turn them off. If the .mcpb install is refused, use the JSON config below. If user-added MCP servers are also disabled by policy, ask your admin to approve the extension.

Using pip

Needs Python 3.10 or newer (the python3 that ships with macOS is 3.9). Install into a virtual environment:

python3 -m venv ~/.venvs/apple-books-mcp
~/.venvs/apple-books-mcp/bin/pip install apple-books-mcp
~/.venvs/apple-books-mcp/bin/apple-books-mcp --version

Upgrade later with ~/.venvs/apple-books-mcp/bin/pip install -U apple-books-mcp.

Using Docker (deprecated)

⚠️ The Docker image is deprecated and only partly works: a Linux container can't be granted the macOS permission, can't reach book files stored in iCloud Drive (so the tools that read book text fail), and can't tell whether Books is running (so collection writes are unsupported). Use uvx instead.

It can still serve library metadata and annotations. Mount the Apple Books container read-only and keep stdin open with -i. The image runs as an unprivileged user and reads the library from the same mount path as before:

docker run -i --rm -v ~/Library/Containers/com.apple.iBooksX/Data/Documents:/root/Library/Containers/com.apple.iBooksX/Data/Documents:ro ghcr.io/vgnshiyer/apple-books-mcp:latest

In a Claude config, spell out your home directory: Claude doesn't expand ~.

{
    "mcpServers": {
        "apple-books-mcp": {
            "command": "docker",
            "args": [
                "run", "-i", "--rm",
                "-v", "/Users/YOU/Library/Containers/com.apple.iBooksX/Data/Documents:/root/Library/Containers/com.apple.iBooksX/Data/Documents:ro",
                "ghcr.io/vgnshiyer/apple-books-mcp:latest"
            ]
        }
    }
}

First-run permission prompt (macOS)

The first time the server reads your library, macOS asks whether the program that started it may "access data from other apps", because Apple Books keeps its library in its own app container (~/Library/Containers/com.apple.iBooksX/). Click Allow.

macOS permission prompt: uvx would like to access data from other apps. Don't Allow / Allow.

macOS asks about the program Claude launches, not about apple-books-mcp itself:

  • uvx with the recommended Claude Desktop config (the prompt above);

  • the Python interpreter with the pip config;

  • claude when the server is configured in Claude Code;

  • your terminal app when you run the server by hand.

The permission belongs to that program, so anything else it launches can use it too. apple-books-mcp only reads the library, plus the book files for chapter text; it changes nothing unless you pass --enable-writes.

To check, run uvx apple-books-mcp --doctor in Terminal: it reports whether the program running it may read the library and, if not, how to fix it. Run that way it checks your terminal app's permission, which macOS asks about separately from uvx or Claude.

Asked again after an update? Homebrew's uv/uvx and Homebrew or uv-managed Python builds aren't signed by a registered developer, so after brew upgrade uv (or a Python upgrade) macOS treats them as a new program and asks again. Click Allow.

Clicked "Don't Allow"? Tools then fail with "macOS denied access to the Apple Books library". (Older releases failed at startup instead, with "No sqlite files found in … Please open Apple Books at least once".) This permission has no switch in System Settings. To be asked again, run:

tccutil reset SystemPolicyAppData

This clears the "data from other apps" decisions for all apps. Then quit and reopen Claude, and click Allow. Adding the program (e.g. /opt/homebrew/bin/uvx) to Full Disk Access in System Settings > Privacy & Security also works, but grants far more access.

Configuration

Claude Desktop Setup

Quit Claude Desktop (Cmd+Q) before editing ~/Library/Application Support/Claude/claude_desktop_config.json: Desktop rewrites the file while it runs, so edits made while it's open can be lost.

{
    "mcpServers": {
        "apple-books-mcp": {
            "command": "uvx",
            "args": [ "apple-books-mcp" ]
        }
    }
}

Plain apple-books-mcp still picks up new releases: uv checks PyPI for a newer version whenever its cached copy of the package index is more than 10 minutes old, which is usually the case when Claude starts. apple-books-mcp@latest gains nothing over that and makes uv build a fresh environment on every launch (3–12 s instead of about 1 s).

Faster or offline startup

Because uvx checks PyPI at launch, the server won't start while PyPI is unreachable. To avoid that:

  • Run uv tool install apple-books-mcp once. The same uvx config then uses the installed copy and starts in about a second without contacting PyPI. Installed copies don't update themselves: run uv tool upgrade apple-books-mcp to get new releases.

  • Or use "args": ["--offline", "apple-books-mcp"] to run whatever version uv has already cached (after at least one online run), without any network access.

Using pip

Point Claude at the script inside the virtual environment from Using pip, with your home directory spelled out:

{
    "mcpServers": {
        "apple-books-mcp": {
            "command": "/Users/YOU/.venvs/apple-books-mcp/bin/apple-books-mcp"
        }
    }
}

Claude Code Setup

Claude Code doesn't read the Claude Desktop config. Add the server with:

claude mcp add --scope user apple-books-mcp -- uvx apple-books-mcp

and check it with /mcp.

Environment variables

Set these in the server's "env" in the Claude config (e.g. "env": {"APPLE_BOOKS_MCP_THREADS": "4"} next to "args"), or with claude mcp add -e NAME=value.

Variable

Default

What it does

APPLE_BOOKS_MCP_ENABLE_WRITES

off

1, true or yes turns on collection editing, like --enable-writes.

APPLE_BOOKS_MCP_THREADS

8

How many tool calls run at once. 0 runs them one at a time on the server's event loop, as before 0.9. Lower values also cap memory on very large libraries.

APPLE_BOOKS_DATA_DIR

Apple Books' own folder

The Apple Books Documents folder to read (the one holding BKLibrary/ and AEAnnotation/).

APPLE_BOOKS_QUERY_TIMEOUT

30

Seconds a library query may run before it is stopped; 0 means no limit.

Troubleshooting

Where to look

  • uvx apple-books-mcp --doctor in Terminal checks the versions, finds the library, explains macOS permission problems and prints counts of what it read. It only reads, and never prints titles or text.

  • ~/Library/Logs/Claude/mcp-server-apple-books-mcp.log (named after your mcpServers key) has the server's own output, including Python tracebacks. For more detail, add "-v" to the args: the server then logs its version, the mcp and py-apple-books versions it runs with, and each request.

  • ~/Library/Logs/Claude/mcp.log lists failures. Its "Server started and connected successfully" line only means the process was launched, not that it works.

  • ~/Library/Logs/Claude/main.log records "Connected to apple-books-mcp (N tools)" when a Claude Code or Cowork session in Desktop loaded the tools.

  • uvx apple-books-mcp --version in Terminal shows which versions uvx resolves.

Common problems

  • "Connection closed", "Server disconnected" or "Server transport closed unexpectedly": the server exited at startup. Read the last error in the traceback in mcp-server-apple-books-mcp.log.

    • No module named 'mcp.server.fastmcp': uv picked an apple-books-mcp release older than 0.8.1 together with mcp 2.x, which removed the API those releases were built on (on Python 3.12 and older, uvx could even fall back to 0.1.2). 0.8.1 and newer work with Python 3.10+ and stay on mcp 1.x. Run uv cache clean apple-books-mcp, check that uvx apple-books-mcp --version reports 0.8.1 or newer, then quit and reopen Claude.

    • A No module named 'server' error in front of the real one is noise from releases before 0.8.4.

  • "Not ready after 60 seconds" or "Request timed out" at startup: the first launch was still downloading and installing dependencies. Run uvx apple-books-mcp --version once in Terminal, then reopen Claude.

  • "macOS denied access to the Apple Books library" (older releases: "No sqlite files found in …"): see First-run permission prompt.

  • "No Apple Books library store found": Apple Books hasn't created its library for this macOS user yet. Open Books once, then try again.

  • Stopping a response while a tool runs: since 0.9 a stopped tool call is answered immediately and the server keeps serving other sessions; the call's remaining work finishes in the background (a write that had already started still completes; one that hadn't started never runs).

  • "Extension apple-books-mcp not found in installed extensions" in main.log is harmless.

Getting Claude to retry

  • Claude Desktop chats: quit Claude completely (Cmd+Q) and reopen it. A server that failed to start isn't retried otherwise.

  • Claude Code and Cowork sessions in Desktop: start a new session; each new session retries the server.

  • Claude Code: run /mcp and reconnect apple-books-mcp, or restart Claude Code.

Upcoming Features

  • Highlight export: a book's highlights and notes in reading order, with chapter headings

  • Fewer, broader tools in 1.0, where today several overlap

  • Titles for removed books, where Apple Books' caches still hold them

  • PDF content access (currently EPUB-only)

Contribution

Thank you for considering contributing to this project!

Development

Clone the repository and let uv create the virtual environment and install the package with its dependencies:

uv sync
uv run apple-books-mcp --version
uv run pytest

To build the Claude Desktop extension locally, install the pinned packer, then build:

npm ci --ignore-scripts --prefix mcpb
uv run python scripts/build_mcpb.py

This writes dist/apple-books-mcp-<version>.mcpb and the registry's dist/server.json (--out DIR picks another folder). python scripts/build_mcpb.py --smoke dist/apple-books-mcp-<version>.mcpb installs the bundle the way Claude Desktop does and checks the server it starts.

Maintainers: publishing a GitHub release runs the release workflow, which checks the tag against every version field, publishes to PyPI, attaches the .mcpb to the release and publishes to the MCP Registry.

Debugging

Logs go to stderr, which Claude Desktop writes to ~/Library/Logs/Claude/mcp-server-<name>.log. Without flags the server logs only warnings and errors; -v adds startup details (versions, whether writes are enabled) and a line per request; -vv adds debug output from the MCP SDK.

With Claude Desktop

{
    "mcpServers": {
        "apple-books-mcp": {
            "command": "uv",
            "args": [
                "--directory",
                "/path/to/apple-books-mcp/",
                "run",
                "apple-books-mcp",
                "-v"
            ]
        }
    }
}

With inspector

npx @modelcontextprotocol/inspector uv --directory /path/to/apple-books-mcp run apple-books-mcp

Opening Issues

If you encounter a bug, have a feature request, or want to discuss something related to the project, please open an issue on the GitHub repository. When opening an issue, please provide:

Bug Reports: Describe the issue in detail. Include steps to reproduce the bug if possible, along with any error messages or screenshots.

Feature Requests: Clearly explain the new feature you'd like to see added to the project. Provide context on why this feature would be beneficial.

General Discussions: Feel free to start discussions on broader topics related to the project.

Contributing

1️⃣ Fork the GitHub repository https://github.com/vgnshiyer/apple-books-mcp
2️⃣ Create a new branch for your changes (git checkout -b feature/my-new-feature).
3️⃣ Make your changes and test them thoroughly.
4️⃣ Push your changes and open a Pull Request to main.

Please provide a clear title and description of your changes.

License

Apple Books MCP is licensed under the Apache 2.0 license. See the LICENSE file for details.

Available Tools

31 tools
add_book_to_collectionAdd a book to a collectionC
Idempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes
collection_idYes

TDQS

C2.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry idempotentHint=true, destructiveHint=false, readOnlyHint=false, so "Idempotent" is redundant. The description does add the write-access authorization requirement, which is genuine behavioral context beyond annotations. However, the garbled phrase "Books to be quit" is confusing and adds no usable trait.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and reasonably short, but the broken "Books to be quit" fragment wastes a sentence and undercuts clarity. The Args block duplicates information already in the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-param mutation with no output schema, the description covers the authorization prerequisite and idempotency, which is the essential gap-fill. But the garbled clause and lack of failure/edge-case behavior (e.g. what happens if the book is already present) leave it only partially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It only restates each parameter as a "numeric ID", which is already implied by the integer type in the schema; no format, valid range, or how to obtain the IDs is given. Minimal value added over the structured fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Add a book to a collection") and clarifies the scope of "collection" by naming user-created collections and "Want to Read". It implicitly contrasts with remove_book_from_collection, though it never names the sibling. Clear purpose, but no explicit sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a prerequisite ("Requires write access") but gives no guidance on when to use this versus alternatives, no preconditions on states (e.g. already-in-collection), and no exclusions. The agent is left to infer usage entirely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_collectionCreate a 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes
detailsNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this is a non-read-only, non-destructive, non-idempotent write, so the bar is lower. The description still adds meaningful context the annotations cannot convey: it requires write access, requires Books to be quit, and takes a backup automatically. It omits duplicate-title behavior and the creation response, keeping it out of the top band.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and preconditions are front-loaded in two tight sentences, then the Args block. The Args section largely restates the schema, which is mildly redundant but conventional and not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, no annotations beyond the safety hints, and a trivial two-parameter schema, the description covers what an agent needs: purpose, permissions, required app state, and backup behavior. Minor gaps (duplicate handling, return value) are acceptable given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does document both parameters: title as the collection name and details as an optional description. It compensates for the empty schema, though it adds no constraints such as uniqueness or length limits.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ("Create") and resource ("collection") scoped to the user's Apple Books library, which cleanly distinguishes it from siblings like rename_collection and delete_collection. It stops short of explicitly contrasting with those siblings, so it is clear but not maximally differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It supplies real preconditions (write access required, Books must be quit, automatic backup) that tell the agent when the tool is usable. However, it never routes the agent among alternatives (e.g., rename vs create, or what to do if the collection already exists), so usage guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_collectionDelete a collectionA
DestructiveIdempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
collection_idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, idempotentHint=true and readOnlyHint=false, so safety is covered. The description adds valuable non-obvious context: the contained books survive the deletion, built-in collections are rejected, and the app must be closed. That is meaningful disclosure beyond the structured hints.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the destructive action and the safeguard about books, then the prerequisites, then the arg. The Args line is slightly redundant with the sentence but does carry the numeric-ID detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter destructive tool with no output schema, the description covers effect scope, prerequisites, and refusal behavior. Return value is trivially implied (success/failure), so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% for the single parameter, so the description must compensate; it states the parameter is a numeric collection ID, which clarifies type and meaning. It adds no format or lookup guidance beyond that, so it is adequate rather than rich.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (delete) and resource (user-created collection), and immediately scopes it by excluding built-in collections. An agent can distinguish this from create_collection and rename_collection without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit preconditions (requires write access, Books must be quit) and an exclusion (built-in collections are refused). It doesn't name a sibling alternative, but the when/when-not guidance is clear and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_annotationDescribe an annotationA
Read-only

Describe a specific annotation in detail — text, note, book (with an Open in Books: link), chapter, color, creation date. For the passage around the highlight, call get_annotation_context instead.

Args: annotation_id: The annotation's numeric ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
annotation_idYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds valuable context beyond that by disclosing the fields returned (text, note, book with an Open in Books link, chapter, color, creation date), which matters since there is no output schema. It does not discuss auth or rate limits, but those are minor for a simple read.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The content is front-loaded in the first sentence with the alternative routing in the second, which is efficient. The trailing 'Args:' block restating the single obvious parameter is mild redundancy but conventional and not harmful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only describe tool with no output schema, the description is nearly complete: it names the fields returned and routes to the correct sibling. It stops short of noting any error behavior for an unknown ID, but the core need to call it correctly is met.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden, and it does identify annotation_id as 'the annotation's numeric ID'. That clarifies type and target, but adds little beyond the obvious given the tool name. Adequate but thin for the single parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (describe), resource (a specific annotation), and enumerates what detail is returned: text, note, book link, chapter, color, creation date. It also distinguishes itself from get_annotation_context, so an agent can tell the two apart without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names an explicit alternative (get_annotation_context) and the condition that selects it ('for the passage around the highlight'). This is exactly the when-to-use-the-other routing an agent needs to choose correctly between the two sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_bookDescribe a bookA
Read-only

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 (Readable text:, and why not), and an Open in Books: link (ibooks://assetid/...) that opens it in Apple Books.

Args: book_id: The book's numeric ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine context beyond that: the specific categories of returned data, a 'Readable text:' field explaining whether chapter tools can extract the text (and why not), and the ibooks:// link format. It stops short of describing any limits, but for a read-only lookup this is solid additional value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then details of the return content, then args. Every sentence contributes, particularly given there is no output schema. The Args section is slightly mechanical but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the full burden of explaining return values, and it does so thoroughly (metadata fields, reading progress, annotation count, readability, link). For a one-parameter read tool nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It documents the single parameter as 'the book's numeric ID', which clarifies identity but largely restates what the integer type in the schema already conveys. Adequate but minimal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (describe) and resource (a specific book), then enumerates exactly what the description returns: metadata, reading status, annotation count, text readability, and an Open in Books link. This clearly separates it from list/search siblings like list_all_books and search_books.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'Describe a specific book' implies it is used when you already have a book_id and want full detail on one book, but there is no explicit when-to-use, when-not-to-use, or named alternative (e.g., versus search_books or list_all_books). Usage is implied rather than guided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_collectionDescribe a collectionB
Read-only

Describe a specific collection in detail — title, details text, and the books contained in it.

Args: collection_id: The collection's numeric ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
collection_idYes

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds that the result includes title, details text, and contained books, which is useful content context but not deeper behavioral detail (no pagination, size, or error notes).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then lists what is returned and the single argument. No wasted sentences, though the 'Args:' block format is boilerplate rather than flowing prose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only lookup with no output schema, the description tells the agent what it does and what it returns. Only the missing routing against sibling list/get tools keeps it from being fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter. It contributes 'The collection's numeric ID', clarifying the type/format beyond the bare 'Collection Id' title, but offers nothing further such as where to obtain the ID.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Describe') and resource ('collection'), plus the fields returned (title, details text, books contained). It does not distinguish itself from the sibling get_collection_books, whose name suggests overlapping content, so sibling differentiation is missing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus get_collection_books, list_all_collections, or search_collections_by_title. The agent must infer usage entirely from the name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_annotation_contextGet the passage around a highlightA
Read-only

Return the passage around a specific highlight — the text before and after, with the highlight itself wrapped in «...». Use this to expand on a highlight without fetching the whole chapter.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
chars_afterNo
chars_beforeNo
annotation_idYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnlyHint and openWorldHint. The description adds substantial behavioral context beyond that: the «...» output formatting convention and explicit failure modes (DRM-protected, iCloud-only, or older annotations lacking the chapter hint) with promises of a clear error message.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and limitation notes are front-loaded and earn their place; the Args block is warranted given 0% schema coverage. Slightly verbose in formatting but no wasted sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly explains the return format (surrounding text with the highlight marked) plus failure modes. For a 3-param read tool with annotations covering safety, nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description bears full burden, and it delivers: annotation_id is identified as the numeric ID, and both chars_before and chars_after are documented with bounds (0–5000) and a default of 500. This fully compensates for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return the passage around a specific highlight') and clarifies the scope (text before/after with the highlight wrapped in «...»). This clearly distinguishes it from siblings like describe_annotation or get_chapter_content, which fetch metadata or full chapters.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit usage context: 'Use this to expand on a highlight without fetching the whole chapter.' This tells the agent when to prefer this over a heavier fetch, though it does not name a specific sibling alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_annotations_by_date_rangeAnnotations by date rangeA
Read-only

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::

YYYY-MM-DD HH:MM [id] text — chapter · Book Title

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: newest (default) or oldest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
afterNo
limitNo
beforeNo
offsetNo
order_byNonewest

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, covering safety. The description adds genuinely non-obvious behavior: timestamps are in the Mac's local time zone, 'newest' is the default order, and the exact row rendering (date, id, text, chapter, book title). No pagination limits or error behavior for malformed dates are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then the return format, then a compact Args block — a sensible order for an agent. Slightly verbose in the repeated 'Only include annotations created on or after/before this date' phrasing, but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly compensates by documenting the row format and time zone, and it covers all five optional parameters. It is complete enough to call correctly; the missing pieces are sibling routing and what happens on invalid or inverted date ranges.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does so: it documents accepted formats for after/before (YYYY-MM-DD vs YYYY-MM-DDTHH:MM, including the whole-day rule for before), the limit range 1–500 with default 50, offset as a paging skip, and the order_by semantics. Every parameter is meaningfully specified beyond its bare schema type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource with scope: annotations filtered by creation date range, ordered newest first. That scope distinguishes it from unfiltered siblings like list_all_annotations, but the description never names an alternative, so the agent must infer the split from sibling names alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is given, and no alternative is named despite several overlapping siblings (search_annotations, recent_annotations, list_all_annotations, list_annotations). The date-range framing implies a use case but the agent is left to infer routing entirely.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_books_by_genreFind books by genreA
Read-only

Get books whose genre matches the given string (substring match). Output is one row per match: [id] title by author (genre).

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
genreYes
limitNo
offsetNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description meaningfully adds the substring-match semantics, the exact output row shape, and the 1-500 limit range, which go beyond structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded: purpose first, then output format, then args. Every line earns its place with no filler, though the prose is slightly verbose in the arg section.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the return row format, and it documents all parameters plus pagination. Read-only behavior is covered by annotations. Adequate and nearly complete for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the load, and it documents all three parameters: genre with concrete examples, limit with max and default (1-500, default 200), and offset as a paging offset. It adds constraints not present in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get books whose genre matches') and clarifies it is a substring match, which is more precise than the bare name. It does not explicitly name a sibling such as search_books or list_all_books to differentiate, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the genre-search framing, but there is no explicit when-to-use guidance or when to prefer this over search_books / list_all_books. No exclusions or alternative routing are provided.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_books_in_progressBooks in progressA
Read-only

Get books currently being read (progress > 0% and < 100%). Output per row: [id] title by author with a progress summary below.

Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful return-format detail ('[id] title by author' rows plus a progress summary) that the annotations do not provide. It stops short of describing ordering or pagination edge behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short lines, purpose front-loaded, then output shape, then args. No filler or restated title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only filtered list with no output schema, the description supplies the filter semantics, the return row format, and both parameters' meaning. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it does explain both parameters: limit with its 1–500 range and 200 default, and offset framed as paging. The schema only lists names and defaults, so this adds real meaning, though it omits what happens when offset exceeds the result count.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get books currently being read') and pins the scope precisely with the progress filter (>0% and <100%), which cleanly separates it from siblings like get_finished_books, get_unstarted_books, and get_recently_read_books. It also previews the output shape.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The inclusion criteria make the when-to-use condition clear: books with partial progress. However, it never names an alternative tool (e.g. use get_finished_books for completed items) or states exclusions, so routing is inferred from the filter rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_chapter_contentGet chapter textA
Read-only

Return the plain-text content of a chapter, paginated by default to protect the context window. Get chapter_id from list_book_chapters or from the (ch=...) suffix on annotation listing rows, or pass "current" (the default) for the chapter the user is reading in Apple Books. Works for non-DRM EPUBs downloaded to this Mac.

Default max_chars=10000 (~2500 words) fits most chapters in one call. Longer chapters return a slice with a footer naming the exact offset to pass next. At most 50000 chars are returned per call.

Every response ends with a footer like one of::

(full chapter returned: 4,872 chars.)
…(returned chars 0–10000 of 24,311 [10000 chars]. Call again with
  offset=10000 to continue; 14,311 chars remaining.)
(returned chars 20000–24311 of 24311 [4311 chars]. End of chapter.)

Args: book_id: The book's numeric ID. chapter_id: Chapter identifier, the 1-based chapter order as a string (e.g. "5"), or "current" (the default): the chapter of the user's reading position. A chapter whose id is literally "current" wins. offset: Character offset to start from. Defaults to 0. max_chars: Max chars to return (1–50000). Default 10000.

ParametersJSON Schema
NameRequiredDescriptionDefault
offsetNo
book_idYes
max_charsNo
chapter_idNocurrent

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover readOnlyHint and openWorldHint; the description adds substantial behavior beyond that: default pagination, the 50000-char hard cap, what the footer looks like and how to continue, the 'current' reading-position semantics, and the non-DRM EPUB limitation. These are exactly the traits an agent needs to call it correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then pagination behavior, then args. Slightly long due to three footer examples, but each illustrates a distinct return state (full, mid-chapter, end-of-chapter), so the space is largely earning its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description documents the return shape via footer examples and continuation semantics, and contextualizes input sources. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the load — and it does: book_id, chapter_id (1-based order, "current" default, literal-'current' edge case), offset (start position), and max_chars (1–50000 range, 10000 default). All four parameters are meaningfully documented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Return the plain-text content of a chapter.' It also scopes itself immediately via 'paginated by default' and 'Works for non-DRM EPUBs,' which distinguishes it from the listing/routing siblings like list_book_chapters.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear routing context: 'Get chapter_id from list_book_chapters or from the (ch=...) suffix on annotation listing rows, or pass "current".' This tells the agent where inputs come from, but stops short of stating when to avoid this tool or an alternative to prefer.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_collection_booksList a collection's booksA
Read-only

List the books in a collection as lean rows: [id] title by author. Descriptions are intentionally omitted — collections with many books would otherwise emit tens of thousands of chars of marketing blurb. Use describe_book(id) for details on any specific book.

Args: collection_id: The collection's numeric ID.

ParametersJSON Schema
NameRequiredDescriptionDefault
collection_idYes

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine behavioral value by disclosing the return format (lean rows) and the deliberate omission of descriptions, explaining the tradeoff. It stops short of noting pagination or ordering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core behavior, then a justified sentence on the omitted descriptions, then the alternative. No wasteful padding; the explanation of the lean-row design earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, but the description compensates by specifying the exact return shape ('[id] title by author') and pointing to describe_book for richer data. Nothing needed to call or interpret the result is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry parameter meaning, and it does document collection_id as 'the collection's numeric ID'. With a single, simple required parameter this is sufficient, though it adds little beyond the schema's integer type.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the books in a collection') and even specifies the exact output shape ('[id] title by author'). It clearly distinguishes itself from siblings like list_all_books and describe_book.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: use describe_book(id) when details on a specific book are needed, and implies a lightweight listing here. The condition for choosing the alternative is stated, not left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_current_reading_positionCurrent reading positionA
Read-only

Return where the user last left off reading a book — chapter title and chapter_id, no text — and an Open in Books: link to the book. Follow up with get_chapter_content for the text.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint=true, openWorldHint=false), yet the description adds real behavioral context: a platform/format limitation, and a fallback path that infers position from the most recent highlight and labels it as such. The only omitted details are error behavior for a missing/invalid book_id.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core return value, then the follow-up action, then applicability limits, then the arg. Every sentence carries new information with no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description appropriately describes the returned fields and the fallback labeling, so an agent knows what it will receive. Missing only failure-mode guidance (unknown book_id, DRM books) for full completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden, and it does: 'book_id: The book's numeric ID' clarifies the expected type beyond the bare integer title. It adds little else (no ID discovery pointer), so it is helpful but not exhaustive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return where the user last left off reading a book') and enumerates exactly what comes back (chapter title and chapter_id, no text) plus an Open in Books link. Combined with the routing hint to get_chapter_content, an agent can distinguish this from sibling chapter/annotation tools without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives an explicit chaining instruction ('Follow up with get_chapter_content for the text') and scopes applicability ('Works for non-DRM EPUBs downloaded to this Mac'). It stops short of naming sibling alternatives such as get_books_in_progress, but the use condition is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_finished_booksFinished booksA
Read-only

Get books that have been finished. Output per row: [id] title by author with a progress summary below.

Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely new behavioral context beyond the annotations: the exact per-row output shape ('[id] title by author') plus a progress summary, which an agent needs to parse results. It stops short of describing ordering or the progress summary's contents.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the purpose and output format, and the Args block is compact. It is well-sized for a two-parameter list tool, though the bare 'Args:' block is slightly boilerplate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully compensates by specifying the return row format, and it covers both parameters. Missing pieces are sort order and what the 'progress summary' contains, which would matter for an agent assembling a reading-status answer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning and it largely does: limit is documented with its range (1–500) and default (200), and offset is explained as a paging skip count. The only gap is that offset's bounds and the meaning of the default are not stated.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get books that have been finished'), which is immediately distinguishable from in-progress/unstarted siblings by the status qualifier. It does not, however, explicitly name or contrast with the nearest siblings (get_books_in_progress, get_recently_read_books), so it falls short of the top score.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use or when-not-to-use guidance is given; the agent must infer from the tool name that this is the status-filtered list and not, say, get_recently_read_books. Usage is implied rather than stated, and no exclusions or alternatives are mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_highlights_by_colorHighlights by colorA
Read-only

Browse highlights of a particular color, grouped by book.

Output is one row per highlight: [id] text — chapter. The book's name is shown once in the header, with a count of matching highlights on this page.

Args: color: yellow, green, blue, pink, or purple. limit: Max annotations to return (1–500, default 50). offset: Annotations to skip, for paging. order_by: newest (default) or oldest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
colorYes
limitNo
offsetNo
order_byNonewest

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description still earns credit by disclosing the actual return shape (one row per highlight as [id] text — chapter, book name in header with a page count) and by explaining that limit/offset drive paging, which is real behavioral context for a tool with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first line, followed by a compact output-format explanation and a clean Args block. Every sentence carries information and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description helpfully describes the rendered result and documents all four parameters, so an agent has enough to call it correctly. It stops short of routing between this tool and the other annotation-listing siblings, which is the one remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the burden and largely does: it names the color values, gives the limit range (1–500) and default, explains offset as paging, and lists the order_by options with defaults. Only minor value is added beyond the enum lists already present in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (browse) and resource (highlights) scoped by color and grouping by book, so the agent knows exactly what it returns. It does not, however, contrast itself with near-siblings like list_annotations, search_annotations, or recent_annotations, so differentiation relies on the name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer it is the tool for pulling highlights of one color, but there is no explicit when-to-use statement, no mention of when a sibling like search_annotations would be preferable, and no prerequisite or exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_library_statsLibrary statsA
Read-only

Get a summary of your Apple Books library with reading stats.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds only the hint that output is a 'summary ... with reading stats', without saying what is aggregated, whether counts are lifetime or filtered, or whether the result is cheap to call repeatedly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler or redundancy. Nothing could be trimmed without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema present, the description carries the burden of describing the return value, and 'summary ... with reading stats' is too vague to tell an agent what fields or metrics come back. Given the tool is a zero-param, low-risk read, this is adequate but leaves an information gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline of 4 applies. There is nothing in the schema for the description to clarify, and it correctly does not invent parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb (Get) and resource (summary of Apple Books library with reading stats). It is implicitly distinct from the many list/search siblings because it is the only aggregate/summary tool, but the description never explicitly contrasts itself with the per-book or per-collection listing tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent can infer you call this for an overview rather than a filtered list, but no when-to-use or when-not-to-use condition is stated, and no alternative sibling is named (e.g. get_books_in_progress, get_finished_books).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recently_read_booksRecently read booksA
Read-only

Get the most recently read books, newest first (by when each was last opened or read, whichever is later). Output per row: [id] title by author with a progress summary below.

Args: limit: Max books to return (1–500, default 10). offset: Books to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the return shape per row ('[id] title by author' plus a progress summary) and the exact sort key, which annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and ordering come first, the output format follows, and the two parameters are listed compactly. Every sentence carries information with no padding or repetition of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description correctly compensates by describing the per-row format and progress summary, and it documents both parameters. It lacks interaction notes (e.g., behavior when offset exceeds results or how progress is computed), so it is strong but not exhaustive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameters, and it does: limit is documented with its 1-500 range and default of 10, and offset is identified as the paging offset. The offset explanation ('Books to skip, for paging') is thin and omits its default, keeping this under a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get the most recently read books') and pins down the ordering rule (last opened or read, whichever is later), which separates it from siblings like get_books_in_progress or get_finished_books. It doesn't explicitly name an alternative tool, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The sort semantics imply when this tool is appropriate (surfacing recent activity), but there is no explicit when-to-use/when-not guidance and no mention of alternatives such as list_all_books or get_books_in_progress. Usage is inferable but not directed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_unstarted_booksUnstarted booksA
Read-only

Get books that haven't been started yet (0% progress). Output per row: [id] title by author with a progress summary below.

Args: limit: Max books to return (1–500, default 200). offset: Books to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description goes beyond them by disclosing the return shape per row ('[id] title by author' with a progress summary) and that offset exists for paging — real behavioral context, especially useful with no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded summary sentence followed by a compact Args block; no filler. The Args section partially restates schema defaults, but the added range and output format justify the length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and no annotation coverage of results, the description supplies the output format itself, plus the result cap and paging mechanism. Nothing essential for calling this read-only list tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameters, and it does: both limit and offset are explained. It adds the 1–500 bound for limit, which the schema omits (only a default of 200 is present), and clarifies offset's paging role.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('get books') and pins the scope with a precise filter: 'haven't been started yet (0% progress)'. That filter implicitly separates it from get_books_in_progress and get_finished_books, though those siblings are never named explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 0%-progress filter implies when to reach for this tool versus the in-progress/finished variants, but there is no explicit when-to-use, when-not-to-use, or named alternative. Usage must be inferred from the scope definition alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_all_annotationsList all annotationsA
Read-only

Browse all annotations grouped by book, most recent first. Rows: [annotation_id] <text> — <chapter title> (ch=<id>), with the user's note, if any, on a second line prefixed with ↳ note:. Pass ch=<id> to get_chapter_content for the chapter, or call get_annotation_context(annotation_id) for the passage around a specific highlight.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine value beyond that: the exact row rendering, the note prefix convention, and the footer that names the next offset, all of which shape how the agent consumes results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and output shape, then arguments. Dense but every element (row template, note prefix, paging footer, range) informs correct invocation; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description rightly specifies the return format and paging footer. Combined with the argument docs, an agent has enough to call and interpret the tool; only the lack of explicit alternative-routing keeps it from full marks.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameters, and it does: 'limit' is given a range (1-500) and default (50), and 'offset' is explained as the skip count for paging. The 1-500 range is information found nowhere in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Browse all annotations') plus grouping ('by book') and ordering ('most recent first'), which distinguishes it from filtered siblings like search_annotations. It does not explicitly contrast against the closely-named list_annotations or recent_annotations, so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides downstream workflow context (pass ch=id to get_chapter_content, call get_annotation_context for a passage) and paging behavior, but never states when to choose this over search_annotations, recent_annotations or get_annotations_by_date_range. Usage is implied rather than framed against alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_all_booksList all booksA
Read-only

List all books in my Apple Books library. Output is one row per book: [id] title by author. Use describe_book(id) for details on any 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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered; the description adds useful behavior beyond that, disclosing the exact row format and the pagination footer that names the next offset. It stops short of stating auth needs or ordering guarantees, but adds real value over the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, followed by output shape, the alternative tool, then args. Three compact blocks with no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description supplies the return format and paging semantics, and parameters are fully specified. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the parameter burden and does: limit is bounded (1–500, default 200) and offset is explained as paging with a footer naming the next offset when more results exist. This is meaning well beyond the bare integer properties in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all books in my Apple Books library') and the scope word 'all' implicitly separates it from filtered siblings such as search_books, get_books_by_genre, and get_books_in_progress. The one-line output format ('[id] title by author') further pins down what this tool returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent onward: 'Use describe_book(id) for details on any book.' However, it never states when to prefer this over search_books or get_collection_books, so it gives a clear follow-up path but no exclusions among the many list/search siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_all_collectionsList collectionsA
Read-only

List all collections in my Apple Books library. Output is one row per collection: [id] title. Use describe_collection(id) for details or get_collection_books(id) to list its books.

Args: limit: Max collections to return (1–500, default 200). offset: Collections to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuinely new behavioral context: the row-per-collection output format (`[id] title`) and that offset enables paging, which the annotations do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then output shape, then alternatives, then args — a logical order with no wasted prose. The Args block slightly duplicates defaults already in the schema, but the added range justification earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only list tool with no output schema, the description supplies the missing return-format detail (`[id] title`), pagination guidance, and sibling routing. Nothing an agent needs to invoke it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must carry the burden, and it does: it explains limit (range 1–500, default 200) and offset ('collections to skip, for paging'). The 1–500 range is meaningful added detail not present in the bare integer schema, though the default values merely repeat the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (all collections in the Apple Books library) with an explicit scope of 'all'. This cleanly distinguishes it from filtered siblings like search_collections_by_title and the detail-oriented describe_collection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the follow-up alternatives explicitly ('describe_collection(id) for details', 'get_collection_books(id) to list its books'), giving clear routing context. It does not state when to prefer search_collections_by_title over this enumeration, so it stops short of the full when/when-not bar.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_annotationsList a book's annotationsA
Read-only

List annotations within a specific book in reading order (their position in the book). Rows are lean — [annotation_id] <text> — <chapter> (ch=<id>) — with the user's note, if any, on a second line prefixed with ↳ note:.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo
book_idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

readOnlyHint=true and openWorldHint=false already establish the safety profile, so the bar is lower. The description adds real value beyond them: the exact row layout, the second-line note prefix, and the pagination-footer behavior ('a footer names the next offset when there are more') are behavioral details not available in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded and the Args block is tightly scoped. The inline row-format snippet is slightly heavy but earns its place by telling the agent what the return text looks like.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a lean, no-output-schema, read-only list tool, the description is complete: it covers the return format, note handling, and the pagination contract an agent needs to page correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries full burden and does: book_id as numeric ID, limit as 1-500 with default 50, and offset explained as a skip count for paging. All three parameters gain meaning beyond the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with an explicit scope: 'List annotations within a specific book in reading order'. The 'within a specific book' qualifier implicitly separates it from list_all_annotations, but it never names a sibling, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the per-book scoping. The description never says when to prefer this over list_all_annotations, search_annotations, recent_annotations, or get_annotations_by_date_range, nor does it state prerequisites or exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_book_chaptersList a book's chaptersA
Read-only

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 list_all_books or similar).

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuinely useful context beyond that: the DRM and local-download constraints that determine success or failure. It stops short of describing failure behavior for nested/edge-case EPUBs, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose, the return contents, and the key constraint all appear in the first two lines, followed by a compact Args block. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description is responsible for the return shape, and it does describe the TOC fields. Combined with the precondition note, an agent has enough to call it correctly, though nothing is said about empty results or chapters-without-TOC cases.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% on a single parameter, so the description must carry the burden — and it does, stating the ID is numeric and pointing to list_all_books as the source. It is slightly under-specified on whether the ID is a library ID versus an external identifier.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the table of contents for a book') and immediately enumerates the returned fields (titles, order, nesting depth), which cleanly separates it from the sibling get_chapter_content that fetches chapter bodies.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear precondition — only non-DRM EPUBs already downloaded to this Mac — which tells the agent when the tool will fail. It does not name an alternative tool or explicitly route the agent elsewhere, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recent_annotationsRecent annotationsA
Read-only

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::

YYYY-MM-DD HH:MM [id] text — chapter · Book Title

Args: limit: Max annotations to return (1–500, default 10). offset: Annotations to skip, for paging.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
offsetNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=true and openWorldHint=false, and the description usefully adds that timestamps are in the server's local time zone plus the exact row layout returned. It does not cover edge behavior such as what happens with an out-of-range offset or an empty result set, keeping it below a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line summary, then a format block, then args. Every element is relevant, though the multi-line row-format example is slightly more elaborate than needed for a two-parameter read tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, describing the row format is the right call, and both parameters are fully documented. Minor gaps remain around empty-result and paging-limit behavior, but an agent has enough to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden, and it does: 'limit' is documented with a range (1-500) and default (10) that the schema lacks, and 'offset' is explained as a paging skip count.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource ('annotations') with a clear recency scope and ordering ('Most recent ... newest first'). This distinguishes it in spirit from list_all_annotations and search_annotations, though it never names those siblings explicitly, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'so Claude can see chronology across books at a glance' implies the browsing use case, but there is no explicit when-to-use or when-not-to-use guidance relative to list_annotations, list_all_annotations, or search_annotations. Usage is inferable but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_book_from_collectionRemove a book from a collectionA
DestructiveIdempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
book_idYes
collection_idYes

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and idempotentHint=true, so 'Idempotent' repeats structured data. However, the description adds value the annotations don't carry: the precondition 'Requires write access and Books to be quit' and the scope note that the book survives the removal. These are genuine behavioral context beyond the structured fields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and its key scope caveat in the first sentence, then layers idempotence and prerequisites. The Args block restates parameter names already present in the schema, which is mildly redundant but keeps the definition self-contained and scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 2-param destructive tool with no output schema, the description covers the essentials: what happens (unlink, not delete), the precondition (write access, Books quit), and idempotence. Nothing critical for correct invocation is missing, though return/error behavior is unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry parameter meaning, and it does document both required params (collection_id and book_id) as numeric IDs. This compensates for the schema gap, though the detail is thin – no format, bounds, or example values beyond 'numeric ID'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Remove a book from a collection') and immediately disambiguates scope with '(the book stays in the library)'. This distinguishes it from delete_collection and from destructive library-level operations, so an agent can place it correctly without opening a sibling schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The parenthetical clarifies what the tool does NOT do (the book isn't deleted), which implicitly contrasts with destructive siblings, but there is no explicit when-to-use guidance or named alternative (e.g., add_book_to_collection or delete_collection). Usage is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

rename_collectionRename a collectionA
DestructiveIdempotent

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
new_titleYes
collection_idYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly=false, idempotent=true, destructive=true). The description adds operational context beyond them: write access required, the app must be quit, and built-in collections are rejected. It does not describe reversibility or return behavior, keeping it below top marks.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded first sentence carries the key scope, followed by prerequisites and a compact Args block. Slight redundancy between the title/name and the Args labels, but nothing wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-param mutation with annotations covering safety and no output schema, the description supplies the needed preconditions and both parameter meanings. Only minor gaps remain (no statement of what happens to the old title or the response shape).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry the params. It documents both: collection_id as the numeric ID and new_title as the new name, which meaningfully clarifies semantics the bare schema titles do not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Rename a ... collection') and immediately scopes it ('user-created ... built-in collections are refused'). This clearly separates it from siblings like create_collection, delete_collection, and describe_collection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear exclusion (built-in collections are refused) plus prerequisites (write access, Books must be quit). It does not name alternative tools, but the operation's context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_annotationsSearch annotationsA
Read-only

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 ↳ note:. Use search_notes when you only want to find your own written notes.

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: newest (default) or oldest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
textYes
limitNo
offsetNo
order_byNonewest

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds genuine behavioral context beyond that: results are grouped by book and a row's note appears on a second line prefixed with '↳ note:'. It doesn't state whether a total count is returned for paging, a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and output format are front-loaded before the alternative and the Args block. Every sentence carries information, though the docstring-style Args section duplicates what a well-documented schema would hold, adding slight redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only search tool with no output schema, the description covers purpose, result grouping/format, the sibling alternative, and all four parameters. It stops short of noting pagination totals or result-size expectations, but nothing critical to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden and does so completely: text is 'Substring to match anywhere', limit is '1–500, default 50', offset is 'Annotations to skip, for paging', and order_by is 'newest (default) or oldest'. All four parameters gain meaning not present in the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (search) and resource (annotations) plus the scope of the search: 'across every annotation field — selected text, the surrounding paragraph, and the user's note body.' It also explicitly distinguishes itself from the sibling search_notes, so an agent can tell them apart without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the key alternative with a selecting condition: 'Use search_notes when you only want to find your own written notes.' However, it gives no guidance relative to other annotation siblings like list_annotations, recent_annotations, or get_annotations_by_date_range, so routing is only partial.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_booksSearch books by title or authorA
Read-only

Search for books whose title or author contains query, ignoring case, accents and quote/dash style ("don't" finds "Don’t", "godel" finds "Gödel"). Output is one row per book, by book id: [id] title by author. Use describe_book(id) for details.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
queryYes
offsetNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this as a safe read (readOnlyHint=true, openWorldHint=false), so the bar for added context is met by real substance: case/accent/quote-dash-insensitive matching, the one-row-per-book output shape, and the paging footer behavior. This discloses matching semantics and return behavior that no annotation or schema field conveys.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and matching behavior are front-loaded in the first sentence, then output format, then the sibling pointer, then per-arg docs. Slight redundancy between the prose output note and the Args block, but with 0% schema coverage the Args section earns its space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly compensates by describing the return format (``[id] title by author``) and the paging footer. Combined with full parameter docs and the describe_book handoff, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full parameter burden and does so completely: ``query`` semantics (matched against title or author), ``limit`` bounds and default (1–500, default 200), and ``offset`` meaning plus the footer hint that reveals the next offset. Every parameter gets meaning and constraints absent from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource plus scope: books whose title OR author contains the query, with normalization rules spelled out. It implicitly separates itself from the title-only sibling, but never names ``search_books_by_title``, so an agent must infer which of the two overlapping search tools to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear routing guidance for the follow-up step ('Use ``describe_book(id)`` for details') and explains when paging applies (the footer names the next offset when there are more). What it lacks is an explicit when-not statement against the near-identical sibling ``search_books_by_title`` or the broader ``list_all_books``.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_books_by_titleSearch books by titleA
Read-only

Search for books by title (substring match, ignoring case, accents and quote/dash style). Output is one row per match: [id] title by author. Use describe_book(id) for details, and search_books to match authors too.

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
titleYes
offsetNo

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, but the description adds non-obvious behavior: substring matching that ignores case, accents, and quote/dash style; one-row-per-match output format; and paging via a footer that names the next offset. These details meaningfully exceed the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, match semantics, and output format before alternatives and parameters. No redundant or filler sentences; the Args block is compact.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for a read-only search tool with no output schema: return row format, match rules, paging, and alternative tools are all specified. Nothing an agent needs to call correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description carries the full burden. It documents all three parameters: title (what to search), limit (range 1–500, default 200), and offset (paging behavior with footer guidance). The added range and paging semantics are valuable beyond the bare schema types.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb and resource ('Search for books by title'), details the matching semantics (substring, case/accent/quote-dash insensitive), and names the output shape. It distinguishes itself from the sibling search_books by noting that tool also matches authors.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly directs to describe_book(id) for details and search_books for author matching, giving clear alternative tools. However, it does not state when not to use this tool (e.g., for genre or status filtering) or provide broader when-to-use beyond title lookup.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_collections_by_titleSearch collections by titleA
Read-only

Search for collections by title (substring match). Output is one row per match: [id] title.

Args: title: The title to search for.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYes

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description goes further by disclosing the exact output shape ('one row per match: [id] title'), which is valuable because no output schema exists. It omits matching behavior details like case sensitivity or result limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and matching mode, then a compact output-format statement. The Args block is largely redundant given the single obvious parameter, but it is brief and causes little bloat.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description responsibly covers the return format, and with one simple required parameter the input side needs little more. Missing case-sensitivity, empty-result behavior, and result-count limits are minor gaps for a simple lookup tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0% and the Args line merely restates the parameter name ('The title to search for'), which is tautological. The body does contribute one real semantic detail — that matching is substring-based rather than exact — which compensates partially for the empty schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Search for collections by title') and adds the matching mode ('substring match'), which meaningfully disambiguates it from list_all_collections and search_books_by_title. It does not explicitly name sibling tools, but the resource is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this tool versus alternatives such as list_all_collections or search_books_by_title, and no preconditions are given. The agent must infer usage from the name alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_notesSearch notesA
Read-only

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 ↳ note:.

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: newest (default) or oldest first.

ParametersJSON Schema
NameRequiredDescriptionDefault
noteYes
limitNo
offsetNo
order_byNonewest

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only safety profile (readOnlyHint=true, openWorldHint=false), so the bar is lower. The description adds genuine behavioral value by disclosing the return layout: highlighted passage on the primary row and matching note on a second line prefixed with '↳ note:'. It does not discuss pagination limits or result caps beyond the limit arg.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose followed by output format and then a compact args list; every sentence carries information. The docstring-style arg block with literal backticks is slightly awkward but not wasteful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description appropriately steps in to describe the returned row structure, and all parameters are documented. Combined with annotations covering read-only behavior, this is largely complete, though grouping/paging semantics of the output could be clearer.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must carry semantics, and it documents all four params: note (substring inside note bodies), limit (1-500, default 50), offset (paging), and order_by (newest/oldest). The 1-500 range and default are constraints the bare schema does not convey, though the note param adds little beyond its name.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (search) and resource (notes), scope ('by substring, grouped by book'), and explicitly excludes highlights ('not highlights'), which separates it from the sibling search_annotations. An agent can identify the tool and its boundary without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The '(not highlights)' parenthetical hints at the boundary versus other annotation-searching tools, but there is no explicit when-to-use/when-not guidance, no named alternative, and no prerequisites. Usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 12 tool updatesv0.9.0
    • Changedcreate_collection2 fields changed
      • addedInput schema / properties / details / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / details / type
        Removed value: -"string"
    • Changeddescribe_annotation1 field changed
      • changedInput schema / properties / annotation_id / type
        Previous value: -"string"New value: +"integer"
    • Changeddescribe_book1 field changed
      • changedInput schema / properties / book_id / type
        Previous value: -"string"New value: +"integer"
    • Changeddescribe_collection1 field changed
      • changedInput schema / properties / collection_id / type
        Previous value: -"string"New value: +"integer"
    • Changedget_annotations_by_date_range5 fields changed
      • addedInput schema / properties / after / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / after / type
        Removed value: -"string"
      • addedInput schema / properties / before / anyOf
        Added value: +[
        +  {
        +    "type": "string"
        +  },
        +  {
        +    "type": "null"
        +  }
        +]
      • removedInput schema / properties / before / type
        Removed value: -"string"
      • addedInput schema / properties / order_by / enum
        Added value: +[
        +  "newest",
        +  "oldest"
        +]
    • Changedget_chapter_content2 fields changed
      • addedInput schema / properties / chapter_id / default
        Added value: +"current"
      • changedInput schema / required
        Previous value: -[
        -  "book_id",
        -  "chapter_id"
        -]New value: +[
        +  "book_id"
        +]
    • Changedget_collection_books1 field changed
      • changedInput schema / properties / collection_id / type
        Previous value: -"string"New value: +"integer"
    • Changedget_highlights_by_color2 fields changed
      • addedInput schema / properties / color / enum
        Added value: +[
        +  "yellow",
        +  "green",
        +  "blue",
        +  "pink",
        +  "purple"
        +]
      • addedInput schema / properties / order_by / enum
        Added value: +[
        +  "newest",
        +  "oldest"
        +]
    • Changedsearch_annotations1 field changed
      • addedInput schema / properties / order_by / enum
        Added value: +[
        +  "newest",
        +  "oldest"
        +]
    • Addedsearch_books
    • Changedsearch_books_by_title2 fields changed
      • addedInput schema / properties / limit
        Added value: +{
        +  "default": 200,
        +  "title": "Limit",
        +  "type": "integer"
        +}
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "title": "Offset",
        +  "type": "integer"
        +}
    • Changedsearch_notes1 field changed
      • addedInput schema / properties / order_by / enum
        Added value: +[
        +  "newest",
        +  "oldest"
        +]
  2. 30 tool updatesv0.8.4
    • First observedadd_book_to_collection
    • First observedcreate_collection
    • First observeddelete_collection
    • First observeddescribe_annotation
    • First observeddescribe_book
    • First observeddescribe_collection
    • First observedget_annotation_context
    • First observedget_annotations_by_date_range
    • First observedget_books_by_genre
    • First observedget_books_in_progress
    • First observedget_chapter_content
    • First observedget_collection_books
    • First observedget_current_reading_position
    • First observedget_finished_books
    • First observedget_highlights_by_color
    • First observedget_library_stats
    • First observedget_recently_read_books
    • First observedget_unstarted_books
    • First observedlist_all_annotations
    • First observedlist_all_books
    • First observedlist_all_collections
    • First observedlist_annotations
    • First observedlist_book_chapters
    • First observedrecent_annotations
    • First observedremove_book_from_collection
    • First observedrename_collection
    • First observedsearch_annotations
    • First observedsearch_books_by_title
    • First observedsearch_collections_by_title
    • First observedsearch_notes

TDQS

A3.5/5.0

Scored across 31 tools

Disambiguation4/5

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.

Naming Consistency4/5

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.

Tool Count2/5

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.

Completeness3/5

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.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers