Agent kit (MCP)
neosyn-fpga-mcp is a Model Context Protocol
server that hands the C⏚ toolchain to an AI agent. The agent writes C⏚, and
the server compiles, simulates and synthesis-checks it against the real
compiler — instead of the agent producing Verilog that has never been near
a toolchain.
That is the point. An LLM asked for Verilog will confidently emit something that does not build, does not synthesize, or silently folds away to nothing. Here every step is verified by the same compiler a human uses, and errors come back as structured diagnostics the model can act on.
It is a separate package from the VS Code extension — install whichever you need, or both. They drive the same compiler.
Install
pip install neosyn-fpga-mcpSome older material — the extension README, the MCP registry entry — calls this
cg-agent-kit.neosyn-fpga-mcpis the package to install. The commandcg-mcp-serverstill works as an alias if you have it in a config.
Then point it at a compiler jar:
export CG_JAR=/path/to/cg-language-server.jarTwo ways to get that jar:
- Open source — download a prebuilt jar from cg-compiler releases, or build it from source. No license required.
- Commercial — the jar inside an installed extension, at
~/.vscode/extensions/neosyn.neosyn-cg-*/server/cg-language-server.jar. This one adds the bytecode Fast Sim and VHDL.
Optional, and worth having — cg_synth and the Icarus simulation backend
shell out to these:
# Debian / Ubuntu
sudo apt install yosys iverilogRequirements: Python 3.10 or newer, and Java 17+ on your PATH for the
jar.
Configure your MCP client
Add the server to your client's config. The shape is the same everywhere:
{
"mcpServers": {
"cg": {
"command": "neosyn-fpga-mcp",
"env": { "CG_JAR": "/path/to/cg-language-server.jar" }
}
}
}- Claude Desktop —
claude_desktop_config.json - Cursor / Windsurf — the MCP section of settings
- Claude Code —
claude mcp add cg --env CG_JAR=/path/to/jar -- neosyn-fpga-mcp
Restart the client. The agent should now list the cg_* tools below.
Tools
Thirteen, and an agent typically moves through them in roughly this order.
| Tool | What it does |
|---|---|
cg_scaffold | Start here from a blank file. Returns a complete, compiling, self-checking skeleton with the datapath left as marked holes |
cg_example | Scored lookup into the validated-code dictionary (38 entries) — returns working code and how to adapt it |
cg_check | Compile and validate C⏚; structured diagnostics with file:line and the fix |
cg_lint | Static checks for C⏚ that compiles cleanly and is still wrong; each finding carries a rule, a severity and a fix |
cg_suggest_for_error | Map a compiler error to the recipe carrying the fix pattern |
cg_generate_verilog | Emit synthesizable Verilog (or VHDL, with the commercial jar) |
cg_simulate | Simulate a design — Icarus backend, or the commercial Fast Sim |
cg_synth | Yosys-synthesize the Verilog: REAL / FOLDED / SUSPECT verdict plus cell count |
cg_report | Render a self-contained HTML report: synthesis verdict and cell counts, simulation PASS/FAIL, generated Verilog, datapath schematics |
cg_fsm / cg_graph | A task's compiled state machine, or a network's wiring graph |
cg_docs | C⏚ language and pattern reference packs |
cg_capabilities | What this install can actually do — jar version, backends present |
Two of these are the difference between an agent that guesses and one that converges:
cg_example is a dictionary, not retrieval. All 38 entries are compiled,
simulated and synthesized before they ship, on the open-source jar as well as
the commercial one. What comes back is a record, not a blob of code, and four
of its fields do distinct work:
adapt— the axes along which that recipe bends. The UART entry's reads "change the frame width/order (add parity, 2 stop bits, MSB-first); gate the loop body behind…". Retrieval hands an agent code and leaves it guessing what is safe to change; this says so.note— provenance in the entry's own words: *"Verified: bytecode sim 2/2- yosys REAL (47 cells) + iverilog elaborates."* A recipe that is known to have reached real hardware gets adopted rather than second-guessed.
tags/ops— an index in its own right, not decoration.windowedretrieves the streaming-reduction entry although that word appears nowhere in its name or its prose.use_when— the selection criterion, and a live index too: it is the only placeunconditionallyappears, and that retrieves the same entry. Browsing with no query returnsname,kind,use_whenandtagsonly, so this is what an agent chooses on before fetching source.
Lookup is scored and specificity-weighted: exact name ≫ name word ≫ tag
phrase ≫ partial overlap. 1/sqrt returns the reciprocal-square-root entry
while a bare sqrt returns the plain one, and naming an entry outright
outscores any descriptive query by two orders of magnitude. Ask for the
narrowest thing you actually want.
It is not substring matching. one result sits verbatim in the
streaming-reduction entry's use_when and still loses to a better-scoring
entry, so phrasing a query in the dictionary's own words is not a way to force
a hit. And a score measures how discriminating your term is, not which field it
matched — accumulate and sum are both exact ops entries on the same entry
and differ five-fold, so there is nothing to gain by aiming queries at tags.
cg_synth catches the failure that matters. Verilog that compiles can
still synthesize to nothing — a constant folded away, logic optimized out.
The REAL / FOLDED / SUSPECT verdict tells the agent whether it built
hardware or an expensive wire.
Free and commercial
The kit and the compiler it drives are open source. cg_check, cg_lint,
cg_generate_verilog, cg_synth, cg_example, cg_docs and the graph tools
run on the open compiler, with no license.
Two things are gated, not one. Simulation speed: cg_simulate's default
bytecode backend is the commercial Fast Sim and will ask you to upgrade,
while the iverilog backend works fully — generate Verilog, run Icarus.
If you want cycle-accurate simulation in seconds without an HDL toolchain,
that is what a license buys.
And some language features. File-scope declarations and VHDL output need
the commercial jar; a design using them will not compile on the open build at
all, which is a harder failure than a missing backend. Call cg_capabilities
— it probes what your install can actually do rather than assuming, so an
agent finds this out before it writes code, not after.
Verify the install
neosyn-fpga-mcp --helpOr drive the verification functions straight from Python, without an MCP client:
from neosyn_fpga_mcp import cg_mcp_server as cg
print(cg.check(open("Counter.cg").read()))
print(cg.generate(open("Counter.cg").read()))If cg_capabilities reports your jar version and the backends you
installed, the setup is good.
Next
- Install — the VS Code extension and the standalone CLI
- Quick tutorial — write a counter yourself in ten minutes
- PyPI · source (MIT)