i3x2ua
Health Warn
- License — License: NOASSERTION
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Turn any OPC UA server into an i3X-compliant REST and MCP Enabled API with OpenAPI docs, JSON, and live SSE streams. No OPC UA expertise required.
i3X API Gateway for OPC UA — REST, MCP & Real-Time Streaming
FastAPI gateway implementing the i3X API over OPC UA — exposes OPC UA address spaces as standardized REST and MCP endpoints with JSON responses, OpenAPI docs, and Server-Sent Event subscriptions. Built for teams that do not have deep OPC UA expertise.

Industrial Information Interoperability eXchange (i3X)
The Industrial Information Interoperability Exchange (i3X™) is an open, common API initiative proposed to address a growing interoperability challenge in modern manufacturing architectures: manufacturing data silo proliferation and API chaos. As manufacturers adopt heterogeneous software stacks from multiple vendors, the industry risks repeating past fragmentation seen with protocols, platforms, and namespaces - this time at the API layer.
License
Personal use only.
All rights reserved. See the LICENSE file for details.
Commercial Licensing
Commercial use, distribution, or modification of this code is strictly prohibited under the standard license. If you want to use this project for commercial purposes, please purchase a commercial license.
However, you can automatically acquire a commercial license by sponsoring this project on GitHub. Commercial use is permitted as long as you maintain an active sponsorship at the [$1 a month] level or higher.
Get your commercial license instantly here:
- Become a Sponsor: Sponsor me on GitHub
Alternatively, for custom licensing agreements or one-time purchases, please contact me directly:
- Email: [email protected]
Architecture Overview
flowchart LR
Client[i3X Client / Consumer] -->|HTTP JSON| Nginx[nginx Reverse Proxy]
Nginx -->|/v1| API[FastAPI App i3x_server.main]
subgraph App[Application Core]
API --> Router[V1 Router /v1]
API -. optional /mcp .-> McpRouter[MCP Router /mcp]
McpRouter -->|generated tools| McpTools[(MCP Tool Catalog)]
McpRouter -->|tool calls| Router
Router --> Deps[Dependency Layer]
Deps --> ModelCache[(Model Cache)]
Deps --> SubSvc[i3X Subscription Service]
Deps --> OpcClient[OPC UA Client]
end
subgraph Model[Model Layer]
Builder[Model Builder] --> Mapper[Node Mapper]
Mapper --> BuildResult[BuildResult Indexes]
BuildResult --> ModelCache
end
OpcClient -->|browse tree + metadata| Builder
OpcClient -->|read values/history| Router
OpcClient <-->|OPC UA binary protocol| UaServer[(External OPC UA Server)]
UaServer -->|address space browse + read + history + events| OpcClient
Router -.->|write endpoints currently not implemented| OpcClient
Router -->|object/value/history responses| Client
subgraph Subs[Subscribe Flow]
Router -->|create/register/sync/list/delete/stream| SubSvc
SubSvc -->|native subscription when limits allow| OpcClient
SubSvc -->|polling fallback| OpcClient
SubSvc -->|SSE updates| Router
Router -->|text/event-stream| Client
end
subgraph Startup[Lifecycle]
StartupCfg[Settings env I3X_* + I3X_ENABLE_MCP] --> API
API -->|startup| OpcClient
API -->|optional preload| Builder
API -->|shutdown| SubSvc
API -->|shutdown| OpcClient
end
sequenceDiagram
participant C as Client
participant R as /v1 Router
participant D as Dependencies
participant M as Model Cache/Builder
participant O as OPC UA Client
participant U as OPC UA Server
participant S as i3X Subscription Service
Note over C,R: Read current values
C->>R: POST /v1/objects/value
R->>D: get_or_build_model()
D->>M: cache hit? else build()
M-->>D: BuildResult
R->>O: read_values(node_ids)
O->>U: Read/Browse requests
U-->>O: values + metadata
O-->>R: values
R-->>C: bulk success/error envelope
Note over C,R: Streaming subscription
C->>R: POST /v1/subscriptions
R->>S: create_subscription()
S-->>R: subscriptionId
R-->>C: success
C->>R: POST /v1/subscriptions/register
R->>S: register_items(elementIds,maxDepth)
S->>O: native subscribe OR polling loop
O->>U: MonitoredItems or periodic reads
U-->>O: data changes
O-->>S: normalized updates
C->>R: POST /v1/subscriptions/stream
R->>S: wait_for_updates(afterSequence)
S-->>R: sequence updates
R-->>C: SSE data events + keepalive
Note over C,R: Write API paths exist in spec but can return 501 when optional update operations are not implemented
Quick Start
Requirements:
- Python 3.10 to 3.12
- uv
- Optional: running OPC UA server
Install dependencies:
uv sync --extra dev
Start API:
uv run uvicorn i3x_server.main:app --reload --host 127.0.0.1 --port 8000
Start without OPC UA server (PowerShell):
$env:I3X_SKIP_OPCUA_CONNECT="1"
uv run uvicorn i3x_server.main:app --reload --host 127.0.0.1 --port 8000
Enable MCP support explicitly when you want the /mcp endpoints and MCP tool catalog to be available:
$env:I3X_ENABLE_MCP="1"
uv run uvicorn i3x_server.main:app --reload --host 127.0.0.1 --port 8000
If you do not set I3X_ENABLE_MCP, the app starts without MCP support and /mcp returns 404.
Use encrypted OPC UA with the included sample client certificate (development/testing):
uv run python scripts/generate_opcua_client_cert.py
$env:I3X_OPCUA_SECURITY_MODE="SignAndEncrypt"
$env:I3X_OPCUA_SECURITY_POLICY="Basic256Sha256"
$env:I3X_OPCUA_CLIENT_CERT_PATH="./certs/opcua-client-sample/client-cert.pem"
$env:I3X_OPCUA_CLIENT_KEY_PATH="./certs/opcua-client-sample/client-key.pem"
uv run uvicorn i3x_server.main:app --reload --host 127.0.0.1 --port 8000
The OPC UA server may require manually trusting the sample client certificate before the secure session can be established.
If you create your own OPC UA client certificates, ensure they include OPC UA-compatible SAN and key usage fields (application URI, DNS names, clientAuth EKU, and signing/encipherment key usages) and match the server's exposed security mode/policy.
OpenAPI/Swagger:
API Surface
Active endpoints are exposed under /v1 for:
- info and metadata (
/info,/namespaces,/objecttypes,/relationshiptypes) - filtered type queries (
/objecttypes/query,/relationshiptypes/query) - object queries and values (
/objects,/objects/list,/objects/related,/objects/value,/objects/history) - subscriptions (
/subscriptions,/subscriptions/register,/subscriptions/unregister,/subscriptions/sync,/subscriptions/list,/subscriptions/delete,/subscriptions/stream)
Current scope emphasis: this implementation currently prioritizes read/query/subscribe operations.
Optional MCP endpoints are exposed only when I3X_ENABLE_MCP=1:
- discovery and tool catalog (
/mcp,/mcp/tools) - JSON-RPC and tool call entry points (
/mcp,/mcp/call)
MCP scope emphasis: the MCP bridge is currently focused on tool calling (initialize, tools/list, tools/call) for the current implementation scope.
Current Limitations
- write APIs currently return
501 Not Implemented(PUT /v1/objects/{element_id}/value,PUT /v1/objects/{element_id}/history) GET /v1/objects/{element_id}/historycurrently returns501 Not Implemented- server capabilities report updates as not supported while read/history/streaming are supported
Documentation
- i3X upstream specification materials:
i3X/spec/README.md - i3X conformance tests:
i3X/conformance-tests/README.md - OPC UA to i3X mapping profile:
docs/OPCUA_I3X_MAPPING_PROFILE.md - OPC UA client behavior and optimization guide:
docs/OPCUA_CLIENT_DOCUMENTATION.md - LM Studio / MCP bridge guide (including capability matrix):
docs/LM_STUDIO_MCP_GUIDE.md - deployment guide index:
docs/PRODUCTION_DEPLOYMENT_INDEX.md - quick ops reference:
docs/QUICK_REFERENCE.md - Python coding requirements:
python-coding-reguirements.md - API definition:
openapi.json
Docker
Run with compose:
docker compose up -d
The stack now starts the API behind an nginx reverse proxy. The app container stays internal, while nginx exposes HTTP and optional HTTPS.
The default compose setup also enables container hardening (read_only, tmpfs, dropped Linux capabilities, no-new-privileges).
Optional environment variables:
I3X_ENABLE_MCP=1to enable MCP support; it is disabled by defaultI3X_OPCUA_CERTS_DIR=./certsto mount OPC UA client/server certificate files into the app container (/app/certs)NGINX_HTTPS_ENABLED=1to enable TLS terminationNGINX_SSL_CERTS_DIR=./certswithfullchain.pemandprivkey.pemNGINX_BASIC_AUTH_ENABLED=1withNGINX_BASIC_AUTH_USERandNGINX_BASIC_AUTH_PASSWORDNGINX_SERVER_NAMEfor the public host name
If you enable HTTPS, mount or place the certificate files in the configured cert directory before starting Compose.
If your OPC UA server runs on the Docker host machine, set I3X_OPCUA_ENDPOINT to opc.tcp://host.docker.internal:<port> instead of 127.0.0.1.
For local HTTPS testing with the nginx reverse proxy, generate sample certificates:
uv run python scripts/generate_https_dev_cert.py
Then use these environment values:
NGINX_HTTPS_ENABLED=1NGINX_SSL_CERTS_DIR=./certsNGINX_SSL_CERTIFICATE=/etc/nginx/certs/https-sample/fullchain.pemNGINX_SSL_CERTIFICATE_KEY=/etc/nginx/certs/https-sample/privkey.pem
Development
uv run ruff check .
uv run ruff format .
uv run mypy .
uv run pytest -q
uv run pytest -q --cov=i3x_server --cov-report=term-missing
Production Deployment and i3X Strict Compliance
This application implements the i3X API specification and is designed to run behind a reverse proxy that is responsible for:
- TLS termination — the app itself serves plain HTTP; all HTTPS is handled by nginx.
- Authentication and authorization — the app has no built-in auth layer; token validation, basic auth, or mTLS are enforced at the proxy level.
Required reverse proxy responsibilities for strict i3X compliance
| Requirement | Implementation |
|---|---|
| TLS (HTTPS) for all client-facing traffic | nginx ssl_certificate + ssl_certificate_key |
| Client authentication (API key / OAuth / mTLS) | nginx auth_request or satisfy any directives |
| Rate limiting | nginx limit_req_zone |
| Access logging | nginx access_log |
See the NGINX configuration reference and HTTPS guide for details.
OPC UA → i3X Relationship Mapping
The model builder maps OPC UA reference types to i3X relationship planes.
Classification is based on the reference type id and recursively resolved supertypes
(following HasSubtype inverse for ReferenceType nodes):
| OPC UA Reference | i3X Relationship Plane | i3X Types |
|---|---|---|
HierarchicalReferences, Organizes and recursively resolved subtypes |
Hierarchy | HasChildren / HasParent |
HasComponent, HasOrderedComponent, HasProperty and recursively resolved subtypes |
Composition | HasComponent / ComponentOf |
NonHierarchicalReferences and recursively resolved subtypes |
Graph | custom label |
HasTypeDefinition |
Type metadata only | — |
HasSubtype |
Type metadata only | — |
If a reference type cannot be classified after id/name/supertype checks, it is mapped
deterministically to the Graph plane.
POST /objects/value and POST /objects/history recurse through composition children only when maxDepth > 1. Hierarchy-only children are never included in value recursion.
maxDepth Semantics (Hierarchy vs Composition)
Value/history recursion follows only the composition plane (HasComponent / ComponentOf).
Hierarchy edges (HasChildren / HasParent) are used for structure/navigation and root selection, not for value recursion.
| Request | Traversal behavior |
|---|---|
maxDepth = 1 |
No recursion. Return only the requested element's value/history payload. |
maxDepth = 2 |
Include direct composition children only. |
maxDepth = n (>1) |
Include composition descendants up to depth n-1 from the root query element. |
maxDepth = 0 |
Unlimited recursion across composition descendants. |
Example:
- Hierarchy:
Plant -> Line -> Pump - Composition:
Pump -> Temperature,Pump -> Pressure
POST /objects/value for Plant with maxDepth = 0 does not include Pump values via hierarchy.POST /objects/value for Pump with maxDepth = 0 includes Temperature and Pressure as components.
POST /objects/related returns relationships across all three planes (hierarchy, composition, and graph) for each requested element.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found