Skip to main content
Glama

gowin-mcp

An MCP server that turns Gowin EDA build reports into structured data.

Gowin EDA writes everything you need after a place & route — resource usage, achieved frequency per clock, the exact register-to-register path that failed setup, the pin every port landed on, the warnings that explain why a clock was never constrained — and then buries it in a multi-megabyte HTML file nobody opens. This server reads those artifacts and hands back the numbers.

Built for Sipeed Tang boards (GW1N / GW2A / GW5A) but it only cares about the report format, so any Gowin EDA project works.

What it answers

  • Did this build close timing, and if not, which path failed and by how much?

  • Could timing even be verified? (unknown is a first-class answer — see below.)

  • What is the achieved fMax on each clock domain versus its constraint, and is a shortfall real or just how Gowin reports multicycle paths?

  • How much of the device am I using — CLS, LUT, ALU, registers, BSRAM, DSP, I/O?

  • Which package pin is each port on, with what I/O standard, drive and pull?

  • Which warnings fired, how often, and which clocks are missing a constraint?

  • What did my last change cost me? (gowin_compare diffs two builds, bitstream included.)

  • Is this build good enough to merge? (gowin_check with CI thresholds.)

Related MCP server: forgejo-mcp

Install

Run it from npm, with no install step:

npx -y gowin-mcp

Or build it from the repository:

git clone https://github.com/Papipapito/gowin-mcp.git
cd gowin-mcp
npm install
npm run build

Register it. For Claude Desktop, in claude_desktop_config.json:

{
  "mcpServers": {
    "gowin": {
      "command": "node",
      "args": ["C:\\path\\to\\gowin-mcp\\dist\\index.js"]
    }
  }
}

For Claude Code:

claude mcp add gowin -- node /path/to/gowin-mcp/dist/index.js

Tools

Tool

Purpose

gowin_summary

Device, resources, fMax, timing status and violations, bitstream header, what the .sdc declares — in one call. Start here.

gowin_check

CI gate: pass / fail / unknown with the reason, optional thresholds, per-clock fMax waivers.

gowin_timing

fMax per clock, total negative slack, worst setup/hold paths, recovery/removal summary.

gowin_resources

Full resource tables, including I/O banks and clock resources.

gowin_pins

Port → package pin, bank, I/O type, drive, pull, dual-function role; global clock routing.

gowin_warnings

Synthesis and PnR log diagnostics grouped by code, with hints; clocks missing a constraint.

gowin_compare

Diff two builds: resource deltas, fMax deltas, violations introduced/fixed, same bitstream or not.

gowin_list_builds

Find every Gowin build under a directory tree (reads only report headers, so it is fast).

Every tool returns a compact text rendering by default. Pass format: "json" for the full data: the JSON comes back as the text and as structuredContent. (No tool declares an MCP outputSchema: declaring one obliges the server to return structuredContent on every call, and clients that understand it then show the JSON instead of the text.) The shapes are documented in src/schemas.ts and the tests hold the JSON to them. All tools are annotated read-only, idempotent and non-destructive.

Paths are forgiving: pass the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt, with either kind of slash. When one impl/pnr/ holds several builds (one per Gowin project file) the most recently written report is used and the others are named in the text and in the JSON (siblings, note); pass name to pick one explicitly. A name that does not match the .rpt.txt you pointed at is an error, not a silent substitution.

gowin_check and the unknown status

Timing has three outcomes, not two:

status

meaning

pass

A timing report was read and shows no violation.

fail

At least one violation, or a threshold breached.

unknown

Timing could not be verified: neither _tr_content.html nor <name>.tr exists (the timing engine did not run), the report layout was not recognised, or it lists no clocks at all (nothing constrained).

unknown is never reported as clean. The JSON carries status and reason; the text starts with UNKNOWN — timing not verified: ….

For CI, gowin_check also takes:

  • maxUtilization — fail when CLS, Logic or BSRAM utilization exceeds this percentage. The percentage is recomputed from used/available (the tool's own column is rounded: 29142/29952 is 97.30 %, reported as 98 %); when the two differ the rounded figure is quoted next to it;

  • minFmaxMarginMhz — fail when any clock achieves less than constraint + this margin;

  • failOnMissingTiming — default true; set false to accept an unknown build on resources alone;

  • ignoreCrossDomain — default false; set true when the paths between clock domains are declared false paths in the .sdc (see TNS versus paths);

  • fmaxWaivers — clock names (or globs with * and ?) whose fMax-only violation is waived (see fMax versus multicycle paths).

The result's ok field is the decision to act on (status says what is known, ok says whether to accept the build); reasons lists why; ignoredViolations lists what the options set aside, with a note each.

Example

Build: project  (GW5AT-60, GW5AT-LV60PG484AC1/I0)
Tool:  V1.9.11.03 Education
Built: Thu Jul 16 20:58:03 2026   PnR 0h 3m 29s   peak 1848MB
Bitstream: 0xDE97 checksum, body sha256 baffbcb9fa04… (Thu Jul 16 20:57:51 2026)

Resources
  Logic: 28034/59904 (47%)
    LUT 21883, ALU 3325, ROM16 0
  CLS: 19618/29952 (66%)
  Register: 15014/60780 (25%)
  BSRAM: 73/118 (62%)
  DSP: 10.5/118 (9%)
  I/O Port: 141/297 (48%)

Timing: 3 VIOLATIONS
  setup clk_54m    -1.826 ns  1 endpoint failing setup — worst path -1.826 ns:
                              cpu1/u0/ISet_1_s87/Q -> mem1/ram_busy_s0/CE
  setup clk_hdmi   -0.378 ns  ...
  hold  clk_27m    -0.028 ns  ...

fMax per clock
  clk_54m: 33.548 MHz vs 53.996 MHz constraint (-20.448) [FAIL]
  clk_hdmi: 72.221 MHz vs 74.25 MHz constraint (-2.029) [FAIL]
  clk_108m: 159.744 MHz vs 107.991 MHz constraint (+51.753) [ok]
  ...

A gate with thresholds:

FAIL — CLS at 76.34% (77% as the tool rounds it) exceeds maxUtilization 50%
  threshold utilization CLS at 76.34% (77% as the tool rounds it) exceeds maxUtilization 50%
  threshold fmaxMargin  clk_eng margin 13.974 MHz is below minFmaxMarginMhz 20 (53.974 vs 40 MHz)

An fMax shortfall with a clean TNS, before and after the waiver:

FAIL — 1 timing violation

Timing: 1 VIOLATION
  fmax  clk_54m   -21.541 MHz  32.455 MHz achieved against a 53.996 MHz constraint, with no
        setup violation reported (setup TNS 0.000). 18 set_multicycle_path commands in the
        .sdc name this clock; 2 of its reported setup paths are half-cycle relations (launch
        and capture on opposite edges). Gowin derives fMax from the worst path's relation
        minus its slack as if that were a single period, so paths under a multicycle or
        half-cycle relation pull the figure below the constraint although they meet it. If
        that is the case here, waive it with fmaxWaivers; otherwise check that the constraint
        covers the domain.
PASS — no timing violations
  ignored fmax clk_54m -21.541 MHz
  note: 1 fMax-only violation waived (fmaxWaivers=["clk_54m"]): clk_54m (-21.541 MHz). Only safe
        when the clock's setup TNS is 0 and the shortfall is how Gowin reports its multicycle or
        half-cycle paths; a TNS violation is never waived.

Warnings, grouped:

demo: 0 errors, 192 warnings (synthesis 186, pnr 6)
  WARN  EX3791 x70   [synthesis] Expression size 8 truncated to fit in target size 7  @ opl3/afifo.v:144, ... +17 more
        -> Right-hand side wider than the target: upper bits are silently dropped.
  WARN  TA1132 x3    [pnr] 'u_top/u_div5m4/CLKOUT.default_gen_clk' was determined to be a clock but was not created.
        -> A net drives clock pins but has no create_clock / create_generated_clock in the .sdc, ...

Clocks without a constraint (TA1132)
  u_top/u_div5m4/CLKOUT.default_gen_clk   <- also "no timing paths" in the timing report

Pins, filtered with a glob:

8 of 102 ports; 121 package pins, 19 unused
  tmds_clk_p             pin 33/5    out  LVCMOS33D  pull NONE  drive 8  IOB24[A]  pair tmds_clk_n
  tmds_data_p[0]         pin 35/4    out  LVCMOS33D  pull NONE  drive 8  IOB30[A]  cfg GCLKT_4  pair tmds_data_n[0]

What it reads

File

Used for

impl/pnr/<name>.rpt.txt

Device, tool version, resource tables, PnR runtime, pinout (sections 6-8)

impl/pnr/<name>_tr_content.html

fMax, total negative slack, setup/hold/recovery/removal path tables

impl/pnr/<name>.tr

The same timing report as plain text; read when the HTML is missing (V1.9.12.04 writes it on every run)

impl/pnr/<name>.fs

Bitstream header (tool version, device, CheckSum, UserCode, Created Time) and a SHA-256 of the body without the // header

impl/pnr/<name>.log

PnR warnings and errors (TA*, PR*, CT* codes)

impl/gwsynthesis/<name>.log

Synthesis warnings and errors (EX*, NL*, DI*, CV* codes)

the .sdc named in the report

Clocks, set_multicycle_path, set_false_path, set_clock_groups — only to explain an fMax shortfall; found at the reported path or by file name under the project. A header of --- means the build has none.

<name>.tr.html is only a ~350-byte frameset wrapper — the data is in the _tr_content sibling.

Tables are parsed structurally (tr/td in HTML, column names in the text tables, the ==== rule's column spans in the .tr), not by position, so a column added between tool versions — the CFG column that appeared in the pinout around V1.9.10 — surfaces as a missing field rather than a silently misaligned number.

Scope

This server reads results. It does not run builds.

A GW5A place & route takes minutes, which does not fit an MCP request, and driving long builds through a tool call hides their output. Keep building with gw_sh, make, or the Gowin GUI as you already do — then point this at the results.

Verified against

The parsers were run over 167 real builds (October 2026) with no parse failures, and 0.2.2 gives the same verdicts and violations as 0.2.1 on every one of them:

Verified

Tool versions

V1.9.8.10, V1.9.8.11, V1.9.9, V1.9.9 Beta-4, V1.9.9.03, V1.9.10.03, V1.9.11, V1.9.11.01, V1.9.11.02, V1.9.11.03, V1.9.12.02_SP2, V1.9.12.03, V1.9.12.04 (Education and 64-bit editions)

Devices

GW1NR-9 (Tang Nano 9K), GW2A-18 (Tang Primer 20K), GW2AR-18 (Tang Nano 20K), GW5A-25 (Tang Primer 25K), GW5AT-60 (Tang Console 60K)

Host

Windows 11

Known gaps:

  • Only the proprietary Gowin EDA flow. Output from the open-source chain (yosys / nextpnr-himbaechel / apicula) is a different format and is not parsed.

  • Only English-language reports.

  • Power reports (*.power.html) are written by the tool but not read yet.

  • The .tr and the HTML of the same build agree on everything except the third decimal of some fMax figures (Gowin rounds the two files differently by 0.001 MHz).

  • The unit tests run on trimmed fixtures from five of those builds (V1.9.12.04, V1.9.12.03 on GW2AR-18 and GW5AT-60, V1.9.11.03 and V1.9.9); the full matrix above was exercised manually.

Failures should be visible rather than silent: fields that do not parse come back absent, timing that cannot be verified comes back unknown. If you get a missing or implausible number, please open an issue with the offending .rpt.txt or _tr_content.html attached.

Notes

TNS versus paths

Gowin's Total Negative Slack summary is per clock, and it leaves out paths whose launch and capture clocks differ. A design can therefore show every TNS row at 0.000 and every fMax above its constraint while the setup table opens with a -2.09 ns path from clock_54m to clock_27m. The GUI's summary page says clean; the design is not.

Violations are collected from both places:

  • TNS summary (source: "tns"): complete for what it counts, since the path tables are capped by -max_paths at report time and would under-report a design with many failures.

  • Path tables (source: "paths"): every setup or hold path with negative slack whose clock pair no negative TNS row of the same kind accounts for. One violation per (from clock, to clock) pair, with clock rendered as from -> to, amount the worst slack, and pathCount the number of such paths — a lower bound, because of the cap. crossDomain is true when the clocks differ.

Cross-domain violations fail gowin_check by default. Whether they are real depends on the constraints: a crossing that goes through a synchroniser or an asynchronous FIFO should be declared with set_false_path or set_clock_groups -asynchronous in the .sdc, after which the timing engine stops reporting it. If the .sdc already declares them and the paths still show, or the crossing is known to be safe, pass ignoreCrossDomain: true: the violations are then listed under ignoredViolations with a note, and do not affect status. A violation the TNS does count is never ignored.

Of 159 local builds checked when this was added, 45 had negative paths the TNS left out; 30 of them had been reported as clean before.

fMax versus multicycle paths

Gowin's Max Frequency summary derives each clock's fMax from its worst path's relation minus slack, as if that were one clock period. A path under set_multicycle_path -end 2 has a relation of two periods; a path launched on one edge and captured on the other has half a period. Either way the figure lands below the constraint although every endpoint meets it — which is exactly what the clock's 0.000 setup TNS says. A GW5AT-60 build with a Z80 on clk_54m and multicycle constraints on its register file reads 32.455 MHz against 53.996 with a clean TNS.

Such a clock is reported as an fMax-only violation (source: "fmax"), which is only raised when no setup violation already covers the clock. Its detail quotes the setup TNS, how many set_multicycle_path / set_false_path commands in the .sdc name the clock, and how many of its reported setup paths are half-cycle relations (fromEdge ≠ toEdge). When that evidence is there, waive the clock with fmaxWaivers: ["clk_54m"]: the violation moves to ignoredViolations with a note, and minFmaxMarginMhz does not re-flag it. When it is not, the constraint probably does not cover the domain. A TNS violation on the same clock is never waived.

Other

  • Recovery and removal paths (asynchronous set/reset checks) are parsed into their own arrays and never mixed into the hold table.

  • gowin_compare across different devices reports the numbers but does not classify violations (comparable: false, safe: null): a violation only one side has belongs to another design, not to the change.

  • The bitstream body hash ignores the // header, so a rebuild that changed nothing but Created Time shows sameBitstream: true.

Development

npm run build      # tsc -> dist/
npm test           # node:test over tests/fixtures (62 tests)
node tests/stdio.mjs <path-to-a-real-build>   # drive the server over stdio
node tests/smoke.mjs <path-to-a-real-build>   # parse one build and print what was read

See CHANGELOG.md for what each release changed.

License

GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See LICENSE.

You can use it freely, including at work. If you distribute a modified version, or offer it to others as a service, you must publish your changes under the same license.

Releases up to and including 0.2.0 were published under the MIT License and remain available under those terms.

Available Tools

8 tools
gowin_checkBuild gateA
Read-onlyIdempotent

Pass/fail/unknown gate for CI. Lists timing violations with the offending path for each, plus optional thresholds on utilization and fMax margin. Negative paths between clock domains count as violations even though Gowin leaves them out of the TNS summary (set ignoreCrossDomain when they are declared false paths). A clock whose fMax misses its constraint while its setup TNS is 0 is reported as an fMax-only violation with the .sdc evidence (multicycle / half-cycle relations); waive it per clock with fmaxWaivers. "unknown" means timing could not be verified (no _tr_content.html or .tr, unrecognised report, or no clocks analysed) and is never a pass.

NameRequiredDescriptionDefault
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
fmaxWaiversNoClock names (or globs with * and ?) whose fMax-only violation is waived: fMax below the constraint with a setup TNS of 0, which is how Gowin reports a clock covered by set_multicycle_path or half-cycle paths. Listed under ignoredViolations; a TNS violation on the clock is never waived.
maxUtilizationNoFail when CLS, Logic or BSRAM utilization exceeds this percentage (recomputed from used/available, not the rounded column).
minFmaxMarginMhzNoFail when any clock achieves less than constraint + this many MHz.
ignoreCrossDomainNoDefault false. Set true when the paths between clock domains are declared false paths (set_false_path / set_clock_groups in the .sdc): their negative slack is then listed but does not fail the gate.
failOnMissingTimingNoDefault true: an unknown timing status fails the gate. Set false to accept on resources alone.

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the read-only, idempotent, safe profile, and the description goes well beyond them: it defines what counts as a violation (cross-domain paths Gowin omits from TNS), explains the fMax-only violation case with .sdc evidence, and gives full semantics of the 'unknown' status (no report/tr file, unrecognised report, no clocks) and that it is never a pass.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose ('Pass/fail/unknown gate for CI'), then structured around violation types and the unknown semantics. It is dense and parenthesis-heavy, but nearly every sentence carries actionable semantics rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex gating tool with 8 parameters, no output schema, and high schema coverage, the description supplies the decision-relevant context: violation classes, waiver behavior, and unknown-status handling. It does not describe the shape of the returned violation list, but the read-only gate is otherwise well specified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the individual property descriptions are already detailed, so the baseline is 3. The description restates the rationale behind fmaxWaivers and ignoreCrossDomain rather than adding syntax or value ranges beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: a pass/fail/unknown gate for CI, with concrete outputs (timing violations plus offending paths, utilization and fMax thresholds). The gate framing implicitly separates it from reporting siblings like gowin_timing or gowin_summary, but no sibling is named to make the distinction explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'for CI' and by the conditional parameter notes (set ignoreCrossDomain when paths are declared false paths; waive with fmaxWaivers). There is no explicit when-to-use-this-vs-gowin_timing guidance or prerequisite statement, so the agent must infer the CI-gate role.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_compareCompare buildsA
Read-onlyIdempotent

Diff two builds: resource deltas, fMax change per clock, which violations were introduced, fixed, or persist, and whether the two .fs bitstreams have the same body. Use this to see what a change actually cost. Builds on different devices are reported but not classified (safe is null).

NameRequiredDescriptionDefault
afterYesNew build path.
beforeYesBaseline build path.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
afterNameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
beforeNameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/idempotent/non-destructive/closed-world, so the bar is lower; the description adds substantive semantics beyond that, namely the violation taxonomy (introduced/fixed/persist) and the important edge case that cross-device comparisons are reported but leave safe as null. It doesn't cover error behavior for missing or unreadable build paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, densely front-loaded: the comparison contents come first, the intended use second, and the cross-device caveat last. Every clause carries information an agent needs at selection time.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of describing what comes back, and it does list the diff categories well. It stops short of describing the overall response shape or how the text vs json format differs in content, though the format parameter's schema description partially compensates.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the schema already documents before/after, format, and the afterName/beforeName sibling-selection behavior in detail. The description only implicitly reinforces the two-build relationship and says nothing about afterName/beforeName naming or the text/json format switch, so it adds little beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (diff) and resource (two builds), then enumerates exactly what the delta covers: resource deltas, fMax change per clock, violation classification, and bitstream body equality. This distinguishes it cleanly from siblings like gowin_summary, gowin_timing, and gowin_resources, which report on a single build.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this to see what a change actually cost" gives a clear motivating context, and the cross-device caveat signals when the classification will be unavailable. However, it doesn't explicitly name alternative tools (e.g., gowin_summary for viewing a single build) for an agent that has no before/after pair to compare.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_list_buildsList Gowin buildsA
Read-onlyIdempotent

Find Gowin EDA builds under a directory tree. Returns project name, device, and when each was built, newest first.

NameRequiredDescriptionDefault
rootYesDirectory to search.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
maxDepthNoSearch depth, default 8.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, so the safety profile is covered. The description adds useful context by specifying result ordering (newest first) and the fields returned, but says nothing about recursion cost, depth-explosion risk, or behavior on a missing/inaccessible root.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the action and scope come first, the return contract second. Every clause carries information and none restates the tool name or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, single-required-param discovery tool with no output schema, the description supplies exactly the missing piece — what a result contains and how it is ordered. Combined with the fully covered schema and annotations, nothing an agent needs to invoke it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% — root, format, and maxDepth are each documented in the schema, including the text/json rendering distinction and the default depth of 8. The description's 'under a directory tree' only loosely restates the root parameter and adds no syntax or format detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Find Gowin EDA builds'), scopes it to 'under a directory tree', and enumerates the returned fields (project name, device, build time). It never distinguishes itself from siblings like gowin_check or gowin_summary, so it is clear but not sibling-differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: an agent infers this is the discovery step for locating builds before drilling into gowin_timing or gowin_pins. No explicit when-to-use, when-not-to-use, or named alternative is given, so the routing burden falls entirely on the sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_pinsPin assignmentB
Read-onlyIdempotent

Pin assignment as placed: every top-level port with its package pin, bank, I/O standard, drive, pull mode and dual-function role, plus the global clock routing. Filter by port name (substring or glob).

NameRequiredDescriptionDefault
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
portNoOnly ports whose name contains this text, or matches it as a glob (* and ?). Case-insensitive. Package pins are filtered by their signal the same way.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
includeClocksNoInclude the global clock routing table. Default true.
includeUnusedNoAlso list package pins with no signal on them. Default false.

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish this as a read-only, idempotent, non-destructive, closed-world tool, so safety needs no restating. The description adds useful content-level context about what appears in the report (banks, I/O standards, dual-function roles) and that clock routing is included, but says nothing about error behavior or handling of ambiguous build paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, with the purpose and reported fields front-loaded before the filtering note. The field enumeration is long but each item is informative rather than decorative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully tells the agent what the return contains and that clock routing and unused pins are options. Combined with 100% parameter documentation and full annotations, an agent has nearly everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters including the glob/substring matching and the includeClocks/includeUnused defaults. The description's filter sentence largely duplicates the port parameter rather than adding new semantics; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (pin assignment as placed) and enumerates exactly what it reports: package pin, bank, I/O standard, drive, pull mode, dual-function role, and clock routing. That is clearly distinct from siblings like gowin_timing or gowin_resources, though no sibling is named explicitly, which is what a 5 would require.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no statement of when to use this report versus gowin_resources, gowin_timing, or gowin_summary, and no prerequisites. The only procedural hint is how to scope results by port name, which is filtering mechanics rather than usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_resourcesResource usageB
Read-onlyIdempotent

Full resource usage for one build: logic, CLS, registers, BSRAM, DSP, I/O banks and clock resources.

NameRequiredDescriptionDefault
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
includeBanksNoInclude the I/O bank and clock resource tables. Default true.

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, non-destructive and closed-world, so the safety profile need not be repeated. The description adds the report's contents but says nothing about preconditions (a completed build must exist on disk) or failure behavior for a bad path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One compact sentence with the scope ('one build') front-loaded and no filler. It is efficient, though a bare noun phrase with no verb leaves the action slightly implicit.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description partially compensates by enumerating the data categories returned, and annotations cover safety. But error conditions, path-precondition behavior, and the text-vs-json output difference are left entirely to the schema descriptions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with rich per-parameter docs for path, name, format and includeBanks, so the schema carries the meaning. The description adds no parameter-level detail at all, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names the specific resource ('resource usage for one build') and enumerates the exact metrics returned (logic, CLS, registers, BSRAM, DSP, I/O banks, clock resources), so an agent can tell this apart from gowin_timing or gowin_pins by content. However it never explicitly contrasts itself with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the agent infers 'call this when you need resource/utilization data for a build.' There is no explicit when-to-use, when-not-to-use, or pointer to alternatives like gowin_summary or gowin_compare, which likely overlap in scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_summaryBuild summaryA
Read-onlyIdempotent

Headline report for one build: device, resource usage, fMax per clock, every timing violation, the bitstream header (.fs) and what the .sdc declares. Start here.

NameRequiredDescriptionDefault
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so the safety profile is covered. The description adds context about report contents but nothing about cost, file-access requirements, or failure modes (e.g. what happens if the path contains no build), so it stays at baseline.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One dense content-enumerating sentence followed by 'Start here.' — zero waste, front-loaded with the tool's role before the field list, and no redundancy with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully previews the return payload (device, resources, fMax, violations, .fs header, .sdc contents), which is what an agent needs to decide to call it. The only gap is routing guidance against the other seven gowin_* tools, which is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema itself carries rich guidance (defaults, the multi-build naming rule, accepted path forms, slash flexibility, format semantics), so the description is not required to compensate. It adds no parameter detail of its own, which is acceptable here — baseline plus the strong schema warrants a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb+resource ('Headline report for one build') and enumerates the concrete contents (device, resource usage, fMax per clock, timing violations, .fs header, .sdc declarations), so an agent knows exactly what it returns. It does not explicitly differentiate itself from siblings like gowin_timing or gowin_resources, which are subsets of this report.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Start here' is an implied-usage hint suggesting this is the entry point, which is directionally useful. But it never states when to prefer a narrower sibling such as gowin_timing or gowin_resources for depth, nor any preconditions other than the shared 'one build' scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_timingTiming detailA
Read-onlyIdempotent

Timing detail for one build: fMax per clock, total negative slack, the worst setup/hold paths with their endpoints, and a summary of the recovery/removal checks. The path tables are trimmed to the worst maxPaths entries in both renderings; paths="all" returns every parsed path, paths="none" only the summaries plus worstSetup/worstHold.

NameRequiredDescriptionDefault
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
pathsNoworst (default): the maxPaths worst of each table; all: every parsed path; none: no path tables.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
maxPathsNoWorst paths to keep per table (text and JSON), default 10.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, so safety is covered. The description adds real value beyond that by disclosing the returned content, the maxPaths trimming behavior, and the distinction between text and JSON renderings.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the returned content, then the trimming and paths-mode behavior. No filler; every clause earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description carries the return-shape burden and does so thoroughly, naming the metrics and tables returned. With annotations covering safety and the schema covering parameters, nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description goes further by describing the cross-parameter interaction (paths=\"all\" vs \"none\" and trimming to worst maxPaths in both renderings), which is not fully captured in the schema's per-parameter text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (timing detail for one build) and enumerates exactly what it contains: fMax per clock, total negative slack, worst setup/hold paths with endpoints, and recovery/removal summaries. This distinguishes it cleanly from siblings like gowin_summary and gowin_check.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context by explaining what paths="all" versus "none" yield and how the tables are trimmed, which guides invocation. It does not, however, explicitly say when to prefer this tool over siblings such as gowin_check or gowin_summary, so a routing statement is missing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

gowin_warningsSynthesis and PnR warningsA
Read-onlyIdempotent

WARN/ERROR lines from impl/gwsynthesis/.log and impl/pnr/.log grouped by diagnostic code, with a hint for the common ones. Cross-checks TA1132 (clock detected but not created) against the timing report to list clocks that are missing a constraint.

NameRequiredDescriptionDefault
codeNoOnly this diagnostic code, e.g. TA1132.
nameNoWhen several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.
pathYesPath to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash.
levelNoMinimum severity. Default all.
stageNoWhich log to read. Default all.
formatNoOutput format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.
maxGroupsNoCodes to show in the text rendering, default 15.

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe read-only/idempotent/non-destructive profile, and the description adds genuinely new behavior: diagnostics are grouped by code, common codes get a hint, and the tool cross-reads the timing report to flag clocks missing a constraint. It does not describe pagination or output size limits, but for an annotated read tool this is useful added context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences that lead with the core extraction behavior and then the special TA1132 cross-check. No filler, no repetition of the schema, and the most distinctive behavior is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 7 parameters and no output schema, the description must sketch the return shape, and it does: results grouped by diagnostic code with hints, plus the extra missing-constraint clock list. It is nearly complete, though it could say more about the text vs json payload and grouping limits.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter (code, name, path, level, stage, format, maxGroups) including defaults and enums. The description adds little parameter-level meaning beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb and resource: it extracts WARN/ERROR lines from the synthesis (impl/gwsynthesis/<name>.log) and PnR (impl/pnr/<name>.log) logs, grouped by diagnostic code. That is far more specific than a generic 'get warnings', but it never names or contrasts a sibling tool (e.g. gowin_summary or gowin_timing), so it stops short of explicit differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the purpose and by the mention of cross-checking TA1132 against the timing report. There is no explicit statement of when to reach for this tool versus gowin_summary, gowin_timing, or gowin_check, and no exclusions or prerequisites.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 8 tool updatesv0.2.2
    • Changedgowin_check9 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / failOnMissingTiming
        Added value: +{
        +  "description": "Default true: an unknown timing status fails the gate. Set false to accept on resources alone.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / fmaxWaivers
        Added value: +{
        +  "description": "Clock names (or globs with * and ?) whose fMax-only violation is waived: fMax below the constraint with a setup TNS of 0, which is how Gowin reports a clock covered by set_multicycle_path or half-cycle paths. Listed under ignoredViolations; a TNS violation on the clock is never waived.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / properties / format / description
        Previous value: -"Output format. Defaults to text, which is far more compact."New value: +"Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent."
      • addedInput schema / properties / ignoreCrossDomain
        Added value: +{
        +  "description": "Default false. Set true when the paths between clock domains are declared false paths (set_false_path / set_clock_groups in the .sdc): their negative slack is then listed but does not fail the gate.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / maxUtilization
        Added value: +{
        +  "description": "Fail when CLS, Logic or BSRAM utilization exceeds this percentage (recomputed from used/available, not the rounded column).",
        +  "maximum": 100,
        +  "minimum": 0,
        +  "type": "number"
        +}
      • addedInput schema / properties / minFmaxMarginMhz
        Added value: +{
        +  "description": "Fail when any clock achieves less than constraint + this many MHz.",
        +  "type": "number"
        +}
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • changedInput schema / properties / path / description
        Previous value: -"Path to the build: the project directory, its impl/ directory, or the .rpt.txt itself."New value: +"Path to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash."
    • Changedgowin_compare4 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / afterName
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • addedInput schema / properties / beforeName
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • changedInput schema / properties / format / description
        Previous value: -"Output format. Defaults to text, which is far more compact."New value: +"Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent."
    • Changedgowin_list_builds2 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • addedInput schema / properties / format
        Added value: +{
        +  "description": "Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent.",
        +  "enum": [
        +    "text",
        +    "json"
        +  ],
        +  "type": "string"
        +}
    • Addedgowin_pins
    • Changedgowin_resources5 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • changedInput schema / properties / format / description
        Previous value: -"Output format. Defaults to text, which is far more compact."New value: +"Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent."
      • changedInput schema / properties / includeBanks / description
        Previous value: -"Include the I/O bank and clock resource tables."New value: +"Include the I/O bank and clock resource tables. Default true."
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • changedInput schema / properties / path / description
        Previous value: -"Path to the build: the project directory, its impl/ directory, or the .rpt.txt itself."New value: +"Path to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash."
    • Changedgowin_summary4 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • changedInput schema / properties / format / description
        Previous value: -"Output format. Defaults to text, which is far more compact."New value: +"Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent."
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • changedInput schema / properties / path / description
        Previous value: -"Path to the build: the project directory, its impl/ directory, or the .rpt.txt itself."New value: +"Path to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash."
    • Changedgowin_timing6 fields changed
      • addedInput schema / $schema
        Added value: +"http://json-schema.org/draft-07/schema#"
      • changedInput schema / properties / format / description
        Previous value: -"Output format. Defaults to text, which is far more compact."New value: +"Output format. Default text: a compact rendering, returned as the only content. json: the full JSON as text and as structuredContent."
      • changedInput schema / properties / maxPaths / description
        Previous value: -"Worst paths to show, default 10."New value: +"Worst paths to keep per table (text and JSON), default 10."
      • addedInput schema / properties / name
        Added value: +{
        +  "description": "When several builds share one impl/pnr/, pick this one by name (the <name> of <name>.rpt.txt). Default: the most recent, with the others listed under siblings.",
        +  "type": "string"
        +}
      • changedInput schema / properties / path / description
        Previous value: -"Path to the build: the project directory, its impl/ directory, or the .rpt.txt itself."New value: +"Path to the build: the project directory, its impl/ directory, impl/pnr/ itself, or the .rpt.txt. Either kind of slash."
      • addedInput schema / properties / paths
        Added value: +{
        +  "description": "worst (default): the maxPaths worst of each table; all: every parsed path; none: no path tables.",
        +  "enum": [
        +    "worst",
        +    "all",
        +    "none"
        +  ],
        +  "type": "string"
        +}
    • Addedgowin_warnings
  2. 6 tool updatesv0.1.0-beta.1
    • First observedgowin_check
    • First observedgowin_compare
    • First observedgowin_list_builds
    • First observedgowin_resources
    • First observedgowin_summary
    • First observedgowin_timing

TDQS

A3.8/5.0

Scored across 8 tools

Disambiguation4/5

Each tool targets a distinct artifact or question: build discovery, headline summary, resources, timing, comparison, pins, warnings, and a CI gate. The main soft overlap is gowin_summary versus gowin_resources/gowin_timing, and gowin_check versus gowin_timing, but the descriptions explicitly position summary as the entry point and check as the pass/fail gate, which resolves most confusion.

Naming Consistency4/5

All tools share a consistent gowin_ prefix and snake_case, with predictable domain nouns (resources, timing, pins, warnings, summary). A few names use verb forms (check, list_builds, compare) while others are bare nouns, a minor deviation that does not harm readability.

Tool Count5/5

Eight tools is well-scoped for an FPGA build-analysis server: one discovery tool, four detail views, one diff, one log/pin reader, and one CI gate. No tool feels redundant or missing at this scale.

Completeness4/5

The surface covers the full read-only analysis lifecycle: find builds, summarize, drill into resources/timing/pins, compare builds, triage warnings, and gate CI. Gaps are minor, e.g. no tool to dump raw report/log files or inspect the .sdc directly beyond what summary reports.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers