RagDocs MCP Server

  • src
import ollama from 'ollama'; import OpenAI from 'openai'; import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; export interface EmbeddingProvider { generateEmbeddings(text: string): Promise<number[]>; getVectorSize(): number; } export class OllamaProvider implements EmbeddingProvider { private model: string; constructor(model: string = 'nomic-embed-text') { this.model = model; } async generateEmbeddings(text: string): Promise<number[]> { try { console.error('Generating Ollama embeddings for text:', text.substring(0, 50) + '...'); const response = await ollama.embeddings({ model: this.model, prompt: text }); console.error('Successfully generated Ollama embeddings with size:', response.embedding.length); return response.embedding; } catch (error) { console.error('Ollama embedding error:', error); throw new McpError( ErrorCode.InternalError, `Failed to generate embeddings with Ollama: ${error}` ); } } getVectorSize(): number { // nomic-embed-text produces 768-dimensional vectors return 768; } } export class OpenAIProvider implements EmbeddingProvider { private client: OpenAI; private model: string; constructor(apiKey: string, model: string = 'text-embedding-3-small') { this.client = new OpenAI({ apiKey }); this.model = model; } async generateEmbeddings(text: string): Promise<number[]> { try { console.error('Generating OpenAI embeddings for text:', text.substring(0, 50) + '...'); const response = await this.client.embeddings.create({ model: this.model, input: text, }); const embedding = response.data[0].embedding; console.error('Successfully generated OpenAI embeddings with size:', embedding.length); return embedding; } catch (error) { console.error('OpenAI embedding error:', error); throw new McpError( ErrorCode.InternalError, `Failed to generate embeddings with OpenAI: ${error}` ); } } getVectorSize(): number { // text-embedding-3-small produces 1536-dimensional vectors return 1536; } } export class EmbeddingService { private provider: EmbeddingProvider; constructor(provider: EmbeddingProvider) { this.provider = provider; } async generateEmbeddings(text: string): Promise<number[]> { return this.provider.generateEmbeddings(text); } getVectorSize(): number { return this.provider.getVectorSize(); } static createFromConfig(config: { provider: 'ollama' | 'openai'; apiKey?: string; model?: string; }): EmbeddingService { switch (config.provider) { case 'ollama': return new EmbeddingService(new OllamaProvider(config.model)); case 'openai': if (!config.apiKey) { throw new McpError( ErrorCode.InvalidRequest, 'OpenAI API key is required' ); } return new EmbeddingService(new OpenAIProvider(config.apiKey, config.model)); default: throw new McpError( ErrorCode.InvalidRequest, `Unknown embedding provider: ${config.provider}` ); } } }