AI-Assisted Development for FactoryTalk Optix via MCP

A language model that authors HMI changes into a live FactoryTalk Optix project, then verifies its own work in the emulator and on the rendered canvas. Open source, with no path to your hardware by design.

I pointed Claude Cowork at a running Optix project, gave it an MCP for authoring and verification, and let it close the loop without me in the middle. It authors a change into the open project, runs the emulator, and then clicks through the rendered screen to check its own work. The model closes the loop with self-verification.

That work is now shipping as ftx-mcp v1.0. One deliberate design decision up front: this tool has no path to production hardware: it authors and verifies locally. Shipping stays yours. When the emulator shows what you want, you change the target in Studio and deploy the way you always have.

0:00
/1:03

Cowork Demo

Repository for download

The repository is open: code, tests, security posture, and quickstarts for Claude Desktop/Cowork, VS Code, and Claude Code.

  • Clone github.com/asqi-carter/ftx-mcp and run the ten-minute install against a scratch project
  • Read SECURITY.md before you form an opinion; it answers the questions you should be asking any AI tooling

The loop: author, then verify

Every controls engineer runs the same loop, formalized or not. Propose a change. Execute it. Verify that the runtime shows what you expected. The interesting question for AI is not whether the model can develop HMIs. It is whether the model can close that loop: act, look at the result, and revise when verify disagrees with propose.

ftx-mcp is the plumbing for that loop: one Windows box, one small service, predefined tools and skills. No embedded model, no API key; the intelligence is whichever MCP client connects (Claude Desktop or Cowork, Claude Code, VS Code, Cursor, etc.).

MCP is what OPC UA looks like for LLM clients

If you have done any cross-vendor integration you have a working mental model for OPC UA: a standardized, typed, discoverable surface for talking to equipment, independent of the other hardware. MCP (Model Context Protocol) is the same protocol shape with the consumer changed. Instead of a SCADA client talking to a controller, you have a language model talking to anything that publishes an MCP server.

The protocol is not the interesting part. The consumer is. A language model is a procedure-follower: give it a typed surface with clear descriptions and it picks the right action the way a good operator does, by reading the SOP first.

Author into the live project

A small design-time bridge (a NetLogic HTTP listener you paste into your project once) edits the live Studio model directly. Create a template, set a property, bind it to a variable, wire a button to a command, attach an expression. The full template workflow is covered too: build a custom Type, add typed Aliases, bind children through the alias, and stamp out instances that each point at different data.

There is also a move tool for restructuring, and it copies rather than re-parents, for reasons the crash-safety section below makes clear.

Verify: run it and look at it

To a controls engineer, verification means running the thing. The service restarts Studio's emulator when a structural edit calls for it, then drives a headless Chrome over the DevTools Protocol against the emulator's web presentation: screenshot the canvas, click a tab, type into a text box, step a control. Trusted CDP input reaches Optix's canvas hit-tester where synthetic browser events simply no-op.

If the header the model authored is not the header it sees, the loop did not close, and it revises. The emulator is the verify path; shipping is a decision, not a debugging step.

Tools are SOPs

Each tool carries a name, a typed schema, and a description that says when to use it and when not to. The model reads that SOP before it acts, and the trace shows which SOP it picked and why. One level up, the server serves authoring playbooks (navigation layouts, bound controls, template patterns, the verify loop itself) to every connected client, version-locked to the tools they describe. No per-machine setup, no copy-pasted prompt folders.

Does it move the needle? On an internal suite of 36 authoring tasks, the model completed 30 unassisted with self-describing tools alone, and the served playbooks held that range on weaker models. Internal numbers, not a benchmark, but the direction is clear: description quality does more work than model heroics.

Skills, served over MCP

Tools are single actions. Skills are procedures: multi-step authoring recipes (navigation layouts, bound controls, template-and-alias patterns, the verify loop itself) written once, tested against the live surface, and served by the same MCP server that serves the tools.

The architecture is the interesting part. Skills live under tools: one tool returns a one-line catalog, another returns the full recipe on request. A session starts context-lean, scanning the catalog in a few hundred tokens and pulling a complete playbook only when the task in front of it matches one. There are no prompt folders to copy between machines and no instructions drifting away from the code, because the skills are version-locked to the server that ships the tools they drive.

In practice this is the difference between the model improvising Optix conventions from training data and following the same proven procedure on every machine that connects.

Safety is structural, not hopeful

A live-authoring bridge runs inside your open Studio process, so a careless write can take down more than the request that made it. Adversarial testing found three distinct ways a naive write could terminate Studio outright. Each is now a typed refusal instead of a crash:

  • Undeclared properties. Materializing a property the widget's type does not declare kills the renderer. Writes are validated against the type's inheritance-complete property list, and rejections name the valid options.
  • Scalar into array. Writing a scalar into an array-typed property (a grid's column definitions, say) crashed Studio. The bridge now recognizes array-ness that the datatype name hides.
  • Re-parenting live children into a Type. The state it leaves behind crashes Studio on the next traversal. Structural refactors copy content into place instead and report link fidelity honestly.

The pattern across all three: validate before touching the model, and when the answer is no, say no with enough information for the caller to self-correct. A good operator checks the tag list before forcing a value. The bridge makes that the only available behavior.

The rest of the posture is interlocks, not hope. The registered tool set is your policy: every tool declares read-only or destructive, so an MCP host can auto-approve reads and gate writes behind confirmation, and every mutation appends a line to a local audit log. The biggest interlock is the one that is absent: there is no deploy tool, no activation path to hardware anywhere in the distribution. You do not protect a process by hoping the operator picks the right valve. You limit which valves are reachable from the seat.

It works for any Optix Project

The loop is validated end to end, then re-validated on disposable, freshly-imaged Windows VMs: cold-install, run the whole author-to-verify loop, tear down, zero code changes. A thing that works on the author's machine is a demo. A thing that works on a machine that has never seen the author is a tool.

Install is a git clone and two PowerShell scripts, about ten minutes including wiring your MCP client. Ask the model to run the doctor tool first; it checks every prerequisite and returns a plain-English fix for anything missing.

What this is not

It is not a code-generation product. Most of the model's budget goes to picking the right tool in the right order and reading responses correctly. For assistance with your C# scripts, see Rockwell's Netlogic Cheatsheet and MCP here.

It is not a deploy pipeline. Shipping stays in Studio, in your hands. And it is not a remote-access story: loopback bind, local client, opt-in bearer auth before any LAN exposure. Single developer seat, intentionally.

Term-mapping for the controls engineer

In your worldIn this world
OPC UAMCP
SOPA tool: typed action plus description
InterlockTool registration, approval toggles
Audit logLocal audit trail (JSONL)

What it looks like in practice

Five things stand out the first time you run it:

  • You watch Studio build it. Widgets appear in the open project as the model authors, live, in the same Studio window you are looking at.
  • It checks its own work. It restarts the emulator, screenshots the rendered canvas, types into text boxes and steps spin boxes, and revises when what it sees is not what it meant.
  • No YAML edits. Everything goes through the live model. No project files rewritten underneath you, nothing to hand-diff, no reformat or corruption risk.
  • Everything runs on your machine. Loopback-only service, your MCP client, your model subscription. Nothing leaves the box.
  • The model stays context-lean. It reads typed tool descriptions and served playbooks instead of ingesting your project. Discovery tools return maps, not dumps.

The tool is specific. The method is not.

ftx-mcp is FactoryTalk Optix specific. The method is not. Any system (an MES, a historian, a test stand, a quoting workflow) can get the same treatment: a typed, SOP-driven surface a model can safely drive, with the same interlocks and the same audit trail. Building that surface well is the actual engineering work.

Bring this to your operation

The repo shows the method on FactoryTalk Optix. The engineering behind it is the work I do at ASQI: building a typed, interlocked, verifiable surface for the systems that actually run your plant, and building custom software that leverages AI where it makes sense.

If you have a supervisory loop that is well-defined but tedious to staff, an Optix project that needs momentum, or a "could AI do this safely?" question, I want to hear about it.

Talk to ASQI →