vivado-mcp

vivado-mcp

Remote automation server for AMD Vivado builds and analysis over SSH, enabling MCP clients to run synthesis, implementation, and debug without local toolchain.

Category
Visit Server

README

vivado-mcp

vivado-mcp is a remote automation server for AMD Vivado built on the Model Context Protocol (MCP). It allows Claude Code and other MCP clients to use Vivado on a Linux build server over SSH, without requiring the Xilinx/AMD toolchain on the client machine.

The current release provides full Vivado session control, Git workspace synchronization, project management, durable build jobs, build progress and log inspection, and structured analysis of utilization, timing, DRC, CDC, power, and related reports.

Key capabilities

  • Connects to the build server over SSH without opening additional TCP ports.
  • Automatically deploys a remote Python agent backed by a persistent Unix socket service.
  • Maintains long-lived Vivado Tcl sessions so open projects and checkpoints can be reused across commands.
  • Runs synthesis, implementation, and bitstream builds as independent jobs. Job state survives SSH disconnections and daemon restarts.
  • Provides cancellable jobs, long polling, and incremental event cursors.
  • Synchronizes dirty Git worktrees through a temporary index without changing the user's branch, HEAD, or staging area.
  • Enforces workspace boundaries for every file path and exposes paths as workspace-relative POSIX paths.
  • Normalizes Vivado reports instead of sending large text reports directly into the model context.
  • Caches report results by DCP content hash and compares utilization or timing across builds.
  • Deduplicates Vivado messages by message ID to condense repeated warnings and errors.
  • Enforces a single-writer lock for each project, preventing multiple Vivado processes from modifying the same .xpr file concurrently.

Requirements

Client

  • Python 3.12 or later
  • uv
  • OpenSSH client
  • Git
  • rsync
  • An MCP client with stdio transport support, such as Claude Code

Build server

  • Linux
  • Python 3.12 or later
  • Git
  • rsync
  • Non-interactive SSH access
  • An installed Vivado release with an accessible settings64.sh

The remote agent uses only the Python standard library. It does not require the project's Python dependencies or root privileges on the build server.

Installation

Clone the repository on the client and install its dependencies:

uv sync --locked

Create ~/.config/vivado-mcp/config.toml. To use a different configuration file, set the VMCP_CONFIG environment variable:

[host]
name = "fpga-builder"
ssh = "fpga-builder"
agent_dir = "~/.vivado-mcp"
max_concurrent_jobs = 1
default_jobs = 16
nice = 10
stall_timeout_s = 900

[[host.tools]]
label = "vivado-2023.2"
kind = "vivado"
settings_sh = "/tools/Xilinx/Vivado/2023.2/settings64.sh"
default = true

[[workspace]]
name = "example-project"
local = "/absolute/path/to/example-project"
host = "fpga-builder"
build = "build"
default = true

[security]
allow_eval = true

host.ssh may be a user@hostname target or a host alias from ~/.ssh/config. Public-key authentication is recommended. Verify that the following command runs without prompting for input:

ssh fpga-builder python3 --version

Multiple [[host.tools]] entries may be configured to select among Vivado versions. The tool argument accepted by MCP tools refers to the corresponding label. When omitted, vivado-mcp uses the entry marked default = true, or the first entry if no default is declared.

Multiple [[workspace]] entries are also supported. MCP calls may omit the workspace argument when exactly one workspace is configured or one entry is marked default = true.

Registering the MCP server

Register the server with Claude Code:

claude mcp add vivado -- uv run --directory /absolute/path/to/vivado-mcp vmcp-mcp

Other MCP clients can use the same stdio command:

command: uv
args: run --directory /absolute/path/to/vivado-mcp vmcp-mcp

On the first tool call, the client builds and deploys the remote agent. Later calls verify the protocol version and payload hash. If the running agent needs an upgrade, the server reports that state explicitly instead of closing active Vivado sessions without authorization.

The remote service uses namespaced host resources under agent_dir: vmcp-agentd.sock, vmcp-agentd.lock, and vmcp-agentd.log. This avoids collisions with unrelated services that use generic agentd names.

Workspace and path model

workspace.local must point to the root of a local Git repository. For each configured workspace, vivado-mcp maintains three separate areas on the build server:

  • a bare Git repository that receives synchronization commits;
  • a source worktree checked out at the exact selected commit;
  • a persistent build directory for non-Git artifacts such as .xpr files, run directories, DCPs, bitstreams, and reports.

Project, source, DCP, and ordinary file paths passed to MCP tools are POSIX-style paths relative to the workspace. For example:

rtl/top.sv
constraints/top.xdc
build/demo/demo.xpr
build/flows/j_12345678/post_synth.dcp

Absolute paths, .., backslashes, and symlink escapes are rejected. Paths that begin with the configured build prefix map to the persistent build directory; all other paths map to the remote source worktree.

File synchronization deliberately has one transport in each direction:

  • sync_push is the only source-upload path. It captures modified, staged, and untracked files through a temporary Git index and a synthetic commit, without altering the user's HEAD, branch, or real index. rsync push, SSHFS, and shared filesystem source backends are not supported.
  • Build artifacts live outside the Git worktree and never enter synchronization commits. sync_pull uses rsync over SSH to copy explicitly requested remote artifacts, including the complete configured build directory when requested. It never performs deletions.

The local checkout remains the source of truth. Direct remote source edits are not part of the normal workflow; edit locally and run sync_push again.

Recommended workflows

Project mode

host_status
  → sync_status
  → sync_push
  → project_create or project_open
  → sources_add / set_top / set_generics / set_property
  → project_close
  → session_close
  → build
  → job_wait
  → report_utilization / report_timing_summary / report_drc

project_close closes the project and releases its single-writer lock. session_close terminates the Vivado process and releases its memory. After editing a project, call both in that order.

Non-project mode

sync_push
  → flow_run
  → job_wait
  → job_artifacts
  → report_timing_summary

flow_run reads HDL and XDC files directly. It is well suited to small experiments, quick synthesis runs, and automation that does not need a long-lived .xpr project.

Iterative optimization

report_utilization(old_job)
  → report_timing_summary(old_job)
  → modify the design and rebuild
  → report_diff(old_job, new_job, kind="utilization")
  → report_diff(old_job, new_job, kind="timing")

MCP tool reference

The current release exposes 47 MCP tools. In the signatures below, workspace and tool may be omitted when the configuration provides an unambiguous default.

Host and agent

Tool Parameters Description
host_status None Returns the agent version and uptime, host CPU/memory/disk information, configured tool probes, active sessions, active jobs, and job-slot usage. This is the recommended first call.
agent_ensure force: bool = false Deploys or upgrades the remote agent. force=true restarts the daemon and closes active sessions; durable jobs are unaffected.

Vivado sessions and Tcl

Tool Parameters Description
session_open tool?: str, cwd?: str Starts a long-lived tool interpreter and returns a session_id. tool selects a configured tool version; cwd is the remote process working directory and can usually be omitted.
session_list None Lists live sessions, including their idle, busy, or dead state, PID, idle time, command count, and log path.
session_close session_id: str Closes a session and releases its memory. Interpreter state that has not been written to disk is lost.
tcl_eval session_id: str, script: str, timeout_s: float = 120, allow_blocking: bool = false Executes Tcl in an existing session and returns rc, result, log, errorinfo, and elapsed time. Long-running synthesis, implementation, and bitstream commands are rejected by default and should be submitted as jobs. exit, quit, and start_gui are always rejected.
tcl_help session_id: str, command: str Runs help <command> in the active Vivado version and returns its actual syntax and option documentation.

tcl_eval is an intentionally powerful interface with the same Tcl privileges as the remote user. If arbitrary Tcl execution is unnecessary, set security.allow_eval = false.

Workspace synchronization and file access

Tool Parameters Description
sync_status workspace?: str Returns the local Git HEAD and dirty-file list together with the exact commit currently active on the build server.
sync_push workspace?: str, paths?: list[str], dry_run: bool = false Synchronizes the local worktree to the build server. Omitting paths captures all changes; providing it limits the overlay on HEAD to those paths. dry_run=true reports status only. The user's branch and staging area are not modified.
sync_pull paths: list[str], workspace?: str Pulls selected remote artifacts or directories into the local workspace using rsync over SSH. Passing the configured build directory pulls the complete build tree. Paths must be workspace-relative, and --delete is never used.
file_read path: str, workspace?: str, offset: int = 0, limit: int = 12000 Reads a bounded UTF-8 segment from a remote workspace file. Returns next_offset, total file size, and truncation status. Each read is limited to 64 KiB.
file_grep pattern: str, workspace?: str, glob: str = "**/*", limit: int = 200 Searches the remote source and build trees with a regular expression and returns relative paths, line numbers, and matching text. Results are capped at 1,000 entries, and the number of scanned files is bounded.

Vivado projects, sources, and IP

Tool Parameters Description
project_create path: str, part?: str, board?: str, top?: str, target_language: str = "Verilog", workspace?: str, tool?: str Creates and opens an .xpr inside the workspace, returning the session_id that holds the project lock. Exactly one of part or board is required. target_language accepts Verilog or VHDL.
project_open path: str, workspace?: str, tool?: str Opens an existing .xpr in a new session and acquires its single-writer lock. The call is rejected if another session owns the project.
project_close session_id: str Closes the current project and releases its single-writer lock without terminating the Vivado session.
project_info session_id: str, workspace?: str Returns the project path, part, board, top, target language, source inventory, run status, IP inventory, and residual lock information. File paths are converted to workspace-relative paths.
sources_add session_id: str, files: list[str], workspace?: str, type: str = "auto", library?: str, scoped_to?: str Adds HDL, constraint, or data files to the current project. Vivado FILE_TYPE, library, and SCOPED_TO_REF values may be set explicitly.
sources_remove session_id: str, files: list[str], workspace?: str Removes file references from the project without deleting the files from disk.
sources_list session_id: str, workspace?: str Lists files registered with the current project, including their type and library.
set_top session_id: str, top: str Sets the top-level module or entity for the current source fileset.
set_generics session_id: str, generics: dict[str, str] Sets generic or parameter overrides on the current fileset.
add_include_dirs session_id: str, directories: list[str], workspace?: str Appends workspace-relative directories to the Verilog/SystemVerilog include path.
set_run_strategy session_id: str, run: str, strategy: str Sets the Vivado strategy for a named synthesis or implementation run.
set_property session_id: str, object: str, name: str, value: str, workspace?: str Sets one Vivado property on a typed object. object accepts project, fileset, run:<name>, ip:<name>, or file:<path>. Values for Tcl pre/post hooks are resolved as workspace paths.
ip_create session_id: str, module_name: str, vlnv: str, config?: dict[str, str] Creates a Vivado IP instance and optionally sets CONFIG.* properties. The CONFIG. prefix is added automatically when omitted.
ip_upgrade session_id: str, ips: list[str] Upgrades selected IP instances to the current catalog version.
ip_generate session_id: str, ips: list[str] Runs generate_target all for the selected IP instances.
flow_run sources: list[str], part: str, top: str, xdc?: list[str], target: str = "synth", workspace?: str, tool?: str, idempotency_key?: str, timeout_s: float = 0 Starts a durable non-project job. target accepts synth, impl, or bitstream; outputs are written under build/flows/<job_id>. timeout_s=0 disables the wall-clock timeout.
project_unlock path: str, workspace?: str Removes stale Vivado .lck files left after a process crash. The operation is rejected while any active session owns the project.

The complete Block Design Tcl interface remains available through tcl_eval. Potentially long-running commands should still be submitted as jobs rather than blocking an interactive interpreter.

Build jobs and observability

Tool Parameters Description
build project: str, target: str = "bitstream", run?: str, jobs?: int, reset: bool = false, strategy?: str, idempotency_key?: str, tool?: str, timeout_s: float = 0, workspace?: str Starts an independent durable job for an existing .xpr and returns its job_id immediately. target accepts synth, impl, bitstream, or flow; non-project builds should normally use flow_run. jobs defaults to the host configuration, and timeout_s=0 disables the wall-clock timeout.
job_list limit: int = 100 Lists durable jobs in reverse creation order.
job_status job_id: str Returns job state, the current step and phase, a monotonic progress estimate, elapsed time, message counts, the log tail, and the latest event sequence number.
job_events job_id: str, since_seq: int = 0, limit: int = 200 Reads events after since_seq from the append-only event stream. Use the returned last_seq as the next cursor to avoid duplicates or gaps.
job_wait job_id: str, timeout_s: float = 600, since_seq?: int Long-polls a job until it reaches a terminal state, emits an important event, or times out. Each call is limited to 3,600 seconds and uses MCP progress notifications to remain visible to the client.
job_cancel job_id: str Cancels a queued or running job and sends a termination signal to its dedicated process group. Calling it on a terminal job is safe.
job_logs job_id: str, tail: int = 100, grep?: str Returns a bounded job log tail, optionally filtered by a regular expression. It never returns an entire multi-megabyte Vivado log.
messages job_id: str, min_severity: str = "warning" Aggregates log messages by Vivado message ID and returns the severity, occurrence count, and one example. min_severity accepts warning, critical_warning, error, or fatal.
job_artifacts job_id: str Lists DCP, bitstream, report, XSA, LTX, and related job artifacts. Workspace-backed jobs return workspace-relative paths.

Job states follow this lifecycle:

queued → starting → running → succeeded
                           ↘ failed
                           ↘ cancelled
                           ↘ timeout
                           ↘ oom
                           ↘ lost

lost means the daemon cannot determine the process's final outcome; it is not reported as an ordinary failure. Use an idempotency_key when retrying a job submission whose response may have been lost to a network interruption. A repeated key returns the existing job instead of launching another expensive build.

Reports and analysis

The source accepted by report tools may be a job_id or a workspace-relative DCP path. Jobs emit a standard report bundle when they finish. When only a DCP is available, the agent reuses a read-only Vivado session to generate missing reports on demand. Normalized results are cached by DCP SHA-256, report type, and arguments.

Tool Parameters Description
report_utilization source: str, hierarchical: bool = false, cells?: list[str], workspace?: str, tool?: str Returns used, available, and percentage values for LUT, LUTRAM, FF, BRAM, URAM, DSP, IO, and BUFG resources. Zero-use resources are omitted by default. Hierarchical output and cell filters are supported.
report_timing_summary source: str, max_paths: int = 5, workspace?: str, tool?: str Returns WNS, TNS, WHS, THS, pulse-width metrics, failing endpoint counts, per-clock-domain statistics, clock frequencies, and compact worst-path summaries. max_paths must be between 1 and 20.
report_timing_paths source: str, from_endpoint?: str, to_endpoint?: str, through?: str, nworst: int = 5, delay_type: str = "max", detail: str = "summary", workspace?: str, tool?: str Queries targeted timing paths. Endpoint arguments use Vivado object-matching patterns. delay_type accepts max or min; detail accepts summary or full. To bound response size, detail="full" requires nworst=1.
report_clocks source: str, workspace?: str, tool?: str Returns clock periods, target frequencies, WNS-derived achieved frequencies, and timing metrics for each clock domain.
report_drc source: str, workspace?: str, tool?: str Aggregates DRC violations by rule and returns the rule, severity, count, description, and one example.
report_methodology source: str, workspace?: str, tool?: str Aggregates Vivado methodology findings by rule without returning the full report.
report_cdc source: str, workspace?: str, tool?: str Aggregates clock-domain crossing findings by rule and severity.
report_power source: str, workspace?: str, tool?: str Returns total on-chip, dynamic, and static power, junction temperature, confidence, and component-level power data.
report_diff a: str, b: str, kind: str, workspace?: str, tool?: str Compares normalized reports from two jobs or DCPs. kind accepts utilization or timing and returns only semantic resource or timing deltas. DCP paths must belong to the same workspace.

Reliability and runtime semantics

vivado-mcp deliberately separates interactive sessions from long-running builds:

  • Sessions handle fast Tcl queries and project editing. They survive SSH reconnections, but a daemon restart closes them.
  • Jobs run in independent process groups with state and events persisted to disk. They survive SSH disconnections and daemon restarts.
  • Job state, events, and JSON indexes are written atomically. Process identity is verified with both the PID and Linux process start time to avoid mistakes caused by PID reuse.
  • Build artifacts and reports remain in the persistent remote build directory; source synchronization does not clear that directory.
  • Large logs and reports are always returned in bounded, paginated, or structured form to protect the MCP context window.

Security considerations

  • Network access inherits the authentication and authorization policy of SSH; the agent does not listen on a TCP port.
  • Workspace tools reject absolute paths, parent-directory traversal, backslashes, and out-of-bounds symlinks.
  • Only one active write session may own a project at any time.
  • sync_pull never deletes remote or local files.
  • tcl_eval is equivalent to executing Vivado Tcl as the SSH user. When MCP callers are not fully trusted, set security.allow_eval = false and apply the principle of least privilege to the remote account.
  • agent_ensure(force=true) closes active sessions. Check host_status or session_list first to understand the impact. Running durable jobs are not terminated.

Supported scope

The public interface currently covers project and non-project Vivado flows, including synthesis, implementation, bitstream generation, IP management, and static report analysis. Vitis Unified, Vitis HLS, and hardware programming are not yet exposed through MCP tools.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured