{
  "markdown": "# pyslang-mcp\n<!-- mcp-name: io.github.ariklapid/pyslang-mcp -->\n\n[![CI](https://github.com/ariklapid/pyslang-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/ariklapid/pyslang-mcp/actions/workflows/ci.yml)\n[![PyPI](https://img.shields.io/pypi/v/pyslang-mcp.svg)](https://pypi.org/project/pyslang-mcp/)\n![Python](https://img.shields.io/badge/python-3.11%20%7C%203.12-blue)\n![Status](https://img.shields.io/badge/status-early--stage-orange)\n![Transport](https://img.shields.io/badge/transport-stdio-informational)\n\n`pyslang-mcp` is a local Model Context Protocol server that gives AI agents\ncompiler-backed, read-only context for Verilog and SystemVerilog projects.\n\nIt wraps [`pyslang`](https://pypi.org/project/pyslang/) so an MCP client can ask\nquestions against parsed and elaborated HDL instead of plain text:\n\n- What modules, interfaces, and packages are in this filelist?\n- What diagnostics does the compiler frontend report?\n- What is the instance hierarchy below this top?\n- Where is this symbol declared or referenced?\n- Did my include paths, defines, and nested `.f` files resolve as expected?\n\nThis is not a simulator, synthesizer, waveform viewer, linter replacement, or\nRTL refactoring tool. It is a small semantic analysis service for local HDL\ncheckouts.\n\nThat read-only boundary is intentional. It keeps the server side-effect free,\nreduces the blast radius in IP-protected workspaces, and makes it safer to use\nin local and CI environments.\n\nIt was decided to keep `pyslang-mcp` read-only. The LLM handles the actual RTL\ncoding, while `pyslang-mcp` serves as the compile/elab-backed reader, checker,\nand explainer for code that already exists. In other words, the model drafts\nthe RTL and the MCP server verifies what the compiler frontend sees.\n\n> [!NOTE]\n> The project is currently early-stage and published on\n> [PyPI](https://pypi.org/project/pyslang-mcp/) and the\n> [MCP Registry](https://registry.modelcontextprotocol.io/?q=pyslang-mcp) for\n> local stdio use.\n\n## Why ASIC And EDA Engineers Might Care\n\nMost AI coding tools are good at searching text. HDL usually needs more than\nthat.\n\nIn real projects, useful answers often depend on filelists, packages, includes,\ndefines, generate blocks, and hierarchy. `pyslang-mcp` gives an agent a compact\ncompiler-backed view of that structure, while keeping the server read-only and\nscoped to a project root you provide.\n\nGood fits:\n\n- triaging parse and semantic diagnostics before asking an agent to reason\n  about RTL\n- checking what a `.f` file expands to\n- listing design units in a block or small IP\n- finding a declaration without chasing comments and stale grep hits\n- getting hierarchy and port-connection context for review/debug prompts\n- giving workflow agents HDL context without handing them an EDA runtime\n\n## Quickstart\n\nInstall the package:\n\n```bash\npip install pyslang-mcp\n```\n\nRun the local stdio server:\n\n```bash\npyslang-mcp\n```\n\nFor contributor setup, clone the repo and install it in editable mode:\n\n```bash\ngit clone https://github.com/ariklapid/pyslang-mcp.git\ncd pyslang-mcp\npython -m venv .venv\n./.venv/bin/pip install -e '.[dev]'\n```\n\nRun the checkout stdio server:\n\n```bash\n./.venv/bin/python -m pyslang_mcp\n```\n\nThe installed console script works too:\n\n```bash\n./.venv/bin/pyslang-mcp\n```\n\nRun tests:\n\n```bash\n./.venv/bin/pytest\n```\n\n## MCP Client Config\n\nUse local `stdio`. The MCP client should launch the server on the same machine,\nVM, or dev container that can see your RTL checkout.\n\n```json\n{\n  \"mcpServers\": {\n    \"pyslang-mcp\": {\n      \"command\": \"pyslang-mcp\",\n      \"args\": []\n    }\n  }\n}\n```\n\nFor editable checkout installs, point the command at the checkout virtual\nenvironment instead:\n\n```json\n{\n  \"mcpServers\": {\n    \"pyslang-mcp\": {\n      \"command\": \"/absolute/path/to/pyslang-mcp/.venv/bin/python\",\n      \"args\": [\"-m\", \"pyslang_mcp\"]\n    }\n  }\n}\n```\n\nTool calls must provide a `project_root`. Source paths, filelists, and include\ndirectories may be absolute or relative, but they must stay under that root.\n\n## Minimal Tool Payloads\n\nAnalyze explicit files:\n\n```json\n{\n  \"project_root\": \"/path/to/rtl-project\",\n  \"files\": [\"rtl/pkg.sv\", \"rtl/top.sv\"],\n  \"include_dirs\": [\"include\"],\n  \"defines\": {\n    \"WIDTH\": \"32\"\n  },\n  \"top_modules\": [\"top\"]\n}\n```\n\nAnalyze a filelist:\n\n```json\n{\n  \"project_root\": \"/path/to/rtl-project\",\n  \"filelist\": \"compile/project.f\"\n}\n```\n\nFind a symbol:\n\n```json\n{\n  \"project_root\": \"/path/to/rtl-project\",\n  \"filelist\": \"compile/project.f\",\n  \"query\": \"payload\",\n  \"match_mode\": \"exact\",\n  \"include_references\": true\n}\n```\n\n## Tools\n\n| Need | Tool |\n|---|---|\n| Load explicit files | `pyslang_parse_files` |\n| Load a `.f` filelist | `pyslang_parse_filelist` |\n| Get parse and semantic diagnostics | `pyslang_get_diagnostics` |\n| List modules, interfaces, and packages | `pyslang_list_design_units` |\n| Inspect one design unit | `pyslang_describe_design_unit` |\n| Walk the elaborated instance tree | `pyslang_get_hierarchy` |\n| Find declarations and references | `pyslang_find_symbol` |\n| Find a local member in one design unit | `pyslang_find_member` |\n| Find assignments involving a signal | `pyslang_get_assignments` |\n| Trace bounded structural connectivity | `pyslang_trace_connectivity` |\n| Dump one instance's port connections | `pyslang_get_instance_connections` |\n| Group diagnostics by code | `pyslang_summarize_diagnostics_by_code` |\n| Summarize syntax node shapes | `pyslang_dump_syntax_tree_summary` |\n| Check preprocessing metadata and excerpts | `pyslang_preprocess_files` |\n| Get a compact project overview | `pyslang_get_project_summary` |\n\nTypical flow:\n\n1. Start with `pyslang_parse_filelist` or `pyslang_parse_files`.\n2. Run `pyslang_get_diagnostics`.\n3. Use `pyslang_list_design_units` to see what the compiler frontend found.\n4. Use `pyslang_describe_design_unit`, `pyslang_get_hierarchy`, or\n   `pyslang_find_symbol` for the actual review/debug question.\n\n## Verilog/SystemVerilog Analysis And Debugging Flow\n\n1. Use `pyslang_summarize_diagnostics_by_code` to separate repeated frontend\n   warnings from unresolved dependency errors.\n2. Use `pyslang_find_member` to locate local names such as `response__vld`.\n3. Use `pyslang_get_assignments` to inspect visible continuous or procedural\n   drivers and loads.\n4. Use `pyslang_get_instance_connections` for one instance's port binding\n   context.\n5. Use `pyslang_trace_connectivity` for bounded structural paths through\n   assignments and instance port bindings.\n\nConnectivity tracing is structural frontend evidence. It is not simulation,\nformal proof, CDC/RDC signoff, timing signoff, or a complete netlist-level\ndriver/load database.\n\n## Filelist Support\n\nThe current parser intentionally supports a practical subset used by many RTL\nflows:\n\n- source file entries\n- nested filelists with `-f` and `-F`\n- include directories with `+incdir+...`, `-I dir`, and `-Idir`\n- defines with `+define+...`, `-D NAME`, and `-DNAME`\n\nUnsupported filelist tokens are reported in the tool output instead of being\nsilently ignored.\n\n## Example Agent Prompts\n\nUse this server when compiler-backed context matters:\n\n- \"Parse `compile/project.f` with `+define+DEBUG` and group diagnostics by\n  source file.\"\n- \"List every design unit in this project and identify the likely top modules.\"\n- \"From `top`, show the instance hierarchy down to depth 4.\"\n- \"Describe module `axi_dma_top`: ports, child instances, and declared names.\"\n- \"Find the declaration and references for `payload_valid`.\"\n- \"Confirm whether `legacy_widget` is instantiated anywhere the elaborator\n  sees it.\"\n- \"Show the resolved files, include dirs, defines, and unsupported entries from\n  this filelist.\"\n\nFor single-line questions, comments, naming searches, or partial/incomplete\nsource sets, regular `rg`, editor search, or direct file reading is usually\nfaster and clearer.\n\n## Guardrails\n\n- Read-only MCP tools. No RTL edits, formatting, simulation, or synthesis.\n- Strict project-root scoping. Paths outside `project_root` are rejected.\n- Compact JSON responses with truncation metadata for large result sets.\n- Process-local cache keyed by project config and tracked file mtimes.\n- `pyslang_preprocess_files` is summary-oriented. It returns preprocessing\n  metadata and source excerpts, not a guaranteed full standalone preprocessed\n  stream.\n- `streamable-http` remains experimental. The internal MaaS path wraps it with\n  a bearer token for single-server use, but it is not a complete production\n  hosted security boundary by itself.\n\n## Remote MaaS Direction\n\nRemote MaaS is planned as two separate tracks, not as one generic hosted mode:\n\n- **Plan A: public OSS MaaS.** A convenience/demo service for public\n  open-source HDL repositories. This is not suitable for proprietary or\n  confidential RTL.\n- **Plan B: internal MaaS.** A self-hosted deployment pattern for companies to\n  run inside their own network, close to internal repositories, auth, logging,\n  and security controls.\n\nStart with the [internal MaaS quickstart](./docs/internal-maas-quickstart.md)\nfor a single internal server. See [REMOTE_DEPLOYMENT.md](./REMOTE_DEPLOYMENT.md)\nfor the full Plan A / Plan B split.\n\nDocker Compose is the recommended bring-up path because it avoids Python setup\nissues and mounts the RTL checkout read-only. Docker is not required; the\nquickstart also includes a native Python path for corporate servers where\ncontainers are not available.\n\n## HDL Example Corpus\n\nThe repo includes generated HDL examples under\n[`examples/hdl`](./examples/hdl/):\n\n- clean reference projects from single modules to small IP-style examples\n- intentionally buggy variants labeled `easy`, `medium`, and `hard`\n- local validation hooks for both `pyslang` and `verilator --lint-only`\n\nRun the full corpus validator:\n\n```bash\n./.venv/bin/python scripts/validate_hdl_examples.py\n```\n\nRun the CI smoke subset:\n\n```bash\n./.venv/bin/python scripts/validate_hdl_examples.py --smoke-only\n```\n\n## Using With Broader RTL Skills\n\nIf your agent environment already has a broad RTL skill such as\n`rtl-analysis`, `rtl-audit`, or `llm-based-verilog-analysis`, use\n`pyslang-verilog-context` as the fine-grained compiler-evidence layer beneath\nthat broader skill.\n\nRecommended setup:\n\n1. Configure the `pyslang-mcp` server in your MCP client so the agent can call\n   the read-only `pyslang_*` tools.\n2. Install or copy the `pyslang-verilog-context` skill from\n   [`skills/pyslang-verilog-context`](./skills/pyslang-verilog-context/).\n3. Add a delegation note like this to your broader RTL skill:\n\n```text\nFor Verilog/SystemVerilog tasks, use $pyslang-verilog-context before making\nclaims about diagnostics, design units, ports, hierarchy, declarations,\nreferences, includes, defines, or filelist behavior. Treat its output as\ncompiler frontend evidence only. Do not present it as simulation, synthesis,\ntiming, CDC/RDC, formal, or full lint signoff.\n```\n\nThe intended flow is:\n\n```text\nuser RTL request\n  -> broad RTL analysis/audit skill\n  -> pyslang-verilog-context\n  -> pyslang-mcp compiler-backed evidence\n  -> final answer with evidence and limitations\n```\n\nThis keeps high-level RTL review policy in the broad skill while grounding\nVerilog/SystemVerilog structure, diagnostics, hierarchy, symbols, includes, and\nfilelists in `pyslang`.\n\n## Evaluation Benchmarks\n\nThe repo includes a `pyslang-verilog-context` skill eval suite under\n[`skills/pyslang-verilog-context/evals`](./skills/pyslang-verilog-context/evals/)\nand comparison reports under [`reports/`](./reports/). The current benchmark\ncompares three local evidence modes:\n\n- text/no skill: source and filelist text heuristics only\n- MCP/no skill: targeted `pyslang-mcp` tool calls\n- skill + MCP: `pyslang-verilog-context` sequencing with `pyslang-mcp`\n\nLatest local result from 2026-06-14:\n\n| Benchmark | Text/no skill | MCP/no skill | Skill + MCP |\n|---|---:|---:|---:|\n| 100 HDL analysis cases | 60/100 | 95/100 | 100/100 |\n\nThe benchmark mixes deterministic repo-local HDL fixtures with real public RTL\nsource files. The local fixtures exercise targeted behaviors such as filelists,\nhierarchy, symbols, diagnostics, clean-frontend functional bugs, and RTL coding\nand bug-audit discipline. The real public RTL cases use source files from\n`lowrisc-ibex`,\n`pulp-common-cells`, `verilog-axis`, `pulp-axi`,\n`pulp-register-interface`, and `picorv32`. They exercise frontend diagnostic\nstatus, design-unit inventory, and first-unit port counts on real source files.\nSee [docs/evaluation-benchmarks.md](./docs/evaluation-benchmarks.md) for the\nprompt/task shapes and MCP functions used.\n\nVerification commands used for the reported run:\n\n```bash\n./.venv/bin/python skills/pyslang-verilog-context/scripts/validate_eval_fixtures.py\n./.venv/bin/python -m pytest\n./.venv/bin/python skills/pyslang-verilog-context/scripts/run_comparison_evals.py\n./.venv/bin/python scripts/run_mcp_comparison.py --output-dir reports/mcp_comparison_comprehensive_20260614\n./.venv/bin/python reports/real_examples_75/run_real75_comparison.py\n./.venv/bin/python -m py_compile reports/real_examples_75/run_real75_comparison.py\n```\n\nThese are deterministic scalar harnesses, not blind autonomous LLM-judge runs.\n`pyslang-mcp` evidence remains frontend/compiler context only, not simulation,\nsynthesis, CDC/RDC, timing, formal, or full lint signoff.\n\nDocumentation-only eval/report updates do not require a PyPI release. A PyPI\nrelease is warranted when package code, public tool behavior, schemas, runtime\ndependencies, CLI behavior, or user-facing install/runtime docs change in a way\npublished users need.\n\n## Project Status\n\nImplemented:\n\n- `FastMCP` stdio server\n- CLI entrypoint via `python -m pyslang_mcp` and `pyslang-mcp`\n- project loader with root checks and `.f` parsing\n- pyslang-backed diagnostics and diagnostic grouping, design-unit and member\n  lookup, assignment and instance-connection analysis, bounded structural\n  connectivity, hierarchy, syntax summaries, and project summaries\n- bounded in-memory cache\n- fixture-backed tests and Ubuntu CI for Python 3.11 and 3.12\n- package smoke CI from a built wheel\n- manual PyPI Trusted Publishing release workflow with release-gate tests\n- PyPI package: [`pyslang-mcp`](https://pypi.org/project/pyslang-mcp/)\n- MCP Registry entry:\n  [`io.github.ariklapid/pyslang-mcp`](https://registry.modelcontextprotocol.io/?q=pyslang-mcp)\n- internal MaaS bring-up artifacts: Dockerfile, Docker Compose config, native\n  Python fallback instructions, systemd template, bearer-token HTTP option, and\n  a single-server quickstart\n\nNot done yet:\n\n- schema freeze for a more mature API-stable release\n- broad platform validation beyond the current Linux-focused CI path\n- production MaaS hardening for broad team use: SSO, multi-workspace routing,\n  Kubernetes deployment, source-safe metrics, and reverse-proxy examples\n\n## Development\n\nUseful commands:\n\n```bash\n./.venv/bin/ruff check .\n./.venv/bin/pyright\n./.venv/bin/pytest\n```\n\nArchitecture and contribution docs:\n\n- [docs/architecture.md](./docs/architecture.md)\n- [docs/internal-maas-quickstart.md](./docs/internal-maas-quickstart.md)\n- [REMOTE_DEPLOYMENT.md](./REMOTE_DEPLOYMENT.md)\n- [docs/mcp-registry.md](./docs/mcp-registry.md)\n- [CONTRIBUTING.md](./CONTRIBUTING.md)\n\n## License\n\nApache-2.0. See [LICENSE](./LICENSE).\n",
  "bytes": 15298,
  "sha": "bc62ae01e38183cc4eebc3c82ef8a4e99a41f1436918cf759416ce6aa8f5daf2",
  "repo_slug": "ariklapid/pyslang-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_ariklapid_pyslang_mcp_3bf6fcf9/readme"
}