From 9bea0f4ebf7b7c0fa55705503f39a2eb885157b8 Mon Sep 17 00:00:00 2001 From: Lauri Gates Date: Thu, 17 Jul 2025 20:13:01 +0300 Subject: [PATCH] feat: migrate to FastMCP 2.0 framework with modern Python packaging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- kicad_mcp/server.py | 43 ++++++++++++++++++++++++++++++++++++++++++- main.py | 8 ++++---- pyproject.toml | 28 ++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 pyproject.toml diff --git a/kicad_mcp/server.py b/kicad_mcp/server.py index b1d9289..4d5b385 100644 --- a/kicad_mcp/server.py +++ b/kicad_mcp/server.py @@ -6,7 +6,7 @@ import os import signal import logging from typing import Callable -from mcp.server.fastmcp import FastMCP +from fastmcp import FastMCP # Import resource handlers from kicad_mcp.resources.projects import register_project_resources @@ -186,3 +186,44 @@ def create_server() -> FastMCP: logging.info(f"Server initialization complete") 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()) diff --git a/main.py b/main.py index 3be66b8..6860fe0 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,7 @@ import logging # Import logging module # 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.server import create_server +from kicad_mcp.server import main as server_main from kicad_mcp.utils.env import load_dotenv # --- Setup Logging --- @@ -70,10 +70,10 @@ if __name__ == "__main__": else: logging.info(f"No additional search paths configured") # Changed print to logging - # Create and run server - server = create_server() + # Run server 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: logging.exception(f"Unhandled exception in main") # Log exception details raise diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e6328bc --- /dev/null +++ b/pyproject.toml @@ -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", +] \ No newline at end of file