Skip to main content
Glama
server.ts8.48 kB
#!/usr/bin/env node 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 { RAGService } from './rag/rag-service.js'; import { FileService } from './connectors/file-service.js'; import { WebService } from './connectors/web-service.js'; import { TaskService } from './connectors/task-service.js'; import { HttpTransport } from './transports/http-transport.js'; class AIOpsHubServer { private server: Server; private ragService: RAGService; private fileService: FileService; private webService: WebService; private taskService: TaskService; private httpTransport?: HttpTransport; constructor() { this.server = new Server( { name: 'ai-ops-hub', version: '0.1.0', } ); // Инициализируем сервисы this.ragService = new RAGService(); this.fileService = new FileService(); this.webService = new WebService(); this.taskService = new TaskService(); this.setupToolHandlers(); } private setupToolHandlers() { // RAG инструменты this.server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ { name: 'rag_search', description: 'Поиск по личному корпусу документов', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Поисковый запрос', }, limit: { type: 'number', description: 'Максимальное количество результатов', default: 5, }, }, required: ['query'], }, }, { name: 'rag_add_document', description: 'Добавить документ в RAG корпус', inputSchema: { type: 'object', properties: { uri: { type: 'string', description: 'URI документа', }, content: { type: 'string', description: 'Содержимое документа', }, title: { type: 'string', description: 'Заголовок документа', }, }, required: ['uri', 'content', 'title'], }, }, // Файловые инструменты { name: 'file_read', description: 'Читать содержимое файла', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Путь к файлу', }, }, required: ['path'], }, }, { name: 'file_write', description: 'Записать содержимое в файл', inputSchema: { type: 'object', properties: { path: { type: 'string', description: 'Путь к файлу', }, content: { type: 'string', description: 'Содержимое для записи', }, }, required: ['path', 'content'], }, }, // Веб инструменты { name: 'web_fetch', description: 'Получить содержимое веб-страницы', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'URL страницы', }, }, required: ['url'], }, }, // Инструменты задач { name: 'task_create', description: 'Создать новую задачу', inputSchema: { type: 'object', properties: { title: { type: 'string', description: 'Заголовок задачи', }, project: { type: 'string', description: 'Проект', }, due: { type: 'string', description: 'Срок выполнения (YYYY-MM-DD)', }, }, required: ['title'], }, }, { name: 'task_list', description: 'Список задач', inputSchema: { type: 'object', properties: { project: { type: 'string', description: 'Фильтр по проекту', }, status: { type: 'string', description: 'Статус (open/completed)', enum: ['open', 'completed'], }, }, }, }, ], }; }); // Обработчики вызовов инструментов this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; if (!args) { throw new Error('Аргументы не предоставлены'); } try { switch (name) { case 'rag_search': return { content: await this.ragService.search(args.query as string, (args.limit as number) || 5) }; case 'rag_add_document': await this.ragService.addDocument(args.uri as string, args.content as string, args.title as string); return { content: 'Документ добавлен' }; case 'file_read': return { content: await this.fileService.readFile(args.path as string) }; case 'file_write': await this.fileService.writeFile(args.path as string, args.content as string); return { content: 'Файл записан' }; case 'web_fetch': return { content: await this.webService.fetchPage(args.url as string) }; case 'task_create': return { content: await this.taskService.createTask(args.title as string, args.project as string, args.due as string) }; case 'task_list': return { content: await this.taskService.listTasks(args.project as string, args.status as string) }; default: throw new Error(`Неизвестный инструмент: ${name}`); } } catch (error) { console.error(`Ошибка выполнения инструмента ${name}:`, error); throw error; } }); } async start() { // Запускаем stdio транспорт (для локального использования) const stdioTransport = new StdioServerTransport(); await this.server.connect(stdioTransport); console.error('📡 AI Ops Hub MCP сервер запущен (stdio)'); // Запускаем HTTP транспорт (для удаленного доступа) const httpPort = parseInt(process.env.HTTP_PORT || '3333'); this.httpTransport = new HttpTransport(httpPort); await this.httpTransport.connect(); console.error(`🌐 HTTP MCP сервер запущен на порту ${httpPort}`); } async stop() { if (this.httpTransport) { await this.httpTransport.disconnect(); } console.error('🛑 AI Ops Hub MCP сервер остановлен'); } } // Запуск сервера const server = new AIOpsHubServer(); server.start().catch((error) => { console.error('Ошибка запуска сервера:', error); process.exit(1); });

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/Galiusbro/MCP'

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