CLI Tool
The opcsharp CLI tool helps you explore and diagnose OPC UA servers from the command line. It supports endpoint discovery, address space browsing, node value reading, connectivity checks, and code scaffolding.
Quick Reference
| Command | Description |
|---|---|
opcsharp discover <endpoint> | List server endpoints, security policies, and auth types |
opcsharp browse <endpoint> | Browse address space as a tree |
opcsharp read <endpoint> <nodeIds...> | Read node values, display names, and status codes |
opcsharp check <endpoint> | Step-by-step connectivity diagnostics |
opcsharp init | Generate a C# client code snippet |
All commands support --json for machine-readable output. The browse, read, and check commands support --username/--password for authenticated servers and --security-policy/--security-mode for explicit security configuration. Credentials can also be set via OPCUA_USERNAME/OPCUA_PASSWORD environment variables or a .env file.
Installation
Install as a .NET global tool:
dotnet tool install --global OpcSharp.ToolAfter installation, the tool is available as opcsharp:
opcsharp --helpRequirements
- .NET 8.0 SDK or later
Update
dotnet tool update --global OpcSharp.ToolUninstall
dotnet tool uninstall --global OpcSharp.ToolCommands
discover — Discover Server Endpoints
Lists all endpoints exposed by an OPC UA server, including their security policies, security modes, and supported authentication types. This command does not require a session — it works even on servers that require credentials.
opcsharp discover <endpoint> [options]Arguments:
| Argument | Description |
|---|---|
endpoint | OPC UA server endpoint URL (e.g., opc.tcp://localhost:4840) |
Options:
| Option | Default | Description |
|---|---|---|
--timeout | 10 | Connection timeout in seconds |
--auto-accept | true | Auto-accept untrusted server certificates |
--json | false | Output as JSON instead of a formatted table |
Examples:
# Discover endpoints on a local server
opcsharp discover opc.tcp://localhost:4840
# Discover with JSON output
opcsharp discover opc.tcp://192.168.1.100:4840 --json
# Discover with a custom timeout
opcsharp discover opc.tcp://192.168.1.100:4840 --timeout 30Example output:
Server: My OPC UA Server
URI: urn:myserver:opcua
┌─────────────────────────────────┬──────────────────┬──────────────────┬────────────────────┐
│ Endpoint URL │ Security Policy │ Security Mode │ User Tokens │
├─────────────────────────────────┼──────────────────┼──────────────────┼────────────────────┤
│ opc.tcp://localhost:4840 │ None │ None │ Anonymous │
│ opc.tcp://localhost:4840 │ Basic256Sha256 │ SignAndEncrypt │ Anonymous, UserName│
└─────────────────────────────────┴──────────────────┴──────────────────┴────────────────────┘browse — Browse the Address Space
Displays the server’s address space as a tree, starting from a given node. When connecting to a server that requires authentication, provide --username and --password to auto-discover the best secure endpoint.
opcsharp browse <endpoint> [options]Arguments:
| Argument | Description |
|---|---|
endpoint | OPC UA server endpoint URL |
Options:
| Option | Default | Description |
|---|---|---|
--node | i=85 | Starting NodeId (default: Objects folder) |
--depth | 2 | Maximum browse depth (1–10) |
--timeout | 10 | Connection timeout in seconds |
--auto-accept | true | Auto-accept untrusted server certificates |
--username | Username for authentication | |
--password | Password for authentication | |
--security-policy | Security policy (e.g., None, Basic256Sha256, Aes128_Sha256_RsaOaep) | |
--security-mode | Security mode: None, Sign, or SignAndEncrypt | |
--json | false | Output as JSON |
Examples:
# Browse the Objects folder (default)
opcsharp browse opc.tcp://localhost:4840
# Browse a specific node with depth 3
opcsharp browse opc.tcp://localhost:4840 --node "i=2253" --depth 3
# Browse a server that requires credentials
opcsharp browse opc.tcp://192.168.1.100:4840 --username myuser --password "mypass"
# Browse with explicit security policy
opcsharp browse opc.tcp://192.168.1.100:4840 --security-policy Basic256Sha256 --security-mode SignAndEncrypt
# Browse with JSON output
opcsharp browse opc.tcp://localhost:4840 --jsonExample output:
Objects (i=85) [Object]
├── Server (i=2253) [Object]
│ ├── ServerStatus (i=2256) [Variable]
│ ├── ServiceLevel (i=2267) [Variable]
│ └── Namespaces (i=11715) [Object]
└── PLC1 (ns=4;s=PLC1) [Object]
└── MAIN (ns=4;s=MAIN) [Object]
└── counter (ns=4;s=MAIN.counter) [Variable]read — Read Node Values
Reads the value, display name, status code, and source timestamp for one or more OPC UA nodes.
opcsharp read <endpoint> <nodeIds...> [options]Arguments:
| Argument | Description |
|---|---|
endpoint | OPC UA server endpoint URL |
nodeIds | One or more Node IDs to read (e.g., i=2258, "ns=2;s=Temperature") |
Options:
| Option | Default | Description |
|---|---|---|
--timeout | 10 | Connection timeout in seconds |
--auto-accept | true | Auto-accept untrusted server certificates |
--username | Username for authentication | |
--password | Password for authentication | |
--security-policy | Security policy (e.g., None, Basic256Sha256, Aes128_Sha256_RsaOaep) | |
--security-mode | Security mode: None, Sign, or SignAndEncrypt | |
--json | false | Output as JSON |
Examples:
# Read the server's current time
opcsharp read opc.tcp://localhost:4840 i=2258
# Read multiple nodes
opcsharp read opc.tcp://localhost:4840 i=2258 i=2259
# Read a namespaced string node with credentials
opcsharp read opc.tcp://192.168.1.100:4840 "ns=4;s=MAIN.counter" --username myuser --password "mypass"
# Read with explicit security policy and credentials
opcsharp read opc.tcp://192.168.1.100:4840 i=2258 --security-policy Basic256Sha256 --username myuser --password "mypass"
# Read with JSON output
opcsharp read opc.tcp://localhost:4840 i=2258 --jsonNote: Node IDs containing semicolons (e.g.,
ns=4;s=MAIN.counter) must be quoted to prevent the shell from interpreting;as a command separator.
Example output:
┌─────────────────────┬─────────────┬──────────────────────────┬────────────┬──────────────────────────────┐
│ NodeId │ DisplayName │ Value │ StatusCode │ Timestamp │
├─────────────────────┼─────────────┼──────────────────────────┼────────────┼──────────────────────────────┤
│ i=2258 │ CurrentTime │ 2026-03-13T14:45:19.959Z │ Good │ 2026-03-13T14:45:19.9598494Z │
└─────────────────────┴─────────────┴──────────────────────────┴────────────┴──────────────────────────────┘Supported NodeId formats:
| Format | Example | Description |
|---|---|---|
i=N | i=2258 | Numeric NodeId in namespace 0 |
s=Name | s=MyVar | String NodeId in namespace 0 |
ns=N;i=M | ns=2;i=1001 | Numeric NodeId in namespace N |
ns=N;s=Name | ns=4;s=MAIN.counter | String NodeId in namespace N |
check — Connectivity Check
Runs a step-by-step connectivity diagnostic against an OPC UA server. Each step is tested independently and reports pass/fail with timing.
opcsharp check <endpoint> [options]Arguments:
| Argument | Description |
|---|---|
endpoint | OPC UA server endpoint URL |
Options:
| Option | Default | Description |
|---|---|---|
--timeout | 30 | Connection timeout in seconds |
--auto-accept | true | Auto-accept untrusted server certificates |
--username | Username for authentication | |
--password | Password for authentication | |
--security-policy | Security policy (e.g., None, Basic256Sha256, Aes128_Sha256_RsaOaep) | |
--security-mode | Security mode: None, Sign, or SignAndEncrypt | |
--json | false | Output as JSON |
Anonymous check (no credentials, no explicit security) runs these steps:
- DNS Resolution
- TCP Connection
- OPC UA Hello/ACK
- OpenSecureChannel
- CreateSession
- ActivateSession
- Read Server Status
- Close Connection
Authenticated check (with --username/--password) runs these steps:
- DNS Resolution
- TCP Connection
- Discover Endpoints — finds the best secure endpoint supporting UserName authentication
- Secure Connect — connects with the discovered security policy and credentials
- Read Server Status
- Close Connection
Examples:
# Anonymous connectivity check
opcsharp check opc.tcp://localhost:4840
# Authenticated check against a secured server
opcsharp check opc.tcp://192.168.1.100:4840 --username myuser --password "mypass"
# Check with explicit security policy
opcsharp check opc.tcp://192.168.1.100:4840 --security-policy Basic256Sha256
# Check with extended timeout
opcsharp check opc.tcp://192.168.1.100:4840 --timeout 60Example output:
Checking opc.tcp://192.168.1.100:4840...
✓ DNS Resolution 12ms
✓ TCP Connection 8ms
✓ Discover Endpoints 156ms
✓ Secure Connect 423ms
✓ Read Server Status 34ms
✓ Close Connection 18ms
All checks passed.init — Generate Client Code
Generates a C# code snippet for setting up an OpcSharp client. In interactive mode (terminal), it prompts for configuration. In non-interactive mode (piped/scripted), it uses defaults or the provided options.
opcsharp init [options]Options:
| Option | Default | Description |
|---|---|---|
--endpoint | opc.tcp://localhost:4840 | OPC UA endpoint URL |
--security-policy | None | Security policy (None, Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss) |
--security-mode | None | Security mode (None, Sign, SignAndEncrypt) |
--auth | Anonymous | Authentication type (Anonymous, Username, Certificate) |
--session-name | MyOpcUaClient | Session name |
--output | Write generated code to a file instead of stdout | |
--json | false | Output as JSON |
Examples:
# Interactive — prompts for all settings
opcsharp init
# Non-interactive with options
opcsharp init --endpoint opc.tcp://192.168.1.100:4840 --security-policy Basic256Sha256 --security-mode SignAndEncrypt --auth Username
# Save to file
opcsharp init --output MyClient.csSecurity Policy Names
The --security-policy option accepts these short names (case-insensitive):
| Name | Full URI |
|---|---|
None | http://opcfoundation.org/UA/SecurityPolicy#None |
Basic128Rsa15 | http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15 |
Basic256 | http://opcfoundation.org/UA/SecurityPolicy#Basic256 |
Basic256Sha256 | http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256 |
Aes128_Sha256_RsaOaep | http://opcfoundation.org/UA/SecurityPolicy#Aes128_Sha256_RsaOaep |
Aes256_Sha256_RsaPss | http://opcfoundation.org/UA/SecurityPolicy#Aes256_Sha256_RsaPss |
ECC_nistP256 | http://opcfoundation.org/UA/SecurityPolicy#ECC_nistP256 |
ECC_nistP384 | http://opcfoundation.org/UA/SecurityPolicy#ECC_nistP384 |
ECC_brainpoolP256r1 | http://opcfoundation.org/UA/SecurityPolicy#ECC_brainpoolP256r1 |
ECC_brainpoolP384r1 | http://opcfoundation.org/UA/SecurityPolicy#ECC_brainpoolP384r1 |
ECC_curve25519 | http://opcfoundation.org/UA/SecurityPolicy#ECC_curve25519 |
ECC_curve448 | http://opcfoundation.org/UA/SecurityPolicy#ECC_curve448 |
Full URIs are also accepted directly. If --security-policy is set but --security-mode is omitted, the mode defaults to SignAndEncrypt (or None for the None policy).
Use opcsharp discover to see which policies a server supports before connecting.
Global Options
All commands support these shared behaviors:
| Option | Description |
|---|---|
--json | Machine-readable JSON output, suitable for piping to jq or other tools |
--help | Show help for any command |
# Top-level help
opcsharp --help
# Command-specific help
opcsharp discover --help
opcsharp browse --helpEnvironment Variables and .env File
Instead of passing --username and --password on every command, you can set them via environment variables or a .env file. This keeps credentials out of your shell history.
Supported variables
| Variable | Description |
|---|---|
OPCUA_USERNAME | Username for authentication |
OPCUA_PASSWORD | Password for authentication |
Precedence
Command-line arguments take priority over environment variables, which take priority over .env file values:
--username/--password(CLI arguments — highest priority)OPCUA_USERNAME/OPCUA_PASSWORD(environment variables)- Values from
.envfile in the current directory (lowest priority)
Using a .env file
Create a .env file in your working directory:
# .env
OPCUA_USERNAME=myuser
OPCUA_PASSWORD=mypasswordThen run commands without credential flags:
opcsharp browse opc.tcp://192.168.1.100:4840
opcsharp read opc.tcp://192.168.1.100:4840 "ns=4;s=MAIN.counter"
opcsharp check opc.tcp://192.168.1.100:4840The .env file supports:
- Comments starting with
# - Quoted values (
"value"or'value') - Empty lines (ignored)
Warning: Do not commit
.envfiles containing credentials to version control. Add.envto your.gitignore.
Using environment variables
export OPCUA_USERNAME=myuser
export OPCUA_PASSWORD='mypassword'
opcsharp browse opc.tcp://192.168.1.100:4840Troubleshooting
Connection refused or timeout
Error: Connection refused- Verify the server is running and reachable:
telnet <host> <port> - Check that the port is correct (default OPC UA port is
4840) - Ensure no firewall is blocking the connection
- Try increasing
--timeout
Server returned error: 0x80550000
Error: Server returned error: 0x80550000 - UnknownThe server rejected the session because it requires authentication. Use --username and --password:
opcsharp browse opc.tcp://server:4840 --username myuser --password "mypass"Use discover first to see which authentication types the server supports:
opcsharp discover opc.tcp://server:4840Bad_LicenseExpired (0x810E0000)
When reading PLC variable values, the server returns an empty value with status 0x810E0000:
┌──────────────┬─────────────┬───────┬────────────┬───────────┐
│ NodeId │ DisplayName │ Value │ StatusCode │ Timestamp │
├──────────────┼─────────────┼───────┼────────────┼───────────┤
│ ns=4;s=MyVar │ MyVar │ │ 0x810E0000 │ ... │
└──────────────┴─────────────┴───────┴────────────┴───────────┘This means the OPC UA server’s license has expired (e.g., Beckhoff TwinCAT TF6100 license). Standard server attributes like DisplayName still work, but reading PLC variable values requires an active license. Contact your PLC vendor to renew the license.
NodeId with semicolons not parsed correctly
Error: Invalid NodeId format: 'ns=4'Your shell is splitting the NodeId on the semicolon. Wrap the NodeId in quotes:
# Wrong — shell splits on ;
opcsharp read opc.tcp://server:4840 ns=4;s=MAIN.counter
# Correct — quoted
opcsharp read opc.tcp://server:4840 "ns=4;s=MAIN.counter"DNS resolution failed
✗ DNS Resolution 0ms
No such host is known.- Verify the hostname is correct and resolvable:
nslookup <hostname> - Try using the IP address directly instead of a hostname
Certificate trust errors
If you see certificate-related errors, the --auto-accept flag (enabled by default) should handle this. If you’ve explicitly disabled it, you may need to trust the server’s certificate or re-enable auto-accept.
Unsupported variant type
Error: Unsupported variant type: ExtensionObjectThe node’s value uses a complex data type (ExtensionObject) that isn’t yet supported by the decoder. Try reading a simpler node, or use the SDK directly with custom type registration. See the Roadmap for planned type support.