Skip to main content
Glama
donghch
by donghch

EPUB 리더 MCP 서버

License MCP Version Node.js Version

AI 에이전트를 위한 "Kindle" 역할을 하며, MCP의 Tools API를 통해 EPUB 파일 콘텐츠를 노출하는 모델 컨텍스트 프로토콜(MCP) 서버입니다.

개요

EPUB 리더 MCP 서버는 AI 에이전트에게 EPUB 파일을 읽고 탐색할 수 있는 기능을 제공합니다. 이 서버는 모델 컨텍스트 프로토콜(MCP)을 구현하여 EPUB 파일 열기, 목차 및 페이지 탐색, 콘텐츠 검색, 각주 확인, 읽기 세션 관리 등을 가능하게 하는 13가지 도구를 노출합니다.

주요 기능

  • EPUB 파일 열기: EPUB 파일 유효성 검사 및 파싱, 읽기 세션 생성

  • 콘텐츠 탐색: 페이지 앞뒤 이동, 특정 페이지나 챕터로 이동

  • 콘텐츠 발견: 목차, 메타데이터 및 챕터 요약 보기

  • 검색 기능: 컨텍스트를 포함한 챕터 전체 텍스트 검색

  • 참조 도구: 각주 참조 해결, 읽기 위치 가져오기

  • 세션 관리: 열려 있는 책 목록 확인, 세션 종료, 리소스 관리

Related MCP server: Readbook MCP Server

사전 요구 사항

  • Node.js 20+

  • npm 또는 호환되는 패키지 관리자

  • 읽을 EPUB 파일 (.epub 형식)

설치

소스에서 설치

git clone https://github.com/your-username/mcp-epub-reader.git
cd mcp-epub-reader
npm install
npm run build

사용법

서버 실행

이 서버는 stdio 전송을 사용하므로 Claude Desktop과 같은 MCP 클라이언트와의 통합에 이상적입니다.

stdio (로컬 통합)

Claude Desktop 또는 기타 MCP 클라이언트와의 통합을 위해:

node build/index.js

서버는 MCP JSON-RPC 프로토콜을 사용하여 stdin/stdout을 통해 통신합니다.

구성

Claude Desktop 구성

Claude Desktop 구성 파일(~/Library/Application Support/Claude/claude_desktop_config.json, macOS 기준)에 서버를 추가합니다:

{
  "mcpServers": {
    "epub-reader": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-epub-reader/build/index.js"],
      "env": {
        "LOG_LEVEL": "info"
      }
    }
  }
}

환경 변수

변수

설명

필수

기본값

LOG_LEVEL

로깅 레벨 (error, warn, info, debug)

아니요

info

도구 참조

이 서버는 EPUB 파일 상호작용을 위한 13가지 도구를 제공합니다:

도구

설명

입력 매개변수

ebook/open

EPUB 파일을 열고 읽기 세션 생성

filePath: string, autoNavigate?: boolean

ebook/close

읽기 세션을 닫고 리소스 해제

sessionId: string

ebook/list_open_books

현재 열려 있는 모든 EPUB 세션 나열

(없음)

ebook/navigate_next

현재 세션의 다음 페이지로 이동

sessionId: string

ebook/navigate_previous

현재 세션의 이전 페이지로 이동

sessionId: string

ebook/jump_to_page

특정 페이지 번호로 이동

sessionId: string, pageNumber: number

ebook/jump_to_chapter

특정 챕터로 이동 (제목 또는 인덱스 기준)

sessionId: string, chapter: string | number

ebook/get_position

현재 읽기 위치 및 진행률 가져오기

sessionId: string

ebook/search

모든 챕터에서 텍스트 검색

sessionId: string, query: string, contextWords?: number

ebook/get_toc

계층적 목차 가져오기

sessionId: string

ebook/get_metadata

EPUB 메타데이터(제목, 저자, 출판사 등) 가져오기

sessionId: string

ebook/get_footnote

ID로 각주 참조 해결

sessionId: string, footnoteId: string

ebook/get_chapter_summary

현재 챕터 요약 가져오기

sessionId: string, maxSentences?: number

도구 상세 정보

ebook/open

EPUB 파일을 열고, 콘텐츠를 파싱하며, 읽기 세션을 생성하고 메타데이터를 반환합니다.

입력 스키마:

{
  filePath: string;      // Absolute or relative path to EPUB file
  autoNavigate?: boolean; // Whether to auto-navigate to first page (default: false)
}

요청 예시:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "ebook/open",
    "arguments": {
      "filePath": "/path/to/book.epub",
      "autoNavigate": true
    }
  }
}

응답 예시:

{
  "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/close

읽기 세션을 닫고 관련 리소스를 해제합니다.

입력 스키마:

{
  sessionId: string;  // Session ID returned by ebook/open
}

ebook/list_open_books

현재 활성화된 모든 읽기 세션을 나열합니다.

입력 스키마: (없음)

응답 예시:

{
  "sessions": [
    {
      "sessionId": "sess_123",
      "filePath": "/path/to/book.epub",
      "metadata": {
        "title": "Sample Book",
        "author": "Author Name",
        "currentPage": 42,
        "totalPages": 250
      }
    }
  ]
}

ebook/navigate_nextebook/navigate_previous

페이지를 앞뒤로 탐색합니다.

입력 스키마:

{
  sessionId: string;
}

응답 예시:

{
  "sessionId": "sess_123",
  "currentPage": 43,
  "content": "Page content here...",
  "chapterTitle": "Chapter 3: The Adventure Begins"
}

ebook/jump_to_page

특정 페이지 번호로 이동합니다.

입력 스키마:

{
  sessionId: string;
  pageNumber: number;  // 1-based page number
}

ebook/jump_to_chapter

제목(대소문자 구분 없는 부분 일치) 또는 챕터 인덱스(1부터 시작)를 기준으로 특정 챕터로 이동합니다.

입력 스키마:

{
  sessionId: string;
  chapter: string | number;  // Chapter title or index
}

ebook/get_position

현재 읽기 위치 및 진행률 통계를 가져옵니다.

응답 예시:

{
  "sessionId": "sess_123",
  "currentPage": 42,
  "totalPages": 250,
  "progress": 0.168,
  "chapterTitle": "Chapter 3: The Adventure Begins",
  "chapterIndex": 3
}

ebook/search

선택적 컨텍스트 단어와 함께 모든 챕터에서 텍스트를 검색합니다.

입력 스키마:

{
  sessionId: string;
  query: string;
  contextWords?: number;  // Number of context words around matches (default: 50)
}

응답 예시:

{
  "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_toc

계층적 목차를 가져옵니다.

응답 예시:

{
  "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_metadata

전체 EPUB 메타데이터를 가져옵니다.

응답 예시:

{
  "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_footnote

ID로 각주 참조를 해결합니다.

입력 스키마:

{
  sessionId: string;
  footnoteId: string;  // Footnote reference ID (e.g., "fn1")
}

응답 예시:

{
  "sessionId": "sess_123",
  "footnoteId": "fn1",
  "content": "Footnote content here...",
  "referencingPage": 42
}

ebook/get_chapter_summary

핵심 문장 추출을 사용하여 현재 챕터의 요약을 가져옵니다.

입력 스키마:

{
  sessionId: string;
  maxSentences?: number;  // Maximum sentences in summary (default: 3)
}

응답 예시:

{
  "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

새 도구 추가

  1. src/tools/에 도구 구현을 위한 새 파일을 생성합니다:

// 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),
  };
}
  1. src/utils/validation.ts에 Zod 스키마를 추가합니다:

export const ExampleToolSchema = z.object({
  sessionId: z.string(),
  // ... other parameters
});
  1. src/server/tool-registration.ts에서 가져오고 등록합니다:

import { createExampleTool } from '../tools/example';

const toolFactories = {
  // ... existing tools
  'ebook/example': createExampleTool,
};

기여

기여를 환영합니다! 다음 단계를 따라주세요:

  1. 저장소 포크

  2. 기능 브랜치 생성 (git checkout -b feature/amazing-feature)

  3. 변경 사항 커밋 (git commit -m 'Add amazing feature')

  4. 브랜치 푸시 (git push origin feature/amazing-feature)

  5. 풀 리퀘스트 열기

개발 설정

# 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

코드 표준

  • 엄격한 타이핑을 포함한 TypeScript 모범 사례를 따릅니다.

  • 가능한 경우 불변성을 가진 순수 함수를 작성합니다.

  • 테스트 용이성을 위해 의존성 주입을 사용합니다.

  • 포괄적인 단위 테스트(AAA 패턴)를 포함합니다.

  • 공개 API 및 복잡한 로직을 문서화합니다.

라이선스

이 프로젝트는 MIT 라이선스에 따라 라이선스가 부여됩니다.

감사의 말

참조

변경 로그

버전 기록은 CHANGELOG.md를 참조하세요.


참고: 이 서버는 Claude Desktop과 같은 MCP 클라이언트와 함께 사용하도록 설계되었습니다. 세션 격리 및 리소스 관리를 유지하면서 AI 에이전트에게 EPUB 읽기 기능을 제공합니다.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides AI agents with research capabilities for local Calibre e-book libraries, including fulltext search across titles, ISBNs, and comments, plus structured excerpt retrieval from books.
    2
    GPL 3.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants to help users manage their reading experience by searching books, tracking reading progress, managing bookmarks, and generating personalized recommendations and summaries.
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables searching, reading, and managing a Calibre ebook library through natural language, with features like metadata search, full-text search, content extraction, and library management.
    40 npm
    Apache 2.0