Skip to main content
Glama
ispyridis

Calibre RAG MCP Server

by ispyridis

search_project_context

Find relevant context chunks within your Calibre ebook projects using semantic search to support research, writing, or content analysis.

Instructions

Search for relevant context chunks within a RAG project using vector similarity

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_nameYesName of the project to search
queryYesQuery to find relevant context
limitNoMaximum number of context chunks to return (default: 5)

Implementation Reference

  • Core handler function that loads vectors and metadata from the project, generates query embedding, computes cosine similarities, retrieves top matching chunks, and returns relevant context.
    async searchProjectContext(projectName, query, limit = CONFIG.RAG.MAX_CONTEXT_CHUNKS) {
        const project = this.projects.get(projectName);
        if (!project) {
            throw new Error(`Project '${projectName}' not found`);
        }
        
        const projectPath = path.join(CONFIG.RAG.PROJECTS_DIR, projectName);
        const vectorsPath = path.join(projectPath, 'vectors.bin');
        const metadataPath = path.join(projectPath, 'metadata.json');
        const chunksPath = path.join(projectPath, 'chunks');
        
        // Load vectors and metadata
        const { vectors } = this.loadVectors(vectorsPath);
        
        if (!fs.existsSync(metadataPath) || vectors.length === 0) {
            throw new Error(`No vector data found for project '${projectName}'`);
        }
        
        const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));
        
        // Generate query embedding
        const queryEmbedding = await this.generateEmbedding(query);
        
        // Calculate similarities
        const similarities = vectors.map((vector, index) => ({
            index,
            similarity: this.cosineSimilarity(queryEmbedding, vector),
            metadata: metadata[index]
        }));
        
        // Sort by similarity and get top results
        similarities.sort((a, b) => b.similarity - a.similarity);
        const topResults = similarities.slice(0, limit);
        
        // Load chunk content
        const contextChunks = [];
        for (const result of topResults) {
            const chunkId = result.metadata.chunk_index !== undefined ? 
                `chunk_${result.metadata.chunk_index}` : `chunk_${result.index}`;
            const chunkPath = path.join(chunksPath, `${chunkId}.json`);
            
            if (fs.existsSync(chunkPath)) {
                const chunk = JSON.parse(fs.readFileSync(chunkPath, 'utf8'));
                contextChunks.push({
                    ...chunk,
                    similarity: result.similarity,
                    book_title: result.metadata.title,
                    authors: result.metadata.authors
                });
            }
        }
        
        return contextChunks;
    }
  • Tool schema definition including name, description, and input validation schema.
    {
        name: 'search_project_context',
        description: 'Search for relevant context chunks within a RAG project using vector similarity',
        inputSchema: {
            type: 'object',
            properties: {
                project_name: {
                    type: 'string',
                    description: 'Name of the project to search'
                },
                query: {
                    type: 'string',
                    description: 'Query to find relevant context'
                },
                limit: {
                    type: 'integer',
                    description: 'Maximum number of context chunks to return (default: 5)',
                    default: 5
                }
            },
            required: ['project_name', 'query']
        }
    },
  • server.js:1188-1205 (registration)
    Tool registration and dispatching logic in the MCP tools/call handler switch statement, which validates arguments and invokes the handler.
    case 'search_project_context':
        const searchProjName = args.project_name;
        const searchQuery = args.query;
        const searchLimit = args.limit || 5;
        
        if (!searchProjName || !searchQuery) {
            this.sendError(id, -32602, 'Missing required parameters: project_name, query');
            return;
        }
        
        try {
            const contextChunks = await this.searchProjectContext(searchProjName, searchQuery, searchLimit);
            const mcpResult = this.formatResponse(contextChunks, searchQuery, 'context');
            this.sendSuccess(id, mcpResult);
        } catch (error) {
            this.sendError(id, -32603, error.message);
        }
        break;

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