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.
[!NOTE] 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-mcp-server | Ignition SCADA — views, scripts, tags, UDTs, alarms, live gateway read/write |
| bridge-mcp-server | 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+.
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
Install from source:
git clone https://github.com/nodeblue-ai/studio5000-mcp-server.git
cd studio5000-mcp-server
pip install .
Requires Python 3.10+.
Note:
pip install studio5000-mcp-serverfrom PyPI is coming soon. For now, install from source.
Quick Start
stdio (local — kiro-cli, Claude Desktop, Claude Code)
studio5000-mcp-server
SSE (remote — server on one machine, agent on another)
studio5000-mcp-server --transport sse --port 8080
Configuration
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 8080
Connect 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 motor
Roadmap
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 pattern - Tag→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/ -v
Project 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 types
License
MIT — see LICENSE.
Built by Nodeblue. Early community tooling behind Nexus — the industrial intelligence system that reads your operation and answers, cited to the source.
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 studio5000_mcp_server-0.4.0.tar.gz.
File metadata
- Download URL: studio5000_mcp_server-0.4.0.tar.gz
- Upload date:
- Size: 21.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
87ec2c75320eda3fb29acfc8da0835ab808d66a74256e03a5c9a431e32dcdc12
|
|
| MD5 |
c388fe813f3aeaf59a95ea66050fc7a0
|
|
| BLAKE2b-256 |
a08a74d8abe2fa3078c296ef8ade8817ae4dac6ef5d6706e574775a5e75f8e3b
|
File details
Details for the file studio5000_mcp_server-0.4.0-py3-none-any.whl.
File metadata
- Download URL: studio5000_mcp_server-0.4.0-py3-none-any.whl
- Upload date:
- Size: 18.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
07f1fdcbdb8b9db7d0ba3cfd06a59d7791fa7e90091d387ebe86b9ee6889962e
|
|
| MD5 |
8ed1d0f79c4d9f97f73c110a418f538a
|
|
| BLAKE2b-256 |
2843f162ad4728dd022941600c209f99d07220e35568de4db80d6c38bf39e64a
|