studio5000-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@studio5000-mcp-serverfind where StartPB is used in Conveyor.l5x"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
studio5000-mcp-server
MCP server for Rockwell/Allen-Bradley Studio 5000 — parse L5X project exports and give AI agents structured access to PLC tags, UDTs, routines, and programs.
This connector is early community tooling from Nodeblue. The complete system is Nexus, our industrial intelligence platform — these repos are just its connector layers.
Nexus reads and reasons over your entire operation: PLC logic, SCADA systems, live controller data, documentation, fault history, and MES/ERP records. It works across vendors — Rockwell, Siemens, Ignition, the CODESYS family, and 500+ more brands through PLCopen. It diagnoses faults on the running line, holds a persistent memory of the operation, and answers in plain English, cited to the source.
The Nodeblue open-source connectors
Connector | What it does |
studio5000-mcp-server (this repo) | Rockwell/Allen-Bradley Studio 5000 — parse L5X exports: tags, UDTs, routines, AOIs, cross-references |
Ignition SCADA — views, scripts, tags, UDTs, alarms, live gateway read/write | |
Correlates Ignition SCADA tags with Studio 5000 PLC logic end-to-end |
What This Does
studio5000-mcp-server connects AI agents (Claude, GPT, local LLMs) to your Rockwell/Allen-Bradley PLC projects via the Model Context Protocol. It parses L5X project exports and gives the AI structured access to:
Tags — controller-scoped and program-scoped tags with data types, descriptions, and values
UDTs — User Defined Type definitions with member details
Routines — ladder logic as compact NeutralText (not raw XML), Structured Text as-is
Programs & Tasks — program structure, task scheduling, and assignments
Rung Comments — per-rung documentation extracted alongside logic
Smart Chunking
A single ladder rung can be hundreds of lines of verbose L5X XML. This server extracts the compact NeutralText representation instead:
// Raw XML: ~200 lines per rung
// NeutralText: 1 line
XIC(StartPB) XIO(StopPB) XIO(EmergencyStop) OTE(SystemRunning) ;This keeps context windows small and gives LLMs something they can actually reason about.
Works with L5X exports from Studio 5000 Logix Designer v20+ and RSLogix 5000 v17+.
Related MCP server: THE_Studio5000_AI_Assistant_V35
Why This Exists
Studio 5000 has ~500,000+ active licenses and zero AI tooling. Rockwell's AI investment targets FactoryTalk Design Studio (their new cloud IDE) — not Studio 5000, which the vast majority of the installed base runs.
This server fills that gap. It's open-source, agent-agnostic, and works offline.
Built and maintained by Nodeblue. These connectors are early community tooling from our work on Nexus, where this capability ships production-grade — alongside cross-vendor correlation, live fault diagnosis, and a persistent memory of the operation.
Installation
pip install studio5000-mcp-serverRequires Python 3.10+.
To install from source instead:
git clone https://github.com/nodeblue-ai/studio5000-mcp-server.git
cd studio5000-mcp-server
pip install .Quick Start
stdio (local — kiro-cli, Claude Desktop, Claude Code)
studio5000-mcp-serverSSE (remote — server on one machine, agent on another)
studio5000-mcp-server --transport sse --port 8080Configuration
kiro-cli
Add to your ~/.kiro/settings.json:
{
"mcpServers": {
"studio5000": {
"command": "studio5000-mcp-server",
"args": []
}
}
}Claude Desktop
Add to your Claude Desktop MCP config:
{
"mcpServers": {
"studio5000": {
"command": "studio5000-mcp-server",
"args": []
}
}
}SSE (remote)
Start the server on your engineering workstation:
studio5000-mcp-server --transport sse --host 0.0.0.0 --port 8080Connect from any MCP client using the SSE URL: http://<host>:8080/sse
Available Tools
ping
Health check. Returns "pong".
load_project(l5x_path)
Parse an L5X file and return a project summary — controller name, processor type, firmware version, programs, tasks, UDT count, tag count.
get_tags(l5x_path, scope?, data_type?)
List tags from the project. Filter by scope ("controller" or a program name) and/or data type ("BOOL", "DINT", "Motor_UDT", etc.).
get_tags("/path/to/project.l5x", "controller", "BOOL")
get_tags("/path/to/project.l5x", "MainProgram")get_tag(l5x_path, tag_name)
Get details for a specific tag — data type, description, scope, radix.
get_udts(l5x_path)
List all User Defined Type names.
get_udt(l5x_path, udt_name?)
Get UDT definition(s) with member details — name, data type, dimension, description.
get_routines(l5x_path, program?)
List routines with type (RLL/ST/FBD/SFC) and size info. Filter by program name.
get_routine(l5x_path, program, routine_name)
Get routine logic. Ladder routines return compact NeutralText with rung comments. Structured Text routines return raw code.
get_routine("/path/to/project.l5x", "MainProgram", "MainRoutine")get_aois(l5x_path)
List all Add-On Instructions with name, description, and revision.
get_aoi(l5x_path, aoi_name)
Get an AOI definition with parameters (name, data type, usage), local tags, vendor info, and internal routine logic.
list_modules(l5x_path)
List all I/O modules with catalog numbers, slot assignments, and descriptions.
search_logic(l5x_path, pattern)
Search for a tag, AOI, or regex pattern across all routines and AOIs. Returns every rung/line that references matching symbols with full context.
search_logic("/path/to/project.l5x", "Motor_1")
search_logic("/path/to/project.l5x", "Motor_\\d")Returns:
[
{
"symbol": "Motor_1",
"program": "MainProgram",
"routine": "MainRoutine",
"rung": 1,
"context": "Motor_Control(Motor1_AOI,SystemRunning,...)"
},
{
"symbol": "Motor_1.Faulted",
"program": "MainProgram",
"routine": "FaultHandler",
"line": 1,
"context": "IF Motor_1.Faulted THEN"
}
]get_routine response example
{
"program": "MainProgram",
"name": "MainRoutine",
"type": "RLL",
"rungs": [
{
"number": 0,
"comment": "System start/stop - start seals in, stop breaks circuit",
"text": "[XIC(StartPB) ,XIC(SystemRunning) ][XIO(StopPB) XIO(EmergencyStop) OTE(SystemRunning) ];"
}
]
}Example Conversation
You: Load the conveyor project and tell me what it does.
Agent calls: load_project("/projects/conveyor.l5x")
Agent: This is a CompactLogix 1769-L33ER project with 2 programs
(MainProgram and MotorProgram), 7 controller tags, and 2 UDTs.
You: What does MainRoutine do?
Agent calls: get_routine("/projects/conveyor.l5x", "MainProgram", "MainRoutine")
Agent: MainRoutine has 7 rungs:
- Rung 0: System start/stop latch (StartPB seals in, StopPB or E-stop breaks)
- Rung 1: Motor 1 control via Motor_Control AOI
- Rung 2: Fault detection — any motor fault sets FaultActive
- Rung 3: Fault counter increments on FaultActive rising edge
- Rungs 4-5: 1-second heartbeat timer
- Rung 6: Sets line speed to 60.0 when system running
You: Show me all Motor_UDT tags.
Agent calls: get_tags("/projects/conveyor.l5x", data_type="Motor_UDT")
Agent: There are 2 Motor_UDT tags:
- Motor_1 (controller scope) — Conveyor 1 drive motor
- Motor_2 (controller scope) — Conveyor 2 drive motorRoadmap
v0.1 — Core L5X Parsing ✅
L5X XML parser with LRU caching
Controller-scoped and program-scoped tag extraction
UDT definitions with member details
Ladder logic as NeutralText + rung comments (smart chunking)
Structured Text routines returned as-is
Program and task structure
Structured error handling on all tools
48 tests
v0.2 — AOIs & Modules ✅
Add-On Instruction definitions with parameters, local tags, and internal logic
I/O module tree (catalog numbers, slot assignments)
66 tests
v0.3 — Cross-Reference Engine ✅
search_logic(pattern)— find all routines/rungs referencing a tag, AOI, or patternTag→usage index built on first parse for instant queries
79 tests
v0.4 — Cross-Platform Intelligence ✅
Cross-reference Ignition tags with Studio 5000 L5X PLC logic via bridge-mcp-server
"This alarm fires when tag X goes true — here's the PLC logic that drives X"
Maintenance
FBD and SFC detailed parsing (contributions welcome)
PyPI publication (
pip install studio5000-mcp-server)New Studio 5000 / L5X schema versions as they come out
Bug fixes and edge cases from real exports — issues welcome
This connector is feature-complete for its scope: single-export L5X comprehension. Development beyond that scope happens in Nexus.
This Connector vs. Nexus
The connector is the access layer. Nexus is the intelligence that sits on top of it — and of every other connector — as one system.
Capability | This connector | Nexus |
Parse L5X exports (tags, UDTs, routines, AOIs, modules) | ✅ | ✅ |
Cross-reference search within one project | ✅ | ✅ |
Live controller connection (read tags, program currency checks) | — | ✅ |
Cross-vendor: Siemens, CODESYS family (500+ brands), Ignition, OPC UA | — | ✅ |
Live fault diagnosis on the running line (root-cause, cited) | — | ✅ |
Knowledge layer: your manuals, SFS/DOO docs, fault history — searchable, linked to logic | — | ✅ |
Persistent memory of the operation across sessions | — | ✅ |
Ladder/ST code generation | — | ✅ |
Fleet scale: auto-discovery, whole-plant inventory, monitoring, alarming | — | ✅ |
Local LLM / air-gapped deployment | — | ✅ |
If you're evaluating this connector for anything beyond a single L5X export, talk to us about Nexus.
Development
git clone https://github.com/nodeblue-ai/studio5000-mcp-server.git
cd studio5000-mcp-server
pip install -e .
python -m pytest tests/ -vProject Structure
src/studio5000_mcp_server/
├── __init__.py
├── __main__.py # CLI entry point (stdio/SSE)
├── server.py # FastMCP server with 12 tool definitions
├── l5x_parser.py # Core L5X XML parser (LRU-cached)
└── parsers/
├── tags.py # Controller + program-scoped tags
├── udts.py # UDT definitions with members
├── routines.py # Ladder NeutralText + ST code
├── programs.py # Program/task structure
├── aois.py # Add-On Instruction definitions
├── modules.py # I/O module tree
└── xref.py # Cross-reference index (tag→usage)
tests/
├── test_server.py # 85 tests — parsers, tools, error handling
└── fixtures/
└── sample.l5x # Synthetic L5X with all resource typesLicense
MIT — see LICENSE.
Available Tools
12 toolsget_aoiB
Get an Add-On Instruction definition with parameters and internal logic.
Args: l5x_path: Path to a .l5x file. aoi_name: AOI name.
| Name | Required | Description | Default |
|---|---|---|---|
| aoi_name | Yes | ||
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose the shape of the result (definition, parameters, internal logic). However it says nothing about failure modes (missing file, unknown AOI name), permissions, or whether the file is read from disk versus an already-loaded project.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The lead sentence is front-loaded and free of padding. The Args block largely duplicates the input schema, which is mild waste but not enough to hurt readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 tool is a simple two-required-parameter read. What is missing is the load-state prerequisite and the list-vs-single relationship to get_aois, leaving the agent to guess the correct call sequence.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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. The Args section only restates the parameter names: 'l5x_path: Path to a .l5x file' adds the file type, but 'aoi_name: AOI name' is pure tautology, and neither explains format, expected location, or case sensitivity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get an Add-On Instruction definition') and adds scope detail ('with parameters and internal logic'). It reasonably distinguishes the single-AOI fetch from the sibling get_aois, though it never names that sibling explicitly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus get_aois, get_routine, or search_logic. There is no mention of prerequisites such as whether the .l5x must be loaded first (load_project exists as a sibling), so the agent must infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_aoisB
List all Add-On Instructions in an L5X project.
Args: l5x_path: Path to a .l5x file.
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it partially meets it: "List all" implies a non-mutating read of a local file, so no side effects are suggested. However, it says nothing about failure modes (missing/invalid .l5x path), size of result sets, or any file-access requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences with the purpose front-loaded and zero filler; the Args block is compact. Slight redundancy in re-declaring the parameter type already visible in the schema, but nothing wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return structure need not be described, and this is a simple one-parameter lister. The only real gap is the absence of any prerequisite or error context, which keeps it just short of fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There is a single parameter with 0% schema description coverage, and the description only restates it as "Path to a .l5x file." That adds a small amount of meaning (file type) but no format, path style, or validation detail, so it only partly compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ("List all") and resource ("Add-On Instructions in an L5X project"), which cleanly separates it from unrelated siblings like get_routines or get_tags. It does not explicitly contrast itself with the singular get_aoi sibling, but the plural/"all" scoping makes the distinction inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use guidance, no mention of the singular alternative get_aoi for fetching one instruction, and no prerequisite information (e.g., whether load_project must run first). The agent must infer the usage context entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_routineA
Get routine logic — NeutralText for ladder, raw code for Structured Text.
Ladder rungs are returned as compact NeutralText with rung comments, not raw XML. A single rung like 'XIC Motor_Start XIO Motor_Fault OTE Motor_Run' replaces hundreds of lines of verbose XML.
Args: l5x_path: Path to a .l5x file. program: Program name containing the routine. routine_name: Routine name.
| Name | Required | Description | Default |
|---|---|---|---|
| program | Yes | ||
| l5x_path | Yes | ||
| routine_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full burden and does disclose a genuinely non-obvious behavioral trait: ladder logic is returned as compact NeutralText with rung comments rather than raw XML. It omits error behavior (e.g., routine not found) and permission/file-access expectations, keeping it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first line, and the NeutralText explanation earns its place by preempting confusion about the return format. The XML-comparison example is slightly verbose but justifies the design rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 all three required parameters are at least named in the description. The main gaps are error handling and routing versus sibling read tools, which are minor for a simple getter.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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 lists all three parameters and clarifies l5x_path is a path to a .l5x file and program is the containing program. However, it adds no format, constraint, or naming-convention detail beyond the parameter names themselves.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb ('Get') plus resource ('routine') with an explicit statement of what is returned: NeutralText for ladder, raw code for Structured Text. It does not explicitly distinguish itself from the sibling get_routines (plural), leaving the single-vs-list distinction to be inferred from the name.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus get_routines, search_logic, or get_aoi. The description never states the conditions or context in which retrieving a single routine is the right call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_routinesB
List routines in an L5X project with type and size info.
Args: l5x_path: Path to a .l5x file. program: Filter by program name. Empty returns routines from all programs.
| Name | Required | Description | Default |
|---|---|---|---|
| program | No | ||
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'List routines ... with type and size info' implies a read-only enumeration and hints at the returned content, but it does not state that the operation is non-mutating, whether the file is read from disk, or any performance/large-project caveats.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the purpose sentence, then a compact Args block limited to the two parameters. No filler sentences, though the Args duplication of the schema adds little formatting value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 both parameters are documented. What is missing is differentiation from the sibling get_routine and any note on project/file prerequisites, leaving an agent to infer the list-vs-single choice.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, and it does: l5x_path is described as the path to a .l5x file and program is described as a name filter whose empty value returns routines across all programs — the latter adds meaning beyond the bare schema default.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List routines in an L5X project') plus the content returned ('type and size info'). It is distinguishable from the singular get_routine by the plural 'List', but the description never explicitly contrasts the two siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this versus get_routine (single routine), get_udts, or get_tags. The only conditional behavior given is the 'program' empty-string filter, which is parameter behavior rather than usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tagB
Get details for a specific tag by name.
Args: l5x_path: Path to a .l5x file. tag_name: Tag name to look up (searches all scopes).
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes | ||
| tag_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden, and it discloses one real trait: the lookup searches all scopes rather than one. It says nothing about what happens when the tag is missing, permission/file-access requirements, or case sensitivity, which are the gaps an agent would care about for a lookup tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single-line purpose is front-loaded and the whole entry is short with no filler. The 'Args:' block duplicates structure already carried by the input schema, which is mildly redundant but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 purpose plus both params are covered. What is missing for a file-path-driven lookup tool is error behavior (unknown tag) and any link to load_project, leaving the agent to guess at the call sequence.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description is the only documentation, and it does name both required params. However, 'l5x_path: Path to a .l5x file' only restates the parameter name plus file type, while only tag_name ('searches all scopes') adds genuine meaning, so it compensates only partially.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Get details for a specific tag by name'), which clearly separates it from the plural sibling get_tags and from get_udt/get_aoi. It never names those siblings explicitly, so the differentiation is inferable rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance, and no mention of prerequisites such as whether load_project must run first even though that sibling exists in the family. The only usage-ish hint is 'searches all scopes', which is behavioral rather than routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tagsA
List tags from an L5X project, optionally filtered by scope and data type.
Args: l5x_path: Path to a .l5x file. scope: "controller" for controller-scoped, a program name for program-scoped, or empty for all. data_type: Filter by data type (e.g. "BOOL", "DINT", "Motor_UDT").
| Name | Required | Description | Default |
|---|---|---|---|
| scope | No | ||
| l5x_path | Yes | ||
| data_type | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'List' implies a read-only operation and the scope semantics are explained, but nothing is said about file access requirements, behavior on large projects, or how scope interacts with data_type filtering. Adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One summary sentence followed by a compact Args block — front-loaded and free of filler. Slightly mechanical but every line earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 no explanation, and all three parameters are documented. The only real gap is routing guidance relative to the singular get_tag sibling, which is a minor omission for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, and it does: l5x_path is identified as a path to a .l5x file, scope is defined with its accepted values ('controller', program name, empty for all), and data_type is illustrated with concrete examples. This meaningfully exceeds the bare schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List tags') scoped to an L5X project, and the filtering dimensions are named. It does not explicitly distinguish itself from the singular sibling get_tag or from get_udts/get_aois, but the plural-list framing makes the distinction inferable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says filters are 'optional' and defines scope values, which implies when to use each filter, but it never names an alternative (e.g. get_tag for a single tag) or states when not to use this tool. Usage is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_udtC
Get UDT definition(s) with member details.
Args: l5x_path: Path to a .l5x file. udt_name: UDT name. If empty, returns all UDTs.
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes | ||
| udt_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are supplied, so the description carries the full behavioral burden. It only implies read-only via the word "Get" and notes that member details are included; it says nothing about whether the .l5x must be pre-loaded via `load_project`, file-access constraints, or size/performance characteristics of returning all UDTs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two lines of prose plus two parameter lines — lean and front-loaded with the action. The docstring-style "Args:" block is a mild stylistic artifact but wastes no words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value explanation is not required, and both parameters are covered. What is missing is the boundary against `get_udts` and any note on how `l5x_path` relates to the `load_project` sibling — exactly the context an agent needs before invoking.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, and it does document both parameters: `l5x_path` as a path to a .l5x file and `udt_name` with the non-obvious empty-string semantics (returns all UDTs). It does not clarify the expected path form (absolute vs relative) or whether the file must already be loaded.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The verb+resource ("Get UDT definition(s) with member details") is stated, but the plural "definition(s)" collides directly with the sibling `get_udts`, which appears to be the list-all variant. Nothing in the description lets an agent tell which of the two to call for which case.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use or when-not-to-use guidance and no mention of alternatives such as `get_udts`. The only conditional given ("If empty, returns all UDTs") is parameter behavior, not tool-selection guidance, and it arguably makes this tool overlap with its sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_udtsA
List all User Defined Type names in an L5X project.
Args: l5x_path: Path to a .l5x file.
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose one meaningful behavioral trait — that only names are returned, not full type definitions — which is the key thing an agent needs to know. However it says nothing about whether the call is read-only (implied by 'List'), error behavior on a bad path, or output shape, though an output schema exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose sentence is front-loaded and wastes no words. The Args block is slightly redundant boilerplate for a single parameter, but it is where the only parameter documentation lives, so it earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-oriented listing tool with an output schema present, the definition covers what the tool returns (names) and how to invoke it (file path). The main remaining gap is the relationship to load_project and whether the L5X must be pre-loaded, which is left to inference.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
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, and it does: it documents the single parameter as 'Path to a .l5x file', which conveys the expected file type and format that the bare string schema does not. It stops short of stating whether the path must be absolute or whether the file must already be loaded.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (List) and resource (User Defined Type names in an L5X project), with the 'names' scope explicitly narrowing it to identifiers only. This naturally distinguishes it from the singular sibling get_udt, which an agent can infer returns details for one type without opening its schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: listing UDT names is the obvious precursor to calling get_udt for a specific type, and it requires an already-available .l5x path. There is no explicit when-to-use statement, no exclusion, and no mention of prerequisites such as whether the project must be loaded first via load_project.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_modulesB
List all I/O modules in an L5X project with catalog numbers and slot assignments.
Args: l5x_path: Path to a .l5x file.
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. 'List' implies a read-only enumeration and it discloses the returned content, but it says nothing about failure modes (invalid/missing .l5x path), permissions, or scale. Adequate but thin for an unannotated tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded purpose sentence followed by a minimal Args block; very little waste. The Args line is largely redundant with the schema, which keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 no explanation, and the tool is single-parameter and simple. However, with no annotations and no usage or error context, an agent still lacks guidance on preconditions and failure behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% for the single required parameter, so the description must compensate. 'l5x_path: Path to a .l5x file' only restates what the parameter name already implies, adding no format, constraint, or example detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List all I/O modules in an L5X project') and even names the returned fields (catalog numbers, slot assignments). The resource is unique among the get_*/search_* siblings, so it is distinguishable, though no sibling is explicitly referenced.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no prerequisites (e.g., whether the project must be loaded first), and no named alternative. Usage is only implied by the tool's name and scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
load_projectC
Parse an L5X file and return a project summary.
Args: l5x_path: Path to a .l5x file exported from Studio 5000.
| Name | Required | Description | Default |
|---|---|---|---|
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It implies a read/parse operation but says nothing about side effects (does it load state into a session?), what happens on a malformed or unreadable file, or permission/format requirements beyond 'exported from Studio 5000'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in one sentence with no filler, and the argument note is compact. The leftover Python 'Args:' docstring formatting is slightly untidy but not wasteful.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 described, and the input is a single documented path. What is missing is the operational context an agent needs — that this is the prerequisite step for the sibling query tools and any state it establishes.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0% and the schema type is a bare string, so the description must compensate. It does add meaning — the value is a path to a .l5x file exported from Studio 5000 — but gives no detail on path form (absolute/relative) or expected file structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (parse) and resource (L5X file) plus the outcome (project summary), which is enough to tell it apart from the get_* query siblings. It does not explicitly say it differs from them in being the loader/entry point, so it stops short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance at all. Crucially, it never states the obvious workflow role — that this must be called before get_tags/get_udts/list_modules — nor any precondition or alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
pingA
Health check — verify the server is running.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. 'Health check — verify the server is running' communicates that this is a non-mutating status probe. It doesn't detail response contents, but the output schema covers that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is exceptionally lean—five words of substance—and every word adds meaning. The 'Health check' label is front-loaded and the explanatory clause follows directly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless status probe with an output schema, this description is complete. It states the tool's purpose and implied read-only nature; nothing else is required to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so parameter documentation is not needed. The baseline of 4 applies because there is no semantic gap for the description to fill.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb, 'verify,' and a clear resource, 'the server is running.' It also establishes the tool as a health check, which sets it apart from sibling tools like correlate_projects and trace_tag.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to call it: any time the agent needs to confirm the server is up. It doesn't contrast against alternatives, but none of the sibling tools are plausible substitutes for a health check, so no exclusion is needed.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_logicA
Search for a tag, AOI, or pattern across all routines in an L5X project.
Returns every routine/rung/line that references the matching symbol(s). Supports regex patterns. Use this to answer "Where is this tag used?" or "Which routines reference this AOI?"
Args: l5x_path: Path to a .l5x file. pattern: Tag name, AOI name, or regex pattern to search for.
| Name | Required | Description | Default |
|---|---|---|---|
| pattern | Yes | ||
| l5x_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden, and it does disclose two useful behaviors: the result granularity (every routine/rung/line) and regex support. It is silent on case sensitivity, behavior with an invalid or missing l5x_path, and cost on large projects, so the behavioral picture is only partially filled in.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose and return shape, then answers the usage question, then lists args — a sensible order with no filler prose. The args block is somewhat redundant in phrasing but justified given the schema carries no parameter descriptions.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the brief mention of return structure is a bonus rather than a requirement, and the regex capability is disclosed. What remains missing is edge-case behavior — no-match results, invalid paths, case sensitivity — which an agent would want for a search tool over an entire project file.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, but the description compensates well for `pattern` by explaining it accepts a tag name, AOI name, or regex pattern — information absent from the schema. `l5x_path` is only restated as "Path to a .l5x file," adding essentially nothing beyond the name, which keeps it from a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (search) and resource (tag, AOI, or pattern) plus the exact scope: across all routines in an L5X project, returning every routine/rung/line that references the match. This clearly separates it from the get_* siblings (get_tag, get_aoi, get_routine), which retrieve a known object rather than locate references to it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete trigger questions — "Where is this tag used?" and "Which routines reference this AOI?" — that tell the agent exactly when this tool applies. It does not, however, name an alternative or state exclusions (e.g., use get_tag when you already know the tag exists), so it falls short of a 5.
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.
12 tool updates
v0.4.0- First observed
get_aoi - First observed
get_aois - First observed
get_routine - First observed
get_routines - First observed
get_tag - First observed
get_tags - First observed
get_udt - First observed
get_udts - First observed
list_modules - First observed
load_project - First observed
ping - First observed
search_logic
TDQS
Scored across 12 tools
Most tools have clearly distinct purposes: list/get pairs for tags, UDTs, AOIs, and routines are well-differentiated, plus search_logic and list_modules cover unique targets. Minor overlap exists because get_udt with an empty name returns all UDTs, duplicating get_udts (and similarly get_aoi vs get_aois), but the boundaries are still understandable.
Nearly all tools follow a predictable verb_noun pattern (get_tags, get_routine, get_aoi, search_logic, load_project). Slight inconsistency in using both get_* and list_* for listing operations (get_udts vs list_modules), and 'ping' is an outlier, but overall it is readable and consistent.
At 12 tools, the surface is well-scoped for a read-only L5X analysis server, with each tool earning its place. No redundant or trivial tools beyond the standard ping health check.
The read/query surface is thorough: project summary, tags, UDTs, AOIs, routines, I/O modules, and cross-routine search all have coverage. Minor gaps include no direct program-list tool (programs are only inferred via get_routines) and no export/reporting operation, but core analysis workflows are fully served.
Maintenance
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Documents and web for AI agents: PDF parse, OCR, web extract, invoice checks. x402, no API key.
141XRPL token rug-checks, issuer reputation & AMM data for AI agents. Pay-per-call USDC via x402.
Code intelligence for LLMs. Analyze, search, and retrieve code from any public git repository.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI-powered PLC programming with natural language to ladder logic conversion, L5X and .ACD project generation, and semantic search through L5X files and documentation.36-
- FlicenseNot gradedqualityCmaintenanceConverts natural language specifications into working ladder logic and complete Studio 5000 projects, enabling AI-powered PLC programming with L5X and .ACD file generation, semantic search, and documentation access.-
- FlicenseAqualityCmaintenanceLets AI agents and users analyze Mitsubishi MELSEC .gx3 projects directly, tracing coil conditions, checking device references, comparing program changes, and inspecting ladder logic without opening GX Works3.134-
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to connect to Allen-Bradley, Siemens, and CODESYS PLC projects for discovering, asking questions about, analyzing, and proposing code changes, with access to live tag values and version exports under permission-scoped controls.-