feat: migrate to FastMCP 2.0 framework with modern Python packaging

- Update imports from 'mcp.server.fastmcp' to 'fastmcp' per FastMCP 2.0 migration
- Add pyproject.toml for modern Python packaging with hatchling build backend
- Implement missing server lifecycle functions: main(), setup_logging(), cleanup_handler()
- Add async main() entry point for proper server execution
- Update main.py to use async server execution pattern
- Add fastmcp>=0.1.0 dependency to replace legacy mcp server imports

This establishes the foundation for all subsequent feature additions and ensures
compatibility with modern MCP clients and development workflows.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Lauri Gates 2025-07-17 20:13:01 +03:00
parent 7019df0ccc
commit 9bea0f4ebf
3 changed files with 74 additions and 5 deletions

View File

@ -6,7 +6,7 @@ import os
import signal import signal
import logging import logging
from typing import Callable from typing import Callable
from mcp.server.fastmcp import FastMCP from fastmcp import FastMCP
# Import resource handlers # Import resource handlers
from kicad_mcp.resources.projects import register_project_resources from kicad_mcp.resources.projects import register_project_resources
@ -186,3 +186,44 @@ def create_server() -> FastMCP:
logging.info(f"Server initialization complete") logging.info(f"Server initialization complete")
return mcp return mcp
def setup_signal_handlers() -> None:
"""Setup signal handlers for graceful shutdown."""
# Signal handlers are set up in register_signal_handlers
pass
def cleanup_handler() -> None:
"""Handle cleanup during shutdown."""
run_cleanup_handlers()
def setup_logging() -> None:
"""Configure logging for the server."""
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
async def main() -> None:
"""Main server entry point."""
setup_logging()
logging.info("Starting KiCad MCP server...")
server = create_server()
try:
await server.run()
except KeyboardInterrupt:
logging.info("Server interrupted by user")
except Exception as e:
logging.error(f"Server error: {e}")
finally:
logging.info("Server shutdown complete")
if __name__ == "__main__":
import asyncio
asyncio.run(main())

View File

@ -9,7 +9,7 @@ import logging # Import logging module
# Must import config BEFORE env potentially overrides it via os.environ # Must import config BEFORE env potentially overrides it via os.environ
from kicad_mcp.config import KICAD_USER_DIR, ADDITIONAL_SEARCH_PATHS from kicad_mcp.config import KICAD_USER_DIR, ADDITIONAL_SEARCH_PATHS
from kicad_mcp.server import create_server from kicad_mcp.server import main as server_main
from kicad_mcp.utils.env import load_dotenv from kicad_mcp.utils.env import load_dotenv
# --- Setup Logging --- # --- Setup Logging ---
@ -70,10 +70,10 @@ if __name__ == "__main__":
else: else:
logging.info(f"No additional search paths configured") # Changed print to logging logging.info(f"No additional search paths configured") # Changed print to logging
# Create and run server # Run server
server = create_server()
logging.info(f"Running server with stdio transport") # Changed print to logging logging.info(f"Running server with stdio transport") # Changed print to logging
server.run(transport='stdio') import asyncio
asyncio.run(server_main())
except Exception as e: except Exception as e:
logging.exception(f"Unhandled exception in main") # Log exception details logging.exception(f"Unhandled exception in main") # Log exception details
raise raise

28
pyproject.toml Normal file
View File

@ -0,0 +1,28 @@
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[project]
name = "kicad-mcp"
version = "0.1.0"
description = "Model Context Protocol (MCP) server for KiCad electronic design automation (EDA) files"
readme = "README.md"
license = { text = "MIT" }
authors = [
{ name = "KiCad MCP Contributors" }
]
requires-python = ">=3.10"
dependencies = [
"mcp[cli]>=1.0.0",
"fastmcp>=0.1.0",
"pandas>=2.0.0",
]
[project.scripts]
kicad-mcp = "kicad_mcp.server:main"
[dependency-groups]
dev = [
"pytest>=7.0.0",
"pytest-asyncio>=0.23.0",
]