SkillAgentSearch skills...

SpiceMCP

LTspice MCP server where the server owns the optimization state, not the LLM.

Install / Use

claude mcp add oniondas -- npx -y github:oniondas/SpiceMCP

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

80/100

Supported Platforms

Claude Code
Claude Desktop

Tags

SpiceMCP

LTspice MCP server where the server owns the optimization state, not the LLM.

The model contributes topology and strategy. Candidate identity, simulation history, dedup, best so far, sensitivities and rollback all live in SQLite and are re derived on every call, so a long optimization can't drift into remembering a circuit that never existed.

Prototype Status & Live Example

SpiceMCP is currently an experimental prototype.

Below is a demonstration of what SpiceMCP generated and analyzed autonomously for Chua's Chaotic Circuit showcasing automated .asc schematic generation, batch LTspice simulations, binary .raw waveform parsing, parameter sweeps, and visualization:

| Schematic Rendering (render_schematic) | 3D Double-Scroll Attractor | | :---: | :---: | | Chua Schematic | Chua 3D Double Scroll Attractor | | Vector schematic generated from .asc in classic style | 3D phase-space trajectory $(v_{C1}, v_{C2}, i_L)$ parsed from binary .raw |

| Bifurcation Route to Chaos (simulate_sweep) | Sensitivity to Initial Conditions (Butterfly Effect) | | :---: | :---: | | Bifurcation Route to Chaos | Butterfly Sensitivity | | Multi-point parameter sweep capturing period-doubling cascades | Lyapunov divergence tracking $1,\mu\text{V}$ initial condition perturbations |

| 2D Phase Plane Portraits & Orbital Density | Nonlinear Diode (NDR) I-V Curve | | :---: | :---: | | 2D Phase Portraits | Chua Diode IV Curve | | Orthogonal projections ($V_{C1}-V_{C2}, V_{C1}-I_L$) with orbital density | Piecewise-linear Negative Differential Resistance ($G_a, G_b$) DC sweep |

Architecture

flowchart TB
    subgraph Client ["LLM / MCP Client"]
        Agent["AI Agent / LLM<br/><i>(Topology & Optimization Strategy)</i>"]
    end

    subgraph Server ["SpiceMCP Server (FastMCP API)"]
        direction TB
        subgraph ToolEndpoints ["Tool Endpoints (24 Tools)"]
            T_Life["<b>Lifecycle Tools</b><br/>start_optimization<br/>stop_optimization<br/>get_optimization_status<br/>list_runs"]
            T_Eval["<b>Evaluation & Search</b><br/>run_optimization<br/>evaluate_candidate<br/>select_next_experiment"]
            T_Sim["<b>Simulation & Sweeps</b><br/>simulate_netlist<br/>simulate_sweep"]
            T_Diag["<b>Feasibility & System</b><br/>check_feasibility<br/>check_ltspice"]
            T_Vis["<b>Schematics & Styling</b><br/>render_schematic<br/>get_visual_style"]
            T_Query["<b>State Queries & Reports</b><br/>get_best_candidate / pareto<br/>sensitivity / history / trace<br/>candidate / similar / compare<br/>generate_design_report<br/>rollback_to_candidate"]
        end
    end

    subgraph Core ["Optimization & Circuit Core"]
        Engine["<b>Optimization Engine</b> (engine.py)<br/>• Coordinate descent & step halving<br/>• Pure-function scoring & Pareto frontier<br/>• Empirical sensitivity analysis (FD / OLS)"]
        IR["<b>Circuit IR & Hashing</b> (ir.py)<br/>• Template placeholder substitution: {param}<br/>• Fingerprinting (topology, design, config)<br/>• Deterministic deduplication"]
        ASC["<b>Schematic Writer</b> (asc.py)<br/>• Pin-name routing with symbol (.asy) parsing<br/>• Orthogonal L-routing (HV/VH/auto)<br/>• Round trip netlist validation via asc.check()"]
        Render["<b>Schematic Renderer</b> (render.py)<br/>• Real .asy geometry & transformation matrices<br/>• SVG (zero dependency) and PNG (matplotlib)<br/>• 3 styles: tech_minimal, classic, sketch<br/>• Label collision avoidance"]
        Robust["<b>Robustness & Waves</b> (robustness.py, raw.py)<br/>• DC operating point & bias audit<br/>• PVT corners & Monte Carlo yield / Cpk<br/>• Binary .raw parser & waveform metrics"]
        Feas["<b>Preflight Feasibility</b> (feasibility.py)<br/>• 3 tiers: static, template, physics<br/>• 3 modes: practical, theoretical, concept<br/>• Closed form limits (SR, GBW, noise, filter order)"]
        Rep["<b>Design Report & Plots</b> (report.py, plots.py)<br/>• Six-section Markdown, rendered from state<br/>• BOM, baseline vs final, Bode/tran/THD figures<br/>• Unified 5-color visualization ramp & chrome"]
    end

    subgraph Simulation ["Simulation Layer (sim.py)"]
        Router{"Backend Router"}
        LTSpice["<b>LTspice Executable</b><br/>Batch process (<code>-b -ascii</code>)"]
        Analytic["<b>Analytic Backend</b><br/>Fast closed form surfaces (test/dry-run)"]
        SweepEngine["<b>Sweep Engine</b><br/>Single launch <code>.step</code> multipoint execution<br/>Value recovery from .log / .raw"]
        MeasParser["<b>Log & Meas Parser</b><br/>• .meas regex metric extraction<br/>• Complex AC magnitude/phase parsing<br/>• Failure taxonomy classifier"]
    end

    subgraph State ["Authoritative State (.ltspice-mcp/)"]
        subgraph DB ["SQLite Database (state.db - WAL Mode)"]
            T_Runs[("<b>runs</b><br/>Templates, parameter bounds, objectives")]
            T_Designs[("<b>designs</b><br/>Byte exact netlists, lineages, SHA hashes")]
            T_Exps[("<b>experiments</b><br/>Metrics, scores, feasibility, failures")]
            T_Sens[("<b>sensitivities</b><br/>Slopes, R2, confidence")]
        end
        subgraph FS ["Filesystem Artifacts"]
            CandDir["<code>candidates/</code> (cand_XXXX.cir)"]
            SimDir["<code>simulations/</code> (adhoc, sweep, logs, raw)"]
            RepDir["<code>reports/</code> & <code>plots/</code>"]
        end
    end

    %% Communication Flow
    Agent -->|"1. Tool calls (goals, param space, evaluations)"| ToolEndpoints
    ToolEndpoints -->|"6. Compact summaries, sensitivities, best candidates"| Agent

    T_Life & T_Eval & T_Query --> Engine
    T_Sim --> Router
    T_Diag --> Feas
    T_Diag --> Router
    T_Vis --> Render
    Engine -->|"Refuse impossible specs before any state is written"| Feas
    Engine --> IR
    Engine --> Robust

    Engine -->|"Execute candidate sim"| Router
    Router -->|"Subprocess"| LTSpice
    Router -->|"In-memory"| Analytic
    Router --> SweepEngine
    LTSpice -->|"Parse .log / .raw"| MeasParser
    SweepEngine --> MeasParser
    Analytic --> MeasParser
    MeasParser -->|"Extracted metrics & failure status"| Engine

    IR -->|"Query existing fingerprints"| T_Designs
    Engine -->|"ACID Transaction (append only history)"| DB
    Engine -->|"Store byte exact netlists & traces"| FS
    T_Query -->|"Rederive dynamically (best, pareto, sensitivities)"| DB
    T_Query --> Rep
    Rep -->|"Read stored state, never hand entered numbers"| DB
    Rep -->|"Resimulate the winner for waveforms & corners"| Robust
    Rep -->|"Write DESIGN_REPORT.md + figures"| RepDir
    ASC -.->|"Round trip verification"| LTSpice
    Render -.->|"Parse .asy symbol definitions"| FS

    %% Styling based on SpiceMCP visual style palette
    classDef client fill:#f9f9f9,stroke:#333,stroke-width:2px,color:#333
    classDef endpoint fill:#1E56A0,stroke:#12396e,stroke-width:2px,color:#fff
    classDef core fill:#38A3A5,stroke:#23696a,stroke-width:2px,color:#fff
    classDef sim fill:#E07A5F,stroke:#9c5340,stroke-width:2px,color:#fff
    classDef db fill:#D9534F,stroke:#933734,stroke-width:2px,color:#fff
    classDef fs fill:#F2CC8F,stroke:#a68a5d,stroke-width:2px,color:#333

    class Agent client
    class T_Life,T_Eval,T_Sim,T_Diag,T_Vis,T_Query endpoint
    class Engine,IR,ASC,Render,Robust,Feas,Rep core
    class Router,LTSpice,Analytic,SweepEngine,MeasParser sim
    class T_Runs,T_Designs,T_Exps,T_Sens db
    class CandDir,SimDir,RepDir fs

Install

pip install -e ".[dev]"
pytest -q                                

LTspice is auto-detected (AppData\Local\Programs\ADI\LTspice\LTspice.exe, Program Files\LTC\LTspiceXVII\XVIIx64.exe, …). Override with LTSPICE_EXE.

Register with your MCP client:

{
  "mcpServers": {
    "spicemcp": {
      "command": "python",
      "args": ["-m", "spicemcp.server"],
      "env": { "SPICEMCP_PROJECT": "C:/path/to/your/circuit/project" }
    }
  }
}

State lands in $SPICEMCP_PROJECT/.ltspice-mcp/:

state.db      authoritative state (SQLite WAL)
candidates/   cand_XXXX.cir, byte exact netlists for rollback
simulations/  LTspice working dirs, logs, and raw waveforms
reports/      Markdown design reports and iteration traces
plots/        Rendered Bode, transient, and THD figures

Metrics come from .meas

Every metric you optimize on is a .meas directive in the netlist, and the server reads the values back from LTspice's .log. The metric definitions then live with the circuit, versioned alongside it. Waveforms are a separate concern: spicemcp.raw parses the binary .raw for the report's plots and for a sweep with no .meas, but nothing in the search loop scores a candidate off a wave.

.ac dec 100 1 10Meg
.meas AC gain_db MAX mag(V(out))          ; mag(), NOT db() (see below)
.meas AC bandwidth WHEN mag(V(out))=0.707 FALL=1
.meas TRAN power AVG (-I(V1)*V(vcc))

Never wrap an AC .meas in db(). LTspice already reports AC measurement magnitudes in dB, so db() converts twice without throwing an error, returning a smaller plausible number. Verified on 26.0.2: a gain of 100 measures as 40dB via mag() but 32.04dB (= 20·log10(40)) via db(). The server lints for this and returns a warning alongside the metrics.

AC results are complex, so the phase is available too, as <name>_deg:

gdb: MAX(mag(V(out)))=(40.0dB,-159.417738334°)   ->  gdb = 40.0, gdb_deg = -159.42

One more trap, because two .meas forms print the same shape with opposite meanings:

bw:   mag(V(out))=0.7071  AT 159158.003411       -> 159158  (WHEN: the crossing)
p050: V(out) =0.140915020014 at 6.666666667e-05  -> 0.1409  (FIND AT: the value)

In a WHEN measure the number after = is the trigger level you specified and AT carries the result; in FIND ... AT it is the reverse. LTspice separates them only by case (uppercase AT for a point it found, lowercase at for one you specified), so the parser is case sensitive here. Getting it backwards returns the sample time as the measurement, which plots as a plausible straight line.

Preflight: is the spec even possible?

check_feasibility answers that before a single LTspice process starts. It costs no simulation and no tokens beyond the call, and it exists because the expensive failure mode is an optimization loop that runs 40 iterations against a requirement no topology can meet, then reports a confident near miss.

check_feasibility(
  objectives=[{"metric": "slew_rate", "direction": "max"}],
  constraints={"slew_rate": ">1e8", "power": "<0.0005"},
  circuit_type="opamp", mode="concept",
  technology_params={"vdd": 1.8, "cload": 10e-12})

# status: "infeasible", passed: false
# power_below_dynamic_floor: power < 0.0005 W, but the slew requirement alone draws
#   0.001 A from 1.8 V = 0.0018 W, before bias, output stage or reference current
# suggestion: raise the power limit above 0.0018 W, drop C_load, or relax the slew
#   requirement
# details: theoretical_min_power = 0.0018, power_floor_from = "slew"

Three layers, each reported separately so you can tell a typo from physics:

| layer | catches | |---|---| | static | contradictory bounds (fc > 10k and fc < 9k), over unity efficiency, inverted or empty param_space, P_max < Vdd·I_load | | template | an objective or constraint with no .meas that produces it, {PARAM} vs param_space mismatches in both directions, gain > 1 demanded of an R and C only deck, reactive element count vs the filter order the mask needs | | physics | closed form limits per circuit_type: filter order (Bu

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategoryAI
Updated19h ago
Forks0

Languages

Python

Security Score

75/100

Audited on Aug 18, 2026

1 medium2 low