Removed unnecessary IPC drc - defaulting to only using the CLI
This commit is contained in:
parent
a95c0a40ba
commit
e5c87df088
@ -152,9 +152,8 @@ The KiCad MCP Server provides several key features, each with detailed documenta
|
|||||||
- **BOM Management**: Analyze and export Bills of Materials
|
- **BOM Management**: Analyze and export Bills of Materials
|
||||||
- *Example:* "Generate a BOM for my smart watch project" → Creates a detailed bill of materials
|
- *Example:* "Generate a BOM for my smart watch project" → Creates a detailed bill of materials
|
||||||
|
|
||||||
- **Design Rule Checking**: Run DRC checks and track your progress over time
|
- **Design Rule Checking**: Run DRC checks using the KiCad CLI and track your progress over time
|
||||||
- *Example:* "Run DRC on my power supply board and compare to last week" → Shows progress in fixing violations
|
- *Example:* "Run DRC on my power supply board and compare to last week" → Shows progress in fixing violations
|
||||||
- *KiCad 9.0+ Compatible:* Uses the new KiCad CLI or IPC API automatically
|
|
||||||
|
|
||||||
- **PCB Visualization**: Generate visual representations of your PCB layouts
|
- **PCB Visualization**: Generate visual representations of your PCB layouts
|
||||||
- *Example:* "Show me a thumbnail of my audio amplifier PCB" → Displays a visual render of the board
|
- *Example:* "Show me a thumbnail of my audio amplifier PCB" → Displays a visual render of the board
|
||||||
|
@ -11,15 +11,7 @@ The Design Rule Check (DRC) functionality allows you to:
|
|||||||
3. Track your progress over time as you fix issues
|
3. Track your progress over time as you fix issues
|
||||||
4. Compare current results with previous checks
|
4. Compare current results with previous checks
|
||||||
|
|
||||||
## KiCad 9.0+ Compatibility
|
It does this all by using the `kicad-cli` command-line tool to run DRC checks without requiring a running instance of KiCad.
|
||||||
|
|
||||||
**Important Update**: With KiCad 9.0+, the DRC functionality has been reimplemented to work with the new KiCad APIs. The server now supports two methods for running DRC:
|
|
||||||
|
|
||||||
1. **KiCad CLI Method** (Recommended) - Uses the `kicad-cli` command-line tool to run DRC checks without requiring a running instance of KiCad.
|
|
||||||
|
|
||||||
2. **IPC API Method** - Connects to a running instance of KiCad through the new IPC API using the `kicad-python` package.
|
|
||||||
|
|
||||||
The server automatically selects the best available method based on your KiCad installation.
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
@ -27,7 +19,6 @@ For optimal DRC functionality with KiCad 9.0+, you should have:
|
|||||||
|
|
||||||
- KiCad 9.0 or newer installed
|
- KiCad 9.0 or newer installed
|
||||||
- `kicad-cli` available in your system PATH (included with KiCad 9.0+)
|
- `kicad-cli` available in your system PATH (included with KiCad 9.0+)
|
||||||
- For IPC API functionality: the `kicad-python` package installed (`pip install kicad-python`)
|
|
||||||
|
|
||||||
## Using DRC Features
|
## Using DRC Features
|
||||||
|
|
||||||
@ -43,7 +34,7 @@ Please run a DRC check on my project at /Users/username/Documents/KiCad/my_proje
|
|||||||
```
|
```
|
||||||
|
|
||||||
The tool will:
|
The tool will:
|
||||||
- Automatically select the best available method (CLI or IPC API)
|
- Use the kicad CLI to run the DRC check
|
||||||
- Analyze your PCB design for rule violations
|
- Analyze your PCB design for rule violations
|
||||||
- Generate a comprehensive report
|
- Generate a comprehensive report
|
||||||
- Save the results to your DRC history
|
- Save the results to your DRC history
|
||||||
@ -141,19 +132,7 @@ If the DRC check fails to run:
|
|||||||
|
|
||||||
1. Ensure your KiCad project exists at the specified path
|
1. Ensure your KiCad project exists at the specified path
|
||||||
2. Verify that the project contains a PCB file (.kicad_pcb)
|
2. Verify that the project contains a PCB file (.kicad_pcb)
|
||||||
3. Check your KiCad installation:
|
3. Check your KiCad installation: Verify `kicad-cli` is in your PATH or in a standard installation location
|
||||||
- For CLI method: Verify `kicad-cli` is in your PATH or in a standard installation location
|
|
||||||
- For IPC API method: Make sure KiCad is running with the API server enabled in Preferences > Plugins
|
|
||||||
4. Try using the full absolute path to your project file
|
4. Try using the full absolute path to your project file
|
||||||
|
|
||||||
### Method Selection Issues
|
|
||||||
|
|
||||||
If you want to force a specific DRC method:
|
|
||||||
|
|
||||||
1. **CLI Method**: Ensure `kicad-cli` is available in your PATH
|
|
||||||
2. **IPC API Method**:
|
|
||||||
- Install the `kicad-python` package
|
|
||||||
- Launch KiCad before running the DRC check
|
|
||||||
- Enable the API server in KiCad preferences
|
|
||||||
|
|
||||||
If you continue to experience issues, check the server logs for more detailed error information.
|
If you continue to experience issues, check the server logs for more detailed error information.
|
||||||
|
@ -1,160 +0,0 @@
|
|||||||
"""
|
|
||||||
Design Rule Check (DRC) implementation using the KiCad IPC API.
|
|
||||||
"""
|
|
||||||
import os
|
|
||||||
from typing import Any, Dict
|
|
||||||
|
|
||||||
from mcp.server.fastmcp import Context
|
|
||||||
|
|
||||||
from kicad_mcp.utils.kicad_api_detection import check_ipc_api_environment
|
|
||||||
|
|
||||||
async def run_drc_with_ipc_api(pcb_file: str, ctx: Context) -> Dict[str, Any]:
|
|
||||||
"""Run DRC using the KiCad IPC API (kicad-python).
|
|
||||||
This requires a running instance of KiCad with the IPC API enabled.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
pcb_file: Path to the PCB file (.kicad_pcb)
|
|
||||||
ctx: MCP context for progress reporting
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Dictionary with DRC results
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Import the kicad-python modules
|
|
||||||
import kipy
|
|
||||||
from kipy.board_types import DrcExclusion, DrcSeverity
|
|
||||||
print("Successfully imported kipy modules")
|
|
||||||
|
|
||||||
# Check if we're running in a KiCad IPC plugin environment
|
|
||||||
is_plugin, socket_path = check_ipc_api_environment()
|
|
||||||
|
|
||||||
# Connect to KiCad
|
|
||||||
await ctx.report_progress(20, 100)
|
|
||||||
ctx.info("Connecting to KiCad...")
|
|
||||||
|
|
||||||
if is_plugin:
|
|
||||||
# When running as a plugin, let kipy use environment variables
|
|
||||||
kicad = kipy.KiCad()
|
|
||||||
else:
|
|
||||||
# When running standalone, try to connect to KiCad
|
|
||||||
if socket_path:
|
|
||||||
kicad = kipy.KiCad(socket_path=socket_path)
|
|
||||||
else:
|
|
||||||
# Try with default socket path
|
|
||||||
kicad = kipy.KiCad()
|
|
||||||
|
|
||||||
# Get the currently open board
|
|
||||||
await ctx.report_progress(30, 100)
|
|
||||||
ctx.info("Getting board...")
|
|
||||||
|
|
||||||
# Check which board to use
|
|
||||||
current_boards = await kicad.get_open_documents("board")
|
|
||||||
|
|
||||||
# If we have an open board, check if it's the one we want
|
|
||||||
use_current_board = False
|
|
||||||
board_doc = None
|
|
||||||
|
|
||||||
if current_boards:
|
|
||||||
for doc in current_boards:
|
|
||||||
if doc.file_path and os.path.normpath(doc.file_path) == os.path.normpath(pcb_file):
|
|
||||||
board_doc = doc
|
|
||||||
use_current_board = True
|
|
||||||
break
|
|
||||||
|
|
||||||
# If the board isn't open, see if we can open it
|
|
||||||
if not use_current_board:
|
|
||||||
ctx.info(f"Opening board file: {pcb_file}")
|
|
||||||
try:
|
|
||||||
# Try to open the board
|
|
||||||
doc = await kicad.open_document(pcb_file)
|
|
||||||
board_doc = doc
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error opening board: {str(e)}")
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"method": "ipc",
|
|
||||||
"error": f"Failed to open board file: {str(e)}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the board
|
|
||||||
board = await kicad.board.get_board(board_doc.uuid)
|
|
||||||
|
|
||||||
# Run DRC
|
|
||||||
await ctx.report_progress(50, 100)
|
|
||||||
ctx.info("Running DRC check...")
|
|
||||||
|
|
||||||
# Define which severities to include
|
|
||||||
severity_filter = DrcSeverity.ERROR | DrcSeverity.WARNING
|
|
||||||
|
|
||||||
# Run DRC on the board
|
|
||||||
drc_report = await kicad.board.run_drc(
|
|
||||||
board.uuid,
|
|
||||||
severity_filter=severity_filter,
|
|
||||||
exclusions=DrcExclusion.NONE # Include all violations
|
|
||||||
)
|
|
||||||
|
|
||||||
# Process results
|
|
||||||
await ctx.report_progress(70, 100)
|
|
||||||
ctx.info("Processing DRC results...")
|
|
||||||
|
|
||||||
# Get all violations
|
|
||||||
violations = drc_report.violations
|
|
||||||
violation_count = len(violations)
|
|
||||||
|
|
||||||
print(f"DRC completed with {violation_count} violations")
|
|
||||||
ctx.info(f"DRC completed with {violation_count} violations")
|
|
||||||
|
|
||||||
# Process the violations
|
|
||||||
drc_errors = []
|
|
||||||
error_types = {}
|
|
||||||
|
|
||||||
for violation in violations:
|
|
||||||
# Get violation details
|
|
||||||
severity = str(violation.severity)
|
|
||||||
message = violation.message
|
|
||||||
|
|
||||||
# Extract location
|
|
||||||
location = {
|
|
||||||
"x": violation.location.x if hasattr(violation, 'location') and violation.location else 0,
|
|
||||||
"y": violation.location.y if hasattr(violation, 'location') and violation.location else 0
|
|
||||||
}
|
|
||||||
|
|
||||||
error_info = {
|
|
||||||
"severity": severity,
|
|
||||||
"message": message,
|
|
||||||
"location": location
|
|
||||||
}
|
|
||||||
|
|
||||||
drc_errors.append(error_info)
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
if message not in error_types:
|
|
||||||
error_types[message] = 0
|
|
||||||
error_types[message] += 1
|
|
||||||
|
|
||||||
# Create result
|
|
||||||
results = {
|
|
||||||
"success": True,
|
|
||||||
"method": "ipc",
|
|
||||||
"pcb_file": pcb_file,
|
|
||||||
"total_violations": violation_count,
|
|
||||||
"violation_categories": error_types,
|
|
||||||
"violations": drc_errors
|
|
||||||
}
|
|
||||||
|
|
||||||
return results
|
|
||||||
|
|
||||||
except ImportError as e:
|
|
||||||
print(f"Failed to import kipy modules: {str(e)}")
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"method": "ipc",
|
|
||||||
"error": f"Failed to import kipy modules: {str(e)}"
|
|
||||||
}
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in IPC API DRC: {str(e)}", exc_info=True)
|
|
||||||
return {
|
|
||||||
"success": False,
|
|
||||||
"method": "ipc",
|
|
||||||
"error": f"Error in IPC API DRC: {str(e)}"
|
|
||||||
}
|
|
@ -8,7 +8,6 @@ from mcp.server.fastmcp import FastMCP, Context
|
|||||||
|
|
||||||
from kicad_mcp.utils.file_utils import get_project_files
|
from kicad_mcp.utils.file_utils import get_project_files
|
||||||
from kicad_mcp.utils.drc_history import save_drc_result, get_drc_history, compare_with_previous
|
from kicad_mcp.utils.drc_history import save_drc_result, get_drc_history, compare_with_previous
|
||||||
from kicad_mcp.utils.kicad_api_detection import get_best_api_approach
|
|
||||||
|
|
||||||
# Import implementations
|
# Import implementations
|
||||||
from kicad_mcp.tools.drc_impl.cli_drc import run_drc_via_cli
|
from kicad_mcp.tools.drc_impl.cli_drc import run_drc_via_cli
|
||||||
|
@ -68,64 +68,3 @@ def check_for_cli_api() -> bool:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error checking for KiCad CLI API: {str(e)}")
|
print(f"Error checking for KiCad CLI API: {str(e)}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def check_for_ipc_api() -> bool:
|
|
||||||
"""Check if KiCad IPC API (kicad-python) is available.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
True if KiCad IPC API is available, False otherwise
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Try to import the kipy module
|
|
||||||
import kipy
|
|
||||||
print("KiCad IPC API (kicad-python) is available")
|
|
||||||
return True
|
|
||||||
except ImportError:
|
|
||||||
print("KiCad IPC API (kicad-python) is not available")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error checking for KiCad IPC API: {str(e)}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def check_ipc_api_environment() -> Tuple[bool, Optional[str]]:
|
|
||||||
"""Check if we're running in a KiCad IPC plugin environment.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple of (is_plugin, socket_path)
|
|
||||||
"""
|
|
||||||
# Check for environment variables that would indicate we're a plugin
|
|
||||||
is_plugin = os.environ.get("KICAD_PLUGIN_ENV") is not None
|
|
||||||
|
|
||||||
# Check for socket path in environment
|
|
||||||
socket_path = os.environ.get("KICAD_SOCKET_PATH")
|
|
||||||
|
|
||||||
if is_plugin:
|
|
||||||
print("Running as a KiCad plugin")
|
|
||||||
elif socket_path:
|
|
||||||
print(f"KiCad IPC socket path found: {socket_path}")
|
|
||||||
|
|
||||||
return (is_plugin, socket_path)
|
|
||||||
|
|
||||||
|
|
||||||
def get_best_api_approach() -> Literal["cli", "ipc", "none"]:
|
|
||||||
"""Determine the best available KiCad API approach.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
String indicating which API approach to use:
|
|
||||||
- "cli": Use KiCad command-line interface
|
|
||||||
- "ipc": Use KiCad IPC API (kicad-python)
|
|
||||||
- "none": No API available
|
|
||||||
"""
|
|
||||||
# Check for IPC API first (preferred if available)
|
|
||||||
if check_for_ipc_api():
|
|
||||||
return "ipc"
|
|
||||||
|
|
||||||
# Check for CLI API next
|
|
||||||
if check_for_cli_api():
|
|
||||||
return "cli"
|
|
||||||
|
|
||||||
# No API available
|
|
||||||
print("No KiCad API available")
|
|
||||||
return "none"
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
mcp[cli]
|
mcp[cli]
|
||||||
httpx
|
|
||||||
pytest
|
|
||||||
pandas
|
pandas
|
||||||
kicad-python
|
|
||||||
|
|
||||||
# Development/Testing
|
# Development/Testing
|
||||||
pytest-asyncio
|
pytest
|
Loading…
x
Reference in New Issue
Block a user