Skip to content

Commit 6ef6857

Browse files
authored
Merge branch 'main' into pr-2-infrastructure-ci-cd
2 parents 371ce03 + e6961ce commit 6ef6857

File tree

10 files changed

+1051
-18
lines changed

10 files changed

+1051
-18
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,3 @@
1-
---
2-
name: Bug Report
3-
about: Report a bug or issue with the KiCad MCP Server
4-
title: "[BUG] "
5-
labels: bug
6-
assignees: ''
7-
---
8-
91
## Bug Description
102
<!-- A clear and concise description of the bug -->
113

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ __pycache__/
1818
dist/
1919
build/
2020
*.egg-info/
21+
*.egg
22+
*.whl
23+
24+
# PyPI
25+
.pypirc
2126

2227
# Unit test / coverage reports
2328
htmlcov/

.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10

MANIFEST.in

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
include README.md
2+
include LICENSE
3+
include requirements.txt
4+
include .env.example
5+
recursive-include kicad_mcp *.py
6+
recursive-include docs *.md

kicad_mcp/__init__.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,27 @@
11
"""
22
KiCad MCP Server - A Model Context Protocol server for KiCad.
33
"""
4+
from .server import *
5+
from .config import *
6+
from .context import *
7+
48
__version__ = "0.1.0"
9+
__author__ = "Lama Al Rajih"
10+
__description__ = "Model Context Protocol server for KiCad on Mac, Windows, and Linux"
11+
12+
__all__ = [
13+
# Package metadata
14+
"__version__",
15+
"__author__",
16+
"__description__",
17+
18+
# Server creation / shutdown helpers
19+
"create_server",
20+
"add_cleanup_handler",
21+
"run_cleanup_handlers",
22+
"shutdown_server",
23+
24+
# Lifespan / context helpers
25+
"kicad_lifespan",
26+
"KiCadAppContext",
27+
]

kicad_mcp/server.py

Lines changed: 46 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@
55
import os
66
import signal
77
import logging
8+
import functools
89
from typing import Callable
9-
from mcp.server.fastmcp import FastMCP
10+
from fastmcp import FastMCP
1011

1112
# Import resource handlers
1213
from kicad_mcp.resources.projects import register_project_resources
@@ -127,9 +128,11 @@ def create_server() -> FastMCP:
127128
# Always print this now, as we rely on CLI
128129
logging.info(f"KiCad Python module setup removed; relying on kicad-cli for external operations.")
129130

131+
# Build a lifespan callable with the kwarg baked in (FastMCP 2.x dropped lifespan_kwargs)
132+
lifespan_factory = functools.partial(kicad_lifespan, kicad_modules_available=kicad_modules_available)
133+
130134
# Initialize FastMCP server
131-
# Pass the availability flag (always False now) to the lifespan context
132-
mcp = FastMCP("KiCad", lifespan=kicad_lifespan, lifespan_kwargs={"kicad_modules_available": kicad_modules_available})
135+
mcp = FastMCP("KiCad", lifespan=lifespan_factory)
133136
logging.info(f"Created FastMCP server instance with lifespan management")
134137

135138
# Register resources
@@ -186,3 +189,43 @@ def cleanup_temp_dirs():
186189

187190
logging.info(f"Server initialization complete")
188191
return mcp
192+
193+
194+
def setup_signal_handlers() -> None:
195+
"""Setup signal handlers for graceful shutdown."""
196+
# Signal handlers are set up in register_signal_handlers
197+
pass
198+
199+
200+
def cleanup_handler() -> None:
201+
"""Handle cleanup during shutdown."""
202+
run_cleanup_handlers()
203+
204+
205+
def setup_logging() -> None:
206+
"""Configure logging for the server."""
207+
logging.basicConfig(
208+
level=logging.INFO,
209+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
210+
)
211+
212+
213+
def main() -> None:
214+
"""Start the KiCad MCP server (blocking)."""
215+
setup_logging()
216+
logging.info("Starting KiCad MCP server...")
217+
218+
server = create_server()
219+
220+
try:
221+
server.run() # FastMCP manages its own event loop
222+
except KeyboardInterrupt:
223+
logging.info("Server interrupted by user")
224+
except Exception as e:
225+
logging.error(f"Server error: {e}")
226+
finally:
227+
logging.info("Server shutdown complete")
228+
229+
230+
if __name__ == "__main__":
231+
main()

kicad_mcp/tools/export_tools.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def register_export_tools(mcp: FastMCP) -> None:
2020
"""
2121

2222
@mcp.tool()
23-
async def generate_pcb_thumbnail(project_path: str, ctx: Context) -> Optional[Image]:
23+
async def generate_pcb_thumbnail(project_path: str, ctx: Context):
2424
"""Generate a thumbnail image of a KiCad PCB layout using kicad-cli.
2525
2626
Args:
@@ -88,14 +88,14 @@ async def generate_pcb_thumbnail(project_path: str, ctx: Context) -> Optional[Im
8888
return None
8989

9090
@mcp.tool()
91-
async def generate_project_thumbnail(project_path: str, ctx: Context) -> Optional[Image]:
91+
async def generate_project_thumbnail(project_path: str, ctx: Context):
9292
"""Generate a thumbnail of a KiCad project's PCB layout (Alias for generate_pcb_thumbnail)."""
9393
# This function now just calls the main CLI-based thumbnail generator
9494
print(f"generate_project_thumbnail called, redirecting to generate_pcb_thumbnail for {project_path}")
9595
return await generate_pcb_thumbnail(project_path, ctx)
9696

9797
# Helper functions for thumbnail generation
98-
async def generate_thumbnail_with_cli(pcb_file: str, ctx: Context) -> Optional[Image]:
98+
async def generate_thumbnail_with_cli(pcb_file: str, ctx: Context):
9999
"""Generate PCB thumbnail using command line tools.
100100
This is a fallback method when the kicad Python module is not available or fails.
101101

main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
# Must import config BEFORE env potentially overrides it via os.environ
1111
from kicad_mcp.config import KICAD_USER_DIR, ADDITIONAL_SEARCH_PATHS
12-
from kicad_mcp.server import create_server
12+
from kicad_mcp.server import main as server_main
1313
from kicad_mcp.utils.env import load_dotenv
1414

1515
# --- Setup Logging ---
@@ -70,10 +70,10 @@
7070
else:
7171
logging.info(f"No additional search paths configured") # Changed print to logging
7272

73-
# Create and run server
74-
server = create_server()
73+
# Run server
7574
logging.info(f"Running server with stdio transport") # Changed print to logging
76-
server.run(transport='stdio')
75+
import asyncio
76+
asyncio.run(server_main())
7777
except Exception as e:
7878
logging.exception(f"Unhandled exception in main") # Log exception details
7979
raise

pyproject.toml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,22 @@ dependencies = [
1616
"mcp[cli]>=1.0.0",
1717
"pandas>=2.0.0",
1818
]
19+
classifiers = [
20+
"Programming Language :: Python :: 3",
21+
"Programming Language :: Python :: 3.10",
22+
"Programming Language :: Python :: 3.11",
23+
"Programming Language :: Python :: 3.12",
24+
"License :: OSI Approved :: MIT License",
25+
"Operating System :: OS Independent",
26+
"Intended Audience :: Developers",
27+
"Topic :: Software Development :: Libraries :: Python Modules",
28+
"Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
29+
]
30+
31+
[project.urls]
32+
"Homepage" = "https://github.com/lamaalrajih/kicad-mcp"
33+
"Bug Tracker" = "https://github.com/lamaalrajih/kicad-mcp/issues"
34+
"Documentation" = "https://github.com/lamaalrajih/kicad-mcp#readme"
1935

2036
[project.scripts]
2137
kicad-mcp = "kicad_mcp.server:main"
@@ -67,3 +83,11 @@ addopts = [
6783
]
6884
testpaths = ["tests"]
6985
asyncio_mode = "auto"
86+
87+
[tool.setuptools.packages.find]
88+
where = ["."]
89+
include = ["kicad_mcp*"]
90+
exclude = ["tests*", "docs*"]
91+
92+
[tool.setuptools.package-data]
93+
"kicad_mcp" = ["prompts/*.txt", "resources/**/*.json"]

0 commit comments

Comments
 (0)