Skip to main content
Glama
guimarais
by guimarais

turnout

A local Python MCP server that helps an AI build flat Märklin C-track layouts for XTrackCAD. Python computes geometry; the AI chooses an ordered sequence of catalogue pieces. The only direct dependency is the official Python MCP SDK.

Run and connect

Requires Python 3.13+ and uv.

uv sync --locked
uv run --locked main.py

The server uses stdio, so the second command waits for an MCP client rather than showing an interactive prompt. Diagnostics go to stderr.

Register this checkout with Codex (run from the repository root):

codex mcp add turnout -- "$PWD/.venv/bin/python" "$PWD/main.py"
codex mcp get turnout

Restart the Codex client or open a new chat if the tools aren't visible. Moving the checkout requires registering the new absolute paths. Alternatively, merge this into your Codex MCP configuration, replacing both example paths:

[mcp_servers.turnout]
command = "/absolute/path/to/turnout/.venv/bin/python"
args = ["/absolute/path/to/turnout/main.py"]

See the official Codex MCP configuration documentation. The server does not call a model or require an API key.

Related MCP server: pcb-mcp

Tools

  • list_parts(query=""): search supported catalogue pieces by part number or description; return lengths, radii, angles and endpoints in millimetres.

  • build_layout(parts, width_mm=2000, height_mm=1200): attach an ordered sequence, validate it, centre it on the board, and save a new layouts/layout-*.xtc. Returns the absolute path, parts quantities, footprint and closure measurements.

Example prompt for Codex:

Use turnout to make a closed oval on a 2000 × 1200 mm board, using twelve Märklin 24130 curves and two 24188 straights. Put six curves, one straight, six curves, then the other straight. Return the file path and parts list.

The equivalent build arguments are:

{
  "parts": ["24130", "24130", "24130", "24130", "24130", "24130", "24188",
            "24130", "24130", "24130", "24130", "24130", "24130", "24188"],
  "width_mm": 2000,
  "height_mm": 1200
}

That oval uses 14 pieces and has a centreline footprint of approximately 908.3 × 720 mm. The file embeds the catalogue geometry and reciprocal endpoint connections, with conversion to inches only at export.

Validation and current scope

  • Reads ordinary straights and curves from files/mrklnhoc-de.xtp; unsupported part numbers, including turnouts and special tracks, are rejected.

  • Traverses every piece from catalogue endpoint 0 to endpoint 1. Curves turn left; reversed traversal and mirrored pieces are not implemented.

  • Requires a closed loop within 0.1 mm and 0.1°, allowing catalogue rounding. Pieces keep their catalogue dimensions; gaps are not filled by stretching.

  • Checks full straight/arc centreline bounds, including arc extrema, with a fixed 50 mm board-edge margin. The layout is centred without trying alternative orientations. Width and height must be finite, greater than 100 mm, and at most 100,000 mm.

  • Rejects centreline crossings and overlaps, permitting only the intended adjacent connections within the positional tolerance. This is not a vehicle clearance or roadbed collision simulation.

  • Accepts 3–500 pieces. Pairwise intersection checks are quadratic; no search engine or layout optimiser is included.

  • Invalid designs return ok: false and errors identifying closure measurements, boundary excess, unsupported pieces, or intersecting piece indices (one-based). They create no layout file. Successful builds use unique filenames and never replace earlier layouts or the supplied sample.

The sample files/mrkln_sample.xtc is a format reference, not an input to edit. The writer targets its VERSION 12 5.2.0 format. See XTrackCAD's compound element format documentation.

Checks and XTrackCAD acceptance

uv run --locked python -m unittest -v

The stdlib tests check catalogue filtering, dimensions, exported reciprocal connections, preservation of prior outputs, failure cases, line/arc intersections, and a real stdio MCP client calling both tools. The protocol test needs normal local subprocess/thread I/O; restrictive agent sandboxes can block that I/O.

For the manual compatibility check, open the returned path:

xtrkcad /absolute/path/from/build_layout.xtc

Confirm that XTrackCAD loads without errors, the oval appears continuous, and all 14 pieces have both ends connected. Save As a separate file, close it, and reopen the saved copy. Check that the pieces and connections remain intact.

Status: first milestone accepted on 2026-11-02. Automated geometry and MCP checks pass, and the user confirmed the generated test oval works in XTrackCAD (layouts/layout-w7r0lfkz.xtc) after the requested open/save verification. xtrackcad_verified: false in new build results still means that each generated file needs its own application check; Python does not perform GUI verification.

Available Tools

2 tools
build_layoutA

Build a flat closed loop from an ordered list of catalogue part numbers.

Python attaches endpoint 0 to the previous endpoint 1. All curves turn left. Example oval: six 24130, one 24188, six 24130, one 24188. Centres the result on the board with a fixed 50 mm centreline edge margin. Rejects gaps >0.1 mm, angle errors >0.1 degrees, crossings and overlaps. On failure returns measured errors and writes nothing. On success creates a unique .xtc in this project's layouts/ and returns its path and parts list. Does not open XTrackCAD or check rolling-stock clearance.

NameRequiredDescriptionDefault
partsYes
width_mmNo
height_mmNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses the connection rule ('endpoint 0 to the previous endpoint 1', 'All curves turn left'), the validation thresholds (0.1 mm, 0.1 degrees, crossings, overlaps), the failure contract ('returns measured errors and writes nothing'), and the success side effect (creates a unique .xtc under layouts/). This is exactly the mutation/side-effect context an agent needs before calling.

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?

Front-loaded with the core action, then geometry rule, example, constraints, and outcome contract in that order. Every sentence adds information an agent would otherwise have to guess; the example is compact and directly illustrative rather than padding.

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?

Output schema exists, so return-value detail is optional, yet the description still summarizes path and parts list. Validation rules and the write-nothing-on-failure guarantee are fully covered. The remaining gap is the unexplained board-size parameters, which matter because they interact with the centring margin and overlap checks.

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 0%, so the description must compensate. It adds real meaning for 'parts' (ordered, catalogue part numbers, ordering drives endpoint chaining), but width_mm and height_mm are never named or explained beyond an oblique 'centres the result on the board with a fixed 50 mm centreline edge margin' — their units, defaults (2000x1200) and effect on validation are left to 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?

States a specific verb and resource ('Build a flat closed loop from an ordered list of catalogue part numbers') and immediately distinguishes itself from the sibling list_parts, which only enumerates parts. An agent knows exactly what artifact is produced (.xtc layout) without opening the schema.

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 a concrete worked example ('six 24130, one 24188...') plus explicit exclusions ('Does not open XTrackCAD or check rolling-stock clearance'), which tells the agent when this tool is the wrong choice. It does not name an alternative tool or state preconditions such as requiring parts to exist in the catalogue, so it stops short of full routing guidance.

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

list_partsA

Find supported ordinary Märklin C-track straights/curves by number or description.

Dimensions are mm. Build sequences enter endpoint 0 and leave endpoint 1; curves turn left. Turnouts, special tracks and catalogue editing are unsupported.

NameRequiredDescriptionDefault
queryNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior4/5

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

No annotations exist, so the description carries the full burden and does a solid job: it declares units (mm), the endpoint 0-in / endpoint 1-out sequence convention, and that curves turn left. It stops short of stating that this is a pure read with no side effects or how results are ordered/limited.

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?

Purpose is front-loaded in the first sentence, and every subsequent sentence adds a distinct constraint (units, endpoint convention, unsupported categories). The telegraphic style is efficient, though the geometry sentence is only loosely tied to a lookup tool's primary job.

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?

An output schema exists, so return values need not be explained, and the description covers the domain constraints an agent would otherwise get wrong. What remains thin is query-matching semantics for the one undocumented parameter, but overall it is sufficient to call the tool 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?

The single 'query' parameter has 0% schema description coverage, so the description must compensate. It partially does by saying the query can be a part number or a description, but it gives no guidance on matching behavior (exact vs. substring), case sensitivity, or what an empty default query returns.

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?

Specific verb ('Find') plus a tightly scoped resource ('supported ordinary Märklin C-track straights/curves') and the lookup key ('by number or description'). The scoping language also implicitly separates it from the sibling build_layout, which assembles rather than looks up parts.

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?

Explicit exclusions are stated: turnouts, special tracks and catalogue editing are unsupported, which is real when-not guidance. It does not explicitly say when to reach for build_layout instead, so the routing to the sibling is left for the agent to infer.

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. 2 tool updatesv0.1.0
    • First observedbuild_layout
    • First observedlist_parts

TDQS

A4.1/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct roles: list_parts is a catalogue lookup, while build_layout performs construction and validation. There is no realistic ambiguity about which tool to use for a given request.

Naming Consistency5/5

Both names follow a consistent snake_case verb_noun pattern: list_parts and build_layout. The convention is predictable and easy to extend.

Tool Count3/5

Two tools is quite thin for a layout-building server, though each has a clear purpose. The surface feels minimal rather than well-scoped, with most capability concentrated in build_layout.

Completeness3/5

The server covers part lookup and layout creation, but lacks lifecycle operations such as listing, inspecting, updating, or deleting existing layouts. It also explicitly excludes turnouts despite the server name, which creates a notable domain gap.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI assistants like Claude to interact with KiCAD for PCB design automation, providing comprehensive tool schemas and real-time project state access.
    40 npm
    2
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI assistants to read and modify KiCAD PCB designs through the KiCAD IPC API, providing tools for board queries, footprint placement, track creation, DRC, and export.
    14
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to interact with KiCAD for PCB design automation. Users can design PCBs using natural language, including component placement, routing, checks, and export.
    40 npm
    MIT
  • A
    license
    B
    quality
    B
    maintenance
    Enables AI assistants to interact with KiCAD for PCB design automation, including schematic editing, component placement, routing, DRC/ERC, and export.
    100
    29 npm
    2
    MIT