Portable RTL Lint MCP
This package moves the RTL lint engine out of a VS Code extension and exposes one stable service to every client:
Codex / VS Code / Cursor / another MCP IDE
|
MCP protocol
+-----------+------------+
| |
stdio (local) Streamable HTTP (remote)
| |
+------ rtl_lint_mcp ----+
|
shared lint service
|
Verilog / SystemVerilog files
KRutrim can use the same service through its existing custom
/api/mcp/invoke dispatcher or, after it gains a standard MCP registry, by
connecting to the remote /mcp endpoint.
Why this is portable
- The lint engine is a normal Python package, not stored inside an IDE extension.
- The official MCP Python SDK handles protocol messages and tool schemas.
- Local IDEs use
stdio; deployed clients use Streamable HTTP. - CLI, MCP, VS Code, and KRutrim receive the same
rtl-lint-report.v1schema. - File access is restricted by
RTL_LINT_ALLOWED_ROOTS. - There are no repository-specific absolute paths in the implementation.
Tools
list_rtl_lint_ruleslint_rtl_textlint_rtl_filelint_rtl_project
Requirements
- Python 3.10 or newer. KRutrim currently reports Python 3.11.13, so it meets this requirement.
uvis recommended, but a Python virtual environment also works.
Install
With uv
cd tools/rtl-lint-mcp-portable
uv sync
With a virtual environment
cd tools/rtl-lint-mcp-portable
python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install -e .
For the optional KRutrim Flask bridge:
python3 -m pip install -e '.[krutrim]'
Local CLI smoke test
The server rejects file paths outside its allowlist. Set the project root before running a file or project check:
export RTL_LINT_ALLOWED_ROOTS=/path/to/rtl/project
rtl-lint /path/to/rtl/project/rtl/top.sv --fail-on never
JSON output:
rtl-lint /path/to/rtl/project/rtl/top.sv --json --fail-on never
Local MCP for any IDE
Run over stdio:
export RTL_LINT_ALLOWED_ROOTS=/path/to/rtl/project
rtl-lint-mcp
Normally the IDE starts this command itself. Use
configs/generic-stdio.json as the base for any
client that accepts an mcpServers configuration.
Codex
From this directory:
codex mcp add rtl-lint \
--env RTL_LINT_ALLOWED_ROOTS=/path/to/rtl/project \
-- uv run --project /absolute/path/to/rtl-lint-mcp-portable rtl-lint-mcp
Verify:
codex mcp list
Start a new Codex conversation, then ask:
Use the RTL lint MCP to lint /path/to/rtl/project/rtl/top.sv.
VS Code / GitHub Copilot Chat
Copy configs/vscode-mcp.json to
.vscode/mcp.json, replace the package path, and open the folder in VS Code.
Use MCP: List Servers to start and inspect it. In Remote SSH, install/run
the server on the remote host so the MCP process can see the remote RTL path.
Other IDEs
For Cursor, Claude-compatible clients, and other MCP hosts, start from
configs/generic-stdio.json. Replace:
- the absolute package path;
RTL_LINT_ALLOWED_ROOTSwith the RTL workspace;uvwith the environment's full executable path when necessary.
Remote Streamable HTTP server
Run the same MCP as a network service:
export RTL_LINT_ALLOWED_ROOTS=/ws:/auto
rtl-lint-mcp --transport streamable-http \
--host 0.0.0.0 \
--port 8765 \
--allowed-host fpga-vm-bgl002.cisco.com:8765
Endpoint:
http://fpga-vm-bgl002.cisco.com:8765/mcp
If a browser calls the endpoint directly, also allow the KRutrim origin:
--allowed-origin http://fpga-vm-bgl002.cisco.com:5200
Do not expose the service beyond the Cisco network without authentication and TLS. The hostname/origin allowlist prevents DNS-rebinding attacks; it is not user authentication.
KRutrim integration
The inspected KRutrim service is a Flask application. Its front end calls:
POST /api/mcp/invoke
with payloads containing toolId, action, and target. Its output renderer
uses the first available string among response, answer, completion,
output, or text.
The bridge therefore returns:
{
"output": "Markdown report for the KRutrim panel",
"result": {"schema_version": "rtl-lint-report.v1"},
"backend": "rtl-lint-mcp",
"tool_id": "rtl_lint"
}
See integrations/krutrim/README.md for the
two deployment choices, the small Flask dispatcher patch, and a matching
front-end invocation example.
Docker deployment
docker build -t rtl-lint-mcp:0.2.0 .
docker run --rm -p 8765:8765 \
-v /ws:/workspace:ro \
-e RTL_LINT_ALLOWED_ROOTS=/workspace \
-e RTL_LINT_ALLOWED_HOSTS=fpga-vm-bgl002.cisco.com:8765 \
rtl-lint-mcp:0.2.0
Mount RTL read-only. The linter never needs write access.
Report contract
A single-file call returns a direct report, not a project wrapper:
{
"schema_version": "rtl-lint-report.v1",
"server_version": "0.2.0",
"operation": "lint_file",
"file": "/project/rtl/top.sv",
"issue_count": 1,
"summary": {"error": 1, "warning": 0, "info": 0},
"issues": []
}
This avoids the earlier VS Code integration bug where a caller expected
result.issues but the CLI returned result.files[0].issues.
Test
Core tests need only the standard library:
PYTHONPATH=src python3 -m unittest discover -s tests -v
For protocol testing, install the development environment and use the official MCP Inspector:
uv run mcp dev src/rtl_lint_mcp/server.py
Production checklist
- Keep
RTL_LINT_ALLOWED_ROOTSnarrow and explicit. - Mount repositories read-only for the HTTP service.
- Use TLS and authenticated access for any non-local endpoint.
- Keep the MCP sidecar on an internal interface or behind the KRutrim proxy.
- Add the
rtl_lintdispatch case to KRutrim's existing route. - Add a KRutrim UI action that sends
toolId: rtl_lintand the selected path. - Run the included tests and the MCP Inspector before deployment.
Important limitation
This is a lightweight text-pattern linter. It is useful for early feedback and demonstrations, but it does not replace compilation, synthesis, formal checks, or sign-off lint products.
References
- Official MCP Python SDK: https://py.sdk.modelcontextprotocol.io/
- VS Code MCP configuration: https://code.visualstudio.com/docs/agents/reference/mcp-configuration
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rtl_lint_mcp-0.2.0.tar.gz.
File metadata
- Download URL: rtl_lint_mcp-0.2.0.tar.gz
- Upload date:
- Size: 92.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a1f61c86e1318d861fbef61f275f9106c45900858c94e2c9593db2528622f74
|
|
| MD5 |
2aafde11cb023e9cdda5bc3da5ffd37b
|
|
| BLAKE2b-256 |
3a8fc8c44ac3ae53b7553fee739df306db84e8275126176c0248328e60632c70
|
File details
Details for the file rtl_lint_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: rtl_lint_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c77234a7563cc076460d9fe20fed01e42dab8e6a062b73d487bdf1872d02f301
|
|
| MD5 |
ced01287a335463c8e6a866398b5dac7
|
|
| BLAKE2b-256 |
1a9b98c8fe2b6c394baa0488bde8760a2b8225f93dcc7bed44545430dd670095
|