280 lines
8.0 KiB
Markdown
280 lines
8.0 KiB
Markdown
# Development Guide
|
|
|
|
This guide provides detailed information for developers who want to modify or extend the KiCad MCP Server.
|
|
|
|
## Development Environment Setup
|
|
|
|
1. **Set up your Python environment**:
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
2. **Run in development mode**:
|
|
```bash
|
|
# Run with development server for better debugging
|
|
python -m mcp.dev main.py
|
|
```
|
|
|
|
3. **Use the MCP Inspector** for debugging:
|
|
```bash
|
|
npx @modelcontextprotocol/inspector uv --directory . run main.py
|
|
```
|
|
|
|
## Project Structure
|
|
|
|
The KiCad MCP Server follows a modular architecture:
|
|
|
|
```
|
|
kicad-mcp/
|
|
├── main.py # Entry point
|
|
├── kicad_mcp/ # 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:
|
|
|
|
1. Add your function to an existing resource file or create a new one in `kicad_mcp/resources/`:
|
|
|
|
```python
|
|
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}"
|
|
```
|
|
|
|
2. Register your resources in `kicad_mcp/server.py`:
|
|
|
|
```python
|
|
from kicad_mcp.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:
|
|
|
|
1. Add your function to an existing tool file or create a new one in `kicad_mcp/tools/`:
|
|
|
|
```python
|
|
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"
|
|
}
|
|
```
|
|
|
|
2. Register your tools in `kicad_mcp/server.py`:
|
|
|
|
```python
|
|
from kicad_mcp.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:
|
|
|
|
1. Add your function to an existing prompt file or create a new one in `kicad_mcp/prompts/`:
|
|
|
|
```python
|
|
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
|
|
```
|
|
|
|
2. Register your prompts in `kicad_mcp/server.py`:
|
|
|
|
```python
|
|
from kicad_mcp.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:
|
|
|
|
```python
|
|
from kicad_mcp.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:
|
|
|
|
```bash
|
|
# Run all tests
|
|
pytest
|
|
|
|
# Run specific test file
|
|
pytest tests/test_resources.py
|
|
|
|
# Run with verbose output
|
|
pytest -v
|
|
```
|
|
|
|
## Debugging
|
|
|
|
For debugging, use:
|
|
|
|
1. The Python debugger (pdb)
|
|
2. Print statements to the console (captured in Claude Desktop logs)
|
|
3. The MCP Inspector tool
|
|
|
|
## Performance Considerations
|
|
|
|
1. Use caching for expensive operations
|
|
2. Report progress to the user for long-running operations
|
|
3. Include proper error handling and fallbacks
|
|
4. Use asyncio for concurrent operations
|
|
|
|
## Security Best Practices
|
|
|
|
1. Validate all file paths and user inputs
|
|
2. Use absolute paths for better predictability
|
|
3. Implement proper error handling
|
|
4. Don't expose sensitive information in responses
|
|
5. Sanitize output before returning it to the client
|
|
|
|
## Documentation
|
|
|
|
When adding new features, remember to:
|
|
|
|
1. Add thorough docstrings to all functions and classes
|
|
2. Update relevant documentation files in the `docs/` directory
|
|
3. Include examples of how to use your feature
|