# Description Expose existing stack APIs through **337 additional domain MCP tools**: 114 industrial-companion tools, 35 WoT/xRegistry/document tools, and 188 higher-level stack-workflow tools. The fully enabled catalogue contains **492 tools**; profile selection is not an execution grant. The packages now follow the reviewed structure: **`Opc.Ua.Mcp.Workflows`** contains roles/users, files, alarms and history; **`Opc.Ua.Mcp.WotCon`** contains management/documents and independently registered live WoT execution. GDS and schema tools remain separate packages. The executable composes **18 libraries**. | Workflow | Added domain tools | Profiles | | --- | ---: | --- | | GDS directory, certificates, reference-only credentials/tokens and Part 21 onboarding | 46 | `gds`, `certificates`, `credentials`, `onboarding` | | Roles/users, regular and temporary files, alarms/conditions and historical access | 74 | `roles`, `users`, `files`, `alarms`, `history` | | Bounded runtime types, XSD/BSD/UA JSON, PubSub and REST OpenAPI artifacts | 6 | `schemas` | | Named PubSub transports, remote configuration, declarative adapters/bridges and SKS | 52 | `pubsub-runtime`, `pubsub-configuration`, `pubsub-bridge`, `pubsub-security` | | Live HTTP(S), MQTT, Modbus TCP and OPC UA WoT forms | 10 | `wot-runtime` | - Reuse typed clients, generated proxies, SDK transports, schema providers and injected services rather than introducing another session manager or protocol engine. - Require host enablement plus exact caller/session/secret/network grants. Protected generic Call/Write/node-management/history/file paths enforce the same policy. - Bind classifications, dispatches, file handles and historical cursors to actual UA generations. Recovery cannot retarget an old handle or authorized mutation. Preserve acknowledged results after late cancellation; do not imply atomicity or retry business commands. - Use opaque secret-store references, explicit writable-store registration, issuer/resource/caller binding and reserved capacity before issuance. Report remote success/local persistence failure as partial completion; redact provider-controlled diagnostic text. - Bound new named runtimes to eight per host, two per caller, five-minute idle expiry and a thirty-minute absolute lease by default. Pending/closing resources consume quota; failed cleanup remains visible. Credential invalidation and session recovery close dependent runtimes. - Keep document planning separate from execution, artifacts root-confined and real JSON inputs typed. Preserve old profile ordinals while widening the set to 64 bits. CI grades fully enabled privileged catalogues rather than connection-only views. **Limitations:** live Kafka remains explicitly unavailable because the backend cannot enforce policy on broker-discovered connections; configuration/schema/capability inspection stays available. The latest public Dekaf v1.23.5 was also checked and its DNS injection remains internal. No private-API workaround or bootstrap-only security claim was added. Full legacy Core registration retains its documented JSON-reflection limitation: native tests isolate its four connection descriptors and validate the expanded production registrations, not whole-host NativeAOT support. ## Related Issues - Fixes #4730. ## 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. - [x] 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. - [x] I have addressed **all** PR feedback received.
5.3 KiB
OPC UA MCP schema workflows
Embeddable schemas profile for runtime type discovery and bounded XSD, BSD,
UA JSON, PubSub and REST OpenAPI schema artifacts.
The module reuses the stack's definition resolvers and schema generators. It does not compile supplied code, use Reflection.Emit, or start a UA server. Generated artifacts use the host's configured transfer root and size limits.
Embedding
services.AddOpcUaMcpCore(new OpcUaMcpOptions
{
TransferRoot = artifactDirectory,
MaxTransferBytes = 16 * 1024 * 1024
});
services.AddOpcUaMcpSchema(new McpSchemaOptions { MaxTypes = 256 });
services.AddMcpServer().WithOpcUaSchemaTools(McpToolProfile.Schemas);
WithOpcUaSchemaTools also accepts a composed McpToolProfileSet. Repeated
registration does not duplicate the six schema tools or the four shared
connection tools. Connection tools are available for explicit Session
operations; registered/standard local schemas and REST OpenAPI do not require
a connection.
Hosts can inject IServiceMessageContext, IDataTypeDefinitionResolver
(the default is DataTypeDefinitionRegistry) and IUaSchemaGenerator
implementations. SchemaTools also has a direct constructor. Per-operation
generation always receives a separate finite registry, never the potentially
unlimited host resolver.
Tools
| Tool | Purpose |
|---|---|
schema_list_types |
A live, bounded local namespace or remote HasSubtype page. |
schema_inspect_type |
Actual structure/enum definition, identity, ranks and remote attribute quality. |
schema_load_types |
Explicit client-side registration through the SDK's AOT-safe default complex-type factory. |
schema_generate |
Xsd, Bsd, JsonCompact or JsonVerbose; Type closure or Namespace. |
schema_generate_pubsub |
Payload, DataSetMessage, NetworkMessage or MetaData JSON schema. |
schema_generate_openapi |
Existing REST OpenAPI generator, with optional bounded component schemas. |
Scalar settings are grouped under options; identifiers and actual arrays
remain typed top-level arguments. For example:
{
"typeId": "i=296",
"outputPath": "argument.schema.json",
"options": {
"source": "Registered",
"format": "JsonCompact",
"scope": "Type"
}
}
Use options.source: "Session" plus sessionName for live server definitions.
schema_load_types takes the non-empty typeIds string array and optional
sessionName; it does not accept assembly paths, code, or a dictionary-loading
fallback. Loading affects the current client session's factory, not the server.
Per-root results can report partial client-side registration; successful roots
and dependencies remain registered.
PubSub input uses either a typed fields array or metadataNodeId with
options.source: "Session". Each inline field contains name, dataTypeId
and optional valueRank. All three numeric options.fieldContentMask,
options.messageContentMask and options.networkContentMask are required.
Unused masks must be zero, unknown/unsupported bits are refused, and RawData
cannot be combined with DataValue quality bits. MetaData describes the SDK's
metadata-message envelope; it does not specialize its generic metadata body.
Remote metadata's built-in hints are preserved; custom namespace tables must
match the selected context. Use inline fields with context-local identifiers
when metadata uses a different namespace table. Custom PubSub type names are
limited to letters, digits and underscores, and distinct types cannot share a
schema name, because the current SDK provider otherwise aliases their references.
serverUrl in OpenAPI options is document metadata and is never fetched.
Bounds and fidelity
The default and maximum ceilings are 512 definitions, 1024 fields per type,
32 dependency/array levels, 16 MiB per artifact and 30 seconds per operation.
The host may lower these limits. The shared transfer byte ceiling also applies.
Registered-factory discovery additionally caps its identifier/encoding-alias
scan at 4096 entries before activating further definitions.
Output destinations are preflighted before remote reads, must have existing
parent directories beneath TransferRoot, and are published atomically without
overwriting existing files. Failures and cancellation leave no partial artifact.
Namespace expansion must fit a complete bounded enumeration; a large remote type hierarchy is an error, not a silently incomplete namespace schema. Choose Type scope for an explicitly bounded root closure on such a server. List offsets refer to a live enumeration, not a durable server snapshot.
The tools preserve DataType identifier namespaces independently of BrowseName namespaces. Unknown definitions, ambiguous schema names and unsupported representations fail explicitly. In particular, the SDK BSD generator cannot preserve multidimensional arrays or OptionSet wire forms, and the current generators cannot fully describe unconstrained-dimensional or subtyped-field envelopes. Integer-backed OptionSets are not registered as signed enumerations by the bounded loader. No fallback invents a permissive successful schema. XML/BSD namespace imports remain references; dependency artifacts are not silently generated or fetched.
See the repository's docs/McpServer.md and docs/SchemaGeneration.md
for configuration and the underlying schema contracts.