Observer-first MCP server for KLayout layout inspection.
Project description
klayout-mcp
MCP server for read-only KLayout inspection: open layouts, inspect hierarchy and geometry, render deterministic views, and run batch DRC decks with structured JSON results.
Features
- Open
gds,gdsii,oas, andoasislayout files - List layers and cell hierarchy
- Query shapes and instances inside a bounding box
- Measure widths, gaps, lengths, overlap, and related geometry
- Render deterministic PNG views
- Run KLayout batch DRC scripts
- Extract DRC markers and optional crop images
- Return structured errors with stable error codes
- Enforce allowlisted roots for layout and DRC inputs
Status
The server is functional over MCP stdio.
Current verification:
- automated suite:
23 passed - live MCP stdio smoke test completed successfully
- exercised against generated fixtures and a real GDS layout
Tested end-to-end flow:
open_layoutlist_layersquery_regionmeasure_geometryrender_viewrun_drc_scriptextract_markersclose_session
Requirements
- Python 3.11+
uvrecommended for environment management- KLayout installed locally
The server uses KLayout's Python bindings for layout inspection and the klayout executable for batch DRC. If the executable is not on PATH, set KLAYOUT_BIN.
On macOS app installs, this is commonly:
export KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout
Install
Published Package
After klayout-mcp is published to PyPI, the simplest ways to run it will be:
uvx klayout-mcp
Or install it once and run the command directly:
uv tool install klayout-mcp
klayout-mcp
For MCP client configuration, this README uses uvx because that is the most common Python MCP pattern.
Source Checkout
For unreleased builds or local development:
uv sync --extra dev
Quick Start
Choose narrow allowlists for the layouts and DRC decks you want the server to access:
export KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS=/abs/path/to/layouts
export KLAYOUT_MCP_ALLOWED_DRC_ROOTS=/abs/path/to/drc-decks
export KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout
Start the server locally from a source checkout:
uv run klayout-mcp
The server speaks MCP over stdio.
Using uv
For Python MCP servers, the common uv patterns are:
uvx <tool>for published servers without a permanent installuv tool install <tool>when you want the command on your machineuv --directory /path/to/repo run <tool>for source checkouts
The recommended client configuration after PyPI release is:
command: uvx
args: klayout-mcp
That matches how many published Python MCP servers are configured in practice.
If your MCP host launches tools with a minimal PATH, replace uvx with its absolute path.
For a local source checkout, use:
command: uv
args: --directory /abs/path/to/klayout-mcp run klayout-mcp
Commit Conventions
This repo uses Conventional Commits and checks them in two places:
- locally with
pre-commiton thecommit-msghook - in GitHub Actions on every push and pull request
Install the local hook once in a source checkout:
uv sync --extra dev
uv run pre-commit install --hook-type commit-msg --install-hooks
Allowed commit types:
buildchorecidocsfeatfixperfrefactorrevertstyletest
Client Setup
All clients below assume the package is published and launched with uvx:
command: uvx
args: klayout-mcp
Recommended environment variables:
KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS=/abs/path/to/layoutsKLAYOUT_MCP_ALLOWED_DRC_ROOTS=/abs/path/to/drc-decksKLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout
If klayout is already on PATH, KLAYOUT_BIN is optional.
Ready-to-copy templates are in:
examples/mcp/codex.config.tomlexamples/mcp/claude-code.mcp.jsonexamples/mcp/cursor.mcp.jsonexamples/mcp/opencode.jsonexamples/mcp/README.md
For a source checkout before the first PyPI release, replace the launcher with:
command: uv
args: --directory /abs/path/to/klayout-mcp run klayout-mcp
Codex
Codex reads MCP servers from ~/.codex/config.toml or project-scoped .codex/config.toml.
[mcp_servers.klayout]
command = "uvx"
args = ["klayout-mcp"]
[mcp_servers.klayout.env]
KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS = "/abs/path/to/layouts"
KLAYOUT_MCP_ALLOWED_DRC_ROOTS = "/abs/path/to/drc-decks"
KLAYOUT_BIN = "/Applications/klayout.app/Contents/MacOS/klayout"
If you prefer the CLI, Codex also supports codex mcp add.
Claude Code
Claude Code supports project-scoped .mcp.json files and user-scoped MCP configuration. For team use, project scope is the clearest option.
Create .mcp.json at the repo root:
{
"mcpServers": {
"klayout": {
"command": "uvx",
"args": ["klayout-mcp"],
"env": {
"KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS": "/abs/path/to/layouts",
"KLAYOUT_MCP_ALLOWED_DRC_ROOTS": "/abs/path/to/drc-decks",
"KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
}
}
}
}
You can also add it from the CLI:
claude mcp add klayout --scope project \
--env KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS=/abs/path/to/layouts \
--env KLAYOUT_MCP_ALLOWED_DRC_ROOTS=/abs/path/to/drc-decks \
--env KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout \
-- uvx klayout-mcp
Cursor
Cursor reads MCP servers from .cursor/mcp.json for a project or ~/.cursor/mcp.json globally.
Create .cursor/mcp.json:
{
"mcpServers": {
"klayout": {
"command": "uvx",
"args": ["klayout-mcp"],
"env": {
"KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS": "/abs/path/to/layouts",
"KLAYOUT_MCP_ALLOWED_DRC_ROOTS": "/abs/path/to/drc-decks",
"KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
}
}
}
}
OpenCode
OpenCode reads MCP servers from opencode.json under the mcp key.
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"klayout": {
"type": "local",
"command": [
"uvx",
"klayout-mcp"
],
"enabled": true,
"environment": {
"KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS": "/abs/path/to/layouts",
"KLAYOUT_MCP_ALLOWED_DRC_ROOTS": "/abs/path/to/drc-decks",
"KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
}
}
}
}
Other MCP Clients And Agents
If your host asks for a local stdio server, use:
- command:
uvx - args:
["klayout-mcp"] - env: the three
KLAYOUT_*variables above
For an unreleased source checkout, use:
- command:
uv - args:
["--directory", "/abs/path/to/klayout-mcp", "run", "klayout-mcp"] - env: the same
KLAYOUT_*variables
This server is a good fit for agentic hosts because it is deterministic and read-only with respect to layout content, but it still writes render and DRC artifacts under the artifact root.
Using With Agents
This server works with agentic clients, but you should keep the tool surface narrow.
- Point
KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTSat a small layout directory. - Point
KLAYOUT_MCP_ALLOWED_DRC_ROOTSat a small deck directory. - Give write access to the artifact root because renders, reports, and marker crops are written there.
- Prefer project-scoped MCP config when you want team members or project-specific agents to share the same server setup.
Client-specific notes:
- Codex: if you use Codex multi-agent workflows, enable
features.multi_agentin the sameconfig.tomllayer that declares the MCP server. - Cursor: Cursor's Composer Agent can use enabled MCP tools directly from
Available Tools. - OpenCode: enabled MCP tools are available to the LLM and can be restricted per agent with
agent.<name>.tools.
Available Tools
Session
open_layout: open a layout and create a sessionclose_session: close a session and delete its artifacts
Structure
list_layers: list layout layers in deterministic orderlist_cells: list cell hierarchydescribe_cell: summarize one cell and its immediate structure
Geometry
query_region: return shapes, texts, and instances overlapping a boxmeasure_geometry: measure geometry from shape ids returned byquery_region
View
set_view: set the session view staterender_view: render the current or requested view to PNG
DRC
run_drc_script: run a KLayout batch DRC script against the session layoutextract_markers: return marker summaries and optional crop images
Typical Workflow
For most users, the normal sequence is:
- Open a layout with
open_layout - Inspect its structure with
list_layers,list_cells, ordescribe_cell - Focus on a region with
query_region - Measure geometry from returned shape ids with
measure_geometry - Render a view with
render_view - Run a deck with
run_drc_script - Inspect markers with
extract_markers - Clean up with
close_session
Configuration
Supported environment variables:
| Variable | Purpose | Default |
|---|---|---|
KLAYOUT_MCP_ARTIFACT_ROOT |
Root directory for runtime artifacts | <repo>/.artifacts |
KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTS |
Colon-separated list of allowed layout roots | repo root |
KLAYOUT_MCP_ALLOWED_DRC_ROOTS |
Colon-separated list of allowed DRC script roots | repo root |
KLAYOUT_MCP_SESSION_TTL_SECONDS |
Session inactivity timeout | 3600 |
KLAYOUT_BIN |
KLayout batch executable for DRC | klayout |
Important behavior:
- layout and DRC paths outside the allowlists are rejected
- artifact paths returned by tools are absolute
- sessions expire lazily after inactivity
close_sessionremoves the session artifact directory
Artifacts
Runtime artifacts are stored under:
.artifacts/
sessions/
<session_id>/
session.json
renders/
drc/
Typical outputs include:
- rendered PNGs
- DRC reports (
.lyrdb) markers.jsonstdout.txtandstderr.txt- crop images for extracted markers
Error Model
Tool failures return structured JSON objects instead of free-form text:
{
"code": "FILE_NOT_FOUND",
"message": "Layout file does not exist",
"details": {
"path": "/abs/path/to/missing.gds"
}
}
Common codes include:
FILE_NOT_FOUNDPATH_NOT_ALLOWEDSESSION_NOT_FOUNDINVALID_BOXINVALID_LAYERINVALID_TARGETDRC_SCRIPT_NOT_ALLOWEDDRC_RUN_FAILED
Security Notes
- This server is read-only with respect to layout content
- Input paths are restricted to configured allowlists
- DRC execution is limited to scripts under
KLAYOUT_MCP_ALLOWED_DRC_ROOTS - Tool parameters are treated as data, not shell fragments
Recommended practice:
- point
KLAYOUT_MCP_ALLOWED_LAYOUT_ROOTSto a small layout directory - point
KLAYOUT_MCP_ALLOWED_DRC_ROOTSto a small deck directory - avoid using broad roots like your home directory
Current Limits
- tested transport is
stdio - no GUI attach mode
- no geometry editing
- no PCell authoring
- DRC usefulness depends on the deck matching the layout technology
Development
Run tests:
./.venv/bin/python -m pytest -q
Run lint:
./.venv/bin/python -m ruff check .
CI And Releases
Baseline GitHub Actions workflows are included:
.github/workflows/ci.yml: runsruff,pytest,uv build, andtwine checkon pushes tomainand on pull requests.github/workflows/release.yml: manual publish workflow fortestpypiorpypi
The release workflow follows the recommended Trusted Publishing shape:
- build distributions in one job
- upload them as artifacts
- publish from a separate job with
id-token: write
Before the first release, configure GitHub and PyPI/TestPyPI:
- Create GitHub environments named
testpypiandpypi. - In TestPyPI and PyPI, add a Trusted Publisher for this repository.
- Use workflow filename
.github/workflows/release.yml. - Set the environment name to match the target index,
testpypiorpypi.
Suggested release flow:
- Update
versioninpyproject.toml. - Merge to
main. - Run the
Releaseworkflow againsttestpypi. - Verify the published package.
- Run the
Releaseworkflow againstpypi.
This baseline does not automate changelogs, tags, or semantic version bumps yet.
Reference Docs
- docs/specs/2026-03-05-klayout-observer-mcp-contract.md
- docs/plans/2026-03-05-klayout-observer-mcp-implementation-plan.md
- docs/plans/2026-03-05-klayout-observer-mcp-design.md
If those documents disagree, follow the contract.
Project details
Release history Release notifications | RSS feed
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 klayout_mcp-0.1.0.tar.gz.
File metadata
- Download URL: klayout_mcp-0.1.0.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8914585a497f76ed5866c4db3a6653f1160d4f40f919e07f5387d6c7a35f2ad2
|
|
| MD5 |
1f10c58b26243aff6c70ee1e44684c80
|
|
| BLAKE2b-256 |
917844eabb0ed88a920b72a009c6b78c5bf63ee20bfd73282a6b4a3e51212fab
|
Provenance
The following attestation bundles were made for klayout_mcp-0.1.0.tar.gz:
Publisher:
release.yml on aycandv/klayout-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
klayout_mcp-0.1.0.tar.gz -
Subject digest:
8914585a497f76ed5866c4db3a6653f1160d4f40f919e07f5387d6c7a35f2ad2 - Sigstore transparency entry: 1050112246
- Sigstore integration time:
-
Permalink:
aycandv/klayout-mcp@c8aa6aecdcd30151116c436b05fbb422d291921f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aycandv
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c8aa6aecdcd30151116c436b05fbb422d291921f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file klayout_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: klayout_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
14308750e4f867035bd0cd78e3ec4e653551271330015e9c63aecb06922e1f28
|
|
| MD5 |
cae20b763ceb7f5ccaac4cf6f54af2bd
|
|
| BLAKE2b-256 |
536e6679321e8da4abc84aa68a9aa08be4c7cc429b68c67f932153cd70c533bb
|
Provenance
The following attestation bundles were made for klayout_mcp-0.1.0-py3-none-any.whl:
Publisher:
release.yml on aycandv/klayout-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
klayout_mcp-0.1.0-py3-none-any.whl -
Subject digest:
14308750e4f867035bd0cd78e3ec4e653551271330015e9c63aecb06922e1f28 - Sigstore transparency entry: 1050112272
- Sigstore integration time:
-
Permalink:
aycandv/klayout-mcp@c8aa6aecdcd30151116c436b05fbb422d291921f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/aycandv
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c8aa6aecdcd30151116c436b05fbb422d291921f -
Trigger Event:
workflow_dispatch
-
Statement type: