# Description Fix five failures reproduced while exercising the recycling sample through a locally built OPC UA MCP server: - Support Certificate authentication through named, host-approved X.509 identity selectors and the existing certificate/identity providers. Tool arguments cannot supply private keys or arbitrary certificate-store paths. - Register custom enumeration dependencies from the validated, bounded type snapshot before loading requested structure roots. - Preserve structured fields and opaque encoded bodies in generic read/call results using the selected session's UA codecs. - Add bounded, explicitly typed UA JSON method arguments while retaining the existing string argument behavior and C# overloads. - Preserve omitted defaults in sparse recycling scenario JSON; explicit invalid values and unknown members still fail validation. All six shipped scenario files are covered by regressions. Update the MCP and recycling documentation. This PR contains one fix commit on a feature branch in **OPCFoundation/UA-.NETStandard**, based directly on upstream `master` at `95850b7e5`. No local registration, certificates, scenario journals or live-test artifacts are included. ### Validation **Final commit `d199feba0`: 216 affected MCP tests and 16 recycling CLI/scenario tests passed on .NET 10**, with no failures, fixture setup/teardown errors or build/analyzer warnings. The repository's TRX verdict helper accepted both reports. **Draft: the full-solution gate is not green.** The .NET 10 solution run encountered an `Opc.Ua.OneFuzz.Validator.Tests` fixture-publication failure outside the files changed by this PR: `MSB3030`, missing `Opc.Ua.OneFuzz.TestDependency.runtimeconfig.json`. It affected 210 tests; the run was stopped rather than expanding this PR into unrelated OneFuzz work. The full .NET Framework 4.8 solution suite was not run. Before the final rebase, the complete managed recycling suite passed **117**, and the CLI/scenario tests passed **16 each on .NET 8 and .NET 9**, with no failures or fixture teardown errors. The five explicit NativeAOT smoke cases were not selected. Actual live qualification used one coordinator and all ten independent process servers with strict certificate trust. Healthy, combined-fault and zero-utility runs each produced 24 complete packages with exact component conservation. Also exercised native companion discovery, subscriptions, authorization, pause/step/enable/disable, durable request replay, quality holds, reset and coordinator crash recovery. NativeAOT executables, container deployment and parity against a complete external producer contract were not qualified. <details> <summary>Exact validation commands and results</summary> Commands ran from the repository root with an isolated .NET SDK 10.0.401. `$root` denotes the private validation-artifact directory; no machine-specific path or key material is included here. Affected MCP matrix, final commit — **passed: 216; failed: 0; skipped: 0**: ```powershell dotnet test tests\Opc.Ua.Tools.Tests\Opc.Ua.Tools.Tests.csproj -c Release -f net10.0 -p:CustomTestTarget=net10.0 -p:CustomTargetFrameworks=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --no-restore --nologo -v:quiet --filter 'FullyQualifiedName~SchemaRemoteTests|FullyQualifiedName~OpcUaJsonHelperTests|FullyQualifiedName~MethodServiceToolsTests|FullyQualifiedName~ConvenienceToolsTests|FullyQualifiedName~AttributeServiceToolsTests|FullyQualifiedName~ViewServiceToolsTests|FullyQualifiedName~OpcUaSessionManagerTests|FullyQualifiedName~ConnectionToolsTests|FullyQualifiedName~McpHostBuilderTests|FullyQualifiedName~ConfigurationToolsTests' --logger 'trx;LogFileName=mcp-pr.trx' --results-directory "$root\pr-validation\focused" ``` .NET 10 CLI/scenario regressions, final commit — **passed: 16; failed: 0; skipped: 0**: ```powershell dotnet test tests\Opc.Ua.Recycling.Samples.Tests\Opc.Ua.Recycling.Samples.Tests.csproj -c Release -f net10.0 -p:CustomTestTarget=net10.0 -p:CustomTargetFrameworks=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --no-restore --nologo -v:quiet --filter 'FullyQualifiedName~RecyclingCommandLineTests' --logger 'trx;LogFileName=recycling-cli-pr.trx' --results-directory "$root\pr-validation\focused" ``` Complete managed recycling suite, before rebase — **passed: 117; failed: 0; skipped: 0** (five explicit NativeAOT cases not selected): ```powershell dotnet test tests\Opc.Ua.Recycling.Samples.Tests\Opc.Ua.Recycling.Samples.Tests.csproj -c Release -f net10.0 -p:CustomTestTarget=net10.0 -p:CustomTargetFrameworks=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --no-restore --nologo -v:quiet --logger 'trx;LogFileName=recycling-final.trx' --results-directory (Join-Path $root 'results') ``` .NET 8 CLI/scenario regressions, before rebase — **passed: 16; failed: 0; skipped: 0**: ```powershell dotnet test tests\Opc.Ua.Recycling.Samples.Tests\Opc.Ua.Recycling.Samples.Tests.csproj -c Release -f net8.0 -p:CustomTestTarget=net8.0 -p:CustomTargetFrameworks=net8.0 -p:UseSharedCompilation=false -m:1 -nr:false --nologo -v:quiet --filter 'FullyQualifiedName~RecyclingCommandLineTests' --logger 'trx;LogFileName=recycling-cli-net8.trx' --results-directory "$root\results" ``` .NET 9 CLI/scenario regressions, before rebase — **passed: 16; failed: 0; skipped: 0**: ```powershell dotnet test tests\Opc.Ua.Recycling.Samples.Tests\Opc.Ua.Recycling.Samples.Tests.csproj -c Release -f net9.0 -p:CustomTestTarget=net9.0 -p:CustomTargetFrameworks=net9.0 -p:UseSharedCompilation=false -m:1 -nr:false --nologo -v:quiet --filter 'FullyQualifiedName~RecyclingCommandLineTests' --logger 'trx;LogFileName=recycling-cli-net9.trx' --results-directory "$root\results" ``` Full .NET 10 solution — **not passed**: stopped after the OneFuzz fixture failure above; incomplete solution run, not a clean validation result: ```powershell dotnet test UA.slnx -c Release -p:CustomTestTarget=net10.0 -p:CustomTargetFrameworks=net10.0 -p:UseSharedCompilation=false -m:1 -nr:false --nologo -v:quiet --logger trx --results-directory "$root\pr-validation\net10" ``` </details> ## Related Issues Follow-up to [#4772](https://github.com/OPCFoundation/UA-.NETStandard/pull/4772), which introduced the recycling sample. No separate tracking issue is currently linked. These fixes preserve the existing architecture and address failures reproduced during live qualification. ## Checklist _Put an `x` in the boxes that apply. You can complete these step by step after opening the PR._ - [ ] I have signed the [CLA](https://opcfoundation.org/license/cla/ContributorLicenseAgreementv1.0.pdf) and read the [CONTRIBUTING](https://github.com/OPCFoundation/UA-.NETStandard/blob/master/CONTRIBUTING.md) doc. - [ ] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added all necessary documentation. - [x] I have verified that my changes do not introduce (new) build or analyzer warnings. - [ ] I ran **all** tests locally using the **UA.slnx** solution against at least .net **framework** and .net **10**, and all passed. - [ ] I fixed **all** failing and flaky tests in the CI pipelines and **all** CodeQL warnings. - [ ] I have addressed **all** PR feedback received. Regression tests were added and passed as recorded above; aggregate coverage was not collected, so the combined coverage checklist item remains unchecked. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: marcschier <11168470+marcschier@users.noreply.github.com>
9.5 KiB
OPC UA MCP Server
A Model Context Protocol (MCP) server that exposes OPC UA Part 4 service calls as MCP tools, enabling AI assistants (Claude, GitHub Copilot, VS Code, etc.) to interact with OPC UA servers.
Run without installing (.NET 10 SDK)
dotnet tool exec OPCFoundation.NetStandard.Opc.Ua.Mcp
# Short form
dnx OPCFoundation.NetStandard.Opc.Ua.Mcp
Install globally
dotnet tool install --global OPCFoundation.NetStandard.Opc.Ua.Mcp
The tool includes Robotics, Vision and the AMB, Machinery, Scales, Pumps,
Device Integration, ISA-95, Positioning, MachineTool (with bundled WMTP), GMS,
CranesHoists, WoT and xRegistry profiles. Profiles compose, for example
--profile machinery,isa95, --profile machinetool,gms,craneshoists, or
--profile core,wot,xregistry,wot-documents. wot-documents needs no UA connection.
Additional profiles expose GDS/credential issuance, roles/users, files, alarms,
history, schemas, PubSub configuration/bridges/SKS and live WoT execution.
Usage
The examples below assume a global installation. For run-on-demand use,
replace opcua-mcp with dnx OPCFoundation.NetStandard.Opc.Ua.Mcp --.
# stdio transport (default) — for Claude Desktop, VS Code, Copilot
opcua-mcp
# Streamable HTTP transport (exposed only at /mcp) — for remote clients
opcua-mcp --transport http --port 5100
# --transport sse is a deprecated alias for --transport http
Client configuration
For on-demand execution, clients supporting command/argument arrays can use:
{
"mcpServers": {
"opcua": {
"command": "dotnet",
"args": ["tool", "exec", "OPCFoundation.NetStandard.Opc.Ua.Mcp", "--", "--profile", "core"]
}
}
}
After global installation, Claude Desktop and Cursor can use:
{
"mcpServers": {
"opcua": { "command": "opcua-mcp" }
}
}
Claude's file is typically %APPDATA%\Claude\claude_desktop_config.json on
Windows or ~/Library/Application Support/Claude/claude_desktop_config.json
on macOS. Use the corresponding MCP settings in Cursor.
VS Code / GitHub Copilot uses .vscode/mcp.json:
{
"servers": {
"opcua": { "command": "opcua-mcp" }
}
}
Host authority and shared transfer configuration are documented in the Core package reference; document dependency configuration is in the WoT package reference.
Tools
The server exposes tools through a tool profile — a bounded, named catalog
selected with
--profile <name>. Run opcua-mcp --help for the current profile names.
Profiles can be composed, for example --profile vision,robotics. full is the
default; the other profiles expose smaller focused subsets. See the
full documentation
for the profile-to-tool mapping.
Host-disabled privileged/live tools stay hidden even under full. Explicit
host capabilities and exact caller/session/network grants are required to
enable them; a profile is never an execution grant.
Tools in the full profile cover all OPC UA Part 4 service sets:
- Connection: Connect, ConnectCertificate, Disconnect, GetConnectionStatus
- Attribute: Read, Write, HistoryRead, HistoryUpdate
- View: Browse, BrowseNext, TranslateBrowsePaths, RegisterNodes, UnregisterNodes, QueryFirst, QueryNext
- Node Management: AddNodes, AddReferences, DeleteNodes, DeleteReferences
- Method: Call
- Subscription: CreateSubscription, ModifySubscription, SetPublishingMode, Publish, Republish, DeleteSubscriptions, TransferSubscriptions
- MonitoredItem: CreateMonitoredItems, ModifyMonitoredItems, SetMonitoringMode, SetTriggering, DeleteMonitoredItems
- Discovery: FindServers, FindServersOnNetwork, GetEndpoints, RegisterServer, RegisterServer2
- Convenience: ReadValue, ReadValues, WriteValue, BrowseAll, CallMethod, ReadNode, Cancel
- Robotics: typed Robot Intent control and missions, paged monitoring,
bounded operation/mission waits, and same-session
robotics_vision_pick - Vision: image capture, structured one-shot inference, result monitoring, feedback and frame-graph composition
- MachineTool/WMTP: native monitoring, tools/life, production/jobs, remote files, independent peripheral measurements, records and explicit configuration
- GMS: native equipment/qualification/calibration and result workflows, bounded observations and consented result acknowledgment
- CranesHoists: observed topology and raw measurements with authorized standard speed-limit requests, never physical motion commands
- Industrial companions: asset management, machinery, weighing, pumps, device integration, ISA-95 jobs and relative/global positioning. See the companion guide.
- WoT and xRegistry: explicit asset/registry/version/label operations, bounded events and content transfers, document validation, binding planning and bidirectional WoT/NodeSet conversion. Remote dependencies require both request opt-in and the host's exact HTTPS origin allowlist; bindings are not executed by these document/management profiles.
- GDS and credentials: directory, pull/push certificate lifecycle, KeyCredential/token issuance and refresh, and Part 21 onboarding. Inputs and outputs use authorized secret-store references, never private material.
- General workflows: role/user administration, bounded regular/temporary files, alarms/conditions, historical reads/mutations and schema artifacts.
- PubSub and live WoT: named runtimes with caller ownership, quotas, idle/absolute expiry and network/operation allowlists. WoT execution supports HTTP(S), MQTT, Modbus TCP and OPC UA. Live Kafka remains disabled until its backend can enforce policy on every broker-discovered connection; Kafka configuration and schema tools remain available.
Companion calls preserve server failures, use bounded lists and observations,
and never acquire locks or retry commands implicitly. Package upload and result
download require OPCUA_MCP_TRANSFER_ROOT; the default streaming byte limit is
64 MiB (OPCUA_MCP_MAX_TRANSFER_BYTES). Paths cannot escape the configured root.
Embedding
The tools also ship as libraries, so an application can offer OPC UA tools to an LLM alongside its own without forking this server:
builder.Services.AddOpcUaMcpCore();
builder.Services.AddMcpServer()
.WithStdioServerTransport()
.WithOpcUaMcpFilters()
.WithOpcUaCoreTools(McpToolProfile.Services)
.WithTools<MyApplicationTools>();
| Package | Tools |
|---|---|
OPCFoundation.NetStandard.Opc.Ua.Mcp.Core |
Part 4 services, connection, configuration, PKI, NodeSet export |
OPCFoundation.NetStandard.Opc.Ua.Mcp.PubSub |
PubSub transports, configuration, bridges, SKS, actions, discovery |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Diagnostics |
UA-TCP capture, decode, replay |
OPCFoundation.NetStandard.Opc.Ua.Mcp.PubSub.Diagnostics |
PubSub capture, decode |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Robotics |
Robot Intent control, missions, waits and Vision-guided Pick |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Vision |
Vision discovery, seeing, inference, feedback and geometry |
OPCFoundation.NetStandard.Opc.Ua.Mcp.MachineTool |
MachineTool and bundled wireless-peripheral workflows |
OPCFoundation.NetStandard.Opc.Ua.Mcp.GMS |
GMS systems, results, downloads and observations |
OPCFoundation.NetStandard.Opc.Ua.Mcp.CranesHoists |
Crane monitoring and authorized limit requests |
OPCFoundation.NetStandard.Opc.Ua.Mcp.AMB |
Asset management |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Machinery |
Machine monitoring, process values, energy and results |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Scales |
Weighing, products and recipes |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Pumps |
Pump values, supervision and maintenance |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Di |
Device integration, locking and updates |
OPCFoundation.NetStandard.Opc.Ua.Mcp.ISA95 |
Common objects and V1/V2 job control |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Positioning |
Spatial frames and coordinate conversion |
OPCFoundation.NetStandard.Opc.Ua.Mcp.WotCon |
WoT management/documents and separately registered, policy-controlled live bindings |
OPCFoundation.NetStandard.Opc.Ua.Mcp.XRegistry |
Generic registry/version/label/content operations |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Gds |
GDS, certificates, credential/token references, onboarding |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Workflows |
Roles/users, files, alarms and historical access |
OPCFoundation.NetStandard.Opc.Ua.Mcp.Schema |
Bounded types and XSD/BSD/JSON, PubSub and OpenAPI artifacts |
Robotics and CranesHoists libraries remain preview-only, including Debug variants. The other MCP libraries, including Vision, MachineTool and GMS, follow the root release channel and are stable when the root release is stable. WMTP has no separate package/profile. A development root version can still be prerelease. Conformance depends on actual endpoints/providers; GMS's documented undefined Production-statistics CU does not justify advertising that full facet.
Documentation
See the full documentation.