Skip to main content
Glama

MCP Power - Knowledge Search Server

by wspotter
server.tsโ€ข5.56 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js'; import { readFile } from 'fs/promises'; import { resolve } from 'path'; import { DatasetRegistry } from './config/datasets.js'; import { logger } from './logger.js'; import { handleSearch } from './tools/search.js'; import { handleListDatasets } from './tools/listDatasets.js'; /** * Server configuration options */ export interface ServerConfig { transport: 'stdio'; datasetsPath: string; logLevel: 'debug' | 'info' | 'warn' | 'error'; } /** * Global dataset registry instance */ let datasetRegistry: DatasetRegistry; /** * Get server version from package.json */ async function getServerVersion(): Promise<string> { try { const packagePath = resolve('./package.json'); const packageContent = await readFile(packagePath, 'utf-8'); const packageData = JSON.parse(packageContent); return packageData.version || '0.1.0'; } catch { // Fallback if package.json can't be read return '0.1.0'; } } /** * Start the MCP server */ export async function startServer(config: ServerConfig): Promise<void> { const startTime = Date.now(); const serverVersion = await getServerVersion(); // Phase 5: Enhanced startup logging (FR-015) logger.info( { version: serverVersion, transport: config.transport, datasetsPath: config.datasetsPath, logLevel: config.logLevel, timestamp: new Date().toISOString(), nodeVersion: process.version, platform: process.platform }, 'Starting MCP Knowledge Server' ); // Initialize dataset registry datasetRegistry = new DatasetRegistry(config.datasetsPath); await datasetRegistry.load(); const stats = datasetRegistry.getStats(); const loadErrors = datasetRegistry.getErrors(); // Phase 5: Enhanced startup diagnostics with operational status (FR-015) logger.info( { total: stats.total, ready: stats.ready, errors: stats.errors, startupDuration: Date.now() - startTime, status: 'ready' }, 'Dataset registry initialized - server ready' ); // Log any dataset loading errors if (loadErrors.length > 0) { for (const error of loadErrors) { logger.error( { manifestPath: error.manifestPath, error: error.error, timestamp: error.timestamp }, 'Dataset failed to load' ); } } // Create MCP server const server = new Server( { name: 'mcpower', version: serverVersion }, { capabilities: { tools: {} } } ); // Register tool list handler server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'knowledge.search', description: 'Search a knowledge dataset for relevant documents using semantic similarity', inputSchema: { type: 'object', properties: { dataset: { type: 'string', description: 'Dataset ID to search (must be a registered dataset)' }, query: { type: 'string', description: 'Natural language search query' }, topK: { type: 'number', description: 'Number of results to return (defaults to dataset\'s defaultTopK)' } }, required: ['dataset', 'query'] } }, { name: 'knowledge.listDatasets', description: 'List all registered knowledge datasets available for searching', inputSchema: { type: 'object', properties: {} } } ] }; }); // Register tool request handler server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; logger.info({ tool: name, args }, 'Tool invocation received'); try { switch (name) { case 'knowledge.search': return await handleSearch(args); case 'knowledge.listDatasets': return await handleListDatasets(args); default: logger.warn({ tool: name }, 'Unknown tool requested'); return { content: [ { type: 'text', text: `Unknown tool: ${name}`, }, ], isError: true, }; } } catch (error) { logger.error({ tool: name, error }, 'Tool execution failed'); return { content: [ { type: 'text', text: `Tool execution failed: ${error instanceof Error ? error.message : String(error)}`, }, ], isError: true, }; } }); // Connect to stdio transport const transport = new StdioServerTransport(); await server.connect(transport); const totalDuration = Date.now() - startTime; logger.info( { status: 'ready', duration: totalDuration, readyDatasets: stats.ready }, 'MCP server ready' ); } /** * Get the dataset registry instance (for use by tools) */ export function getDatasetRegistry(): DatasetRegistry { if (!datasetRegistry) { throw new Error('Dataset registry not initialized'); } return datasetRegistry; }

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/wspotter/mcpower'

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