motionworks-iec-mcp-server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| MOTIONWORKS_FWLIB | No | Path to the FW_LIB folder, or a folder of already-extracted .htm pages. If set but missing, it is treated as an error. | |
| MOTIONWORKS_SAMPLES | No | Only used by the test suite, to point at real exports. | |
| MOTIONWORKS_FWLIB_CACHE | No | Path 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
| Capability | Details |
|---|---|
| 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
| Name | Description |
|---|---|
| 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. Returns the project summary plus a If you passed a native project ( 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. 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 Args: path: File or directory to inspect. |
| get_tagsA | List project variables (the MotionWorks equivalent of tags). Combines global variables (which carry 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 ( 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 Args:
path: Project file or directory.
type_name: Exact type name. Empty returns every type that matches |
| 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:
Pins the project does not mention are still listed, so a block can be called
with parameters it has never been called with here. 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 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 Long bodies are paged: check Args:
path: Project file or directory.
pou_name: POU name exactly as reported by |
| get_routineA | Get a POU's body (alias for 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 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 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 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 ( 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 Whether the IDE imports this shape is not verified: that format is
undocumented in the installed help, whose documented import path is PLCopen XML
( 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 Same caveat as Args:
name: Type name.
members: List of objects like |
| 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
|
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 28 tools
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 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.
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.
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.