/
Soitch
/
vacation-schedule
Обзор
Документация
Войти
/
Soitch
/
vacation-schedule
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/server.py
154 строки
6 KB
Soitch
server
12 дек 2025, 00:31
12 дек 2025, 00:31
ffa7e44
Код
Авторство
О чём код?
""" MCP сервер для управления отпусками с HTTP транспортом. """ # Standard library import os import sys # Добавляем путь к src для корректного импорта sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # Third-party from dotenv import load_dotenv, find_dotenv # Load environment variables load_dotenv(find_dotenv()) from opentelemetry import trace from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter as OTLPHTTPSpanExporter from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor OPENTELEMETRY_AVAILABLE = True # Constants PORT = int(os.getenv("PORT", "8000")) # Импортируем единый экземпляр FastMCP from src.mcp_instance import mcp # Используем глобальные настройки вместо deprecated mcp.settings import fastmcp fastmcp.settings.port = PORT fastmcp.settings.host = "0.0.0.0" """Инициализация OpenTelemetry для трейсинга.""" def init_tracing(): """Инициализация чистого OpenTelemetry для трейсинга.""" if not OPENTELEMETRY_AVAILABLE: print("⚠️ OpenTelemetry недоступен, пропускаем инициализацию") return try: # Получаем настройки из переменных окружения otel_endpoint = os.getenv("OTEL_ENDPOINT", "").strip() otel_service_name = os.getenv("OTEL_SERVICE_NAME", "mcp-vacation-server") # Настраиваем OpenTelemetry tracer_provider = TracerProvider( resource=Resource.create({ "service.name": otel_service_name, "service.version": "1.0.0", }) ) if otel_endpoint: # Если есть OTLP endpoint, используем его if otel_endpoint.startswith("http"): otlp_exporter = OTLPHTTPSpanExporter(endpoint=otel_endpoint) else: from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter otlp_exporter = OTLPSpanExporter(endpoint=otel_endpoint) span_processor = BatchSpanProcessor(otlp_exporter) tracer_provider.add_span_processor(span_processor) print(f"✅ OpenTelemetry настроен для OTLP экспорта: {otel_endpoint}") else: # Используем консольный экспортер для локальной разработки from opentelemetry.sdk.trace.export import ConsoleSpanExporter console_exporter = ConsoleSpanExporter() span_processor = BatchSpanProcessor(console_exporter) tracer_provider.add_span_processor(span_processor) print("✅ OpenTelemetry настроен для консольного вывода") # Устанавливаем tracer provider trace.set_tracer_provider(tracer_provider) print("✅ OpenTelemetry инициализирован") except Exception as e: print(f"⚠️ Не удалось инициализировать OpenTelemetry: {e}") print("ℹ️ Продолжаем работу без трейсинга") # Инициализируем трейсинг при импорте модуля init_tracing() # Импортируем инструменты print("🔧 Загружаем инструменты отпусков...") try: from src.tools.vacation_entitlement import vacation_entitlement_tool print("✅ vacation_entitlement_tool загружен") except Exception as e: print(f"❌ Ошибка импорта vacation_entitlement_tool: {e}") import traceback traceback.print_exc() try: from src.tools.vacation_planning import plan_vacation_tool print("✅ plan_vacation_tool загружен") except Exception as e: print(f"❌ Ошибка импорта plan_vacation_tool: {e}") import traceback traceback.print_exc() try: from src.tools.vacation_carryover import vacation_carryover_tool print("✅ vacation_carryover_tool загружен") except Exception as e: print(f"❌ Ошибка импорта vacation_carryover_tool: {e}") import traceback traceback.print_exc() try: from src.tools.vacation_optimizer import find_optimal_vacation_tool print("✅ find_optimal_vacation_tool загружен") except Exception as e: print(f"❌ Ошибка импорта find_optimal_vacation_tool: {e}") import traceback traceback.print_exc() print("✅ Все инструменты загружены:") print(" - calculate_vacation_entitlement (расчет положенных дней отпуска)") print(" - plan_vacation (планирование отпуска с расчетом выплат)") print(" - calculate_vacation_carryover (расчет переноса дней)") print(" - find_optimal_vacation_period (поиск оптимального периода)") def main(): """Запуск MCP сервера с HTTP транспортом.""" print("=" * 60) print("🌐 ЗАПУСК MCP СЕРВЕРА ОТПУСКОВ") print("=" * 60) print(f"🚀 MCP Server: http://0.0.0.0:{PORT}/mcp") print(f"📊 Метрики: http://0.0.0.0:{PORT}/metrics") print(f"🏥 Health check: http://0.0.0.0:{PORT}/health") print("🔧 Используйте MCP Inspector для подключения к серверу") print("=" * 60) print("⏳ Запускаем сервер...") # Запускаем MCP сервер с streamable-http транспортом try: mcp.run(transport="streamable-http", host="0.0.0.0", port=PORT) except KeyboardInterrupt: print("\n🛑 Получен сигнал остановки (Ctrl+C)") print("🔄 Выполняем graceful shutdown...") print("✅ Сервер остановлен") except Exception as e: print(f"❌ Ошибка запуска сервера: {e}") import traceback traceback.print_exc() if __name__ == "__main__": main()