Merge pull request #19 from laurigates/pr-1-fastmcp-2.0-migration
FastMCP 2.0 Migration & Foundation
This commit is contained in:
commit
e6961ceefb
@ -5,8 +5,9 @@ import atexit
|
|||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import logging
|
import logging
|
||||||
|
import functools
|
||||||
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
|
||||||
@ -127,9 +128,11 @@ def create_server() -> FastMCP:
|
|||||||
# Always print this now, as we rely on CLI
|
# Always print this now, as we rely on CLI
|
||||||
logging.info(f"KiCad Python module setup removed; relying on kicad-cli for external operations.")
|
logging.info(f"KiCad Python module setup removed; relying on kicad-cli for external operations.")
|
||||||
|
|
||||||
|
# Build a lifespan callable with the kwarg baked in (FastMCP 2.x dropped lifespan_kwargs)
|
||||||
|
lifespan_factory = functools.partial(kicad_lifespan, kicad_modules_available=kicad_modules_available)
|
||||||
|
|
||||||
# Initialize FastMCP server
|
# Initialize FastMCP server
|
||||||
# Pass the availability flag (always False now) to the lifespan context
|
mcp = FastMCP("KiCad", lifespan=lifespan_factory)
|
||||||
mcp = FastMCP("KiCad", lifespan=kicad_lifespan, lifespan_kwargs={"kicad_modules_available": kicad_modules_available})
|
|
||||||
logging.info(f"Created FastMCP server instance with lifespan management")
|
logging.info(f"Created FastMCP server instance with lifespan management")
|
||||||
|
|
||||||
# Register resources
|
# Register resources
|
||||||
@ -186,3 +189,43 @@ 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'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
"""Start the KiCad MCP server (blocking)."""
|
||||||
|
setup_logging()
|
||||||
|
logging.info("Starting KiCad MCP server...")
|
||||||
|
|
||||||
|
server = create_server()
|
||||||
|
|
||||||
|
try:
|
||||||
|
server.run() # FastMCP manages its own event loop
|
||||||
|
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__":
|
||||||
|
main()
|
||||||
|
8
main.py
8
main.py
@ -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
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=61.0", "wheel"]
|
requires = ["hatchling"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "kicad-mcp"
|
name = "kicad-mcp"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = [{ name = "Lama Al Rajih" }]
|
description = "Model Context Protocol (MCP) server for KiCad electronic design automation (EDA) files"
|
||||||
description = "Model Context Protocol server for KiCad on Mac, Windows, and Linux"
|
|
||||||
license = { text = "MIT" }
|
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
license = { text = "MIT" }
|
||||||
|
authors = [
|
||||||
|
{ name = "KiCad MCP Contributors" }
|
||||||
|
]
|
||||||
requires-python = ">=3.10"
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"mcp[cli]>=1.0.0",
|
||||||
|
"fastmcp>=0.1.0",
|
||||||
|
"pandas>=2.0.0",
|
||||||
|
]
|
||||||
classifiers = [
|
classifiers = [
|
||||||
"Programming Language :: Python :: 3",
|
"Programming Language :: Python :: 3",
|
||||||
"Programming Language :: Python :: 3.10",
|
"Programming Language :: Python :: 3.10",
|
||||||
@ -17,12 +24,10 @@ classifiers = [
|
|||||||
"Programming Language :: Python :: 3.12",
|
"Programming Language :: Python :: 3.12",
|
||||||
"License :: OSI Approved :: MIT License",
|
"License :: OSI Approved :: MIT License",
|
||||||
"Operating System :: OS Independent",
|
"Operating System :: OS Independent",
|
||||||
"Development Status :: 4 - Beta",
|
|
||||||
"Intended Audience :: Developers",
|
"Intended Audience :: Developers",
|
||||||
"Topic :: Software Development :: Libraries :: Python Modules",
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
||||||
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
|
||||||
]
|
]
|
||||||
dependencies = ["mcp[cli]>=1.11.0", "pandas>=2.3.1", "pytest>=8.4.1"]
|
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
"Homepage" = "https://github.com/lamaalrajih/kicad-mcp"
|
"Homepage" = "https://github.com/lamaalrajih/kicad-mcp"
|
||||||
@ -30,7 +35,13 @@ dependencies = ["mcp[cli]>=1.11.0", "pandas>=2.3.1", "pytest>=8.4.1"]
|
|||||||
"Documentation" = "https://github.com/lamaalrajih/kicad-mcp#readme"
|
"Documentation" = "https://github.com/lamaalrajih/kicad-mcp#readme"
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
kicad-mcp = "kicad_mcp.main:main"
|
kicad-mcp = "kicad_mcp.server:main"
|
||||||
|
|
||||||
|
[dependency-groups]
|
||||||
|
dev = [
|
||||||
|
"pytest>=7.0.0",
|
||||||
|
"pytest-asyncio>=0.23.0",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["."]
|
where = ["."]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user