-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcp_server.py
More file actions
134 lines (102 loc) · 4.03 KB
/
mcp_server.py
File metadata and controls
134 lines (102 loc) · 4.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#!/usr/bin/env python3
"""
Standalone MCP (Model Context Protocol) server entry point for NASDAQ Stock Agent
"""
import asyncio
import logging
import sys
import signal
from pathlib import Path
# Add src to path for imports
sys.path.insert(0, str(Path(__file__).parent / "src"))
from src.mcp.mcp_server import mcp_server
from src.core.config_manager import config_manager
from src.core.dependencies import service_container
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
class MCPServerRunner:
"""Standalone MCP server runner"""
def __init__(self):
self.server = mcp_server
self.running = False
self.shutdown_event = asyncio.Event()
async def start(self):
"""Start the MCP server"""
try:
logger.info("Starting NASDAQ Stock Agent MCP Server...")
# Load configuration
config = config_manager.load_configuration()
mcp_config = config_manager.get_mcp_config()
if not mcp_config.enabled:
logger.error("MCP server is disabled in configuration")
return False
# Initialize core services (without full web app)
logger.info("Initializing core services...")
await self._initialize_core_services()
# Start MCP server
logger.info(f"Starting MCP server on {mcp_config.host}:{mcp_config.port}")
# Set up signal handlers for graceful shutdown
self._setup_signal_handlers()
# Run MCP server with stdio transport
self.running = True
await self.server.run_stdio()
except KeyboardInterrupt:
logger.info("Received interrupt signal")
except Exception as e:
logger.error(f"MCP server failed: {e}")
return False
finally:
await self.shutdown()
return True
async def _initialize_core_services(self):
"""Initialize only the core services needed for MCP"""
try:
# Initialize agent orchestrator
from src.agents.stock_analysis_agent import agent_orchestrator
health = await agent_orchestrator.get_health_status()
logger.info(f"Agent orchestrator initialized: {health.get('overall_status')}")
logger.info("Core services initialized successfully")
except Exception as e:
logger.error(f"Failed to initialize core services: {e}")
raise
def _setup_signal_handlers(self):
"""Set up signal handlers for graceful shutdown"""
def signal_handler(signum, frame):
logger.info(f"Received signal {signum}")
self.shutdown_event.set()
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
async def shutdown(self):
"""Shutdown the MCP server and cleanup"""
if not self.running:
return
logger.info("Shutting down MCP server...")
try:
# Stop MCP server
await self.server.stop_server()
self.running = False
logger.info("MCP server shutdown complete")
except Exception as e:
logger.error(f"Error during MCP server shutdown: {e}")
async def main():
"""Main entry point for standalone MCP server"""
runner = MCPServerRunner()
try:
success = await runner.start()
if not success:
sys.exit(1)
except Exception as e:
logger.error(f"MCP server startup failed: {e}")
sys.exit(1)
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
logger.info("MCP server stopped by user")
except Exception as e:
logger.error(f"MCP server failed: {e}")
sys.exit(1)