Skip to content
Start free evaluation

MCP server

pdcomm-opcua-mcp exposes the OPC UA simulator as an MCP (Model Context Protocol) server. AI tools such as Claude Code and Cursor can then start the simulator’s server, connect to it, read and write nodes, and work with subscriptions and alarms. The actions and arguments are the same as in the headless simulator. You find it in bin/ of the apps package.

Every simulator action is a tool named with the opcua_ prefix, 37 tools in all. cancel isn’t a tool; MCP cancellation notifications take its place.

Workspace Tools
connection opcua_capabilities, opcua_state, opcua_configure, opcua_server_start, opcua_server_stop, opcua_server_status, opcua_discover, opcua_connect, opcua_disconnect, opcua_project_export, opcua_project_import
address_space opcua_browse, opcua_server_nodes
read_write_methods opcua_read, opcua_write, opcua_call, opcua_server_write
subscriptions opcua_subscribe, opcua_publish, opcua_notifications, opcua_notifications_clear, opcua_unsubscribe
events opcua_event_subscribe, opcua_alarm_set, opcua_condition, opcua_condition_refresh
history opcua_history_read
pubsub opcua_pubsub_start, opcua_pubsub_publish, opcua_pubsub_status, opcua_pubsub_received, opcua_pubsub_stop
trace opcua_trace, opcua_trace_clear, opcua_logging_configure, opcua_logging_status, opcua_logging_flush

A tool’s input is the argument object of the headless action; opcua_read, for example, takes {"node":"ns=2;s=Simulator.Double"}. Each tool definition carries a closed input schema (JSON Schema 2020-12) with the type, range and description of every argument, as in the action list of the headless simulator. The server checks the arguments against that schema before it runs the action, so an unknown argument, a wrong type or a value out of range never reaches the simulator.

One MCP server process owns one simulator. Its server, session and subscriptions live until the AI tool ends the process.

Register the server from a terminal, using the path where you unpacked the apps package:

터미널 창
claude mcp add --transport stdio pdcomm-opcua -- /opt/pdcomm/pdcomm-opcua-apps-darwin-arm64/bin/pdcomm-opcua-mcp

Run claude mcp list, or type /mcp in a session, to check the connection.

Once connected, ask your AI tool things like:

  • “Start the OPC UA simulator server and read Simulator.Double.”
  • “Browse the Simulator object, list its methods, and use Simulator.Add to add 1.5 and 2.”
  • “Activate the alarm, receive its event and acknowledge it.”

These are messages an MCP client sends and the server’s replies. The server handles tool requests only after initialize.

{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"docs","version":"1"}}}
{"id":1,"jsonrpc":"2.0","result":{"capabilities":{"tools":{"listChanged":false}},"protocolVersion":"2025-06-18","serverInfo":{"name":"pdcomm-opcua","version":"0.1.0"}}}

The opcua_read tool in tools/list:

{"description":"Read an attribute of nodes; give node or nodes.","inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"anyOf":[{"required":["node"]},{"required":["nodes"]}],"properties":{"attribute":{"description":"AttributeId (default 13, Value).","maximum":27,"minimum":1,"type":"integer"},"node":{"description":"Node. NodeId text such as ns=2;s=Simulator.Double or i=85.","maxLength":512,"minLength":1,"type":"string"},"nodes":{"description":"Up to 100 NodeIds; use instead of node.","items":{"description":"Node. NodeId text such as ns=2;s=Simulator.Double or i=85.","maxLength":512,"minLength":1,"type":"string"},"maxItems":100,"minItems":1,"type":"array"}},"required":[],"type":"object"},"name":"opcua_read","title":"Read"}

A tool call returns the action’s result JSON as text content:

{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"opcua_read","arguments":{"node":"ns=2;s=Simulator.Double"}}}
{"id":5,"jsonrpc":"2.0","result":{"content":[{"text":"{\"values\":[{\"good\":true,\"node\":\"ns=2;s=Simulator.Double\",\"server_time\":1791998196809,\"source_time\":1791998196683,\"status\":\"Good (0x00000000)\",\"type\":\"Double\",\"value\":0.0}]}","type":"text"}],"isError":false}}

When the action fails, isError is true and the text is the error message:

{"id":6,"jsonrpc":"2.0","result":{"content":[{"text":"NodeId must use i= or s= identifiers","type":"text"}],"isError":true}}

Arguments that don’t match the input schema are rejected with a message that starts with Invalid arguments:. How the rejection arrives depends on the negotiated protocol version, as the MCP specification defines it. With 2025-06-18 and 2024-11-05, it’s the JSON-RPC error -32602:

{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"opcua_read","arguments":{"nodes":"ns=2;s=Simulator.Double"}}}
{"error":{"code":-32602,"message":"Invalid arguments: nodes must be an array"},"id":7,"jsonrpc":"2.0"}

With 2025-11-25, it’s a tool result with isError set to true, so the AI tool can correct the call:

{"id":7,"jsonrpc":"2.0","result":{"content":[{"text":"Invalid arguments: nodes must be an array","type":"text"}],"isError":true}}
Error Meaning
-32601 Unknown method or server is not initialized The request came before initialize, or the method isn’t supported.
-32602 Unknown tool: <name> No tool has that name; opcua_shutdown, for example, isn’t a tool.
-32602 Invalid arguments: <reason> With protocol 2025-06-18 or 2024-11-05, the arguments don’t match the tool’s input schema.
-32602 Arguments must be an object arguments isn’t an object.
-32700 The line isn’t valid JSON.

When you cancel a running request with notifications/cancelled, the request is interrupted and gets no reply. When standard input closes, the server cleans up the simulator and exits.

  • The MCP server opens servers and network connections on this computer as the AI tool directs. Connect it only to AI tools you trust.
  • Passwords go in the password argument of opcua_server_start and opcua_connect. The simulator never puts them in replies or logs, but the AI tool’s conversation history may keep them, so use test passwords.