Rename source directory kicad_mcp/ → mckicad/, update all imports, pyproject.toml metadata, documentation references, Makefile targets, and .gitignore paths. All 195 tests pass.
7.9 KiB
7.9 KiB
Development Guide
This guide provides detailed information for developers who want to modify or extend the KiCad MCP Server.
Development Environment Setup
-
Set up your Python environment:
# Create and activate a virtual environment python3 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate # Install development dependencies pip install -r requirements.txt -
Run the server:
python main.py -
Use the MCP Inspector for debugging:
npx @modelcontextprotocol/inspector uv --directory . run main.py
Project Structure
The KiCad MCP Server follows a modular architecture:
mckicad/
├── main.py # Entry point
├── mckicad/ # Main package
│ ├── __init__.py
│ ├── server.py # Server creation and setup
│ ├── config.py # Configuration settings
│ ├── context.py # Lifespan context management
│ ├── resources/ # Resource handlers
│ │ ├── __init__.py
│ │ ├── projects.py # Project listing resources
│ │ ├── files.py # File content resources
│ │ ├── drc_resources.py # DRC report resources
│ │ └── bom_resources.py # BOM resources
│ ├── tools/ # Tool handlers
│ │ ├── __init__.py
│ │ ├── project_tools.py # Project management tools
│ │ ├── analysis_tools.py # Design analysis tools
│ │ ├── drc_tools.py # DRC check tools
│ │ ├── export_tools.py # Export and thumbnail tools
│ │ └── bom_tools.py # BOM management tools
│ ├── prompts/ # Prompt templates
│ │ ├── __init__.py
│ │ ├── templates.py # General KiCad prompts
│ │ ├── drc_prompt.py # DRC-specific prompts
│ │ └── bom_prompts.py # BOM-specific prompts
│ └── utils/ # Utility functions
│ ├── __init__.py
│ ├── file_utils.py # File handling utilities
│ ├── kicad_utils.py # KiCad-specific functions
│ ├── python_path.py # Python path setup for KiCad modules
│ ├── drc_history.py # DRC history tracking
│ └── env.py # Environment variable handling
Adding New Features
Creating a New Resource
Resources provide read-only data to the LLM. To add a new resource:
- Add your function to an existing resource file or create a new one in
mckicad/resources/:
from mcp.server.fastmcp import FastMCP
def register_my_resources(mcp: FastMCP) -> None:
"""Register my custom resources with the MCP server."""
@mcp.resource("kicad://my-resource/{parameter}")
def my_custom_resource(parameter: str) -> str:
"""Description of what this resource provides.
Args:
parameter: Description of parameter
Returns:
Formatted data for the LLM
"""
# Implementation goes here
return f"Formatted data about {parameter}"
- Register your resources in
mckicad/server.py:
from mckicad.resources.my_resources import register_my_resources
def create_server() -> FastMCP:
# ...
register_my_resources(mcp)
# ...
Creating a New Tool
Tools are functions that perform actions or computations. To add a new tool:
- Add your function to an existing tool file or create a new one in
mckicad/tools/:
from typing import Dict, Any
from mcp.server.fastmcp import FastMCP, Context
def register_my_tools(mcp: FastMCP) -> None:
"""Register my custom tools with the MCP server."""
@mcp.tool()
async def my_custom_tool(parameter: str, ctx: Context) -> Dict[str, Any]:
"""Description of what this tool does.
Args:
parameter: Description of parameter
ctx: MCP context for progress reporting
Returns:
Dictionary with tool results
"""
# Report progress to the user
await ctx.report_progress(10, 100)
ctx.info(f"Starting operation on {parameter}")
# Implementation goes here
# Complete progress
await ctx.report_progress(100, 100)
ctx.info("Operation complete")
return {
"success": True,
"message": "Operation completed successfully",
"result": "Some result data"
}
- Register your tools in
mckicad/server.py:
from mckicad.tools.my_tools import register_my_tools
def create_server() -> FastMCP:
# ...
register_my_tools(mcp)
# ...
Creating a New Prompt
Prompts are reusable templates for common interactions. To add a new prompt:
- Add your function to an existing prompt file or create a new one in
mckicad/prompts/:
from mcp.server.fastmcp import FastMCP
def register_my_prompts(mcp: FastMCP) -> None:
"""Register my custom prompts with the MCP server."""
@mcp.prompt()
def my_custom_prompt() -> str:
"""Description of what this prompt is for."""
prompt = """
I need help with [specific task] in KiCad. Please assist me with:
1. [First aspect]
2. [Second aspect]
3. [Third aspect]
My KiCad project is located at:
[Enter the full path to your .kicad_pro file here]
[Additional contextual information or instructions]
"""
return prompt
- Register your prompts in
mckicad/server.py:
from mckicad.prompts.my_prompts import register_my_prompts
def create_server() -> FastMCP:
# ...
register_my_prompts(mcp)
# ...
Using the Lifespan Context
The KiCad MCP Server uses a typed lifespan context to share data across requests:
from mckicad.context import KiCadAppContext
@mcp.tool()
def my_tool(parameter: str, ctx: Context) -> Dict[str, Any]:
"""Example tool using lifespan context."""
# Access the typed context
app_context: KiCadAppContext = ctx.request_context.lifespan_context
# Check if KiCad modules are available
if app_context.kicad_modules_available:
# Use KiCad Python modules
pass
else:
# Fall back to alternative method
pass
# Use the cache to store expensive results
cache_key = f"my_operation_{parameter}"
if cache_key in app_context.cache:
return app_context.cache[cache_key]
# Perform operation
result = {}
# Cache the result
app_context.cache[cache_key] = result
return result
Testing
To run tests:
# Run all tests
pytest
# Run specific tests:
pytest tests/test_tools.py::test_run_drc_check
Debugging
For debugging, use:
- The Python debugger (pdb)
- Print statements to the console (captured in Claude Desktop logs)
- The MCP Inspector tool
Performance Considerations
- Use caching for expensive operations
- Report progress to the user for long-running operations
- Include proper error handling and fallbacks
- Use asyncio for concurrent operations
Security Best Practices
- Validate all file paths and user inputs
- Use absolute paths for better predictability
- Implement proper error handling
- Don't expose sensitive information in responses
- Sanitize output before returning it to the client
Documentation
When adding new features, remember to:
- Add thorough docstrings to all functions and classes
- Update relevant documentation files in the
docs/directory - Include examples of how to use your feature