loading…
Search for a command to run...
loading…
Enables AI agents to read and navigate EPUB files through 13 specialized tools for pagination, full-text search, metadata access, and footnote resolution. Suppo
Enables AI agents to read and navigate EPUB files through 13 specialized tools for pagination, full-text search, metadata access, and footnote resolution. Supports session-based reading with table of contents navigation and chapter summaries.
License MCP Version Node.js Version
A Model Context Protocol (MCP) server that acts as a "Kindle for AI agents," exposing EPUB file content through standard MCP protocol operations and the Tools API.
The EPUB Reader MCP server provides AI agents with the ability to read and navigate EPUB files. It implements the Model Context Protocol (MCP) to expose 13 tools, and now follows the standard MCP handshake/discovery flow so clients like OpenClaw can initialize, list tools, and call them normally.
.epub format)git clone https://github.com/your-username/mcp-epub-reader.git
cd mcp-epub-reader
npm install
npm run build
The server uses stdio transport, making it ideal for local MCP clients (including OpenClaw).
For integration with OpenClaw or other MCP clients:
node build/index.js
The server communicates via stdin/stdout using the MCP JSON-RPC protocol and supports standard MCP operations like initialization, tools/list, tools/call, and ping.
OpenClaw can connect to MCP servers over stdio. Add this server in OpenClaw’s MCP settings (exact location may vary). Tool discovery now works through standard MCP tools/list, so no custom wiring is needed.
Example (stdio):
{
"command": "node",
"args": ["/absolute/path/to/mcp-epub-reader/build/index.js"]
}
Then use the tools like this:
{
"method": "tools/call",
"params": {
"name": "ebook__open",
"arguments": {
"filePath": "/path/to/book.epub",
"autoNavigate": true
}
}
}
{
"method": "tools/call",
"params": {
"name": "ebook__navigate_next",
"arguments": {
"sessionId": "<sessionId>"
}
}
}
{
"method": "tools/call",
"params": {
"name": "ebook__search",
"arguments": {
"sessionId": "<sessionId>",
"query": "adventure",
"limit": 10,
"contextWindow": 80
}
}
}
This server validates filePath (prevents traversal), validates EPUB type (requires .epub + ZIP magic bytes), wraps the callback-based EPUB chapter API safely, and strips HTML from search snippets.
| Variable | Description | Required | Default |
|---|---|---|---|
LOG_LEVEL |
Logging level (error, warn, info, debug) |
No | info |
Tools are published through MCP discovery, so clients can enumerate them automatically before calling them.
The server provides 13 tools for EPUB file interaction:
| Tool | Description | Input Parameters |
|---|---|---|
ebook__open |
Open an EPUB file and create a reading session | filePath: string, autoNavigate?: boolean |
ebook__close |
Close a reading session and release resources | sessionId: string |
ebook__list_open_books |
List all currently open EPUB sessions | (none) |
ebook__navigate_next |
Move to the next page in the current session | sessionId: string |
ebook__navigate_previous |
Move to the previous page in the current session | sessionId: string |
ebook__jump_to_page |
Jump to a specific page number | sessionId: string, page: number |
ebook__jump_to_chapter |
Jump to a specific chapter | sessionId: string, chapterId: string |
ebook__get_position |
Get current reading position and progress | sessionId: string |
ebook__search |
Search across all chapters for text | sessionId: string, query: string, caseSensitive?: boolean, limit?: number, contextWindow?: number |
ebook__get_toc |
Get hierarchical table of contents | sessionId: string |
ebook__get_metadata |
Get EPUB metadata (title, author, publisher, etc.) | sessionId: string |
ebook__get_footnote |
Resolve a footnote reference by ID | sessionId: string, footnoteId: string |
ebook__get_chapter_summary |
Get a summary of the current chapter | sessionId: string, maxSentences?: number |
ebook__openOpens an EPUB file, parses its content, creates a reading session, and returns metadata.
Input Schema:
{
filePath: string; // Absolute or relative path to EPUB file
autoNavigate?: boolean; // Whether to auto-navigate to first page (default: false)
}
Example Request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ebook__open",
"arguments": {
"filePath": "/path/to/book.epub",
"autoNavigate": true
}
}
}
Example Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "{\"sessionId\":\"sess_123\",\"metadata\":{\"title\":\"Sample Book\",\"author\":\"Author Name\",\"totalPages\":250,\"totalChapters\":12}}"
}
]
}
}
ebook__closeCloses a reading session and releases associated resources.
Input Schema:
{
sessionId: string; // Session ID returned by ebook__open
}
ebook__list_open_booksLists all currently active reading sessions.
Input Schema: (none)
Example Response:
{
"sessions": [
{
"sessionId": "sess_123",
"filePath": "/path/to/book.epub",
"metadata": {
"title": "Sample Book",
"author": "Author Name",
"currentPage": 42,
"totalPages": 250
}
}
]
}
ebook__navigate_next and ebook__navigate_previousNavigate forward or backward through pages.
Input Schema:
{
sessionId: string;
}
Example Response:
{
"sessionId": "sess_123",
"currentPage": 43,
"content": "Page content here...",
"chapterTitle": "Chapter 3: The Adventure Begins"
}
ebook__jump_to_pageJump to a specific page number.
Input Schema:
{
sessionId: string;
page: number; // 1-based page number
}
ebook__jump_to_chapterJump to a specific chapter by chapterId (from the EPUB flow entry).
Input Schema:
{
sessionId: string;
chapterId: string; // Chapter identifier from EPUB flow
}
ebook__get_positionGet current reading position and progress statistics.
Example Response:
{
"sessionId": "sess_123",
"currentPage": 42,
"totalPages": 250,
"progress": 0.168,
"chapterTitle": "Chapter 3: The Adventure Begins",
"chapterIndex": 3
}
ebook__searchSearch across all chapters for text, with optional context words.
Input Schema:
{
sessionId: string;
query: string;
caseSensitive?: boolean;
limit?: number;
contextWindow?: number;
}
Example Response:
{
"sessionId": "sess_123",
"query": "adventure",
"matches": [
{
"chapterIndex": 3,
"chapterTitle": "Chapter 3: The Adventure Begins",
"pageNumber": 42,
"context": "...the great adventure began when...",
"position": 1250
}
],
"totalMatches": 1
}
ebook__get_tocGet hierarchical table of contents.
Example Response:
{
"sessionId": "sess_123",
"toc": [
{
"title": "Chapter 1: Introduction",
"level": 1,
"pageNumber": 1,
"children": []
},
{
"title": "Part I: The Beginning",
"level": 1,
"pageNumber": 10,
"children": [
{
"title": "Chapter 2: First Steps",
"level": 2,
"pageNumber": 12,
"children": []
}
]
}
]
}
ebook__get_metadataGet complete EPUB metadata.
Example Response:
{
"sessionId": "sess_123",
"metadata": {
"title": "Sample Book",
"author": "Author Name",
"publisher": "Publisher Name",
"description": "Book description...",
"language": "en",
"publishedDate": "2023-01-01",
"totalPages": 250,
"totalChapters": 12
}
}
ebook__get_footnoteResolve a footnote reference by ID.
Input Schema:
{
sessionId: string;
footnoteId: string; // Footnote reference ID (e.g., "fn1")
}
Example Response:
{
"sessionId": "sess_123",
"footnoteId": "fn1",
"content": "Footnote content here...",
"referencingPage": 42
}
ebook__get_chapter_summaryGet a summary of the current chapter using key sentence extraction.
Input Schema:
{
sessionId: string;
maxSentences?: number; // Maximum sentences in summary (default: 3)
}
Example Response:
{
"sessionId": "sess_123",
"chapterTitle": "Chapter 3: The Adventure Begins",
"summary": [
"The protagonist begins their journey.",
"They encounter their first challenge.",
"A mysterious figure offers guidance."
]
}
mcp-epub-reader/
├── src/
│ ├── epub/ # EPUB domain logic
│ │ ├── parser.ts # EPUB parsing and metadata extraction
│ │ ├── paginator.ts # Page splitting and content retrieval
│ │ └── types.ts # EPUB domain types
│ ├── server/ # MCP server implementation
│ │ ├── index.ts # Server entry point (stdio transport)
│ │ ├── book-manager.ts # Session lifecycle management
│ │ ├── tool-registration.ts # Tool registration and routing
│ │ └── types.ts # Server-side types
│ ├── tools/ # All 13 tool implementations
│ │ ├── open.ts # ebook__open tool
│ │ ├── close.ts # ebook__close tool
│ │ ├── list-books.ts # ebook__list_open_books tool
│ │ ├── navigate.ts # Navigation tools (next/previous)
│ │ ├── jump.ts # Jump tools (page/chapter)
│ │ ├── position.ts # ebook__get_position tool
│ │ ├── search.ts # ebook__search tool
│ │ ├── toc.ts # ebook__get_toc tool
│ │ ├── metadata.ts # ebook__get_metadata tool
│ │ ├── footnote.ts # ebook__get_footnote tool
│ │ └── summary.ts # ebook__get_chapter_summary tool
│ └── utils/ # Shared utilities
│ └── validation.ts # Zod schemas and input validation
├── tests/ # Test suites
│ ├── unit/ # Unit tests
│ └── integration/ # Integration tests
├── package.json
├── tsconfig.json
└── jest.config.js
# Install dependencies
npm install
# Build the project (TypeScript → JavaScript)
npm run build
# Output goes to `build/` directory
# Run all tests
npm test
# Run tests with coverage
npm test -- --coverage
# Run specific test file
npm test -- tests/unit/epub/parser.test.ts
src/tools/ with the tool implementation:// src/tools/example.ts
import { BookManager } from '../server/book-manager';
import { ExampleToolInput, ExampleToolOutput } from '../server/types';
export async function handleExampleTool(
input: ExampleToolInput,
bookManager: BookManager
): Promise<ExampleToolOutput> {
// Tool implementation
return { result: 'success' };
}
export function createExampleTool(bookManager: BookManager) {
return {
name: 'ebook__example' as const,
handler: (input: ExampleToolInput) => handleExampleTool(input, bookManager),
};
}
src/utils/validation.ts:export const ExampleToolSchema = z.object({
sessionId: z.string(),
// ... other parameters
});
src/server/tool-registration.ts:import { createExampleTool } from '../tools/example';
const toolFactories = {
// ... existing tools
'ebook__example': createExampleTool,
};
Contributions are welcome! Please follow these steps:
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)# Clone the repository
git clone https://github.com/your-username/mcp-epub-reader.git
cd mcp-epub-reader
# Install dependencies
npm install
# Set up environment
cp .env.example .env # if applicable
# Run development server with watch mode
npm run dev
This project is licensed under the MIT License.
See CHANGELOG.md for version history.
Note: This server is designed for use with MCP clients (e.g., OpenClaw). It provides AI agents with EPUB reading capabilities while maintaining session isolation and resource management.
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"epub-reader-mcp-server": {
"command": "npx",
"args": []
}
}
}Web content fetching and conversion for efficient LLM usage.
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also