#!/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