Skip to main content
Glama
README.md
# KiCad MCP SEA

[![Python](https://img.shields.io/badge/python-3.11%2B-blue?logo=python)](https://python.org)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)
[![Build](https://img.shields.io/badge/build-passing-brightgreen)](https://github.com/kiedma/kicad-mcp-sea)

**KiCad PCB manufacturing audit via MCP + Ollama. IPC rules engine for SEA fabs.**

KiCad MCP SEA is a Python server that audits KiCad PCB designs against South-East Asian (SEA) manufacturer capabilities. It combines an IPC-compatible DFM rules engine with an LLM (via Ollama) to generate actionable fabrication reports.

The server exposes 6 tools through the Model Context Protocol (MCP), making them accessible from Claude Desktop, VS Code Copilot, and any MCP-compatible client.

---

## Architecture

```mermaid
graph TD
    Client[MCP Client<br/>Claude / VS Code / Custom]
    Server[kicad-mcp-sea server]
    BR[BoardReader<br/>KiCad IPC]
    DE[DFM Engine<br/>IPC Rules]
    FR[Fab Report Generator]
    FS[Fab Selector<br/>Formula Score]
    LC[LLM Client<br/>Ollama]
    FP[(Fab Profiles<br/>JSON)]
    DIST[(Distributor<br/>Catalogs)]
    KICAD[KiCad IPC API]
    OLLAMA[Ollama<br/>localhost:11434]

    Client -->|Streamable HTTP| Server
    Server --> BR
    Server --> DE
    Server --> FR
    Server --> FS
    Server --> LC
    Server -->|BOM crossref| DIST
    BR --> KICAD
    DE --> FP
    FR --> FP
    FS --> FP
    LC --> OLLAMA
```

### Request Flow

```mermaid
sequenceDiagram
    participant C as MCP Client
    participant S as kicad-mcp-sea
    participant BR as BoardReader
    participant DE as DFMEngine
    participant FS as FabSelector
    participant LC as LLMClient
    participant KiCad
    participant Ollama

    Note over C,Ollama: analyze_board
    C->>S: analyze_board(board_path)
    S->>BR: read_board(path)
    BR->>KiCad: IPC get board data
    KiCad-->>BR: board metadata + DRC violations
    BR-->>S: board dict
    S-->>C: {"success": true, "data": {...}}

    Note over C,Ollama: run_dfm
    C->>S: run_dfm(board_path, fab_slug)
    S->>BR: read_board(path)
    S->>DE: run_dfm(board_data, fab_slug)
    DE->>DE: load fab profile & check rules
    DE-->>S: violations + verdicts
    S-->>C: {"success": true, "data": {...}}

    Note over C,Ollama: select_best_fab
    C->>S: select_best_fab(board_path, priorities)
    S->>BR: read_board(path)
    S->>FS: score fabs by compatibility
    FS->>FS: load all profiles & rank
    FS-->>S: ranked fab list
    S-->>C: {"success": true, "data": {...}}

    Note over C,Ollama: ai_review
    C->>S: ai_review(board_path, fab_slug, language)
    S->>BR: read_board(path)
    S->>DE: run_dfm(board_data, fab_slug)
    S->>LC: explain_violations_bulk(violations, lang)
    LC->>Ollama: POST /api/generate (GBNF grammar)
    Ollama-->>LC: structured JSON explanations
    LC-->>S: enriched violations
    S-->>C: {"success": true, "data": {report, ai_status}}
```

Data flows through a linear pipeline: board file to BoardReader (IPC) to DFMEngine (rule check) to FabReportGenerator (report). The LLMClient enriches violation explanations when Ollama is available. See [docs/architecture.md](docs/architecture.md) for additional sequence diagrams and ADRs.

---

## Quick Start

```bash
# 1. Install from PyPI
pip install kicad-mcp-sea

# 2. Start the MCP server
kicad-mcp-sea serve --host 127.0.0.1 --port 8080

# 3. Connect your MCP client
```

Step 3 means adding the server config to your MCP client. For Claude Desktop, add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "kicad-mcp-sea": {
      "command": "kicad-mcp-sea",
      "args": ["serve", "--port", "8080"],
      "env": {}
    }
  }
}
```

See [docs/usage.md](docs/usage.md) for VS Code and other client configurations.

### Prerequisites

- **KiCad 8+** with IPC API enabled (Preferences > Plugins > API Server)
- **Ollama** (optional) for AI-enriched DFM review

---

## Tools

All tools accept a `dry_run` parameter and return a consistent JSON envelope: `{"success": bool, "data": ..., "error": ...}`.

| Tool | Description | Key Parameters |
|------|-------------|----------------|
| `analyze_board` | Parse a KiCad PCB file and extract design features | `board_path` (required) |
| `run_dfm` | Check a design against IPC-compatible DFM rules for a fab | `board_path`, `fab_slug` (both required) |
| `generate_fab_report` | Produce a structured fabrication report with DFM results and pricing | `board_path`, `fab_slug`, `language` |
| `ai_review` | Review a design using Ollama for manufacturability with AI explanations | `board_path`, `fab_slug`, `language` ("en" or "ms") |
| `select_best_fab` | Rank SEA fabs by board compatibility (formula-based scoring) | `board_path`, `priorities` (cost/quality/speed) |
| `crossref_bom` | Cross-reference BOM against distributor inventory (offline) | `board_path`, `distributor` ("gennex" or "all") |

### Dry Run Mode

Every tool supports `dry_run=True`. This returns a plan without executing:

```json
{
  "success": true,
  "data": {
    "dry_run": true,
    "tool": "run_dfm",
    "would_read": "simple.kicad_pcb",
    "would_check_against": "guh",
    "description": "Run DFM checks against fab profile and return violations"
  }
}
```

Use dry run to validate tool parameters before touching KiCad or reading files.

---

## Fab Profiles

A **fab profile** is a JSON file describing a PCB fabrication house: capabilities, DFM rules, pricing, and contact info. Profiles live in `fabs/` and are auto-discovered. Adding a new fab is as simple as dropping a `*.json` file.

```json
{
  "fab_name": "GUH PCB Sdn Bhd",
  "slug": "guh",
  "location": "Penang",
  "country": "Malaysia",
  "capabilities": {
    "max_layers": 6,
    "min_trace_mm": 0.2032,
    "min_space_mm": 0.2032,
    "min_drill_mm": 0.3,
    "min_annular_ring_mm": 0.15,
    "max_board_size_mm": [600, 600],
    "copper_weight_oz": [1, 2, 3]
  },
  "dfm_rules": [
    { "rule_name": "track_width", "severity": "error", "min": 0.2032, "unit": "mm" },
    { "rule_name": "clearance",   "severity": "error", "min": 0.2032, "unit": "mm" },
    { "rule_name": "drill_size",  "severity": "error", "min": 0.3,    "unit": "mm" },
    { "rule_name": "annular_width","severity": "warning","min": 0.15,  "unit": "mm" },
    { "rule_name": "copper_weight","severity": "info",   "min": 1, "max": 3, "unit": "oz" }
  ],
  "pricing": {
    "setup_cost": 120.0,
    "per_cm2_cost": 0.035,
    "min_order_qty": 5,
    "lead_time_days": 10
  },
  "contact": {
    "phone": "+604-616-6333",
    "email": "sales@guhpcb.com.my",
    "website": "https://www.guhpcb.com.my"
  }
}
```

**To add a new fab:** Create a JSON file in `fabs/` named after the fab slug (e.g. `fabs/jlpcb.json`), fill in the fields, validate against `fabs/schema.json`, and commit. No code changes needed. See [docs/fab-profiles.md](docs/fab-profiles.md) for the full schema reference.

---

## Requirements

- **Python** 3.11 or later
- **KiCad** 8+ with IPC API server enabled
- **Ollama** (optional) for LLM-backed DFM analysis
- **OS**: macOS, Linux (Windows via WSL)

---

## FAQ

### Does this work without KiCad running?

Yes, but in degraded mode. The `analyze_board` and `run_dfm` tools detect when KiCad is unreachable and return a warning with limited data. The server still starts and responds, but board data requires the KiCad IPC API. Tools that depend on board data (`run_dfm`, `generate_fab_report`, `ai_review`) return a `"status": "skipped"` response when KiCad is not running.

### Can I use this with cloud LLMs?

Technically yes. Set `OLLAMA_HOST` to point at any OpenAI-compatible API endpoint. However, the server was designed for local, offline use. The GBNF grammars and prompt templates assume a local Ollama instance. Cloud API calls may introduce latency and data privacy concerns that the project does not address.

### What file formats are supported?

Currently only KiCad PCB files (`.kicad_pcb`). The BoardReader uses the KiCad IPC API which expects KiCad's native board format. Other EDA formats (Altium, Eagle, OrCAD) are not supported. If you need support for other formats, consider opening a feature request.

### Does this work without Ollama?

Yes. The `analyze_board`, `run_dfm`, `generate_fab_report`, `select_best_fab`, and `crossref_bom` tools work fully without Ollama. Only `ai_review` requires Ollama, and it falls back to rule-based recommendations with a warning if Ollama is unreachable.

### Can I use it with non-SEA fabs?

Yes. The fab profile schema is generic. Profiles for non-SEA fabs work identically. Just create a JSON profile for any fab worldwide and the DFM engine and fab selector will use it.

### What KiCad versions are supported?

KiCad 8+ with the IPC API plugin enabled. KiCad 9 and 10 are recommended for stable IPC support. KiCad 11+ adds native headless `kicad-cli api-server` support. See [docs/architecture.md](docs/architecture.md) for version-specific notes.

### Does the DFM engine modify my board files?

No. All KiCad IPC calls are read-only. The server never writes to `.kicad_pcb` files.

### How do I add a new fab?

Create a JSON file in `fabs/` following the schema in `fabs/schema.json`. See [Fab Profiles](#fab-profiles) above and [docs/fab-profiles.md](docs/fab-profiles.md) for the complete guide.

### Does BOM cross-reference need internet?

No. Distributor catalogs are bundled as static JSON files. All matching is done offline with fuzzy string comparison. No API keys or network calls are needed.

### What languages does the AI review support?

English (`"en"`) and Bahasa Malaysia (`"ms"`). The Malay language support includes full DFM explanations and recommendations translated into Malaysian technical terminology. Add more languages by creating prompt templates in `src/kicad_mcp_sea/prompts/`.

### Is this ready for production?

The project is in **Alpha**. The API and CLI are under active development. Breaking changes may occur between minor versions. Not yet recommended for production use.

---

## Documentation

| Document | Description |
|----------|-------------|
| [docs/architecture.md](docs/architecture.md) | Component diagrams, data flow, KiCad IPC notes, ADRs |
| [docs/dfm-rules.md](docs/dfm-rules.md) | DFM rule types, IPC standards mapping, examples |
| [docs/usage.md](docs/usage.md) | CLI examples, tool reference, MCP client configs |
| [docs/fab-profiles.md](docs/fab-profiles.md) | Fab profile schema, adding a new fab |
| [CONTRIBUTING.md](CONTRIBUTING.md) | Dev setup, code style, PR workflow |

---

## License

MIT. See [LICENSE](LICENSE).

## Project Links

- [GitHub](https://github.com/kiedma/kicad-mcp-sea)
- [PyPI](https://pypi.org/project/kicad-mcp-sea/)
- [Issue Tracker](https://github.com/kiedma/kicad-mcp-sea/issues)