Skip to main content
Glama

klayout-mcp

CI Docs

Read-only MCP server for KLayout. It opens GDS/OAS layouts, inspects geometry and hierarchy, renders deterministic PNGs, and runs batch DRC with structured JSON output.

Install

Fastest one-off run:

uvx klayout-mcp@latest

Install once:

uv tool install klayout-mcp

Traditional Python install:

python -m pip install klayout-mcp

For batch DRC, the klayout executable must be on PATH or exposed through KLAYOUT_BIN.

export KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout

Related MCP server: mcp-kicad

Quick Start

klayout-mcp is a stdio MCP server. The default launch shape is:

command: uvx
args:    klayout-mcp@latest

If your client cannot use uvx, install the tool once and launch klayout-mcp directly.

Typical workflow:

  1. open_layout

  2. list_layers

  3. list_cells or describe_cell

  4. query_region

  5. measure_geometry

  6. analyze_waveguide

  7. render_view

  8. run_drc_script

  9. extract_markers

  10. close_session

Client Setup

More copy-paste examples live in examples/mcp/README.md.

Codex

[mcp_servers.klayout]
command = "uvx"
args = ["klayout-mcp@latest"]

[mcp_servers.klayout.env]
KLAYOUT_BIN = "/Applications/klayout.app/Contents/MacOS/klayout"

Or add it with the CLI:

codex mcp add klayout \
  --env KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout \
  -- uvx klayout-mcp@latest

Claude Code

{
  "mcpServers": {
    "klayout": {
      "command": "uvx",
      "args": ["klayout-mcp@latest"],
      "env": {
        "KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
      }
    }
  }
}

Or add it with the CLI:

claude mcp add --transport stdio klayout \
  --scope project \
  --env KLAYOUT_BIN=/Applications/klayout.app/Contents/MacOS/klayout \
  -- uvx klayout-mcp@latest

Cursor

Cursor is file-config based:

{
  "mcpServers": {
    "klayout": {
      "command": "uvx",
      "args": ["klayout-mcp@latest"],
      "env": {
        "KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
      }
    }
  }
}

OpenCode

OpenCode is file-config based:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "klayout": {
      "type": "local",
      "command": ["uvx", "klayout-mcp@latest"],
      "enabled": true,
      "environment": {
        "KLAYOUT_BIN": "/Applications/klayout.app/Contents/MacOS/klayout"
      }
    }
  }
}

Other MCP Hosts

Use:

  • command: uvx

  • args: ["klayout-mcp@latest"]

  • env: KLAYOUT_BIN when needed

Tools

  • Session: open_layout, close_session

  • Structure: list_layers, list_cells, describe_cell

  • Geometry: query_region, measure_geometry, analyze_waveguide

  • View: set_view, render_view

  • DRC: run_drc_script, extract_markers

Configuration

Variable

Purpose

Default

KLAYOUT_MCP_ARTIFACT_ROOT

Root directory for runtime artifacts

<repo>/.artifacts in a source checkout, otherwise the user cache directory (see below)

KLAYOUT_MCP_SESSION_TTL_SECONDS

Session inactivity timeout

3600

KLAYOUT_BIN

KLayout batch executable for DRC

klayout

Behavior:

  • any absolute local path can be used for layouts and DRC scripts

  • artifact paths returned by tools are absolute

  • sessions expire lazily after inactivity

  • close_session removes the session artifact directory

Default artifact location:

  • source checkout (uv run klayout-mcp in this repository): <repo>/.artifacts

  • installed package (uvx, uv tool install, pip): the per-user cache directory

    • Linux: $XDG_CACHE_HOME/klayout-mcp (default ~/.cache/klayout-mcp)

    • macOS: ~/Library/Caches/klayout-mcp

    • Windows: %LOCALAPPDATA%\klayout-mcp\Cache

  • a relative KLAYOUT_MCP_ARTIFACT_ROOT resolves against the repository root in a checkout, or the server's working directory otherwise

Artifacts And Errors

Artifacts are stored under <artifact root>/sessions/<session_id>/ and include renders, DRC reports, marker crops, and logs.

Tool failures return structured JSON such as:

{
  "code": "FILE_NOT_FOUND",
  "message": "Layout file does not exist",
  "details": {
    "path": "/abs/path/to/missing.gds"
  }
}

Common codes: FILE_NOT_FOUND, SESSION_NOT_FOUND, INVALID_BOX, INVALID_LAYER, INVALID_TARGET, DRC_RUN_FAILED.

Development

For a source checkout:

uv sync --extra dev
uv run klayout-mcp

If an MCP client needs to launch the checkout directly:

command: uv
args:    --directory /abs/path/to/klayout-mcp run klayout-mcp

Contributor workflow is in CONTRIBUTING.md. Release notes are in CHANGELOG.md.

Releases

Normal releases are automated with release-please.

  • merge Conventional Commits to main

  • release-please opens or updates a release PR

  • merging that release PR updates pyproject.toml, CHANGELOG.md, creates the tag and GitHub release, and publishes to PyPI

To let the release PR run normal CI under branch protection, configure a repository secret named RELEASE_PLEASE_TOKEN with a GitHub token that can open pull requests. Without it, release-please falls back to github.token, which may not trigger PR workflows.

The manual release.yml workflow remains available for TestPyPI validation and recovery publishing.

Reference

Documentation Site

The repository is configured for Read the Docs with MkDocs.

Build the docs locally:

uv run --extra docs mkdocs build --strict

Serve the docs locally:

uv run --extra docs mkdocs serve

After importing the GitHub repository into Read the Docs, it can build directly from the default branch using .readthedocs.yaml.

Available Tools

12 tools
analyze_waveguideA

Analyze a path shape as a waveguide: width, length, orientation, and bend estimate.

Args: session_id: Session returned by open_layout. target_id: Id of a path shape returned by query_region.

Inputs: target_id (required), session_id (required). Returns: object

close_sessionB

Close a session and delete its artifact directory (renders, DRC output).

Args: session_id: Session returned by open_layout.

Inputs: session_id (required). Returns: object

describe_cellA

Describe one cell: bounding box, child instances, text labels, and shapes per layer.

Args: session_id: Session returned by open_layout. cell: Name of the cell to describe. depth: How many levels of child instances to expand (0 = none).

Inputs: cell (required), session_id (required), depth. Returns: object

extract_markersA

Return the violation markers from a run_drc_script run.

Args: session_id: Session returned by open_layout. run_id: Run id returned by run_drc_script. include_crops: Also render a PNG crop around each marker. crop_size_um: Crop window size in microns: {"x": float, "y": float} (default 20x20).

Inputs: run_id (required), session_id (required), crop_size_um, include_crops. Returns: object

list_cellsA

List cells in the layout hierarchy, sorted by name.

Each entry has the cell bounding box in microns, whether it is a top cell, its direct child instance count, and its direct shape count.

Args: session_id: Session returned by open_layout. max_depth: Only include cells within this many levels of a top cell (0 = top cells only, 1 = top cells and their direct children). Omit to list every cell.

Inputs: session_id (required), max_depth. Returns: object

list_layersA

List every layer in the layout with its layer/datatype, name, and shape count.

Use the returned {layer, datatype} pairs as layer filters in other tools.

Args: session_id: Session returned by open_layout.

Inputs: session_id (required). Returns: object

measure_geometryA

Measure a value from shapes previously returned by query_region.

Modes and the number of target_ids they take: path_width (1), segment_length (1), bend_radius_estimate (1), centerline_distance (2, bounding-box centers), edge_gap (2, bounding-box gap), overlap (2, bounding-box overlap area). Results are in microns and database units.

Args: session_id: Session returned by open_layout. mode: Measurement mode (see above). target_ids: Shape ids from query_region.

Inputs: mode (required), session_id (required), target_ids (required). Returns: object

open_layoutA

Open a GDS or OASIS layout read-only and start a session.

Call this first. The returned session_id is required by every other tool. Sessions expire after a period of inactivity; call close_session when finished.

Args: path: Absolute path to a .gds or .oas file. top_cell: Top cell to use by default. Defaults to the alphabetically first top cell. format: Explicit format (gds or oas) when the file extension is ambiguous.

Inputs: path (required), format, top_cell. Returns: object

query_regionA

Return shapes, text labels, and child instances overlapping a box.

Each returned shape has a session-stable id (e.g. shp_1a2b3c4d). Pass these ids to measure_geometry, analyze_waveguide, or render_view annotations. Results are sorted deterministically; truncation reports how many items the limits dropped.

Args: session_id: Session returned by open_layout. box: Query window in microns: {"left", "bottom", "right", "top"}. cell: Cell to query. Defaults to the session's selected top cell. layers: Optional [{"layer": int, "datatype": int}] filter. Defaults to all layers. hierarchy_mode: top for shapes placed directly in the cell, or recursive / flattened to include shapes from child cells transformed into the cell's coordinates. max_shapes: Maximum number of shapes to return. max_instances: Maximum number of child instances to return. max_texts: Maximum number of text labels to return.

Inputs: box (required), session_id (required), cell, layers, +4 more. Returns: object

render_viewA

Render layout geometry to a PNG and return its absolute path.

Arguments given here also update the session's default view (see set_view).

Args: session_id: Session returned by open_layout. box: View window in microns. Defaults to the current view. cell: Cell to render. Defaults to the current view's cell. layers: Visible layers as [{"layer": int, "datatype": int}]. image_size: Output size in pixels: {"width": int, "height": int} (default 1200x800). annotations: Overlays such as [{"kind": "shape_outline", "target_ids": ["shp_..."], "color": "#ff3b30"}]. Targets must come from query_region on the rendered cell. style: light, dark, or mask.

Inputs: session_id (required), box, cell, style, +3 more. Returns: object

run_drc_scriptA

Run a KLayout DRC deck in batch mode against the session layout.

The deck receives $input_path and $report_path variables and must write its report to $report_path. Returns a run_id and marker counts per rule; pass the run_id to extract_markers for marker locations. Requires the klayout executable (on PATH or via KLAYOUT_BIN).

Args: session_id: Session returned by open_layout. script_path: Absolute path to the DRC deck. script_type: Deck language. Only ruby is supported. params: Extra variables passed to the deck with -rd name=value.

Inputs: session_id (required), script_path (required), params, script_type. Returns: object

set_viewA

Set the session's default render view used by later render_view calls.

Omitted arguments keep their current value. Changing cell without a box auto-fits the view to that cell.

Args: session_id: Session returned by open_layout. box: View window in microns: {"left", "bottom", "right", "top"}. cell: Cell to render. layers: Visible layers as [{"layer": int, "datatype": int}].

Inputs: session_id (required), box, cell, layers. Returns: object

Tool Schema Changelog

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

Loading tool schema changelog…

    TDQS

    A4/5.0

    Scored across 12 tools

    Disambiguation4/5

    Most tools have clearly distinct purposes (session lifecycle, listing, querying, measuring, rendering, DRC), and descriptions clarify boundaries. Minor overlap exists between analyze_waveguide and measure_geometry's path_width/bend_radius_estimate modes, which could cause occasional misselection.

    Naming Consistency5/5

    Every tool follows a consistent snake_case verb_noun pattern (open_layout, list_cells, query_region, render_view, extract_markers, etc.), with only minor multi-word variations like run_drc_script that still fit the convention. No style mixing.

    Tool Count5/5

    12 tools is well-scoped for a read-only layout inspection/analysis server, with each tool covering a distinct capability from session management to DRC. No redundant or filler tools.

    Completeness4/5

    The surface covers the full read-only workflow: open/close session, inspect cells and layers, query regions, measure geometry, render views, and run DRC with marker extraction. Edit/write operations are intentionally absent given the read-only design, and there is no way to list past DRC runs, but core workflows are complete.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      C
      maintenance
      Read-only MCP server for accessing local Kindle library data, exposing tools to query profile, health, and book metadata.
      MIT
    • A
      license
      A
      quality
      C
      maintenance
      A read-only MCP server for AI agents to understand KiCad projects through progressive disclosure, providing compact summaries and drill-down tools for components, nets, traces, and ERC/DRC checks without blowing context budgets.
      7
      1
      MIT