Skip to main content
Glama
Atomic-Germ

MCP Ollama Consult Server

callToolHandler.ts7.52 kB
import { BaseHandler } from './BaseHandler.js'; import { ConsultOllamaHandler } from './ConsultOllamaHandler.js'; import { ModelValidator } from '../services/ModelValidator.js'; import type { OllamaService } from '../services/OllamaService.js'; interface CallToolRequest { params: { name: string; arguments: Record<string, unknown>; }; } interface ToolResponse { content: Array<{ type: string; text: string }>; isError?: boolean; } export class CallToolHandler extends BaseHandler { private ollamaService: OllamaService; private sessionContext: Map<string, unknown>; private modelValidator: ModelValidator; constructor(ollamaService: OllamaService, sessionContext: Map<string, unknown>) { super(); this.ollamaService = ollamaService; this.sessionContext = sessionContext; this.modelValidator = new ModelValidator(this.ollamaService.getConfig()); } async handle(request: CallToolRequest): Promise<ToolResponse> { const { name, arguments: args } = request.params; switch (name) { case 'consult_ollama': { const handler = new ConsultOllamaHandler(this.ollamaService, this.modelValidator); return await handler.handle(args); } case 'list_ollama_models': { try { const available = await this.modelValidator.getAvailableModels(); if (available.length === 0) { return { content: [ { type: 'text', text: 'No models available. Please install a model locally or use a cloud-based model (e.g., qwen2.5-coder:7b-cloud)', }, ], isError: true, }; } const modelNames = available.map((m) => m.name); return { content: [ { type: 'text', text: JSON.stringify( { models: modelNames, count: modelNames.length, note: 'These are available models (installed locally or cloud-based)', }, null, 2 ), }, ], }; } catch (error) { const message = error instanceof Error ? error.message : 'Failed to list models'; return { content: [ { type: 'text', text: `Error: ${message}`, }, ], isError: true, }; } } case 'compare_ollama_responses': { try { const { models, prompt, context = {}, } = args as { models: string[]; prompt: string; context?: unknown; }; if (!prompt || typeof prompt !== 'string' || prompt.trim().length === 0) { return { content: [ { type: 'text', text: 'Error: prompt is required and must be a non-empty string', }, ], isError: true, }; } // Validate model availability let modelsToUse: string[] = []; if (Array.isArray(models) && models.length > 0) { const available = await Promise.all( models.map(async (m) => ({ model: m, isAvailable: await this.modelValidator.isModelAvailable(m), })) ); modelsToUse = available.filter((m) => m.isAvailable).map((m) => m.model); if (modelsToUse.length === 0) { const suggestions = await this.modelValidator.getSuggestions(3); return { content: [ { type: 'text', text: `None of the requested models are available: ${models.join(', ')}. Try these instead: ${suggestions.join(', ')}`, }, ], isError: true, }; } } else { // Use available models if not specified const available = await this.modelValidator.getAvailableModels(); modelsToUse = available.slice(0, 2).map((m) => m.name); if (modelsToUse.length === 0) { return { content: [ { type: 'text', text: 'Error: No models available to compare', }, ], isError: true, }; } } const results = await Promise.allSettled( modelsToUse.map(async (model: string) => { const handler = new ConsultOllamaHandler(this.ollamaService, this.modelValidator); const result = await handler.handle({ model, prompt, context }); return { model, response: result.content[0]?.text || '', isError: result.isError, }; }) ); const responses = results.map((result, index) => { if (result.status === 'fulfilled') { return result.value; } return { model: modelsToUse[index], response: '', error: 'Request failed', isError: true, }; }); return { content: [ { type: 'text', text: JSON.stringify(responses, null, 2), }, ], }; } catch (error) { const message = error instanceof Error ? error.message : 'Comparison failed'; return { content: [ { type: 'text', text: `Error: ${message}`, }, ], isError: true, }; } } case 'remember_context': { try { const { key, value, metadata } = args as { key: string; value: unknown; metadata?: unknown; }; if (!key || typeof key !== 'string') { return { content: [ { type: 'text', text: 'Error: key parameter is required and must be a string', }, ], isError: true, }; } this.sessionContext.set(key, { value, metadata, timestamp: Date.now() }); return { content: [ { type: 'text', text: `Context stored with key: ${key}`, }, ], }; } catch (error) { const message = error instanceof Error ? error.message : 'Failed to store context'; return { content: [ { type: 'text', text: `Error: ${message}`, }, ], isError: true, }; } } default: return { content: [ { type: 'text', text: `Error: Unknown tool '${name}'`, }, ], isError: true, }; } } } export const callToolHandler = ( ollamaService: OllamaService, sessionContext: Map<string, unknown> ) => new CallToolHandler(ollamaService, sessionContext);

Implementation Reference

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