cx-programmer-mcp
This server is an MCP interface for programmatically creating, inspecting, editing, and validating OMRON CX-Programmer ladder logic projects (.CXP/.CXT) without opening the GUI.
Load existing .CXP/.CXT files or create new blank projects from built-in templates (e.g., CJ2M_CPU11) or custom native templates.
Explore project structure: programs, sections, rung counts, symbols, PLC model, and full ladder context.
Analyze rungs by parsing mnemonics into boolean AST, read/write sets, timers, counters, and simulate supported boolean logic.
Search mnemonic text, addresses, comments, and symbols; cross-reference every read/write/coil/set/reset usage of an address.
Edit in-memory with undo/redo: replace, insert, delete, or batch-patch rungs; also set rung comments and create/rename/delete sections.
Program ladder logic from structured JSON boolean expressions and preview compiled mnemonics.
Manage global/local symbols by creating, updating, or deleting symbol table entries.
Run diagnostics: duplicate coils, SET/RSET imbalance, unused symbols, unclassified instructions, and XML/program validation.
Preview/apply reusable ladder recipes, such as first-press-wins exclusive latches using SET/RSET.
Save edited projects as .CXT, optionally back up, diff pending edits, take semantic snapshots, and launch CX-Programmer on Windows for review.
List CPU-specific instruction tables (e.g., CP1E-NA) grouped by family.
Scope is limited to program logic and symbols; PLC setup, I/O tables, network configuration, passwords, and PLC transfer are not touched.
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., "@cx-programmer-mcp @cx-programmer-mcp Add a rung in Main to set output 100.00 when input 0.00 is ON"
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.
Omron CP1E MCP Server & Automation Toolkit
A Model Context Protocol (MCP) server and Python automation library designed for AI agents (Claude Desktop, Cursor, Cline, Roo Code, etc.) and engineers to inspect, analyze, validate, and safely edit Omron CX-Programmer project files (.cxt and .cxp).
1. Important Warning & PLC Compatibility
TARGET HARDWARE WARNING:
This toolkit is currently configured, tested, and validated specifically for the Omron CP1E Series (such asCP1E-NA20DR-A,CP1E-NA20DT-D,CP1E-E20,CP1E-E/Nseries).Key CP1E Constraints & Memory Boundaries Enforced:
Timers: Standard BCD timers (
TIM xxx #SV). CP1E does not supportTIMX(Binary Timers).Counters:
CNT xxx #SV(0 to 255).Data Memory:
D0-D7999(Non-volatile).Work Area:
W0.00-W99.15.Holding Area:
H0.00-H49.15(Retentive).CIO Area: Physical Inputs
CIO 0.00 - 0.11, OutputsCIO 100.00 - 100.07, InternalCIO 2 - 199.Auxiliary / System Flags:
P_On(CF113.00),P_First_Cycle(A200.11),P_1s(CF002),P_1m(CF001), etc.
Related MCP server: tiacommander-mcp
2. Base Templates for CP1E Series
Clean, validated base templates are included in templates/CP1E/:
CP1E-NA.cxt/CP1E-NA.cxp: For CP1E-NA models (Built-in Analog I/O).CP1E-E20.cxt/CP1E-E20.cxp: For CP1E-E20 models (Standard Basic I/O).
Each template contains:
Section1: A clean workspace section ready for user/AI ladder logic.END: A dedicated termination section containing the mandatoryEND(001)instruction.Zero leftover variables and valid
AtchCmtsheaders (0 Errors, 0 Warnings when opened in CX-Programmer).
Automatic Project Creation:
Auto-Initialization on Startup: If you run the server targeting a non-existent file (e.g.
--project project/new_plc.cxt --allow-write), the server will automatically clone the base template and generate its twin.cxpbinary.Dynamic Creation via MCP Tool: Call
create_projecttool at runtime to generate a new.cxtand.cxppair anywhere on disk.
3. How AI Agents Connect to this MCP Server
The server communicates via stdio following the Model Context Protocol specification.
A. Claude Desktop Configuration
Add the server definition to claude_desktop_config.json:
{
"mcpServers": {
"omron-plc": {
"command": "python",
"args": [
"C:/path/to/omron-cp1e-mcp/server.py",
"--project",
"C:/path/to/omron-cp1e-mcp/project/my_controller.cxt",
"--allow-write",
"--auto-reload-cxp"
]
}
}
}B. VS Code (Cline / Roo Code / Cursor)
In your MCP settings configuration (cline_mcp_settings.json or Cursor MCP settings):
{
"mcpServers": {
"omron-plc": {
"command": "python",
"args": [
"C:/path/to/omron-cp1e-mcp/server.py",
"--project",
"C:/path/to/omron-cp1e-mcp/project/my_controller.cxt",
"--allow-write",
"--auto-reload-cxp"
],
"disabled": false,
"autoApprove": []
}
}
}Server Startup Flags & Configurations:
--allow-write: Enables editing & commit tools (without this flag, server is strictly read-only).--auto-reload-cxp: Enables automatic closing of CX-Programmer before writing and re-opening after commit.--no-auto-reload-cxp: Disables automatic closing and re-opening of CX-Programmer GUI on commit.Environment Variable
OMRON_AUTO_RELOAD_CXP: Set to1/trueto enable or0/falseto disable by default.--cxp-path <PATH>(optional): Specifies custom path toCX-P.exeif not installed in default Omron directory. (Can also be configured via environment variableOMRON_CXP_PATH).
4. Available MCP Tools Reference
Tool Name | Parameters | Description |
|
| Overview of PLC model, total rungs, sections, and symbols count. |
|
| Lists all sections and rung counts. |
|
| Reads paginated rungs within a section. |
|
| Reads a single rung by index with comments and instructions. |
|
| Lists all symbols with addresses, types, and comments. |
|
| Fast regex search across instructions and symbols. |
|
| Detects logic anomalies, unreset SET coils, and double outputs. |
|
| Validates ladder structure and CP1E instruction constraints. |
|
| Replaces a rung in memory (requires |
|
| Inserts a new rung in memory (requires |
|
| Deletes a rung in memory (requires |
|
| Creates or updates a symbol in memory. |
|
| Validates staged changes, writes twin |
|
| Adds a new ladder section (requires |
|
| Renames an existing ladder section (requires |
|
| Creates a brand-new project pair from base template. |
|
| Launches the active project in CX-Programmer GUI on Windows. |
5. CX-Programmer Auto-Close & Auto-Reopen Integration
When CX-Programmer (CX-P.exe) has a .cxp file open on Windows, it holds a lock on the binary project file.
Controlling Auto-Reload Behavior:
Auto-Reload Enabled (
--auto-reload-cxporreload_cxp=true):Auto-Close: When
commit_projectis executed, MCP safely closesCX-P.exeto avoid file locking issues.Atomic Write & Sync: MCP updates the formatted
.cxtfile and encodes the binary.cxpfile.Auto-Reopen: MCP immediately re-launches
CX-P.exewith the updated file, displaying the latest ladder changes instantly.
Auto-Reload Disabled (
--no-auto-reload-cxporreload_cxp=false):MCP writes
.cxtand.cxpfiles directly to disk without touching the runningCX-P.exeprocess.CRITICAL PROCEDURE FOR USERS WHEN AUTO-RELOAD IS DISABLED:
If CX-Programmer is currently open with the target project file when MCP commits changes:Close CX-Programmer WITHOUT SAVING (
Don't Save). (Do NOT hit Save inside CX-Programmer, or CX-Programmer will overwrite disk files with its old in-memory state!)Re-open the
.cxpor.cxtproject file in CX-Programmer to load the new changes committed by MCP.
On-Demand Launch: Use the
open_in_cxptool at any time to open the project in CX-Programmer GUI.
6. Programmatic Python API (SafePlcProject)
from api import SafePlcProject
# 1. Open existing project or create new from template
project = SafePlcProject("project/my_controller.cxt")
# 2. Inspect sections
print("Sections:", project.list_sections())
# 3. Modify logic
project.replace_rung("Section1", 0, ["LD 0.00", "OUT 100.00"], "Toggle Output 100.00")
# 4. Save and auto-reload in CX-Programmer GUI
project.commit(backup=True, reload_cxp=True)Available Tools
38 toolsanalyze_rungARead-only
Parse one rung into structured mnemonic, boolean AST, reads/writes, stateful writes, timers and counters.
Inputs: project_id (required), rung_index (required), program_name (required), section_name (required). Returns: object
apply_exclusive_latch_groupBDestructive
Replace a non-END section with a first-press-wins SET/RSET latch program plus one trailing empty rung.
Inputs: project_id (required), participants (required), program_name (required), section_name (required), +2 more. Returns: object
apply_program_patchADestructive
Apply multiple program-only edits atomically; any failing operation rolls the entire patch back.
Inputs: operations (required), project_id (required), expected_revision. Returns: object
close_projectADestructive
Discard an in-memory project session without writing changes.
Inputs: project_id (required). Returns: object
compile_structured_rungBRead-only
Compile a boolean AST into CX mnemonic using LD/AND LD/OR LD plus OUT/SET/RSET outputs.
This is a preview and does not edit a project.
Inputs: outputs (required), expression (required). Returns: object
create_project_from_templateADestructive
Create a new offline CX-Programmer project session from a native CXT/CXP template.
Use a bundled template_id for supported CPUs. For maximum fidelity with another CPU or CX-Programmer release, create one blank project in CX-Programmer and pass its .CXT/.CXP as template_path. The MCP clones the opaque PLC setup/I/O/unit configuration from that native template and blanks only the program surfaces. Optionally saves the new project as .CXT immediately.
Inputs: plc_name, overwrite, output_path, template_id, +4 more. Returns: object
create_sectionCDestructive
Create a program section, normally immediately before END.
Inputs: project_id (required), program_name (required), section_name (required), before_section, +1 more. Returns: object
cross_reference_addressARead-only
Find every program reference to an address and classify it as read/write/coil/set/reset.
Inputs: address (required), project_id (required). Returns: object
delete_rungBDestructive
Delete one rung and repair CX-Programmer rung indexes/counts.
Inputs: project_id (required), rung_index (required), program_name (required), section_name (required), +1 more. Returns: object
delete_sectionADestructive
Delete a section. END is protected.
Inputs: project_id (required), program_name (required), section_name (required), expected_revision. Returns: object
delete_symbolCDestructive
Delete a symbol-table entry by address.
Inputs: address (required), project_id (required), scope, program_name, +1 more. Returns: object
get_program_contextBRead-only
Return AI-friendly program context: ladder, comments, symbols and optional rung analysis.
Inputs: project_id (required), program_name (required), structured, include_empty_rungs. Returns: object
get_rungsARead-only
Read rungs from one section. structured=true adds read/write and boolean-expression analysis.
Inputs: project_id (required), program_name (required), section_name (required), structured, +1 more. Returns: object
insert_rungCDestructive
Insert a mnemonic rung at a zero-based rung index.
Inputs: project_id (required), rung_index (required), instructions (required), program_name (required), +3 more. Returns: object
insert_rung_structuredCDestructive
Insert a rung compiled from a structured boolean expression.
Inputs: outputs (required), expression (required), project_id (required), rung_index (required), +4 more. Returns: object
launch_in_cx_programmerBDestructive
Save a CXT and open it in locally installed CX-Programmer on Windows.
This never performs GUI automation, online edit, PLC download, force-set/reset, or mode changes.
Inputs: project_id (required), output_path (required), cx_programmer_exe, expected_revision. Returns: object
list_programsARead-only
List programs and their section names.
Inputs: project_id (required). Returns: object
list_project_templatesARead-only
List bundled blank CX-Programmer project templates available for native-structure project creation.
Inputs: no named parameters. Returns: object
list_sectionsBRead-only
List sections and rung counts for one program.
Inputs: project_id (required), program_name (required). Returns: object
list_symbolsBRead-only
List global or local CX-Programmer symbols/address comments.
Inputs: project_id (required), scope, program_name. Returns: object
load_projectA
Load a CX-Programmer .CXP or .CXT into an offline, in-memory editing session.
The input file is never modified. Set CX_MCP_ALLOWED_ROOTS to restrict filesystem access.
Inputs: path (required). Returns: object
plan_exclusive_latchARead-only
Preview a first-press-wins latch recipe using SET/RSET; does not edit a project.
Inputs: participants (required), reset_address (required). Returns: object
program_diagnostics_toolBRead-only
Report duplicate coils, mixed writes, SET/RSET imbalance, unused symbols, and unclassified instructions.
Inputs: project_id (required). Returns: object
project_diffARead-only
Show a unified CXT diff of pending edits versus the loaded project.
Inputs: project_id (required), context_lines. Returns: object
project_summaryBRead-only
Return PLC identity and the program/section tree without PLC setup payloads.
Inputs: project_id (required). Returns: object
redo_last_editBDestructive
Redo the last undone in-memory edit.
Inputs: project_id (required), expected_revision. Returns: object
rename_sectionCDestructive
Rename one program section.
Inputs: new_name (required), project_id (required), program_name (required), section_name (required), +1 more. Returns: object
replace_rungBDestructive
Replace one rung using CX-Programmer mnemonic lines. Revision guard prevents stale edits.
Inputs: project_id (required), rung_index (required), instructions (required), program_name (required), +3 more. Returns: object
replace_rung_structuredBDestructive
Replace a rung from a structured boolean expression instead of raw mnemonic text.
Inputs: outputs (required), expression (required), project_id (required), rung_index (required), +4 more. Returns: object
save_cxtADestructive
Validate and save edited source as CXT. Source overwrite is refused unless explicitly allowed.
Inputs: project_id (required), output_path (required), backup, expected_revision, +1 more. Returns: object
search_programBRead-only
Search mnemonic text, addresses, comments, and global/local symbols.
Inputs: query (required), project_id (required). Returns: object
semantic_snapshotBRead-only
Return program-only semantic JSON suitable for AI review or external versioning.
Inputs: project_id (required). Returns: object
session_statusBRead-only
Return revision, dirty state, undo/redo depth, and program-scope integrity.
Inputs: project_id (required). Returns: object
set_rung_commentCDestructive
Set the comment attached to one rung.
Inputs: comment (required), project_id (required), rung_index (required), program_name (required), +2 more. Returns: object
simulate_rungARead-only
Evaluate the supported boolean mnemonic subset for reasoning/testing only, not PLC-cycle simulation.
Inputs: bits (required), project_id (required), rung_index (required), program_name (required), +2 more. Returns: object
undo_last_editADestructive
Undo the last in-memory edit without touching disk.
Inputs: project_id (required), expected_revision. Returns: object
upsert_symbolBDestructive
Create or update a global/local program symbol without touching PLC setup or I/O tables.
Inputs: address (required), project_id (required), name, scope, +4 more. Returns: object
validate_programBRead-only
Run CXT structural checks, protected-scope integrity checks, and ladder diagnostics.
Inputs: project_id (required). Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 38 tools
Most tools have distinct action-object purposes, but the set includes overlapping pairs such as analyze_rung vs get_rungs with structured=true and validate_program vs program_diagnostics_tool. The raw/structured rung variants are clearly documented, so an agent can disambiguate with careful reading.
The large majority use a consistent snake_case verb_noun pattern, and structured variants are labeled uniformly. A few noun-style names like project_diff, semantic_snapshot, session_status, and project_summary, plus program_diagnostics_tool, are the main exceptions.
38 tools is well above the comfortable range, and the surface feels padded with near-duplicate operations that could be parameterized, such as raw vs structured insert/replace and plan vs apply latch. The broad offline-editing purpose justifies a sizable API, but this count makes tool selection harder for agents.
Project/session, section, rung, symbol, diagnostics, and patch workflows are well covered, and online/PLC operations are deliberately excluded. However, programs can be listed and inspected but not created, renamed, or deleted, and save_cxt only writes .CXT, leaving notable lifecycle gaps.
Maintenance
Related MCP Connectors
Cloud renderer: TIA Portal SimaticML (FC/FB/OB, LAD or SCL) into PNG ladder diagrams over MCP.
MCP Server for Slima - AI Writing IDE for Novel Authors with AI Beta Reader.
MCP server for generating rough-draft project plans from natural-language prompts.
Related MCP Servers
- AlicenseBqualityDmaintenanceAn MCP server for validating, auto-fixing, and scaffolding TwinCAT 3 XML files using deterministic code quality tools and IEC 61131-3 OOP checks. It enables AI assistants to perform structural validation, apply safe fixes, and generate canonical code skeletons for industrial automation projects.1640MIT
- FlicenseNot gradedqualityCmaintenanceMCP server that connects AI assistants to Siemens TIA Portal via the Openness API. AI-assisted PLC programming, project management, hardware configuration, cross-reference analysis, and deployment. 19 tools, 230 actions.60-
- AlicenseBqualityDmaintenanceMCP server that enables AI agents to read, edit, and create PLC projects in EcoStruxure Control Expert via COM automation.524MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for TwinCAT 3 PLC development enabling AI coding agents to build, configure, deploy, and debug TwinCAT PLC projects through a standard tool interface.2-