Skip to main content
Glama
KphungFROMM

motionworks-iec-mcp-server

by KphungFROMM

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
MOTIONWORKS_FWLIBNoPath to the FW_LIB folder, or a folder of already-extracted .htm pages. If set but missing, it is treated as an error.
MOTIONWORKS_SAMPLESNoOnly used by the test suite, to point at real exports.
MOTIONWORKS_FWLIB_CACHENoPath where extraction and the parsed catalog are cached.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
pingA

Health check — verify the server is running.

open_projectA

Open a MotionWorks IEC project, merging every export form present.

This is the entry point for every other tool. path may be a PLCopen XML file, an Extended IEC 61131-2 export directory, or a native project directory — the source is detected, not declared.

Returns the project summary plus a divergences list. Read that list: the exports are incomplete in different ways (an XML export can omit POUs that the Extended export has, or ship them with an empty body), so a divergence is often the most important thing about a project.

If you passed a native project (.mwt) with no export beside it, the response also carries an exportGuidance block. Its code lives in a compound binary, so no source, variables, types or I/O can be read. The block says exactly what is missing, what that costs you, the verbatim steps to produce each export, and — if exports exist elsewhere on disk — the path to the one matching this project. Relay those steps to the user rather than guessing at the code.

Args: path: File or directory to open.

load_projectA

Parse a PLCopen XML export and return a project summary.

Kept for parity with the studio5000 connector. open_project is preferred because it also finds the Extended and native sources.

Args: plcopen_xml_path: Path to a PLCopen XML file exported from MotionWorks IEC.

get_sourcesA

Report which export forms exist for a project and what each contributes.

Use this when a tool returns less than you expected: it says which sources are readable, what each one supplied, and exactly where they disagree. When a source is missing — including the common case of a native project with no export beside it — the response carries an exportGuidance block with the steps to produce it, taken from MotionWorks' own help.

Args: path: File or directory to inspect.

get_tagsA

List project variables (the MotionWorks equivalent of tags).

Combines global variables (which carry AT % addresses) with every POU's declared interface variables, so this is the full symbol surface of the project.

Args: path: Project file or directory. scope: Filter by scope, e.g. "VAR_GLOBAL", "VAR_EXTERNAL", "VAR", "VAR_INPUT". data_type: Filter by data type, e.g. "BOOL", "LREAL", "AXIS_REF". address: Substring filter on the AT address, e.g. "%MX1.7" . search: Case-insensitive substring filter on the variable name.

get_tagA

Get one variable's full detail plus every place it is used.

Use this to answer "what is this signal and what drives it?" — it returns the declaration (with address and comment) alongside every POU, net and line that references it.

Args: path: Project file or directory. tag_name: Variable name. A qualified name such as "Products.Sensor.Bit" also works.

get_typesA

List data types, structs and function blocks available in the project.

This is the vocabulary an agent must code against — including the Yaskawa motion library (AXIS_REF, Y_ENGAGE_DATA, MC_*, Y_*, AxisControl) when the PLCopen XML export is present, which it is the only source that carries.

Args: path: Project file or directory. search: Case-insensitive substring filter on the type name. kind: Filter by kind: "struct", "enum", "array", "alias" or "fb". limit: Maximum number of types to return.

get_typeA

Get a type definition with its members.

Use get_fb_signature instead when you want a function block's pin table in a form oriented around calling it.

Args: path: Project file or directory. type_name: Exact type name. Empty returns every type that matches search, or all types when search is empty too. search: Case-insensitive substring filter, used when type_name is empty.

get_udtsA

List user-defined types only (project-defined, excluding the vendor library).

Args: path: Project file or directory.

get_udtA

Get a user-defined type definition with its members.

Args: path: Project file or directory. udt_name: Type name. Empty returns all project-defined types.

get_fb_signatureA

Get a function block's interface — for calling or instancing it correctly.

Combines two authorities, because each knows something the other does not:

  • the project knows the exact pin list its firmware build compiled against (from .DIT metadata) or what the code actually passes;

  • the firmware library reference knows data types, defaults, per-pin meaning, which pins this firmware leaves unimplemented, the block's purpose, and a usage example.

Pins the project does not mention are still listed, so a block can be called with parameters it has never been called with here. unsupportedPins names parameters that exist on the block but do nothing on this firmware.

Args: path: Project file or directory. fb_name: Function block name, e.g. "MC_Power", "Y_CamIn", "AxisControl".

list_library_blocksA

List the function blocks the MotionWorks firmware library provides.

This is device documentation, not project state: it works without opening a project, and it includes blocks this project never uses. Use it to find out what is available before writing code.

Args: search: Case-insensitive substring filter on the block name. library: Filter by library, e.g. "YMotion" or "PLCopen". limit: Maximum number of blocks to return.

search_libraryA

Search the firmware library by block name, pin name, type or description.

Answers "which block do I use for X?" — searching names, formal parameters, descriptions, notes and example code, plus enumerated types and their values.

Args: query: Text to look for, e.g. "torque", "cam in", "BufferMode", "alarm". limit: Maximum number of matches.

get_library_reference_statusA

Report whether the firmware library reference is available, and how to enable it.

The reference is the vendor's own help, installed with MotionWorks and decompiled locally. It is what makes the motion library's parameters, types and semantics knowable. If this reports it is unavailable, that is the reason library signatures fall back to observed usage.

list_fb_catalogA

List every function block the project uses, with the parameters it passes.

This is the practical coding vocabulary: the blocks that are actually available in this machine and the formal parameter names they are actually called with. The vendor library is not exported as type definitions, so this is the only complete view of it for a given project.

Args: path: Project file or directory. search: Case-insensitive substring filter on the block name.

get_pousA

List programs and function blocks with language, task and size.

Args: path: Project file or directory. language: Filter by body language: "ST", "LD", "FBD". task: Filter by the task the program runs under, e.g. "FastTsk". search: Case-insensitive substring filter on the POU name.

get_routinesC

List POUs (alias for get_pous, for familiarity with studio5000).

Args: path: Project file or directory. program: Filter by POU name.

get_pouA

Get one POU: its interface, its body, and every network it contains.

This is the workhorse tool. Structured Text is returned as the original source, tab alignment and inline comments intact. Ladder and FBD bodies are returned as one compact text line per network plus a structured nets array naming each block, its instance and each formal parameter's source — the equivalent of NeutralText for Studio 5000, and far smaller than the raw XML.

Long bodies are paged: check body.truncated and pass offset to continue.

Args: path: Project file or directory. pou_name: POU name exactly as reported by get_pous. offset: Line offset into the body, for paging long POUs. include_interface: Include the declared variables for each scope. include_outputs: For graphical bodies, include each block's output pins.

get_routineA

Get a POU's body (alias for get_pou, for familiarity with studio5000).

Args: path: Project file or directory. program: POU name. routine_name: Ignored; present so the studio5000 calling convention works.

get_tasksA

List controller tasks with timing and the programs each one runs.

Task assignment decides execution order and jitter, so check this before assuming code in two POUs runs in a particular sequence.

Args: path: Project file or directory.

get_io_configA

List the controller and network I/O configuration.

Each entry is a named I/O group mapped to an address range and a driver, which is how the AT %I/%Q variables in the global variable table get their physical meaning.

Args: path: Project file or directory.

get_motion_configA

Summarise the motion setup: axes, their amplifier bindings and network nodes.

MotionWorks binds an axis to hardware through <var>.AxisNum assignments in startup code (e.g. TopCutter.AxisNum := UINT#1;) and the servo groups in the I/O configuration (SGD7S Network #1 Node #1). This tool joins those two so "which servo is axis 1?" is answerable.

Args: path: Project file or directory.

search_logicA

Search for a tag, block or regex across every POU and network.

Answers "where is this used?" and "which routines call this block?". Matches symbol-table entries (declarations, block types, instances, pins) first, then raw Structured Text lines, so both a tag name and a regex work.

Note the pattern is an ordinary regex, so MC_ matches every MC_* block reference (the underscore is literal, and MC_\d+ would require digits after it and so match nothing).

Args: path: Project file or directory. pattern: Tag name, block name, or regex pattern. limit: Maximum number of matches to return.

get_code_conventionsA

Report the coding conventions this project already follows.

Call this before generating code. Conventions are written down nowhere — they are visible only in the existing symbols — and code that compiles but breaks them reads as foreign in review. Each rule carries the evidence behind it and a confidence, so a weak signal is not mistaken for a house standard.

Covers: variable name prefixes by type (x→BOOL, r→LREAL, udi→UDINT), function-block instance naming, established signal families, documentation habits, task structure and the languages in use.

Args: path: Project file or directory.

validate_pouA

Validate agent-written IEC code against the project's real symbols.

Call this on generated code before handing it to a user. It catches the mistakes an LLM actually makes: tags that do not exist in the project, types that are not defined, function blocks that are not in the library, and formal parameter names that the target block does not have.

Args: path: Project file or directory. code: The Structured Text body to check (no declaration blocks). declared_vars: Any VAR blocks the code relies on, so locally declared symbols are not reported as undeclared. pou_name: Optional name, used only for labelling the result.

render_pou_sourceA

Emit a POU in the shape MotionWorks' Extended IEC 61131-2 export uses.

Produces the (*@PROPERTIES_EX@ ... *) header, the PROGRAM/FUNCTION_BLOCK line, the declaration blocks and the (*@KEY@: WORKSHEET ... *) body region — the same structure the IDE writes when exporting a POU as text.

Whether the IDE imports this shape is not verified: that format is undocumented in the installed help, whose documented import path is PLCopen XML (File → Import → "Import PLCopen xml file"). So either create a POU in the IDE and paste the code, or wrap the result in PLCopen XML for the documented route.

Args: name: POU name. pou_type: "program", "function_block" or "function". language: Body language — "ST", "LD" or "FBD". declaration: The VAR blocks, without the closing END_* keyword. code: The Structured Text body. description: Free text stored in the POU's DESCRIPTION region.

render_type_sourceA

Emit a TYPE ... END_TYPE struct definition in MotionWorks' text shape.

Same caveat as render_pou_source: the structure matches what the IDE exports, but the documented import path is PLCopen XML.

Args: name: Type name. members: List of objects like {"name": "PartLength", "type": "LREAL", "comment": "mm"}. comment: Optional description stored in the DESCRIPTION region.

list_languagesA

Report which IEC body languages this server can render, and how well.

Useful context for interpreting results: graphical bodies from the PLCopen XML export are complete, whereas the same logic recovered from an Extended export's .GE file is partial by design (see the server README).

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.5/5.0

Scored across 28 tools

Disambiguation3/5

Several tools have overlapping boundaries: get_udt/get_udts/get_type/get_types all deal with type definitions, get_routine/get_routines are aliases for get_pou/get_pous, and list_library_blocks/list_fb_catalog both list function blocks. The descriptions usually clarify which one is intended, but an agent must read carefully to pick the right tool.

Naming Consistency3/5

Naming is mostly lowercase snake_case verb_noun, but the verb set is inconsistent: reads mix get_ (get_pous, get_types) with list_ (list_library_blocks, list_fb_catalog), and there are open_/load_/ping/validate_/render_ actions. The core get_* pattern is recognizable, so it remains readable but not fully predictable.

Tool Count2/5

28 tools is over the 25-tool heavy threshold, and the count is inflated by redundant aliases (get_routine/get_routines), a parity loader (load_project), and overlapping type-list tools. A leaner set of roughly 20 distinct operations could cover the same domain without losing real capability.

Completeness4/5

For an analysis/code-generation server, coverage is strong: project opening, source-form diagnostics, tags, types, POUs, tasks, I/O, motion, library search, validation, and source rendering are all present. The main gap is the absence of any project-write or import operation, but that appears intentional since edits are expected through the IDE.

Maintenance

ActivityMaintained
ResponsivenessNo issues