Notifications
All checks were successful
Build And Test / publish (push) Successful in 45s

This commit is contained in:
2025-12-30 15:45:50 -08:00
parent 4f6098e8c2
commit 0bbb5a5a2c
10 changed files with 752 additions and 3 deletions

View File

@@ -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())