Fix .env loading order so KICAD_SEARCH_PATHS takes effect

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.
This commit is contained in:
Ryan Malloy 2026-03-03 16:53:40 -07:00
parent 687e14bd11
commit 4ebf8f08e9
2 changed files with 35 additions and 43 deletions

69
main.py
View File

@ -4,13 +4,7 @@ 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 sys
import logging # Import logging module
# Must import config BEFORE env potentially overrides it via os.environ
from mckicad.config import KICAD_USER_DIR, ADDITIONAL_SEARCH_PATHS
from mckicad.server import main as server_main
from mckicad.utils.env import load_dotenv
import logging
# --- Setup Logging ---
log_file = os.path.join(os.path.dirname(__file__), 'mckicad.log')
@ -18,46 +12,43 @@ logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - [PID:%(process)d] - %(message)s',
handlers=[
logging.FileHandler(log_file, mode='w'), # Use 'w' to overwrite log on each start
# logging.StreamHandler() # Optionally keep logging to console if needed
logging.FileHandler(log_file, mode='w'),
]
)
# ---------------------
logging.info("--- Server Starting ---")
logging.info(f"Initial KICAD_USER_DIR from config.py: {KICAD_USER_DIR}")
logging.info(f"Initial ADDITIONAL_SEARCH_PATHS from config.py: {ADDITIONAL_SEARCH_PATHS}")
# Get PID for logging (already used by basicConfig)
_PID = os.getpid()
# 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")
# Load environment variables from .env file if present
# This attempts to update os.environ
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
logging.info(f"Attempting to load .env file from: {dotenv_path}")
found_dotenv = load_dotenv() # Assuming this returns True/False or similar
logging.info(f".env file found and loaded: {found_dotenv}")
# 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
# Log effective values AFTER load_dotenv attempt
# Note: The config values might not automatically re-read from os.environ
# depending on how config.py is written. Let's check os.environ directly.
effective_user_dir = os.getenv('KICAD_USER_DIR')
effective_search_paths = os.getenv('KICAD_SEARCH_PATHS')
logging.info(f"os.environ['KICAD_USER_DIR'] after load_dotenv: {effective_user_dir}")
logging.info(f"os.environ['KICAD_SEARCH_PATHS'] after load_dotenv: {effective_search_paths}")
# Re-log the values imported from config.py to see if they reflect os.environ changes
# (This depends on config.py using os.getenv internally AFTER load_dotenv runs)
try:
from mckicad import config
import importlib
importlib.reload(config) # Attempt to force re-reading config
logging.info(f"Effective KICAD_USER_DIR from config.py after reload: {config.KICAD_USER_DIR}")
logging.info(f"Effective ADDITIONAL_SEARCH_PATHS from config.py after reload: {config.ADDITIONAL_SEARCH_PATHS}")
except Exception as e:
logging.error(f"Could not reload config: {e}")
logging.info(f"Using potentially stale KICAD_USER_DIR from initial import: {KICAD_USER_DIR}")
logging.info(f"Using potentially stale ADDITIONAL_SEARCH_PATHS from initial import: {ADDITIONAL_SEARCH_PATHS}")
logging.info(f"KICAD_USER_DIR: {KICAD_USER_DIR}")
logging.info(f"ADDITIONAL_SEARCH_PATHS: {ADDITIONAL_SEARCH_PATHS}")
if __name__ == "__main__":
try:

View File

@ -1,2 +1,3 @@
#!/bin/bash
/home/rpm/claude/kicad-mcp/venv/bin/python /home/rpm/claude/kicad-mcp/main.py "$@"
cd /home/rpm/claude/kicad-mcp
uv run python main.py "$@"