Skip to main content
Glama
ispyridis

Calibre RAG MCP Server

by ispyridis

search

Search your Calibre ebook library using natural language queries or field-specific metadata syntax to find books by content or attributes.

Instructions

Search the Calibre ebook library. Supports both full-text content search (default) and metadata search using field syntax.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
queryYesSearch query. For full-text: use natural language. For metadata: use field syntax (author:Name, title:"Title").
limitNoMaximum number of results (default: 50)
fuzzy_fallbackNoAlternative search terms if exact query fails

Implementation Reference

  • Core handler function that executes the book search using Calibre's 'calibredb search' and 'list' commands, fetches metadata, and formats results with epub URLs.
    async searchBooksMetadata(query, limit = 50) { try { const searchResult = await this.runCalibreCommand(['search', '--limit', limit.toString(), query]); if (!searchResult.trim()) { return []; } const bookIds = searchResult.trim(); const idQuery = `id:${bookIds.replace(/,/g, ' OR id:')}`; const listResult = await this.runCalibreCommand([ 'list', '--fields', 'id,title,authors,series,tags,publisher,pubdate,formats,identifiers,comments', '--for-machine', '--search', idQuery ]); const books = JSON.parse(listResult || '[]'); return books.map(book => ({ id: book.id, title: book.title, authors: book.authors, series: book.series, tags: book.tags, publisher: book.publisher, published: book.pubdate, epub_url: this.createEpubUrl(book.authors, book.title, book.id), formats: book.formats ? book.formats.map(f => path.basename(f)) : [], full_formats: book.formats || [], has_text: book.formats ? book.formats.some(f => f.endsWith('.txt')) : false, description: book.comments ? book.comments.replace(/<[^>]+>/g, '').split('\n').slice(0, 2).join(' ').substring(0, 200) + '...' : null })); } catch (error) { this.log(`Metadata search failed: ${error.message}`); return []; } }
  • Input schema defining parameters for the 'search' tool: query (required), limit, fuzzy_fallback.
    inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query. For full-text: use natural language. For metadata: use field syntax (author:Name, title:"Title").' }, limit: { type: 'integer', description: 'Maximum number of results (default: 50)', default: 50 }, fuzzy_fallback: { type: 'string', description: 'Alternative search terms if exact query fails' } }, required: ['query'] }
  • server.js:966-987 (registration)
    Registration of the 'search' tool in the static tools array returned by 'tools/list' method.
    name: 'search', description: 'Search the Calibre ebook library. Supports both full-text content search (default) and metadata search using field syntax.', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query. For full-text: use natural language. For metadata: use field syntax (author:Name, title:"Title").' }, limit: { type: 'integer', description: 'Maximum number of results (default: 50)', default: 50 }, fuzzy_fallback: { type: 'string', description: 'Alternative search terms if exact query fails' } }, required: ['query'] } },
  • Tool dispatch handler in 'tools/call' that validates input, calls searchBooksMetadata, formats response, and sends MCP success response.
    case 'search': const query = args.query; const limit = args.limit || 50; if (!query) { this.sendError(id, -32602, 'Missing required parameter: query'); return; } const results = await this.searchBooksMetadata(query, limit); const mcpResult = this.formatResponse(results, query, 'search'); this.sendSuccess(id, mcpResult); break;
  • Helper function to format search results into MCP-compatible response structure with text summary and structured results.
    } formatResponse(searchResults, query, searchType = 'search') {

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/ispyridis/calibre-rag-mcp-nodejs'

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