Metadata-Version: 2.4
Name: l5x-toolkit
Version: 2.1.0
Summary: AI Agent Toolkit for Rockwell Automation L5X file manipulation
Home-page: https://github.com/Axiara/l5x-toolkit
Author: Megan Fox
License: Apache-2.0
Project-URL: Homepage, https://github.com/Axiara/l5x-toolkit
Project-URL: Repository, https://github.com/Axiara/l5x-toolkit
Project-URL: Issues, https://github.com/Axiara/l5x-toolkit/issues
Project-URL: Changelog, https://github.com/Axiara/l5x-toolkit/blob/main/CHANGELOG.md
Keywords: rockwell,studio5000,l5x,plc,mcp,automation,logix
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Manufacturing
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: lxml>=4.9.0
Requires-Dist: PyYAML>=6.0.2
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.15.7; extra == "dev"
Requires-Dist: mypy>=1.11; extra == "dev"
Provides-Extra: mcp
Requires-Dist: mcp[cli]>=1.2.0; extra == "mcp"
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: license-file
Dynamic: project-url
Dynamic: provides-extra
Dynamic: requires-dist
Dynamic: requires-python
Dynamic: summary

# L5X Agent Toolkit

![CI](https://github.com/Axiara/l5x-toolkit/actions/workflows/ci.yml/badge.svg)
![Python](https://img.shields.io/badge/python-3.12%2B-blue)
![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-green)

**Read, edit, validate, simulate, diff, and merge Rockwell Studio 5000 projects — with no Studio 5000 install.**

l5x-toolkit is an MCP server that gives an AI agent a validated, structurally-safe surface over L5X files. The agent never hand-edits XML: every operation goes through functions that understand the schema, CDATA encoding, dual data-format synchronization, and Studio 5000's import rules. You describe the change in plain English; the toolkit makes it byte-correct.

No other public tool — open-source or commercial — combines offline authoring, validation, scan-cycle **simulation**, semantic **diff/merge**, and **template-driven instantiation** for Logix projects in one surface.

## What makes it different

**Simulation calibrated against real firmware.** The `simulate` tool runs your logic — ladder, Structured Text, FBD, SFC, and AOI bodies, with JSR-reached subroutines inlined — through a deterministic scan loop with true prescan and first-scan semantics. Its behavior is pinned by **68 golden traces captured from a physical 1756-L83E controller**: the simulator and the firmware agree on every case. On top of the engine: scenario stimuli, temporal assertions (`by_scan`, `always`, `eventually`, …), automatic counterexample search for behavioral claims, and last-writer attribution that tells you *which rung* drove a tag.

**Semantic diff and three-way merge.** `compare` routes every difference between two projects to one of three aspects — structure, code, or values — so a retuned timer preset and a rewired rung don't blur together. `merge` is its write counterpart: two-way or three-way with a base, conservative by design (overlapping edits are reported, never guessed), and dry-run by default. Line-based text diff can't tell you a rung changed *meaning*; this can.

**Authoring that can't produce broken files.** Twelve write tools cover tags, rungs, ST lines, SFC charts, FBD sheets, programs and tasks, I/O modules, alarms, trends, axes, and native in-place AOI/UDT editing — most with batch operations, all with `dry_run` previews and a uniform result envelope. Tag-based alarm definitions propagate automatically: redefine an alarm on a data type and every instance tag — including arrays and AOI-locals — updates in one commit.

**Review at project scale.** One call returns a whole-project digest with precomputed review findings (unused tags, duplicate AOI instances, orphaned routines, unscheduled programs). Dataflow extraction builds the write/read graph and detects seal-ins, one-shots, and cross-scan feedback. Validation runs 13 check families, including a config-driven standards engine for *your* naming and instruction rules. GuardLogix fault and diagnostic codes decode offline from vendored Rockwell reference tables (236 fault + 62 diagnostic codes).

**Orchestration and templating built in.** `playbook` serves parameterized multi-step procedures the agent can fetch and follow (shipping with four: `copy-logic` dependency-closure logic transplant, `repair-logic`, `ci-drift-gate`, and `audit-program` whole-project review), `dispatch` executes a whole tool sequence in one call — including a cross-step dry-run that previews step N against step N−1's uncommitted effect — and `apply_template` compiles a parameterized YAML spec into a concrete tool sequence and runs it transactionally, so a multi-part composite (e.g. a control-area instance wired into its collector) is one call instead of a dozen.

## Example: prove a change is safe — without a controller

> **You:** I refactored the Station 3 jam-recovery logic in `Line4_v2.L5X`. Compare it against the shipped version and tell me what actually changed.
>
> **Claude:** *(calls `compare`)* Three changes. Aspect `code`: rung 12 of `S3_JamRecovery` adds `XIC(S3_ClearPB)` ahead of the reset branch, and a new rung 15 latches `S3_JamLatched`. Aspect `values`: the rung-14 debounce preset dropped from 3000 to 1500. Structure is otherwise identical.
>
> **You:** Prove recovery still works if the jam photo-eye chatters while the operator holds the clear button.
>
> **Claude:** *(calls `simulate` with a chatter scenario and assertions)* Ran the scenario with `S3_JamPE` toggling every scan and `S3_ClearPB` held. Assertion `S3_JamLatched == 0 by_scan 25` **failed** — counterexample at scan 18: the latch re-sets because rung 15 reads the raw photo-eye, not the debounced bit. Last writer: rung 15, `OTL(S3_JamLatched)`.
>
> **You:** Fix it to use the debounced bit and re-verify.
>
> **Claude:** *(calls `manage_rungs`, then `simulate`)* Rung 15 now reads `XIC(S3_JamDebounced)`. All assertions pass; the scan settles by scan 9 with no oscillation flag. *(calls `validate`, then `save_project`)* Validation clean. Saved.

## Capabilities at a glance

| | Tools |
|---|---|
| **Understand** | `inspect` (project digest, dataflow graph, safety-code decode), `list`, `find_references`, `compare` |
| **Author** | `manage_tags` · `manage_rungs` · `manage_lines` (ST) · `manage_steps` (SFC) · `manage_blocks` (FBD) · `manage_programs` (incl. tasks) · `manage_modules` · `manage_alarms` · `manage_trends` · `manage_axes` · `manage_aoi` · `manage_udt` |
| **Verify** | `validate` (13 check families + user-defined standards rules), `simulate` (firmware-calibrated, assertions/falsify) |
| **Reconcile** | `merge` (2-way / 3-way, dry-run default) |
| **Orchestrate** | `playbook`, `dispatch`, `apply_template` (YAML spec → transactional tool sequence) |
| **Lifecycle** | `load_project`, `save_project`, `convert_version` (v30–v38, handles the v36 mnemonic renames), `import_component` (rename-on-import, dependency closure), `export_component` |

27 tools total. Extensible via a plugin system: pip-installable packages register additional MCP tools through entry points, with zero core-code changes (see [PLUGINS.md](PLUGINS.md)).

## Quick Start

Install from PyPI:

```bash
pip install "l5x-toolkit[mcp]"
```

Or from source:

```bash
git clone https://github.com/Axiara/l5x-toolkit.git
cd l5x-toolkit
pip install -e ".[mcp]"
```

Either way this installs `lxml` and `mcp[cli]`. Requires **Python 3.12+** (install 3.13 — see Getting Started). The import package is `l5x_agent_toolkit`.

Then register the MCP server using the `l5x-mcp-server` console command (installed by the step above):

**Claude Code:**
```bash
claude mcp add l5x-toolkit -- l5x-mcp-server
```

**Claude Desktop:** Add to your `claude_desktop_config.json`:
```json
{
  "mcpServers": {
    "l5x-toolkit": {
      "command": "l5x-mcp-server",
      "args": [],
      "env": {}
    }
  }
}
```

Verify the connection in Claude Code with the `/mcp` slash command — `l5x-toolkit` should appear as connected.

**New to Python?** See [Getting Started](docs/getting-started.md) for the full from-scratch setup (installing Python, PATH, and verifying the connection).

## Documentation

| Document | Description |
|----------|-------------|
| [Documentation index](docs/README.md) | The docs hub — Using vs Contributing tracks |
| [Getting Started](docs/getting-started.md) | Install Python, the toolkit, and the MCP server, from zero |
| [Component Libraries](docs/library-setup.md) | Configure library directories so Claude can import components by name |
| [Cookbook](docs/cookbook.md) | Task recipes — what to ask Claude, and which tools run |
| [Tool Reference](docs/tool-reference.md) | All 27 tools with parameters and behavior |
| [Architecture](docs/architecture.md) | The layered design and the 27-tool surface |
| [Development & Roadmap](docs/development.md) | Status, supported scope, known limitations, roadmap |
| [Known Limits](docs/known-limits.md) | The full honestly-cataloged supported-surface & known-limits reference |
| [Changelog](CHANGELOG.md) | Version history |
| [Contributing](CONTRIBUTING.md) | Setup, tests, and how to contribute |

## Project Structure

The package is layered; `lxml` is isolated to `core/`. See [Architecture](docs/architecture.md) for detail.

```
l5x_agent_toolkit/
  core/        XML tree, CDATA, reference scanner, config — the only layer that imports lxml
  model/       typed DTOs / view objects
  query/       read-only projections: inspect, inventory/list, references, resolver
  ops/         language & structural operation helpers
  validate/    typed Finding/Report checks (default + opt-in families)
  server/      MCP tool wrappers (envelope, reads, write/structural/lifecycle dispatch)
  mcp_server.py    registers the 27 tools over stdio
```

## License

Apache License 2.0 (v2.0.0 and later; releases through v1.3.2 remain MIT). See
[LICENSE](LICENSE) and [NOTICE](NOTICE). Contributions are accepted under the
Developer Certificate of Origin — sign off with `git commit -s`
(see [CONTRIBUTING.md](CONTRIBUTING.md#developer-certificate-of-origin-dco)).

Created by Megan Fox. Uses [lxml](https://lxml.de/) for XML processing and the [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) for the Model Context Protocol server.

Rockwell Automation, Studio 5000, Logix Designer, and RSLogix 5000 are trademarks of Rockwell Automation, Inc. This toolkit is not affiliated with or endorsed by Rockwell Automation.
