# Silica (pypi · silica-eda)

RTL and FPGA tools: lint, simulate, formal, synthesize, place and route, program a board.

- Trust score: 75/100 (medium)
- Change this week: +7
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- pypi · `silica-eda`: 75/100 (this document), [markdown](https://verifymcp.io/servers/simaanc-silica-eda/silica-eda.md), [page](https://verifymcp.io/servers/simaanc-silica-eda/silica-eda)

## Channel facts

- Registry: `pypi`
- Package: `silica-eda`
- Version: `0.5.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 100/100
  - No malware found by supply-chain analysis.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - 1 of 29 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (AGPL-3.0-only).
  - Actively maintained (last published 16 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 72/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 7604 tokens (~422/item across 18 items; 18 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 53/100
  - Stability observed for 16 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 67/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 0% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 18 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 19 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the Silica MCP server?

Silica runs locally as a PyPI package, launched with uvx silica-eda. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add simaanc-silica-eda -- uvx silica-eda
```

### Cursor

```json
{
  "mcpServers": {
    "simaanc-silica-eda": {
      "command": "uvx",
      "args": [
        "silica-eda"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "simaanc-silica-eda": {
      "command": "uvx",
      "args": [
        "silica-eda"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add simaanc-silica-eda -- uvx silica-eda
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "simaanc-silica-eda": {
      "type": "local",
      "command": [
        "uvx",
        "silica-eda"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add simaanc-silica-eda --command uvx --arg silica-eda
```

### Hermes

```yaml
mcp_servers:
  simaanc-silica-eda:
    command: "uvx"
    args: ["silica-eda"]
```

### Netclaw

```json
{
  "McpServers": {
    "simaanc-silica-eda": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "silica-eda"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add simaanc-silica-eda -t stdio -c uvx -a silica-eda
```

### Other

```json
{
  "mcpServers": {
    "simaanc-silica-eda": {
      "command": "uvx",
      "args": [
        "silica-eda"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-05 (score 75, +7)

- [functional improvement] Stability: unverified → 0.53

### 2026-11-04 (score 68, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-11-02 (score 53, −15)

- [security regression] Malware scan: pass → unverified

### 2026-11-01 (score 68, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-10-30 (score 53, −15)

- [security regression] Malware scan: pass → unverified

### 2026-10-29 (score 68, +15)

- [security improvement] Malware scan: unverified → pass

### 2026-10-28 (score 53, −15)

- [security regression] Malware scan: pass → unverified

### 2026-10-21 (score 68, +15)

- [security improvement] Malware scan: unverified → pass

## MCP tools (18)

### `run_simulation` (~486 tokens)

Run RTL simulation and return structured diagnostics.

The simulator runs in the DUT file's directory, so relative paths in
the testbench (e.g. $readmemh("../fw/firmware.hex")) resolve from
there, with or without trace/coverage. A failing $fatal/$error comes
back in errors with its file, line and message.

Args:
    file: Path to the DUT source file (.sv / .v for Verilog, .vhd for
          VHDL). May instead be a ``.f`` filelist (one source path per
          line); its entries become the design sources.
    testbench: Path to the testbench file.
    simulator: "auto" | "verilator" | "icarus" | "iverilog" | "ghdl" |
               "vcs" | "questa" | "xcelium". "iverilog" is accepted as
               an alias for "icarus". Auto uses config priority order.
    top: Top module/entity name (inferred from testbench filename if omitted).
    timeout: Seconds before killing the simulator process.
    trace: When True, collect the VCD the testbench writes (it must call
           $dumpfile/$dumpvars) into a persistent directory and return
           its path as trace_vcd. Read it with read_waveform, or open it
           with launch_waveform.
    extra_sources: Additional design files (submodules, packages)
           compiled alongside the DUT. Each entry may itself be a ``.f``
           filelist, which is expanded in place.
    coverage: When True, collect line/toggle coverage (Verilator only).
           Returns coverage_dat in the result — pass it to
           read_coverage for a structured report.

Returns a SimulationResult dict:
    exit_code, errors [{file, line, severity, message}], warnings,
    raw_stdout, raw_stderr, trace_vcd (str path or None), and
    coverage_dat (str path or None, Verilator + coverage=True only)

Input parameters:

- `coverage` (boolean)
- `extra_sources`
- `file` (string, required)
- `simulator` (string)
- `testbench` (string, required)
- `timeout` (integer)
- `top`
- `trace` (boolean)

### `synthesize` (~532 tokens)

Synthesize RTL and return structured utilization and timing summary.

Args:
    top_module: Name of the top-level module to synthesize.
    files: List of source file paths (.sv / .v).
    target: Synthesis target.
            Yosys:   "generic" | "ice40" | "ecp5" | "xilinx" | "gowin"
            Vivado:  FPGA part string e.g. "xc7a35tcsg324-1", or shorthand
                     "artix7" | "kintex7" | "ultrascale" | "ultrascale+" | "zynq"
            Quartus: device family e.g. "cyclone5" | "arria10" | "stratix10"
            DC Shell: technology library path, or "generic"
    tool: "auto" | "yosys" | "vivado" | "quartus" | "dc_shell".
          Auto uses config priority order.
    timeout: Seconds before killing the synthesis process.

Returns a SynthesisResult dict:
    tool, target, exit_code, utilization {luts, ffs, bram, dsp, lut_pct, ff_pct},
    timing_summary {wns, tns, failing_endpoints}, netlist, memories,
    warnings, errors, raw_output

    netlist: path to a JSON netlist ready for run_place_route. Written by
    yosys for FPGA targets ("ice40" | "ecp5" | "xilinx" | "gowin");
    None for generic/commercial-tool runs and on failure.

    memories (yosys; [] for other tools and on failure): every
    inferred memory as {name (module.memory), module, depth, width,
    bits, read_ports, write_ports, has_init, type, mapped_to}. type is
    "block_ram" | "distributed_ram" | "logic" (flip-flops and LUTs) |
    "removed" (optimized away); mapped_to is the primitive yosys chose.
    has_init is False when no $readmemh/initial data reached
    synthesis; a read-only memory without init data also adds a
    warning, since its contents (usually firmware) are missing.

    files may include ``.f`` filelists (one source path per line),
    expanded in place.

Input parameters:

- `files` (array, required)
- `target` (string)
- `timeout` (integer)
- `tool` (string)
- `top_module` (string, required)

### `run_place_route` (~762 tokens)

Place and route an FPGA netlist and return timing and utilization.

Takes a Yosys JSON netlist (from synthesize with target "ice40"/"ecp5"/
"xilinx"/etc.). The output is a bitstream ready for program_device
when the packing tool is available: a .bit for xilinx (openXC7's
fpga-as), a .bin for ice40 (icepack) and a .bit for ecp5 (ecppack).
Without it, the output is nextpnr's FASM or text config (.asc /
.textcfg) and a warning says what is missing.

Args:
    netlist: Path to Yosys JSON netlist (produced by the synthesize tool).
    arch: FPGA architecture — "ice40" | "ecp5" | "nexus" | "machxo2" |
          "generic" | "xilinx".
    device: Device variant within the architecture:
            ice40: "hx1k" | "hx4k" | "hx8k" | "up5k" | "lp1k" | "lp8k" | ...
            ecp5:  "LFE5U-12F" | "LFE5U-25F" | "LFE5U-45F" | "LFE5U-85F",
                   also LFE5UM-/LFE5UM5G- parts; a speed grade suffix
                   (e.g. "LFE5U-25F-6") sets --speed.
            xilinx: full 7-series part with speed grade, e.g.
                    "xc7a100tcsg324-1" (Arty A7-100T). Uses openXC7's
                    nextpnr-xilinx; its chip database is found through
                    NEXTPNR_XILINX_CHIPDB_DIR or <FAMILY>_CHIPDB, and
                    the FASM is assembled into a .bit with fpga-as when
                    PRJXRAY_DB_DIR is set. A chip database path also
                    works as device (the result is then FASM).
    package: Package code, e.g. "ct256" (ice40), "CABGA381" (ecp5). Optional.
    constraint: Path to physical constraint file (.pcf for ice40, .lpf for ecp5,
                .xdc for xilinx).
    output: Output file path for the bitstream. Auto-placed in temp dir
            if omitted — the path is returned in the result. A path
            ending in .asc/.textcfg/.fasm keeps nextpnr's file there
            and writes the bitstream beside it.
    freq: Target clock frequency in MHz for timing checks.
    tool: "auto" | "nextpnr". Auto uses config prio…

Input parameters:

- `arch` (string)
- `constraint`
- `device` (string)
- `freq`
- `netlist` (string, required)
- `output`
- `package`
- `timeout` (integer)
- `tool` (string)

### `program_device` (~445 tokens)

Program a bitstream to an FPGA device with openFPGALoader.

Loads volatile SRAM by default, which is safe to repeat. For Xilinx
devices success means the FPGA asserted DONE; a rejected bitstream is
reported as a failure even though openFPGALoader exits 0. The design
starts running as soon as loading finishes, so boot output is usually
missed by a serial capture started afterwards (see capture_serial).

Args:
    bitstream: Path to a loadable bitstream from run_place_route:
               .bit (Xilinx, ECP5) or .bin (iCE40). nextpnr's
               .asc/.textcfg text configs can't be loaded directly.
    board: Board preset name, e.g. "arty_a7_100t", "arty_a7_35t",
           "basys3", "cmod_a7", "nexys4ddr", "ice40_hx8k_b_evn".
           Plain "arty" is the 35T. Run openFPGALoader --list-boards
           for all.
    cable: JTAG cable, e.g. "ft2232", "digilent_hs2", "jlink", "olimex".
           Run openFPGALoader --list-cables for all options.
    device: Explicit FPGA part number override, e.g. "xc7a35t". Optional.
    spi_flash: When True, program SPI flash (persistent across power
               cycles), replacing whatever design the board boots.
               Only do this when the user asks. Default False: SRAM
               (volatile, erased on power cycle).
    tool: "auto" | "openfpgaloader". Auto uses config priority order.
    timeout: Seconds before killing the programmer.

Returns a ProgramResult dict:
    tool, exit_code, success, errors [{message}], raw_output

Input parameters:

- `bitstream` (string, required)
- `board`
- `cable`
- `device`
- `spi_flash` (boolean)
- `timeout` (integer)
- `tool` (string)

### `lint` (~257 tokens)

Lint a SystemVerilog/Verilog file and return structured warnings.

Args:
    file: Path to the source file to lint. May instead be a ``.f``
          filelist (one path per line); each listed file is linted.
    ruleset: "default" | "all" | comma-separated rule list (tool-specific).
    tool: "auto" | "verible" | "verilator" | "svlint" | "spyglass".
          Auto uses config priority order.
    timeout: Seconds before killing the linter (applied per file).
    extra_files: Additional files to lint. Each may itself be a ``.f``
          filelist, expanded in place. Warnings across all files are
          merged into one result. Verilator elaborates all the files
          together, so pass a design's submodules here when linting
          its top level.

Returns a LintResult dict:
    warnings [{file, line, severity, rule_id, message}], tool, raw_output

Input parameters:

- `extra_files`
- `file` (string, required)
- `ruleset` (string)
- `timeout` (integer)
- `tool` (string)

### `format_rtl` (~232 tokens)

Auto-format a SystemVerilog/Verilog file and return a unified diff.

Call with dry_run=True first to review the diff, then dry_run=False to
write the formatted source back. The file must stay inside the project
directory (same confinement as write_rtl).

Args:
    file: Path to the source file to format.
    dry_run: If True (default), return the diff without writing. If
             False, overwrite the file with the formatted output.
    tool: "auto" | "verible". Auto uses config priority order.
    timeout: Seconds before killing the formatter.

Returns:
    {dry_run, written, diff, lines_changed, path, tool} on success, or
    {"error": str, ...} if the file escapes the project dir, the
    formatter is missing/disabled, or formatting fails (e.g. a syntax
    error — the formatter refuses rather than mangle the source).

Input parameters:

- `dry_run` (boolean)
- `file` (string, required)
- `timeout` (integer)
- `tool` (string)

### `run_formal` (~517 tokens)

Run formal verification or equivalence checking and return structured results.

Two usage modes for property verification (sby/jaspergold/vc_formal):
  1\. Pass sby_file — run an existing .sby or .tcl config file directly.
  2\. Pass files + top — auto-generate a config and run it.

For equivalence checking (tool="eqy"):
  1\. Pass sby_file pointing to an .eqy config file.
  2\. Pass gold_files + gate_files + top — auto-generate an .eqy config.

Args:
    sby_file: Path to an existing config file (.sby, .eqy, or .tcl).
    files: RTL source files for property verification (when sby_file is omitted).
    top: Top module name.
    mode: "prove" | "bmc" | "cover" | "live". Default: "prove". (sby only)
    depth: Bound depth for bmc/prove. Default: 20. (sby only)
    engine: "auto" or explicit e.g. "smtbmc z3". (sby only)
    tool: "auto" | "sby" | "eqy" | "jaspergold" | "vc_formal".
          Auto uses config priority order.
    timeout: Seconds before killing the tool. Default: 300.
    gold_files: Gold (reference) design files for equivalence checking (eqy only).
    gate_files: Gate (implementation) design files for equivalence checking (eqy only).

Returns a FormalResult dict:
    status: "PASS" | "FAIL" | "ERROR" | "UNKNOWN"
    rc: exit code
    failures: [{property, file, line}]
    traces: [path to counterexample VCD — open with launch_waveform] (sby only)
    induction_failures, induction_traces: assertions the k-induction
        step could not prove and its trace (sby only). They explain an
        UNKNOWN prove and are not reachable failures.
    warnings, errors, workdir, raw_output

Input parameters:

- `depth` (integer)
- `engine` (string)
- `files`
- `gate_files`
- `gold_files`
- `mode` (string)
- `sby_file`
- `timeout` (integer)
- `tool` (string)
- `top`

### `get_project_structure` (~174 tokens)

List the project's RTL and constraint files.

Start here in an unfamiliar project to find the sources to pass to
lint, run_simulation and synthesize, and the constraint file for
run_place_route.

Args:
    root: Directory to scan, inside the project (defaults to the
          project root).

Returns:
    root: the directory scanned (absolute)
    rtl_files: relative paths of .v/.sv/.svh/.vh/.vhd/.vhdl files
    constraint_files: relative paths of .xdc, .lpf, .sdc, .upf and
        .pdc files (iCE40 .pcf files are not listed)
    file_count: number of RTL files
    error: present only when root escapes the project directory

Input parameters:

- `root` (string)

### `read_rtl` (~103 tokens)

Read an RTL file, optionally restricted to a line range.

Args:
    file: Path to the file; must stay inside the project directory.
    start_line: First line to return (1-indexed, inclusive).
    end_line: Last line to return (1-indexed, inclusive).

Returns:
    content: file text with line numbers, path, total_lines

Input parameters:

- `end_line`
- `file` (string, required)
- `start_line`

### `write_rtl` (~143 tokens)

Write (or diff) proposed RTL content to a file.

Always call with dry_run=True first to review the unified diff before committing.

Args:
    file: Path to the target file; must stay inside the project directory.
    content: Complete new file content.
    dry_run: If True (default), return a unified diff without writing. If False, write.

Returns:
    diff: unified diff string (dry_run=True) or empty string after write
    lines_changed: number of changed lines
    written: True if file was actually written

Input parameters:

- `content` (string, required)
- `dry_run` (boolean)
- `file` (string, required)

### `search_rtl` (~139 tokens)

Grep across project RTL files with surrounding context.

Args:
    query: Search string (literal, not regex).
    root: Directory to search, inside the project (defaults to the
          project root).
    scope: "all" | "sv" | "v" — filter by file extension.

Returns:
    matches: [{file, line, context}] — capped at 50 entries
    match_count: total matches found (may exceed len(matches))
    truncated: True when matches were dropped by the 50-entry cap

Input parameters:

- `query` (string, required)
- `root` (string)
- `scope` (string)

### `get_constraints` (~75 tokens)

Read and return the content of a constraint file (.xdc / .sdc / .lpf / .upf).

Args:
    file: Path to the constraint file; must stay inside the project directory.

Returns:
    content: raw file text, path, format (inferred from extension)

Input parameters:

- `file` (string, required)

### `launch_waveform` (~164 tokens)

Open a VCD/FST/FSDB trace file in a waveform viewer (fire-and-forget).

Typical flow:
    1. result = run_simulation(..., trace=True)
    2. launch_waveform(result["trace_vcd"])

Args:
    trace_file: Absolute path to the .vcd, .fst, or .fsdb trace file.
    viewer: "auto" | "surfer" | "gtkwave" | "verdi".
            Auto picks from config priority order.

Returns:
    {"viewer": str, "launched": bool, "trace": str}
    or {"launched": False, "error": str} on failure.

Input parameters:

- `trace_file` (string, required)
- `viewer` (string)

### `read_waveform` (~385 tokens)

Read signal values from a VCD or FST trace — no viewer needed.

Typical debug flow:
    1. result = run_simulation(..., trace=True)   # note failure time T
    2. read_waveform(result["trace_vcd"])          # discover signal names
    3. read_waveform(result["trace_vcd"],
                     signals=["dut.state", "dut.count"],
                     time_start=T-100, time_end=T+10)

Args:
    trace_file: Path to the trace. VCD is read directly; .fst is
                converted via the OSS CAD Suite's fst2vcd first.
    signals: Signal names to read. A name matches on the full
             hierarchical path ("tb.dut.count") or any trailing
             component ("count", "dut.count"). Omit to list the
             signals available in the trace instead.
    time_start: Window start in VCD ticks (multiply timescale to get
                time). Each signal's value just before the window is
                included so state at window start is known.
    time_end: Window end in VCD ticks.
    max_transitions: Per-signal cap; "truncated" is set when hit.

Returns:
    Discovery mode: {trace, timescale, end_time, signal_count,
                     signals [{name, width}]}
    With signals:   {trace, timescale, end_time,
                     signals [{name, width,
                               transitions [{time, value}],
                               truncated}],
                     not_found}
    {"error": str} on failure. Values are bit strings ("0101",
    may contain x/z); times are VCD ticks.

Input parameters:

- `max_transitions` (integer)
- `signals`
- `time_end`
- `time_start`
- `trace_file` (string, required)

### `read_coverage` (~211 tokens)

Summarize a Verilator coverage.dat as structured line coverage.

Typical flow:
    1. result = run_simulation(..., simulator="verilator", coverage=True)
    2. read_coverage(result["coverage_dat"])   # find the weak spots

Args:
    coverage_dat: Path to the coverage.dat produced by a coverage run
                  (the run_simulation result's coverage_dat field).
    max_uncovered: Cap on uncovered line numbers reported per file;
                   "uncovered_truncated" is set when the cap is hit.
    timeout: Seconds before killing verilator_coverage.

Returns:
    {coverage, total {lines_total, lines_covered, coverage_pct},
     files [{file, lines_total, lines_covered, coverage_pct,
             uncovered_lines, uncovered_truncated?}], file_count}
    or {"error": str} on failure.

Input parameters:

- `coverage_dat` (string, required)
- `max_uncovered` (integer)
- `timeout` (integer)

### `run_cocotb` (~298 tokens)

Run a cocotb (Python) testbench against an HDL design.

cocotb writes testbenches as Python coroutines instead of an HDL
testbench; this builds the design and runs the cocotb tests via
cocotb's runner, returning per-test pass/fail.

Args:
    sources: HDL design files. May include ``.f`` filelists (one path
             per line), expanded in place.
    test_module: Path to the Python cocotb test file (contains the
             @cocotb.test() coroutines).
    toplevel: Top-level HDL module cocotb instantiates.
    simulator: "icarus" | "verilator" | "ghdl" | "questa" | "xcelium"
             | "vcs". Icarus is the most common cocotb pairing.
    timeout: Seconds before killing the build+test run.

Returns:
    {simulator, passed, failed, tests [{name, status, time, message}],
     raw_stdout, raw_stderr} or {"error": str} (cocotb/simulator
     missing, module not found, or build failed before any test ran).

Input parameters:

- `simulator` (string)
- `sources` (array, required)
- `test_module` (string, required)
- `timeout` (integer)
- `toplevel` (string, required)

### `capture_serial` (~401 tokens)

Capture a board's UART output, optionally sending text first.

Use after program_device to check what the design prints, e.g. a
firmware banner, or that typed characters are echoed. Only the port
you name is opened; silica never scans for serial ports.

Args:
    port: Serial device to open, e.g. "/dev/ttyUSB1" or
          "/dev/serial/by-id/usb-...-if01-port0" (Linux), "COM4" (Windows).
          On boards with an FTDI JTAG+UART bridge the UART is usually
          the second interface (if01).
    baud: Baud rate; 8N1, no flow control.
    duration: Seconds to listen (at most 600).
    send: Text to write once send_delay has passed, e.g. "hello\r".
    send_delay: Seconds to listen before sending.
    expect: Regex searched for in the captured text, e.g. "Silica .* SoC".
    stop_on_match: Stop as soon as expect matches (default) instead of
          listening for the full duration.

Returns a SerialCapture dict:
    port, baud, elapsed_s, bytes_received, bytes_sent,
    lines [{t, text, partial?}] (t = seconds from the start of the
    capture to the line's first byte), text (everything received,
    UTF-8 with replacement characters), expect, matched (bool, or
    None without expect), match (the matched text).
    On failure also error (message) and, when there is one, fix
    (a command or step to resolve it, e.g. granting port access).

Input parameters:

- `baud` (integer)
- `duration` (number)
- `expect`
- `port` (string, required)
- `send`
- `send_delay` (number)
- `stop_on_match` (boolean)

### `doctor` (~356 tokens)

Report silica's version and which EDA tools it can use, with a fix for each gap.

Call this first in a new environment, or when a tool call says a tool
is missing, to see what is installed before choosing a flow. It finds
tools the same way the other tools do (PATH, then an OSS CAD Suite
install) and asks each open-source tool for its version. Commercial
tools (VCS, Questa, Xcelium, Vivado, ...) are only looked up, never
run, so no license is checked out. Takes a few seconds.

Args:
    check_updates: Also ask PyPI (3 s timeout) whether a newer
        silica-eda exists. Offline or blocked networks just report
        the check as unavailable. Set SILICA_NO_UPDATE_CHECK=1 to
        skip it everywhere.

Returns:
    silica {version, latest, update_available, update_check, fix?},
    python, platform, executable, oss_cad_suite (path or None),
    tools [{name, used_by, found, path, version, min_version,
            status: "ok" | "found" (version unknown) | "missing" |
            "outdated", fix?, note?}],
    python_extras [{name, extra, used_by, installed, version, fix?}]
        (cocotb for run_cocotb, pyserial for capture_serial),
    commercial [{name, category, found, path}],
    summary {ok, missing, outdated} (tool names).
    Every missing or outdated entry carries a concrete "fix": an
    install command for this platform or the upgrade to make.

Input parameters:

- `check_updates` (boolean)

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/simaanc-silica-eda/silica-eda#diagnostics

## Score history

- 2026-11-05: 75
- 2026-11-04: 68
- 2026-11-03: 53
- 2026-11-02: 53
- 2026-11-01: 68
- 2026-10-31: 53
- 2026-10-30: 53
- 2026-10-29: 68
- 2026-10-28: 53
- 2026-10-27: 68
- 2026-10-26: 68
- 2026-10-25: 68
- 2026-10-24: 68
- 2026-10-23: 68
- 2026-10-22: 68
- 2026-10-21: 68
- 2026-10-20: 53

## Common questions

### What is the Silica MCP server?

Silica is an MCP server listed in the public MCP registry as io.github.simaanc/silica-eda. RTL and FPGA tools: lint, simulate, formal, synthesize, place and route, program a board. This page covers its PyPI package (silica-eda).

### Is the Silica MCP server safe to use?

Silica scores 75 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 5 November 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Silica MCP server expose?

Silica exposes 18 tools: run_simulation, synthesize, run_place_route, program_device, lint, and 13 more. Their descriptions and schemas cost roughly 5,680 tokens of context every time the server is loaded.

### Is the Silica MCP server still maintained?

Silica is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Silica MCP server under?

Silica declares the AGPL-3.0-only licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/silica-eda/
- Socket report: https://socket.dev/pypi/package/silica-eda
- Repository: https://github.com/simaanc/silica-eda
- Changelog RSS feed: https://verifymcp.io/servers/simaanc-silica-eda/silica-eda.xml
- Changelog JSON feed: https://verifymcp.io/servers/simaanc-silica-eda/silica-eda.json
- HTML version of this page: https://verifymcp.io/servers/simaanc-silica-eda/silica-eda
