Skip to main content
Glama
Atomic-Germ

MCP Ollama Consult Server

OllamaService.ts5.15 kB
import { ConfigManager } from '../config/ConfigManager'; import { OllamaModel, ConsultRequest, ConsultResponse, ComparisonResult, OllamaError, ValidationError, } from '../types'; export class OllamaService { constructor(private config: ConfigManager) {} getConfig(): ConfigManager { return this.config; } async listModels(): Promise<OllamaModel[]> { try { const url = this.config.getApiUrl('/api/tags'); const response = await fetch(url, { method: 'GET', signal: AbortSignal.timeout(this.config.getTimeout()), }); if (!response.ok) { throw new OllamaError( `Failed to list models: ${response.statusText}`, 'LIST_MODELS_FAILED', response.status ); } const text = await response.text(); const data = JSON.parse(text) as { models?: OllamaModel[] }; return data.models || []; } catch (error) { if (error instanceof OllamaError) throw error; throw new OllamaError( `Failed to connect to Ollama: ${error instanceof Error ? error.message : 'Unknown error'}`, 'CONNECTION_FAILED' ); } } async consult(request: ConsultRequest): Promise<ConsultResponse> { this.validateConsultRequest(request); try { const response = await this.makeRequest( '/api/generate', { model: request.model, prompt: request.prompt, system: request.systemPrompt, temperature: request.temperature, stream: false, }, request.timeout ); return response as ConsultResponse; } catch (error) { if (error instanceof OllamaError || error instanceof ValidationError) throw error; throw new OllamaError( `Consultation failed: ${error instanceof Error ? error.message : 'Unknown error'}`, 'CONSULT_FAILED' ); } } async compareModels( models: string[], prompt: string, systemPrompt?: string, timeoutMs?: number ): Promise<ComparisonResult[]> { if (!models || models.length === 0) { throw new ValidationError('At least one model is required', 'models'); } if (!prompt || prompt.trim().length === 0) { throw new ValidationError('Prompt cannot be empty', 'prompt'); } const results = await Promise.allSettled( models.map(async (model) => { const startTime = Date.now(); try { const response = await this.consult({ model, prompt, systemPrompt, stream: false, timeout: timeoutMs, }); return { model, response: response.response, duration: Date.now() - startTime, }; } catch (error) { return { model, response: '', duration: Date.now() - startTime, error: error instanceof Error ? error.message : 'Unknown error', }; } }) ); return results.map((result, index) => { if (result.status === 'fulfilled') { return result.value; } return { model: models[index], response: '', error: 'Request failed', }; }); } private validateConsultRequest(request: ConsultRequest): void { if (!request.model || request.model.trim().length === 0) { throw new ValidationError('Model name is required', 'model'); } if (!request.prompt || request.prompt.trim().length === 0) { throw new ValidationError('Prompt is required', 'prompt'); } if (request.temperature !== undefined) { if (request.temperature < 0 || request.temperature > 2) { throw new ValidationError('Temperature must be between 0 and 2', 'temperature'); } } } private async makeRequest(endpoint: string, body: any, timeoutMs?: number): Promise<any> { let lastError: Error | null = null; const timeout = timeoutMs || this.config.getTimeout(); for (let attempt = 0; attempt <= this.config.getMaxRetries(); attempt++) { try { const response = await fetch(this.config.getApiUrl(endpoint), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), signal: AbortSignal.timeout(timeout), }); if (!response.ok) { const errorText = await response.text(); throw new OllamaError(`Ollama API error: ${errorText}`, 'API_ERROR', response.status); } return await response.json(); } catch (error) { lastError = error instanceof Error ? error : new Error('Unknown error'); if (error instanceof OllamaError) throw error; if (attempt < this.config.getMaxRetries()) { await this.delay(1000 * Math.pow(2, attempt)); } } } throw new OllamaError( `Failed after ${this.config.getMaxRetries()} retries: ${lastError?.message}`, 'MAX_RETRIES_EXCEEDED' ); } private delay(ms: number): Promise<void> { return new Promise((resolve) => setTimeout(resolve, ms)); } }

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/Atomic-Germ/mcp-consult'

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