Skip to main content
Glama
README.md
# DCIR-MCP

A [Model Context Protocol](https://modelcontextprotocol.io) server that lets an AI assistant drive **DC IR drop analysis** on Ansys HFSS 3D Layout through natural language — describe a board's power source and current loads, and the assistant configures, solves, and reports back, without opening the GUI.

> **Status: early / actively developed.** Configuration and solving work end to end and are validated against Ansys's own official example. Post-processing (loop resistance, via-current hotspots, voltage/current plots) is currently done ad hoc through the script escape hatch rather than as typed tools — see [Roadmap](#roadmap).

---

## Why gRPC, not COM

Ansys automation is commonly done through SIwave's standalone COM interface. This project deliberately avoids that path after hitting real reliability problems with it in practice: intermittent apartment-threading failures, and a hard AEDT crash traced to an EDB version mismatch (a board that opened fine on AEDT 2025 R2 crashed AEDT outright on 2026 R1).

Instead, everything here runs through:
- **`Hfss3dLayout`** (from `ansys.aedt.core`) — gRPC-based, same reliable family as PyAEDT's `Hfss`/`Icepak` classes.
- **`pyedb.Edb`** — also gRPC-backed on AEDT 2025 R2+, used standalone (no live AEDT desktop) to configure sources and pin groups directly on the `.aedb`.

No COM, no pythonnet automation of a live SIwave session.

**Known-good version: AEDT 2025 R2.** AEDT 2026 R1 has shown real bugs in this workflow (an EDB-backend crash on one board, a `KeyError` in `pyedb`'s configuration loader on another) — stick to 2025.2 until that's resolved upstream.

---

## How it works

1. **`configure_dcir`** — applies current/voltage sources, auto-generated pin groups, and a `siwave_dc` setup to an `.aedb`, standalone. AEDT must be closed for this step (a live desktop and a standalone `Edb()` session can't hold the same board open — hits `"Can't acquire license"`). Idempotent: every call fully redefines the DC IR configuration rather than merging with a previous one.
2. **`open_edb`** — launches AEDT fresh with the now-configured board loaded.
3. **`run_dcir_script`** — the escape hatch: runs arbitrary PyAEDT/PyEDB code against the live session. Solving (`h3d.analyze(setup=...)`) and result extraction currently go through here.

---

## Setup

```bash
cd dcir-mcp
python -m venv venv
venv\Scripts\python.exe -m pip install -e .
```

Add to your MCP client config:

```json
{
  "mcpServers": {
    "dcir-mcp": {
      "command": "C:/path/to/dcir-mcp/venv/Scripts/python.exe",
      "args": ["C:/path/to/dcir-mcp/dcir_mcp_server.py"],
      "env": {
        "ANSYSEM_ROOT252": "C:/Program Files/ANSYS Inc/v252/AnsysEM"
      }
    }
  }
}
```

Set the `ANSYSEM_ROOTxxx` env var(s) to match your installed AEDT version(s) — the number encodes the version (`ROOT252` = 2025 R2, `ROOT261` = 2026 R1).

---

## Tools

| Tool | Does |
|---|---|
| `configure_dcir` | Apply sources, pin groups, and the DC setup to a board, standalone (no AEDT needed) |
| `open_edb` | Launch AEDT with a configured board loaded |
| `connect_to_hfss3dlayout` | Attach to an AEDT session that's already open, by gRPC port |
| `check_connection` | Check current connection status |
| `disconnect` | Release the AEDT connection without closing the project |
| `run_dcir_script` | Escape hatch: run arbitrary PyAEDT/PyEDB code against the live session |
| `get_script_result` | Retrieve output of a `run_dcir_script`/`configure_dcir` job |

---

## Usage

> *"Here's my board: `C:/boards/my_design.aedb`. U1 draws 5A on net VCORE — that's the load. U2 supplies 1.2V on the same net — that's the regulator. Set up and solve a DC IR drop analysis."*

The assistant will typically:
1. `configure_dcir` with the sources you described (AEDT must be closed at this point)
2. `open_edb` to load the configured board
3. `run_dcir_script` to solve and pull back results

## A real gotcha worth knowing

A component you'd call "the voltage source" on a schematic doesn't always share a physical net with the loads you'd expect — power-sequenced designs (rails split by state, e.g. `S0`/`S3`/`S5` domains) can look disconnected until you check what the solver actually reports as included in the simulation. Always verify the source and sink nets genuinely connect (or are bridged by a low-impedance component like a ferrite bead) before trusting a result — this project's `configure_dcir` won't catch that mismatch for you.

---

## Roadmap

- Typed `solve_dcir` tool (currently done via `run_dcir_script`)
- Typed result-retrieval tools: loop resistance, via currents, voltage/current field plots
- Board-import tooling (bringing in a raw layout from a non-EDB format)
- Thermal handoff to Icepak

---

## License

MIT — see [LICENSE](LICENSE)