Skip to main content
Glama
vgnshiyer
by vgnshiyer
server.py6.02 kB
import logging import json from mcp.types import ( TextContent ) from mcp.server.fastmcp import FastMCP from py_apple_books import PyAppleBooks logger = logging.getLogger("apple-books-mcp") mcp = FastMCP("apple-books") apple_books = PyAppleBooks() # -- Collections Tools -- @mcp.tool() def list_all_collections() -> TextContent: """List all collections in my Apple Books library.""" collections = apple_books.list_collections() collections_str = "\n".join([f"{str(collection)}\n" for collection in collections]) return TextContent( type="text", text=f"Collections:\n{collections_str}" ) @mcp.tool() def get_collection_books(collection_id: str) -> TextContent: """ Get all books in a particular collection. Args: collection_id: The ID of the collection to get books from. """ collection = apple_books.get_collection_by_id(collection_id) books_str = "\n".join([f"{str(book)}\n" for book in collection.books]) return TextContent( type="text", text=f"Books:\n{books_str}" ) @mcp.tool() def describe_collection(collection_id: str) -> TextContent: """ Get details of a particular collection. Args: collection_id: The ID of the collection to get details for. """ collection = apple_books.get_collection_by_id(collection_id) return TextContent( type="text", text=f"{json.dumps(collection.__dict__, default=str)}" ) # -- Books Tools -- @mcp.tool() def list_all_books() -> TextContent: """List all books in my Apple Books library.""" books = apple_books.list_books() books_str = "\n".join([f"{str(book)}\n" for book in books]) return TextContent( type="text", text=f"Books:\n{books_str}" ) @mcp.tool() def get_book_annotations(book_id: str) -> TextContent: """ Get all annotations for a particular book. Args: book_id: The ID of the book to get annotations for. """ book = apple_books.get_book_by_id(book_id) annotations_str = "\n".join([ f"{annotation.selected_text}\n" for annotation in book.annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def describe_book(book_id: str) -> TextContent: """ Get details of a particular book. Args: book_id: The ID of the book to get. """ book = apple_books.get_book_by_id(book_id) return TextContent( type="text", text=f"{json.dumps(book.__dict__, default=str)}" ) # -- Annotations Tools -- @mcp.tool() def list_all_annotations() -> TextContent: """List all my annotations in my Apple Books library.""" annotations = apple_books.list_annotations() annotations_str = "\n".join([ f"ID: {annotation.id} - Selected Text: {annotation.selected_text}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def get_highlights_by_color(color: str) -> TextContent: """ Get all annotations/highlights by color. Args: color: The color of the annotations/highlights. """ annotations = apple_books.get_annotations_by_color(color) annotations_str = "\n".join([ f"{annotation.selected_text} from {annotation.book.title}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def search_highlighted_text(text: str) -> TextContent: """ Search for annotations/highlights by highlighted text. Args: text: The text to search for. """ annotations = apple_books.search_annotation_by_highlighted_text(text) annotations_str = "\n".join([ f"{annotation.selected_text} from {annotation.book.title}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def search_notes(note: str) -> TextContent: """ Search for annotations by note. Args: note: The note to search for. """ annotations = apple_books.search_annotation_by_note(note) annotations_str = "\n".join([ f"{annotation.selected_text}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def full_text_search(text: str) -> TextContent: """ Search for annotations by any text that contains the given text. Args: text: The text to search for. """ annotations = apple_books.search_annotation_by_text(text) annotations_str = "\n".join([ f"{annotation.selected_text} from {annotation.book.title}, Chapter: {annotation.chapter}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def recent_annotations() -> TextContent: """ Get 10 most recent annotations. """ annotations = apple_books.list_annotations(limit=10, order_by="-creation_date") annotations_str = "\n".join([ f"{annotation.selected_text} from {annotation.book.title}, Chapter: {annotation.chapter}\n" for annotation in annotations ]) return TextContent( type="text", text=f"Annotations:\n{annotations_str}" ) @mcp.tool() def describe_annotation(annotation_id: str) -> TextContent: """ Get details of a particular annotation. Args: annotation_id: The ID of the annotation to get. """ annotation = apple_books.get_annotation_by_id(annotation_id) return TextContent( type="text", text=f"{json.dumps(annotation.__dict__, default=str)}" ) def serve(): """Serve the Apple Books MCP server.""" logger.info("--- Started Apple Books MCP server ---") mcp.run(transport="stdio")

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vgnshiyer/apple-books-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server