This commit is contained in:
@@ -8,6 +8,7 @@ A self-hosted MCP server that provides tools for managing:
|
||||
- Contacts (CardDAV)
|
||||
"""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
@@ -19,6 +20,12 @@ from fastmcp import FastMCP
|
||||
from config import settings
|
||||
from database import init_db, close_db
|
||||
|
||||
# Configure logging
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
)
|
||||
|
||||
# Initialize MCP server
|
||||
mcp = FastMCP(
|
||||
settings.server_name,
|
||||
@@ -29,6 +36,7 @@ mcp = FastMCP(
|
||||
email_service = None
|
||||
calendar_service = None
|
||||
contacts_service = None
|
||||
email_monitor = None
|
||||
|
||||
|
||||
def setup_services():
|
||||
@@ -57,6 +65,22 @@ def setup_services():
|
||||
print(" Contacts service: disabled (not configured)")
|
||||
|
||||
|
||||
async def setup_email_monitor():
|
||||
"""Initialize email notification monitoring."""
|
||||
global email_monitor
|
||||
|
||||
if settings.is_notification_configured() and email_service:
|
||||
from services.webhook_service import WebhookService
|
||||
from services.email_monitor import EmailMonitor
|
||||
|
||||
webhook_service = WebhookService(settings)
|
||||
email_monitor = EmailMonitor(email_service, webhook_service, settings)
|
||||
await email_monitor.start()
|
||||
print(f" Email notifications: enabled (monitoring: {settings.notification_mailboxes})")
|
||||
else:
|
||||
print(" Email notifications: disabled (not configured)")
|
||||
|
||||
|
||||
def register_tools():
|
||||
"""Register MCP tools based on enabled services."""
|
||||
if email_service:
|
||||
@@ -117,11 +141,31 @@ async def initialize():
|
||||
print(f"\nRegistering tools...")
|
||||
register_tools()
|
||||
|
||||
print(f"\nStarting background services...")
|
||||
await setup_email_monitor()
|
||||
|
||||
print(f"\n{'='*60}")
|
||||
|
||||
|
||||
async def shutdown():
|
||||
"""Shutdown the server gracefully."""
|
||||
global email_monitor
|
||||
print("\nShutting down...")
|
||||
|
||||
if email_monitor:
|
||||
await email_monitor.stop()
|
||||
email_monitor = None
|
||||
|
||||
await close_db()
|
||||
print("Shutdown complete")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
import signal
|
||||
import uvicorn
|
||||
|
||||
from middleware import APIKeyAuthMiddleware
|
||||
|
||||
async def main():
|
||||
await initialize()
|
||||
@@ -129,15 +173,44 @@ if __name__ == "__main__":
|
||||
port = settings.server_port
|
||||
host = settings.server_host
|
||||
|
||||
# Get the underlying ASGI app from FastMCP
|
||||
app = mcp.http_app(path="/mcp")
|
||||
|
||||
# Add authentication middleware if API key is configured
|
||||
if settings.mcp_api_key:
|
||||
app.add_middleware(
|
||||
APIKeyAuthMiddleware,
|
||||
api_key=settings.mcp_api_key.get_secret_value(),
|
||||
)
|
||||
print(f"\n Authentication: enabled (API key required)")
|
||||
else:
|
||||
print(f"\n Authentication: disabled (no MCP_API_KEY set)")
|
||||
|
||||
print(f"\nStarting server on {host}:{port}")
|
||||
print(f"MCP endpoint: http://{host}:{port}/mcp")
|
||||
print(f"{'='*60}\n")
|
||||
|
||||
mcp.run(
|
||||
transport="http",
|
||||
# Setup signal handlers for graceful shutdown
|
||||
loop = asyncio.get_running_loop()
|
||||
|
||||
def signal_handler():
|
||||
asyncio.create_task(shutdown())
|
||||
|
||||
for sig in (signal.SIGTERM, signal.SIGINT):
|
||||
loop.add_signal_handler(sig, signal_handler)
|
||||
|
||||
# Run with uvicorn
|
||||
config = uvicorn.Config(
|
||||
app,
|
||||
host=host,
|
||||
port=port,
|
||||
stateless_http=True,
|
||||
log_level="info",
|
||||
)
|
||||
server = uvicorn.Server(config)
|
||||
|
||||
try:
|
||||
await server.serve()
|
||||
finally:
|
||||
await shutdown()
|
||||
|
||||
asyncio.run(main())
|
||||
|
||||
Reference in New Issue
Block a user