Reach a private or self-signed controller
A controller that is not reachable from the internet, or that has a self-signed
certificate, can be reached through the controller tunnel: a Cloudflare
Tunnel that SZ-MCP creates for your organisation. You run its connector,
cloudflared, on a machine next to the controller. That machine needs only
outbound HTTPS, so you open no inbound port.
The tunnel is in limited rollout and must be enabled for your account: contact support to have it enabled. Until then the card reads “Controller tunnels are in limited rollout; ask an sz-mcp admin to enable them for your account.” Only an organisation admin (or the owner) can create, change or remove a tunnel. Every member can see its status.
A controller with a publicly trusted certificate on a public address doesn’t need the tunnel. See Controller requirements.
How does the tunnel connect SZ-MCP to my controller?
Section titled “How does the tunnel connect SZ-MCP to my controller?”SZ-MCP calls a hostname of its own on Cloudflare, and Cloudflare forwards the
request down the tunnel to cloudflared, which calls your controller on the
LAN. Each organisation’s tunnel gets:
- a random hostname such as
sz-abcdefghijkl.neuralconfig.dev, served on port 443; - a Cloudflare Access application on that hostname that admits one service token. Only SZ-MCP holds it, and it is sent with every request, so nobody else gets past Cloudflare’s edge;
- a tunnel whose only route is your controller’s LAN address. Requests whose
path starts
/wsg/api/or/switchm/api/(the WSG and SwitchM APIs) are passed through. Everything else, including the controller’s web UI, gets a404.
On the last hop, cloudflared connects to the controller over HTTPS but does
not check the controller’s certificate. That is why a self-signed controller
works through the tunnel. The certificate SZ-MCP checks is Cloudflare’s own,
for the tunnel hostname.
How do I set up the tunnel?
Section titled “How do I set up the tunnel?”Everything happens on Configure › Controller (/settings/controller), in
the Private controller (tunnel) card and the SmartZone login card above
it.
-
Create the tunnel. Under Controller address on your network, enter the controller’s address as the machine running
cloudflaredreaches it: a name, an IPv4 address or a bracketed IPv6 address, such as192.168.1.20orsz.corp.local. Set Port to the controller’s HTTPS API port; it defaults to8443. Click Create tunnel. Private addresses are fine here, because onlycloudflaredconnects to them. -
Run the connector next to the controller. The card shows two commands; run either one on a machine on the controller’s network:
Terminal window cloudflared tunnel --no-autoupdate run --token <token>Terminal window docker run -d --name sz-mcp-tunnel --restart unless-stopped cloudflare/cloudflared:latest tunnel --no-autoupdate run --token <token>The token is the tunnel’s credential: keep it like a password. If you need the commands again later, an admin can click Show run command.
-
Use the tunnel for the login. Click Use for the login. The SmartZone login form fills in the tunnel hostname and port
443, clears the password, and says “Host set to the controller tunnel. Enter the username and password, then Save & detect.” -
Save & detect. Enter the SmartZone username and password and click Save & detect. SZ-MCP logs in through the tunnel and detects the API version, as for any controller. See SmartZone credentials.
-
Test. Click Test connection to check the saved login end to end. The tunnel card now shows Used by the login: yes.
When the login uses the tunnel, the port is always 443, whatever you choose.
A hostname in the tunnel’s domain must be your own organisation’s tunnel.
Anyone else’s is refused with forbidden_host and ”… is not this
organisation’s controller tunnel”.
What do the tunnel’s status chips mean?
Section titled “What do the tunnel’s status chips mean?”The chip is Cloudflare’s view of the tunnel. Next to it, the card shows how
many connections cloudflared holds and which Cloudflare locations they go to.
| Chip | Meaning |
|---|---|
waiting for cloudflared | The tunnel exists but cloudflared has never connected. Run the command from step 2 |
healthy | cloudflared is connected |
degraded | Cloudflare reports the tunnel as degraded. The chip is drawn as a warning |
down | Cloudflare reports the tunnel as down. The chip is drawn as critical |
deleted | The tunnel no longer exists on Cloudflare |
unknown | Cloudflare did not report a status. If the status could not be read at all, the card also says “Couldn’t read the tunnel’s status: …” |
The card also lists the Hostname (with “(port 443)”), the Controller on your network (the LAN address and port you entered), and whether it is Used by the login.
What are the tunnel’s limits?
Section titled “What are the tunnel’s limits?”| Limit | Value | At the limit |
|---|---|---|
| Tunnels per organisation | 1 | This organisation already has a controller tunnel. |
| Tunnel creations per organisation | 5 an hour | rate_limited |
| Tunnels on the service | 200 in total | No more controller tunnels can be created right now. |
| Paths passed to the controller | /wsg/api/… and /switchm/api/… | Any other path gets 404 from Cloudflare |
How do I change or remove the tunnel?
Section titled “How do I change or remove the tunnel?”Use Change address when the controller moves, and Remove when you no longer need the tunnel.
- Change address points the same tunnel at a new LAN address and port. The
hostname and the token stay the same, so
cloudflaredand the saved login carry on. The card says “LAN address changed.” - Remove deletes the hostname, the Access application and its token, and
the tunnel itself. After confirming “Remove the controller tunnel?” the
hostname stops working at once, and you can stop
cloudflared.
You can’t remove a tunnel while the controller login uses it. The card hides
Remove and says “To remove the tunnel, change or delete the controller
login first.” The API refuses with tunnel_in_use: “The controller login uses
this tunnel: remove or change the login first.”
What errors can the tunnel cause?
Section titled “What errors can the tunnel cause?”Three errors come from Cloudflare’s edge rather than from the controller. They appear when SZ-MCP logs in through the tunnel: on Save & detect, on Test connection, or when it fetches a fresh SmartZone service ticket for Claude or for background polling.
| Code | Detail | What to check |
|---|---|---|
tunnel_down | no cloudflared is connected to the tunnel: start it next to the controller | cloudflared is running; the chip shows down or waiting for cloudflared |
tunnel_origin_unreachable | cloudflared is running but cannot reach the controller at the LAN address the tunnel names | The controller’s LAN address and port. Use Change address if it moved |
tunnel_access_denied | Cloudflare Access refused the tunnel's service token | Contact support |
These errors are treated as temporary. Unlike a rejected password, they do not pause the background inventory sync or metric polling, which retry on their next run.
Errors from the card itself appear as Error: …:
| Code | Message |
|---|---|
tunnel_exists | This organisation already has a controller tunnel. |
invalid_origin | Name the controller as the LAN reaches it, not a tunnel hostname. |
tunnel_in_use | The controller login uses this tunnel: remove or change the login first. |
tunnel_capacity | No more controller tunnels can be created right now. |
tunnel_failed | Cloudflare refused a step; the detail names the step. A failed creation undoes what it made, and a failed removal can be retried |