Two Model Context Protocol (MCP) servers to automate Intel Quartus FPGA builds and DE10-Nano board management.
FPGA build automation for Intel Quartus projects.
IMPORTANT: ALWAYS USE ASYNC MODE FOR BUILDS
Quartus FPGA builds take 20-45 minutes. Always use
quartus_build_asyncto avoid blocking. The synchronousquartus_buildwill block Claude for the entire build duration - don't use it.Async workflow:
quartus_build_async()- Start build, get task_id, continue workingquartus_task_status()- Check if done (poll periodically)quartus_task_wait()- Block until complete (when you need the result)quartus_task_cancel()- Abort if needed
| Tool | Description |
|---|---|
quartus_build_async(project_path, clean_first?) |
USE THIS - Start build in background, returns immediately. |
quartus_task_status(task_id?) |
Check build progress without blocking. |
quartus_task_wait(timeout?) |
Wait for current build to complete, returns result. |
quartus_task_cancel() |
Cancel the currently running build. |
quartus_task_list() |
List current + recent completed builds. |
quartus_status(project_path) |
Check if build artifacts exist. |
quartus_clean(project_path) |
Clean build artifacts. |
quartus_build(project_path, clean_first?) |
Sync build - AVOID (blocks 20-45 min). |
Features:
- Auto-configures
PATHandQSYS_ROOTDIRfor Quartus 24.1 - 1-hour build timeout
- Parses build logs for errors
- Returns structured results with RBF path and size
- Async builds: Run builds in background without blocking Claude
- Single build enforcement: Only one build at a time per machine (via
~/.quartus-mcp/state.json) - Build history: Keeps last 10 completed builds with results
Board management and deployment for DE10-Nano (Cyclone V SoC).
| Tool | Description |
|---|---|
board_status() |
Quick health check - SSH connectivity, serial port, uptime. |
ssh_cmd(command, timeout?, sudo?) |
Execute command via SSH. |
serial_cmd(command, timeout?) |
Execute command via serial console (pyserial). |
sw_sync(local_dir, remote_dir?) |
Rsync entire folder to board (default: ~/sw). |
fpga_verify() |
Read registers to verify bitstream is loaded. |
fpga_deploy(rbf_path) |
Full deploy: backup, copy, reboot, wait, verify. |
fpga_recover() |
U-Boot recovery via serial when board won't boot. |
Features:
- Uses
paramikofor SSH (proper timeout handling) - Uses
pyserialfor serial (never hangs like shell commands) fpga_deploypolls for board online after reboot (90s timeout)fpga_recoverauto-calculates hex file size for U-Bootfatwrite
Default board settings (hardcoded in de10nano_mcp/server.py):
| Setting | Value |
|---|---|
| SSH Host | analog.local |
| SSH User | analog |
| SSH Port | 22 |
| Serial Port | /dev/ttyUSB0 |
| Serial Baud | 115200 |
| Boot RBF | /boot/soc_system.rbf |
Default Quartus settings (in quartus_mcp/server.py):
| Setting | Value |
|---|---|
| Quartus Path | /opt/altera_lite/24.1std/quartus/bin |
| QSYS Root | /opt/altera_lite/24.1std/quartus/sopc_builder/bin |
| Build Timeout | 3600 seconds (1 hour) |
cd ~/Documents/dvp/mcp-servers
# Create virtual environment
python3 -m venv .venv
# Install both servers (editable mode)
.venv/bin/pip install -e quartus-mcp -e de10nano-mcpAdd to your project's .mcp.json:
{
"mcpServers": {
"quartus": {
"command": "/home/abb/Documents/dvp/mcp-servers/.venv/bin/quartus-mcp"
},
"de10nano": {
"command": "/home/abb/Documents/dvp/mcp-servers/.venv/bin/de10nano-mcp"
}
}
}Restart Claude Code to load the servers.
# Start build in background (returns immediately)
quartus_build_async(project_path="/home/abb/de10-nanon/hdl-phase/projects/cn0579/de10nano")
# Do other work while build runs...
# Check status periodically
quartus_task_status()
# Or wait for completion when you need the result
quartus_task_wait()
Use fpga_deploy with rbf_path="/home/abb/de10-nanon/hdl-phase/projects/cn0579/de10nano/cn0579_de10nano.rbf"
Use sw_sync with local_dir="/home/abb/de10-nanon/hdl-phase/sw"
This syncs the entire sw/ folder to ~/sw/ on the board. Then run scripts as:
sudo python3 ~/sw/pll_tuner.py monitorUse board_status (no arguments)
If the board is stuck at U-Boot prompt after a bad bitstream:
Use fpga_recover (no arguments)
This will:
- Connect via serial
- Load backup RBF from SD card
- Calculate file size and write to main RBF
- Reboot and verify
FPGA builds take 20-45 minutes. ALWAYS use async mode to avoid blocking Claude.
1. START BUILD (returns immediately):
quartus_build_async(project_path="/path/to/project")
-> Returns: task_id (e.g., "build-20240122-153000")
-> Claude can now do other work!
2. CHECK PROGRESS (non-blocking):
quartus_task_status()
-> Returns: RUNNING + elapsed time, or SUCCESS/FAILED + results
3. WAIT FOR COMPLETION (when you need the result):
quartus_task_wait(timeout=3600)
-> Blocks until build finishes, returns full result
-> Use this when you're ready to deploy
4. CANCEL IF NEEDED:
quartus_task_cancel()
-> Kills the running build process
5. VIEW HISTORY:
quartus_task_list()
-> Shows current task + last 10 completed builds
Why async matters: Synchronous builds block Claude for 20-45 minutes, wasting context and preventing any other work. Async lets Claude start a build, do other tasks (edit code, run tests, answer questions), then check back when the build completes.
Run tests with mock mode (no real Quartus needed):
cd ~/Documents/dvp/mcp-servers-async
QUARTUS_MCP_MOCK=3 .venv/bin/python quartus-mcp/tests/test_quartus_mcp.pyMock mode environment variable:
QUARTUS_MCP_MOCK=1- Enable mock with 10s buildsQUARTUS_MCP_MOCK=<N>- Enable mock with N-second builds
- Python >= 3.10
mcp>= 1.0.0 (MCP Python SDK)paramiko>= 3.4.0 (SSH)pyserial>= 3.5 (Serial)
MIT