UNPKG

nmp-mcp-server

Version:

NMP Plus MCP Server - 36 commands via HTTP API for Cursor

215 lines (180 loc) 7.52 kB
#!/usr/bin/env node const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs'); // Создаем директорию для логов, если её нет try { if (!fs.existsSync('./logs')) { fs.mkdirSync('./logs', { recursive: true }); } } catch (e) { // Игнорируем ошибки создания директории } // Путь к Python серверу const pythonServerPath = path.join(__dirname, 'nmp_mcp_server_complete.py'); // Ищем подходящую команду Python let pythonPath = 'python3'; try { const testPython3 = spawn('python3', ['--version']); testPython3.on('error', () => { pythonPath = 'python'; console.error('Python3 не найден, используем python'); }); } catch (e) { pythonPath = 'python'; console.error('Python3 не найден, используем python'); } console.error('🧠 Запуск NMP_Plus MCP Server...'); console.error(`Python: ${pythonPath}`); console.error(`Server: ${pythonServerPath}`); // Проверяем наличие файла Python сервера if (!fs.existsSync(pythonServerPath)) { console.error(`❌ ОШИБКА: Python сервер не найден: ${pythonServerPath}`); // Создаем базовую версию Python сервера если его нет const basicServerContent = `#!/usr/bin/env python3 """ NMP_Plus MCP Server - базовая версия """ import asyncio import json import sys import urllib.request import urllib.parse class NMPMCPServer: def __init__(self): self.server_host = "localhost" self.server_port = "8001" self.base_url = f"http://{self.server_host}:{self.server_port}" def make_request(self, endpoint, data=None): try: url = f"{self.base_url}/{endpoint}" # Debug логи убраны для MCP if data: json_data = json.dumps(data).encode('utf-8') req = urllib.request.Request( url, data=json_data, headers={'Content-Type': 'application/json'} ) else: req = urllib.request.Request(url) with urllib.request.urlopen(req, timeout=10) as response: return json.loads(response.read().decode('utf-8')) except Exception as e: # Debug логи убраны для MCP return {"error": f"Server connection failed: {str(e)}"} async def handle_request(self, request): method = request.get('method') params = request.get('params', {}) if method == 'initialize': return { "protocolVersion": "2024-11-05", "capabilities": { "tools": {} }, "serverInfo": { "name": "nmp-plus-mcp", "version": "1.0.0" } } elif method == 'tools/list': return { "tools": [ { "name": "mcp_nmp_memory_save", "description": "🧠 Сохранить информацию в память NMP" }, { "name": "mcp_nmp_memory_search", "description": "🔍 Поиск в памяти NMP" }, { "name": "mcp_nmp_memory_stats", "description": "📊 Статистика системы NMP" } ] } elif method == 'tools/call': name = params.get('name', '') args = params.get('arguments', {}) # Преобразуем имя инструмента в эндпоинт API clean_name = name.replace("mcp_nmp_", "") parts = clean_name.split('_') endpoint = f"api/{'/'.join(parts)}" result = self.make_request(endpoint, args) return { "content": [{ "type": "text", "text": json.dumps(result, ensure_ascii=False, indent=2) }] } return {"error": f"Unknown method: {method}"} async def run(self): # Убрано логирование для чистого MCP вывода while True: try: line = await asyncio.get_event_loop().run_in_executor(None, sys.stdin.readline) if not line: break request = json.loads(line) response = await self.handle_request(request) print(json.dumps({ "jsonrpc": "2.0", "id": request.get('id'), "result": response })) sys.stdout.flush() except Exception as e: print(json.dumps({ "jsonrpc": "2.0", "id": None, "error": {"code": -1, "message": str(e)} })) sys.stdout.flush() async def main(): server = NMPMCPServer() await server.run() if __name__ == "__main__": asyncio.run(main()) `; try { fs.writeFileSync(pythonServerPath, basicServerContent); console.error(`✅ Создан базовый Python сервер: ${pythonServerPath}`); } catch (e) { console.error(`❌ Не удалось создать Python сервер: ${e.message}`); process.exit(1); } } // Запускаем Python сервер const pythonProcess = spawn(pythonPath, [pythonServerPath], { stdio: ['pipe', 'pipe', 'pipe'], env: { ...process.env, PYTHONIOENCODING: 'utf-8' } }); // Настраиваем логи const logStream = fs.createWriteStream('./logs/mcp_server.log', { flags: 'a' }); const timestamp = () => new Date().toISOString(); // Перенаправляем stdout и stderr Python процесса на stdin и stderr текущего процесса pythonProcess.stdout.pipe(process.stdout); pythonProcess.stderr.on('data', (data) => { const message = data.toString(); process.stderr.write(message); logStream.write(`[${timestamp()}] ${message}`); }); // Перенаправляем stdin текущего процесса на stdin Python процесса process.stdin.pipe(pythonProcess.stdin); // Обработка сигналов process.on('SIGINT', () => { console.error('\n🛑 Остановка NMP сервера...'); logStream.write(`[${timestamp()}] Остановка сервера по SIGINT\n`); pythonProcess.kill('SIGINT'); process.exit(0); }); process.on('SIGTERM', () => { logStream.write(`[${timestamp()}] Остановка сервера по SIGTERM\n`); pythonProcess.kill('SIGTERM'); process.exit(0); }); pythonProcess.on('close', (code) => { console.error(`🧠 NMP сервер завершен с кодом ${code}`); logStream.write(`[${timestamp()}] Сервер завершен с кодом ${code}\n`); logStream.end(); process.exit(code); }); pythonProcess.on('error', (err) => { console.error('❌ Ошибка запуска NMP сервера:', err); logStream.write(`[${timestamp()}] Ошибка запуска: ${err.message}\n`); logStream.end(); process.exit(1); });