Initial commit
All checks were successful
Build And Test / publish (push) Successful in 1m30s

This commit is contained in:
2025-12-30 15:16:45 -08:00
parent 4df9a7229e
commit 4f6098e8c2
28 changed files with 3080 additions and 0 deletions

143
src/server.py Normal file
View File

@@ -0,0 +1,143 @@
#!/usr/bin/env python3
"""
PIM MCP Server - Personal Information Management via Model Context Protocol
A self-hosted MCP server that provides tools for managing:
- Email (IMAP/SMTP)
- Calendar (CalDAV)
- Contacts (CardDAV)
"""
import os
import sys
# Add src directory to path for imports
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from fastmcp import FastMCP
from config import settings
from database import init_db, close_db
# Initialize MCP server
mcp = FastMCP(
settings.server_name,
description="Personal Information Management MCP Server for Email, Calendar, and Contacts",
)
# Initialize services based on configuration
email_service = None
calendar_service = None
contacts_service = None
def setup_services():
"""Initialize services based on configuration."""
global email_service, calendar_service, contacts_service
if settings.is_email_configured():
from services.email_service import EmailService
email_service = EmailService(settings)
print(f" Email service: enabled (IMAP: {settings.imap_host})")
else:
print(" Email service: disabled (not configured)")
if settings.is_calendar_configured():
from services.calendar_service import CalendarService
calendar_service = CalendarService(settings)
print(f" Calendar service: enabled (CalDAV: {settings.caldav_url})")
else:
print(" Calendar service: disabled (not configured)")
if settings.is_contacts_configured():
from services.contacts_service import ContactsService
contacts_service = ContactsService(settings)
print(f" Contacts service: enabled (CardDAV: {settings.carddav_url})")
else:
print(" Contacts service: disabled (not configured)")
def register_tools():
"""Register MCP tools based on enabled services."""
if email_service:
from tools.email_tools import register_email_tools
register_email_tools(mcp, email_service)
print(" Registered email tools")
if calendar_service:
from tools.calendar_tools import register_calendar_tools
register_calendar_tools(mcp, calendar_service)
print(" Registered calendar tools")
if contacts_service:
from tools.contacts_tools import register_contacts_tools
register_contacts_tools(mcp, contacts_service)
print(" Registered contacts tools")
# Server info tool (always available)
@mcp.tool(description="Get information about this PIM MCP server including enabled services and version.")
def get_server_info() -> dict:
"""Get server information and status."""
return {
"server_name": settings.server_name,
"version": "1.0.0",
"environment": settings.environment,
"services": {
"email": {
"enabled": email_service is not None,
"imap_host": settings.imap_host if email_service else None,
"smtp_configured": settings.is_smtp_configured() if email_service else False,
},
"calendar": {
"enabled": calendar_service is not None,
"caldav_url": settings.caldav_url if calendar_service else None,
},
"contacts": {
"enabled": contacts_service is not None,
"carddav_url": settings.carddav_url if contacts_service else None,
},
},
}
async def initialize():
"""Initialize the server."""
print(f"\n{'='*60}")
print(f" {settings.server_name}")
print(f"{'='*60}")
print(f"\nInitializing database...")
await init_db(settings.sqlite_path)
print(f" Database: {settings.sqlite_path}")
print(" Using SQLModel with Alembic migrations")
print(f"\nConfiguring services...")
setup_services()
print(f"\nRegistering tools...")
register_tools()
print(f"\n{'='*60}")
if __name__ == "__main__":
import asyncio
async def main():
await initialize()
port = settings.server_port
host = settings.server_host
print(f"\nStarting server on {host}:{port}")
print(f"MCP endpoint: http://{host}:{port}/mcp")
print(f"{'='*60}\n")
mcp.run(
transport="http",
host=host,
port=port,
stateless_http=True,
)
asyncio.run(main())