config.py evaluates os.environ at import time, but mckicad/__init__.py eagerly imports config via 'from .config import *'. The old main.py loaded .env after importing from mckicad, so the search paths were always empty. Now .env is parsed with stdlib before any mckicad imports. Also fix start.sh to use 'uv run' instead of stale venv/ path.
70 lines
2.6 KiB
Python
70 lines
2.6 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
KiCad MCP Server - A Model Context Protocol server for KiCad on macOS.
|
|
This server allows Claude and other MCP clients to interact with KiCad projects.
|
|
"""
|
|
import os
|
|
import logging
|
|
|
|
# --- Setup Logging ---
|
|
log_file = os.path.join(os.path.dirname(__file__), 'mckicad.log')
|
|
logging.basicConfig(
|
|
level=logging.INFO,
|
|
format='%(asctime)s - %(levelname)s - [PID:%(process)d] - %(message)s',
|
|
handlers=[
|
|
logging.FileHandler(log_file, mode='w'),
|
|
]
|
|
)
|
|
# ---------------------
|
|
|
|
logging.info("--- Server Starting ---")
|
|
|
|
# Load .env BEFORE any mckicad imports. Importing mckicad.utils.env would
|
|
# trigger mckicad/__init__.py which eagerly imports config.py, evaluating
|
|
# os.environ.get("KICAD_SEARCH_PATHS") before .env is loaded. So we
|
|
# inline the loading here using only stdlib.
|
|
_dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
|
|
if os.path.exists(_dotenv_path):
|
|
logging.info(f"Loading .env from: {_dotenv_path}")
|
|
with open(_dotenv_path) as _f:
|
|
for _line in _f:
|
|
_line = _line.strip()
|
|
if not _line or _line.startswith("#"):
|
|
continue
|
|
if "=" in _line:
|
|
_key, _val = _line.split("=", 1)
|
|
_key, _val = _key.strip(), _val.strip()
|
|
if (_val.startswith('"') and _val.endswith('"')) or (
|
|
_val.startswith("'") and _val.endswith("'")
|
|
):
|
|
_val = _val[1:-1]
|
|
os.environ[_key] = _val
|
|
logging.info(f" {_key}={_val}")
|
|
else:
|
|
logging.info("No .env file found")
|
|
|
|
# Now safe to import mckicad — config.py will see the .env values
|
|
from mckicad.config import KICAD_USER_DIR, ADDITIONAL_SEARCH_PATHS
|
|
from mckicad.server import main as server_main
|
|
|
|
logging.info(f"KICAD_USER_DIR: {KICAD_USER_DIR}")
|
|
logging.info(f"ADDITIONAL_SEARCH_PATHS: {ADDITIONAL_SEARCH_PATHS}")
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
logging.info(f"Starting KiCad MCP server process")
|
|
|
|
# Print search paths from config
|
|
logging.info(f"Using KiCad user directory: {KICAD_USER_DIR}") # Changed print to logging
|
|
if ADDITIONAL_SEARCH_PATHS:
|
|
logging.info(f"Additional search paths: {', '.join(ADDITIONAL_SEARCH_PATHS)}") # Changed print to logging
|
|
else:
|
|
logging.info(f"No additional search paths configured") # Changed print to logging
|
|
|
|
# Run server
|
|
logging.info(f"Running server with stdio transport") # Changed print to logging
|
|
server_main()
|
|
except Exception as e:
|
|
logging.exception(f"Unhandled exception in main") # Log exception details
|
|
raise
|