OPC UA Modeler

io.github.node-opcuaPublished by GitHub account node-opcuav1.6.1Updated Oct 26, 2026

OPC UA companion spec types, namespace dependencies, and engineering units for AI agents

VerifiedStreamable HTTPWeb executableKnowledge & MemoryDeveloper ToolsAI & ML

Overview

AI-generated overview

Gives assistants OPC UA companion-spec type knowledge and tools to validate, generate, reverse-engineer and AI-create OPC UA information models.

What you can do
  • Look up companion spec namespaces, resolve their dependency chains, and list or search types across all specs
  • Inspect a type's components, properties, methods and interfaces, and find reusable Interfaces or AddIns by capability
  • Find official UNECE Rec. 20 engineering unit symbols and read the YAML DSL grammar reference
  • Validate an OPC UA YAML model and get diagnostics with severity, codes and line numbers
  • Generate NodeSet2.xml and a symbols CSV from a model, or reverse-engineer a NodeSet2.xml back into YAML
  • Create a YAML model from a natural language description using AI
When to use it
Useful when an assistant helps design or review OPC UA information models, industrial digital twins or companion-spec-based device models, and needs accurate type names, namespace dependencies and unit symbols instead of guessing.
Requirements
Node.js 18 or newer to run the npm package via npx over stdio, or the hosted streamable HTTP endpoint. Discovery tools and validation work offline; generation, reverse-engineering and AI creation need an OPCUA_MODELER_API_KEY. A local backend can be selected with OPCUA_MODELER_BACKEND=local, which requires the OPC UA Modeler CLI running with a licence that includes the serve entitlement.
Before you install
Model generation, reverse-engineering and AI creation send your YAML or XML to the hosted API unless the local backend is used; the two backends never mix and there is no fallback. An API key is required for those tools and the free tier is limited (25 calls/day for 90 days); anonymous validation is capped at 50 calls/day per IP. Regenerating without passing the previous symbols CSV allocates new NodeIds and can break existing servers and clients. Local mode writes files beside the model.

Installation

In SourceWeft

  1. Open OPC UA Modeler in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.node-opcua%2Fnode-opcua-modeler-mcp-server/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "opc-ua-modeler": {
      "type": "http",
      "url": "https://api.opcua-modeler.sterfive.io/api/mcp"
    }
  }
}

README

node-opcua-modeler-mcp-server

[npm version] [npm downloads/month] [npm downloads total] [License: Apache-2.0] [MCP]

An MCP server that gives AI agents access to the OPC UA companion specification type system — 817 types across 33 industrial namespaces, plus 1,533 engineering units — and lets agents validate, generate, reverse-engineer, and create OPC UA information models.

Built on node-opcua, the most widely used OPC UA stack for Node.js.

Why?

When an AI agent needs to build an OPC UA information model, it must know:

  • What companion spec types exist (DI, Machinery, Robotics, Machine Tools…)
  • What components, properties, and methods each type has
  • What namespace dependencies are required
  • What engineering unit symbols are valid (UNECE Rec. 20)

This MCP server answers all of those questions — offline, for free, in milliseconds.

Quick Start

With Claude Desktop

Add to your claude_desktop_config.json:

json
{  "mcpServers": {    "opcua-modeler": {      "command": "npx",      "args": ["-y", "node-opcua-modeler-mcp-server"],      "env": {        "OPCUA_MODELER_API_KEY": "stfv_your_api_key_here"      }    }  }}

Note: The API key is optional for discovery tools (offline) and opcua_model_validate (50 anonymous calls/day). It is required for opcua_model_generate, opcua_model_reverse, and opcua_model_create. Register at opcua-modeler.sterfive.io and create a key under Settings → API — the free tier gives 25 calls/day for 90 days; see pricing for paid plans.

With any MCP client

bash
npx node-opcua-modeler-mcp-server

The server communicates over stdio using the Model Context Protocol.

Using a local backend instead of the hosted API

If you run the OPC UA Modeler CLI on the same machine, the model tools can be served from it instead of the hosted API — your YAML never leaves the host.

Start the server (requires a licence that includes the serve entitlement):

bash
opcua-modeler serve

Then set one environment variable in your MCP client config:

json
{  "mcpServers": {    "opcua-modeler": {      "command": "npx",      "args": ["-y", "node-opcua-modeler-mcp-server"],      "env": {        "OPCUA_MODELER_BACKEND": "local"      }    }  }}

No API key is needed in this mode — the client discovers the local endpoint and its credentials automatically.

VariableValuesPurpose
OPCUA_MODELER_BACKENDcloud (default), localWhich backend serves the model tools
OPCUA_MODELER_API_KEYstfv_…API key, cloud backend only
OPCUA_MODELER_API_URLURLOverride the hosted API base URL

Notes

  • The two backends are never mixed, and there is no fallback between them. If local is selected and no server is running, the call fails with instructions rather than silently sending your model to the hosted API.
  • The seven discovery tools are local to this package and work offline on either setting.
  • opcua_model_create (AI generation) is available on the cloud backend only.

Tools

list_namespaces

List all 33 OPC UA companion spec namespaces with aliases, URIs, and dependencies.

→ list_namespaces()← [    { "alias": "di", "name": "OPC UA for Devices", "uri": "http://opcfoundation.org/UA/DI/", "dependencies": [] },    { "alias": "robotics", "name": "OPC UA for Robotics", "uri": "http://opcfoundation.org/UA/Robotics/", "dependencies": ["di", "ia"] },    ...  ]

resolve_dependencies

Resolve the full dependency chain for companion spec aliases. Returns a topologically sorted list for the YAML namespaces: block.

→ resolve_dependencies({ aliases: ["machineTool"] })← ["di", "ia", "machinery", "isa95JobControl", "machineryJobs", "machineTool"]

list_types

List all ObjectTypes and VariableTypes defined in a companion spec namespace.

→ list_types({ alias: "robotics" })← [    { "browseName": "MotionDeviceType", "kind": "ObjectType", "subtypeOf": "di:ComponentType", ... },    { "browseName": "AxisType", "kind": "ObjectType", "subtypeOf": "di:ComponentType", ... },    ...  ]   // 25 types

get_type_details

Get the full structure of a type — components, properties, methods, interfaces, including inherited members.

→ get_type_details({ alias: "robotics", browseName: "MotionDeviceType" })← {    "browseName": "MotionDeviceType",    "kind": "ObjectType",    "subtypeOf": "di:ComponentType",    "interfaces": ["di:IVendorNameplateType", "di:ITagNameplateType"],    "components": [      { "browseName": "robotics:Axes", "nodeClass": "Object", "typeDefinition": "FolderType", "modellingRule": "Mandatory" },      { "browseName": "robotics:PowerTrains", "nodeClass": "Object", "typeDefinition": "FolderType", "modellingRule": "Mandatory" },      ...    ],    "properties": [      { "browseName": "di:Manufacturer", "dataType": "LocalizedText", "modellingRule": "Mandatory" },      { "browseName": "robotics:MotionDeviceCategory", "dataType": "MotionDeviceCategoryEnumeration", "modellingRule": "Mandatory" },      ...    ]  }

search_types

Search for types across all companion specs by keyword.

→ search_types({ query: "temperature" })← [    { "alias": "glass", "browseName": "MotorTemperatureTooHighEventType", ... },    { "alias": "padim", "browseName": "TemperatureMeasurementVariableType", ... },    { "alias": "amb", "browseName": "OverTemperatureConditionClassType", ... }  ]

find_reusable_block

Find reusable Interfaces and AddIns by capability — pass a member name or keyword and get the standard blocks that already expose it. Prefer composing an existing block over redefining its members by hand.

→ find_reusable_block({ query: "SerialNumber" })← [    {      "browseName": "di:IVendorNameplateType",      "alias": "di",      "kind": "interface",      "matchedMembers": ["di:SerialNumber"],      "members": ["di:Manufacturer", "di:Model", "di:SerialNumber", ...]    },    {      "browseName": "machinery:MachineIdentificationType",      "alias": "machinery",      "kind": "addin",      "matchedMembers": ["di:SerialNumber"],      "members": ["machinery:Location", "di:SerialNumber", ...]    }  ]

kind tells you how to apply it: interface goes in interfaces:, addin in addIns:.

find_engineering_unit

Find the official UNECE Rec. 20 engineering unit symbol. Supports fuzzy matching and natural language aliases.

→ find_engineering_unit({ query: "celsius" })← { "symbol": "°C", "matchType": "alias", "confidence": 1 }
→ find_engineering_unit({ query: "revolutions per minute" })← { "symbol": "r/min", "matchType": "alias", "confidence": 1 }
→ find_engineering_unit({ query: "bar" })← { "symbol": "bar", "matchType": "exact", "confidence": 1 }

get_dsl_reference ☁️

Fetch the YAML DSL grammar reference — the file header, top-level sections, type and instance syntax, and a list of common mistakes. No API key required.

Served from the API rather than bundled into this package, so the reference an agent reads always matches the validator that will judge its output.

→ get_dsl_reference()← { "version": "1", "reference": "# OPC UA Modeler YAML DSL ..." }

opcua_model_validate ☁️

Validate an OPC UA YAML model for correctness. Returns diagnostics with severity, codes, messages, and line numbers. Works without an API key (limited to 50 calls/day per IP).

→ opcua_model_validate({ yaml: "namespaces:\n  di:\n..." })← {    "valid": true,    "diagnostics": [      { "severity": "warning", "code": "W001", "message": "...", "line": 42 }    ]  }

By path (local stdio server only). Pass model_path instead of yaml. With OPCUA_MODELER_BACKEND=local, the model's imports: then resolve from its own folder (beside it, then deps/), as in VS Code: an import that names only a uri: needs this, because a model sent as text resolves against the folder opcua-modeler serve was started in. The hosted connector never takes paths.

→ opcua_model_validate({ model_path: "C:/models/cip/cip-example.model.yaml" })

opcua_model_generate ☁️

Generate OPC UA NodeSet2.xml and the symbols CSV from a validated YAML model. Requires an API key.

Keep NodeIds stable. The symbols CSV records the NodeId given to every node. A regeneration that does not pass it back allocates new ids, which breaks every server and client bound to the old ones. So each call must say what it is:

CallMeaning
symbols_csv: "<previous CSV>"Regeneration: existing nodes keep their ids. Accepts the CSV text, or the base64 symbols_csv a previous call returned.
mode: "new"First generation: there are no symbols yet.
mode: "renumber"Allocate new ids on purpose.
a self-contained .opcua.yaml streamIt carries its own symbol table, which is replayed.

A call with none of these is refused before reaching the backend with SYMBOLS_DECISION_REQUIRED, and the message says how to retry.

By path (local stdio server only). Pass model_path instead of yaml. The server reads the model and its paired <name>.model.symbols.csv, and writes <name>.Nodeset2.xml, the CSV and, with include_docs, <name>.md beside the model (or into output_dir): the same files and bytes as opcua-modeler generate. Unchanged files are not touched. Nothing large passes through the conversation: for the demoRobot sample the result is about 700 characters instead of about 71 KB of base64. include_artifacts: "inline" also returns the artefacts. With OPCUA_MODELER_BACKEND=local, the model's deps/ folder is resolved too. The hosted connector never takes paths.

→ opcua_model_generate({ model_path: "models/pump.model.yaml" })← {    "valid": true,    "mode": "update",    "symbols_source": "paired-file",    "symbols": { "reused": 41, "new": 1, "dropped": 0, "renumbered": 0, "match": 1,                 "new_names": ["Pump_Temperature"], "dropped_names": [] },    "files": [      { "role": "nodeset", "path": ".../pump.model.Nodeset2.xml", "bytes": 54210, "status": "written" },      { "role": "symbols", "path": ".../pump.model.symbols.csv", "bytes": 1312, "status": "written" }    ],    "diagnostics": [],    "hints": [{ "code": "SYMBOLS_UPDATED", "level": "info", "message": ".../pump.model.symbols.csv updated: 1 new id(s) (Pump_Temperature)." }],    "next_steps": ["Commit pump.model.Nodeset2.xml, pump.model.symbols.csv with the model."]  }

As text. Pass yaml; the artefacts come back base64-encoded in artifacts.nodeset2_xml / artifacts.symbols_csv, with the same symbols, hints and next_steps.

Hint codes: INVALID, IDS_RENUMBERED, IDS_DROPPED, SYMBOLS_LOW_MATCH (the CSV passed probably belongs to another model), SAVE_SYMBOLS, SYMBOLS_UPDATED, STREAM_TABLE_NOT_UPDATED, WARNINGS_PRESENT, PREFER_STREAM. Refusal codes: SYMBOLS_DECISION_REQUIRED, SYMBOLS_REQUIRED, SYMBOLS_FILE_EXISTS, MODE_CONFLICT.

opcua_model_reverse ☁️

Reverse-engineer a NodeSet2.xml file back into the YAML DSL format. Requires an API key. On the local stdio server, pass xml_path instead of xml: the file is read by the server, so even a multi-megabyte companion spec never passes through the conversation.

→ opcua_model_reverse({ xml: "<?xml version=..." })← {    "yaml": "namespaces:\n  di:\n...",    "diagnostics": []  }

opcua_model_create ☁️

Generate an OPC UA YAML model from a natural language description using AI. The AI will auto-detect relevant companion specs, generate a validated model with documentation, and auto-correct validation errors. Requires an API key.

→ opcua_model_create({ prompt: "A robotic welding cell with two robot arms, each having 6 axes, temperature monitoring on each motor" })← {    "success": true,    "yaml": "namespaces:\n  di:\n  robotics:\n...",    "attempts": 2,    "diagnostics": [],    "model": "gemini-2.5-pro",    "tokens": { "input": 4200, "output": 1800 }  }
→ opcua_model_create({ prompt: "A CNC lathe with spindle speed and temperature", forceSpecs: ["di", "cnc"] })← {    "success": true,    "yaml": "namespaces:\n  di:\n  cnc:\n...",    "attempts": 1,    "diagnostics": [],    "model": "gemini-2.5-pro",    "tokens": { "input": 3500, "output": 1200 }  }

Coverage

Companion Specifications (33)

AliasSpecificationTypes
padimOPC UA for PA-DIM101
ijtBaseOPC UA for IJT Base65
machineToolOPC UA for Machine Tools63
scalesOPC UA for Scales58
ladsOPC UA for Laboratory Devices53
diOPC UA for Devices44
glassOPC UA for Glass Manufacturing36
machineVisionOPC UA for Machine Vision36
adiOPC UA for Analyzer Devices35
commercialKitchenEquipmentOPC UA for Commercial Kitchen Equipment35
i4aasOPC UA for I4AAS32
fxAcOPC UA FX Automation Component28
roboticsOPC UA for Robotics25
fxCmOPC UA FX Connection Manager24
iaOPC UA for Industrial Automation20
ambOPC UA for AMB18
autoIdOPC UA for AutoID18
iolinkOPC UA for IO-Link16
metalFormingOPC UA for Metal Forming16
…and 13 more
Total32 namespaces with types817 types

The registry holds 33 specs; irdi is a dictionary-entry namespace and defines no ObjectTypes or VariableTypes. These figures come from catalog/catalog.json and are asserted against it by test/catalog-coverage.test.ts, so they cannot drift silently.

Engineering Units

1,533 official UNECE Rec. 20 symbols plus 136 natural language aliases (e.g., "celsius" → °C, "revolutions per minute" → r/min). Every alias resolves to a symbol the modeler engine accepts — the lookup never invents one.

How It Works

The server ships with a pre-generated catalog.json containing all type information extracted from OPC Foundation's official NodeSet2.xml files via node-opcua. All queries are answered from this static catalog — no network required, no API key needed.

┌──────────────────────────────────────────────────┐│  node-opcua-modeler-mcp-server                   ││                                                  ││  LOCAL TOOLS (offline, free)                      ││  ┌────────────────────────────────────────┐       ││  │ catalog.json (1.7 MB)                  │       ││  │ • 33 companion spec registries         │       ││  │ • 817 type summaries + details         │       ││  │ • 1,533 engineering units              │       ││  └────────────────────────────────────────┘       ││  7 tools → query the catalog                     ││                                                  ││  CLOUD TOOLS (via api.opcua-modeler.sterfive.io) ││  5 tools → reference / validate / generate /     ││           reverse / create                       ││                                                  ││  stdio transport (JSON-RPC)                      │└──────────────────────────────────────────────────┘

Use Cases

  • AI-assisted OPC UA modeling — agents can discover types, resolve dependencies, and validate unit symbols before generating YAML/XML models
  • Copilot integration — add OPC UA awareness to coding assistants
  • Industrial digital twin design — explore companion spec type hierarchies interactively
  • Learning OPC UA — ask an AI to explain types and their relationships

Requirements

  • Node.js ≥ 18

Related

Licensing

Three layers, stated once:

WhatLicence
This package (node-opcua-modeler-mcp-server, the MCP client and its catalog)Apache License 2.0 from version 1.5.0 — see NOTICE for trademark and third-party notices. Versions 1.0–1.4.x were published under MIT and remain so.
The hosted OPC UA Modeler API (opcua-modeler.sterfive.io/api/v1) that the cloud backend callsSterfive API Terms of Use — anonymous discovery, free and paid plans.
The OPC UA Modeler CLI and opcua-modeler serve (the local backend)Sterfive commercial licence — see the product page.

"OPC UA Modeler" and "Sterfive" are trademarks of Sterfive SAS; the Apache licence grants no rights to them. Contributions are accepted under the Developer Certificate of Origin.

© Sterfive SAS

Source: README.md at commit ca6bbcd

Tools

12

resolve_dependencies

Resolve namespace dependencies

Given one or more companion spec namespace aliases, returns the full resolved dependency list that MUST go in the YAML `namespaces:` section. Always call this before generating the namespaces block.

Parametersaliasesrequired

list_namespaces

List companion specifications

List all well-known OPC UA companion spec namespace aliases with their full names, URIs, and dependencies. Use this to discover what namespaces are available.

Takes no parameters.

list_types

List types in a namespace

List ALL ObjectTypes, VariableTypes, and InterfaceTypes defined in a specific companion spec namespace. ALWAYS call this before using any type from a namespace — NEVER guess type names.

Parametersaliasrequired

get_type_details

Get type details

Get detailed information about a specific type: its components, properties, methods, interfaces, and optional members. Use this to understand a type's structure before creating instances or subtypes. `specRef`, on the type and on a member, is the link to the section of the specification that defines it: cite it.

ParametersaliasrequiredbrowseNamerequired

search_types

Search types across specs

Search for types across ALL companion specs by keyword. Use this when you don't know which namespace defines a type. Returns matching types with their namespace alias.

Parametersqueryrequired

find_reusable_block

Find a reusable interface or AddIn

Find reusable Interfaces / AddIns by capability — pass a member name or keyword (e.g. "SerialNumber", "DeviceHealth", "Location") and get the standard blocks that already expose it. PREFER applying/composing an existing block over redefining its members inline. Interfaces are applied with `interfaces:`; addins (types with a DefaultInstanceBrowseName) are composed with `addIns:`. A single property → use the Interface; a whole named sub-object → use the AddIn.

Parametersqueryrequired

find_engineering_unit

Find an engineering unit

Find the official UNECE Rec. 20 engineering unit symbol for a given description. ALWAYS call this before using any engineering unit — NEVER guess unit symbols.

Parametersqueryrequired

get_dsl_reference

Get the DSL grammar reference

Get the grammar reference for the OPC UA modeler YAML DSL: file header, top-level sections, name-prefix conventions, minimal examples, and common mistakes. Call this FIRST before writing any YAML model by hand. Works without an API key.

Takes no parameters.

opcua_model_validate

Validate an OPC UA model

Validate an OPC UA YAML model for correctness. Returns diagnostics with severity (error/warning/info), codes, messages, and line numbers. Works without an API key (limited to 50 calls/day). ALWAYS validate before generating.

Parametersyamlrequired

opcua_model_generate

Generate NodeSet2 XML

Generate OPC UA NodeSet2.xml and the symbols CSV from a YAML model. Requires an API key (set OPCUA_MODELER_API_KEY env var). NodeIds stay stable only if each regeneration passes back the symbols of the previous one: pass symbols_csv, or mode "new" for a first generation, or mode "renumber" to change ids on purpose. A call with none of these is refused with SYMBOLS_DECISION_REQUIRED. Returns base64-encoded artifacts if the model is valid. The result lists symbol counts (reused/new/dropped), hints and next steps.

Parametersmodeyamlrequiredsymbols_csvinclude_docs

opcua_model_reverse

Reverse-engineer NodeSet2 XML

Reverse-engineer a NodeSet2.xml file back into the YAML DSL format. Requires an API key (set OPCUA_MODELER_API_KEY env var). Optionally specify the target namespace URI to extract.

Parametersxmlrequirednamespace_uriself_contained

opcua_model_create

Create a model from a description

Generate an OPC UA YAML model from a natural language description using AI. Requires an API key (set OPCUA_MODELER_API_KEY env var). The AI will auto-detect relevant companion specs, generate a validated model with documentation, and auto-correct validation errors.

ParameterspromptrequiredforceSpecs

Version history

1
  1. v1.6.1LatestSep 16, 2026

Score

100% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts
  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts