virtuoso-skill-mcp
by haykv-cr
README.md
# virtuoso-skill-mcp
Connect Cadence Virtuoso SKILL to Claude Code via a Model Context Protocol (MCP) server.
Load files, evaluate expressions, inspect GUI forms, and read CIW errors — all from natural language.
---
## Prerequisites
| Requirement | Version | Notes |
|---|---|---|
| Cadence Virtuoso | IC6.1.8 or ICADVM20.1+ | Any release with skillbridge support |
| Python | 3.8 or newer | `python3 --version` to check |
| Claude Code | latest | Install below |
**Install Claude Code** (if you haven't already):
```bash
npm install -g @anthropic/claude-code
# or, on macOS with Homebrew:
brew install claude-code
```
---
## One-command install
```bash
cd virtuoso-skill-mcp
chmod +x install.sh
./install.sh
```
That's it. The script will:
- Find your Python and create an isolated virtualenv
- Install all dependencies (`skillbridge`, `fastmcp`, `mcp[cli]`)
- Auto-detect your Virtuoso installation and CIW log
- Generate the Virtuoso SKILL bootstrap file with the correct socket path
- Register the MCP server with Claude Code
- Print a colour-coded summary of everything it found
---
## Start the bridge in Virtuoso
### One-time (in the CIW)
Type this in the Virtuoso Command Interpreter Window:
```
load("/path/to/virtuoso-skill-mcp/skill/start_server.il")
```
You will see:
```
╔══════════════════════════════════════════════════════╗
║ ✓ Claude Code MCP bridge ready ║
║ Virtuoso ←→ skillbridge ←→ FastMCP ←→ Claude ║
╚══════════════════════════════════════════════════════╝
```
### Auto-start every session (.cdsinit)
Add **this one line** to your `~/.cdsinit`:
```
load("/path/to/virtuoso-skill-mcp/skill/start_server.il")
```
Replace `/path/to/virtuoso-skill-mcp` with the absolute path printed by `install.sh`.
---
## How to use it
Open Claude Code in your terminal (`claude`) and try:
**1. Test a SKILL file and report any errors**
```
Load /home/me/projects/myForm.il into Virtuoso and show me all errors and warnings.
```
**2. Inspect and open GUI forms**
```
List all registered forms in Virtuoso, then open myDesignForm and tell me
if any callback errors appear in the CIW.
```
**3. Debug an expression interactively**
```
Evaluate this SKILL expression and explain the result:
hiCreateStringField(?name 'myField ?prompt "Enter value:" ?value "default")
```
**4. Full test cycle**
```
Reload /home/me/skill/layout_form.il, open the first new form,
and give me a full test report.
```
---
## Available tools
| Tool | What it does |
|---|---|
| `virtuoso_status()` | Check whether Virtuoso is running and the IPC socket is live |
| `load_skill_file(file_path)` | Load a `.il` file; return only errors |
| `eval_skill(expression)` | Evaluate arbitrary SKILL; return result |
| `check_syntax(file_path)` | Syntax check without execution |
| `get_errors(lines=100)` | Tail CIW log; return ERROR/WARNING lines |
| `list_forms()` | List all registered `hiForm` names |
| `open_form(form_name)` | Open a form; capture callback errors |
| `reload_and_test(file_path)` | Full cycle: load → open → collect errors |
---
## Troubleshooting
### Virtuoso is not running
```
ERROR: Cannot connect to Virtuoso: the IPC socket does not exist.
```
**Fix:** Start Virtuoso, then source `start_server.il` in the CIW.
---
### Wrong Python version
```
[ERROR] Python 3.6 is too old. Requires Python 3.8+.
```
**Fix** — pass the path to a 3.8+ Python explicitly:
```bash
# Via environment variable
PYTHON=/usr/cad/chn/python3/python-3.10.0/bin/python3 ./install.sh
# Via flag
./install.sh --python /usr/cad/chn/python3/python-3.10.0/bin/python3
# Find available candidates
ls /usr/cad/chn/python3/*/bin/python3
which python3.10 python3.11 python3.12
```
The installer also automatically checks `/usr/cad/chn/python3/python-3.10.0/` before any PATH candidates.
---
### `claude` CLI not found
```
[WARN] claude CLI not found on PATH.
```
**Fix:** Install Claude Code and add it to your PATH.
```bash
# bash/zsh
export PATH="$HOME/.claude/bin:$PATH"
# csh/tcsh (common in EDA environments)
setenv PATH "$HOME/.claude/bin:$PATH"
```
Then re-run `./install.sh` to register the MCP server automatically.
---
### skillbridge connection refused
```
ERROR: Cannot connect to Virtuoso after 3 attempts.
```
**Checklist:**
1. Is Virtuoso running? (`ps aux | grep virtuoso`)
2. Did you source `start_server.il` in the CIW?
3. Does the IPC socket path in `config/defaults.json` match what skillbridge expects?
```bash
.venv/bin/python -c "from skillbridge import Workspace; print(Workspace.DEFAULT_SOCKET)"
```
4. Re-run `./install.sh` to regenerate `config/defaults.json` with fresh paths.
---
### CIW log not found
```
ERROR: CIW log file not found.
```
**Fix:**
```bash
# Find the log Virtuoso is writing
ls -lh ~/.cdnstmp/*.log ~/virtuoso.log /tmp/virtuoso.log 2>/dev/null
# Set the path
export CDS_LOG_PATH=/path/to/virtuoso.log
# Re-run installer so config picks it up
./install.sh
```
Or edit `config/defaults.json` directly:
```json
{
"ciw_log_path": "/home/you/.cdnstmp/virtuoso.log"
}
```
---
### `pyStartServer` is not defined
```
*ERROR* [virtuoso-skill-mcp] pyStartServer is not defined.
```
**Fix:** The skillbridge SKILL helper (`server.il`) is not loading.
Check `config/defaults.json` → `skillbridge_il_path` and confirm the file exists:
```bash
ls -l "$(python3 -c 'import skillbridge, pathlib; print(pathlib.Path(skillbridge.__file__).parent)')"
```
Then re-run `./install.sh`.
---
## Project layout
```
virtuoso-skill-mcp/
├── install.sh # One-command installer
├── pyproject.toml # Package metadata
├── README.md # This file
├── src/
│ ├── server.py # FastMCP server (MCP entry point)
│ ├── skill_bridge.py # skillbridge connection + retry logic
│ ├── ciw_monitor.py # CIW log parser
│ └── health_check.py # Pre-flight checks
├── skill/
│ └── start_server.il # Virtuoso SKILL bootstrap
├── config/
│ └── defaults.json # Paths and settings (generated by install.sh)
└── tests/
└── test_connection.py # Unit tests (mock-based, no Virtuoso needed)
```
---
## Running tests
No Virtuoso required — all SKILL calls are mocked:
```bash
.venv/bin/python -m pytest tests/ -v
```
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing