Also, Claude can help you setup this configuration, just point Claude at this article.
EnvisionSCADA exposes an MCP (Model Context Protocol) server at /mcp on its HTTP or HTTPS port. By connecting Claude Code to this endpoint, the AI assistant can read pages, inspect design objects, upload files to the Online Files and Offline Files sections of the project, and perform configuration tasks directly against your EnvisionSCADA instance.
A small Node.js proxy script is required to bridge Claude Code (which communicates over STDIO) with the EnvisionSCADA HTTP(S) server. The proxy supports both plain HTTP and HTTPS. For HTTPS with a self-signed certificate, certificate verification is automatically disabled.
- Claude Cowork does not support local MCP servers.
- Claude Chat does support local MCP Servers, see at the bottom of this article.
Prerequisites
Step 1: Create the proxy script
Create the file C:\Users\<you>\.claude\mcp-envision.js with the following content. The script automatically detects whether to use HTTP or HTTPS based on the URL you provide in the config.
// MCP STDIO-to-HTTP(S) proxy for EnvisionSCADA
const http = require("node:http");
const https = require("node:https");
const SERVER_URL = process.argv[2] || "http://localhost/mcp";
const AUTH_HEADER = process.argv[4] || "Basic QWRtaW46QWRtaW4=";
const isHttps = SERVER_URL.startsWith("https://");
const transport = isHttps ? https : http;
const agent = isHttps ? new https.Agent({ rejectUnauthorized: false }) : undefined;
let sessionId = null;
let buffer = "";
let processing = false;
const queue = [];
function postToServer(body) {
return new Promise((resolve, reject) => {
const url = new URL(SERVER_URL);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream",
"Authorization": AUTH_HEADER,
};
if (sessionId) headers["mcp-session-id"] = sessionId;
const req = transport.request({
hostname: url.hostname,
port: url.port || (isHttps ? 443 : 80),
path: url.pathname,
method: "POST",
headers,
agent,
}, (res) => {
if (res.headers["mcp-session-id"]) sessionId = res.headers["mcp-session-id"];
let data = "";
res.on("data", chunk => { data += chunk; });
res.on("end", () => resolve({ status: res.statusCode, body: data, headers: res.headers }));
});
req.on("error", reject);
req.write(typeof body === "string" ? body : JSON.stringify(body));
req.end();
});
}
async function processQueue() {
if (processing) return;
processing = true;
while (queue.length > 0) {
const msg = queue.shift();
try {
const res = await postToServer(msg);
if (res.status === 202 || !res.body.trim()) continue;
const ct = res.headers["content-type"] || "";
if (ct.includes("text/event-stream")) {
for (const evtLine of res.body.split("\n")) {
if (evtLine.startsWith("data:")) {
const payload = evtLine.slice(5).trim();
if (payload) process.stdout.write(payload + "\n");
}
}
} else {
process.stdout.write(res.body.trim() + "\n");
}
} catch (e) {
process.stderr.write(`Error: ${e.message}\n`);
}
}
processing = false;
}
process.stdin.setEncoding("utf8");
process.stdin.on("data", (chunk) => {
buffer += chunk;
const lines = buffer.split("\n");
buffer = lines.pop();
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed) continue;
try {
queue.push(JSON.parse(trimmed));
} catch (e) {
process.stderr.write(`Parse error: ${e.message}\n`);
}
}
processQueue();
});Step 2: Generate your auth token
The proxy authenticates using HTTP Basic auth. Generate the base64 token for your EnvisionSCADA credentials by running the following in PowerShell. Copy the output, because you will need it in Step 3.
[Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("Admin:Admin"))Step 3: Create the project MCP config
In the root of your project, create the file .claude\settings.json. Replace <you> with your Windows username, <server-url> with your EnvisionSCADA address, and <base64-token> with the output from Step 2.
{
"mcpServers": {
"EnvisionSCADA": {
"command": "node",
"args": [
"C:\\Users\\<you>\\.claude\\mcp-envision.js",
"http://<server-url>/mcp",
"--transport",
"http-first",
"--header",
"Basic <base64-token>"
]
}
}
}{
"mcpServers": {
"EnvisionSCADA": {
"command": "node",
"args": [
"C:\\Users\\<you>\\.claude\\mcp-envision.js",
"https://<server-url>/mcp",
"--transport",
"http-first",
"--header",
"Basic <base64-token>"
]
}
}
}Step 4: Test the connection
Before starting Claude, verify the proxy works by running the following in PowerShell. You should receive a JSON response containing "name":"ENVISION".
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"1"}}}' | node "C:\Users\<you>\.claude\mcp-envision.js" http://<server-url>/mcp{"result":{"protocolVersion":"2025-11-25","serverInfo":{"name":"ENVISION","version":"1.0.0.0"},...}}Step 5: Start Claude Code
Open the Claude desktop app and start a new Code session on your project. The EnvisionSCADA MCP tools will be available automatically. Claude can now read pages, inspect design objects, and interact with your SCADA project directly.
OAuth 2.0 authentication (optional)
The MCP endpoint uses HTTP Basic authentication and the EnvisionSCADA session cookie by default, as described above. You can optionally enable OAuth 2.0 so that OAuth-aware clients sign in interactively and present a bearer token instead of a stored username and password. EnvisionSCADA acts as its own authorization server, so no external identity provider or internet access is required.
OAuth is turned off by default. When it is off, the MCP endpoint behaves exactly as documented above and existing Basic authentication setups are unaffected. Turn it on with Enable MCP OAuth 2.0 in the MCP OAuth section of the Parameters page (parameter EnableMcpOAuth). When it is on, the MCP endpoint additionally accepts OAuth 2.0 bearer tokens and publishes the discovery endpoints listed below.
Access granted through OAuth carries the same permissions as the EnvisionSCADA account used to sign in. Administrators reach the configuration and design tools; other users reach the read-only runtime tools, the same as with Basic authentication.
| EnableMcpOAuth | Turns OAuth 2.0 on for the MCP endpoint. Leave off to keep Basic and session authentication only. | True |
| McpOAuthAccessTokenMinutes | Access token lifetime in minutes. Clients refresh automatically before it expires. | 60 |
| McpOAuthSigningKey | Secret that signs access tokens. Leave empty on a single server and a key is generated automatically. Set the same value on both servers of a redundant pair. | (secret) |
No rows match the filter.
| /.well-known/oauth-protected-resource | Protected resource metadata. Points the client to the authorization server. |
| /.well-known/oauth-authorization-server | Authorization server metadata. Lists the authorize, token and registration endpoints. |
| /mcp/oauth/authorize | Interactive sign-in page. Issues an authorization code (authorization code flow with PKCE). |
| /mcp/oauth/token | Issues and refreshes access tokens. |
| /mcp/oauth/register | Dynamic client registration. |
No rows match the filter.
EnableMcpOAuth, McpOAuthAccessTokenMinutes and the signing key are set on the Parameters page.curl -X POST http://<server-url>/mcp/oauth/token -d "grant_type=password&username=Admin&password=Admin"
# The response contains access_token. Send it on each MCP request as:
# Authorization: Bearer <access_token>McpOAuthSigningKey on both servers so a token issued by the primary is accepted by the standby.Claude custom connector (claude.ai)
Claude can connect to the MCP endpoint directly as a custom connector, without the proxy script and without storing a username or password. This requires Enable MCP OAuth 2.0 to be turned on and the server to be reachable on a public HTTPS address with a certificate issued by a trusted certificate authority. Use a DNS host name in the address; the connector does not accept self-signed certificates, and certificates for a bare IP address are normally not obtainable.
- In Claude, open Settings > Connectors and select Add custom connector.
- Enter a Name and the MCP address, for example
https://scada.example.com/mcp. - Leave OAuth Client ID and OAuth Client Secret under Advanced settings empty. Claude registers itself through dynamic client registration.
- Select Add, then Connect. The Authorize MCP access sign-in page of the EnvisionSCADA server opens.
- Sign in with an EnvisionSCADA account. Members of the Administrators group reach the configuration and design tools; other users reach the read-only runtime tools.
No token is copied or stored anywhere during this setup. Claude receives an access token after sign-in, sends it on every MCP request and renews it automatically until the refresh token expires (30 days). The table below lists the server-side actions that affect a connected client.
| Restart of the EnvisionSCADA application | Connected clients are signed out because refresh tokens are kept in memory. Select Connect on the connector and sign in again. |
| Enable MCP OAuth 2.0 turned off | The connector stops working until the parameter is turned on again and the client reconnects. |
| McpOAuthSigningKey changed or cleared | Issued access tokens become invalid. A client that holds a refresh token obtains a new access token automatically and continues without a new sign-in. |
No rows match the filter.
/mcp address, leave the client credentials empty and sign in on the Authorize MCP access page.Troubleshooting
| ECONNREFUSED | EnvisionSCADA is not running or unreachable | Verify the server is up and the URL is correct |
| Invalid Username/Password | Wrong credentials in the auth token | Redo Step 2 with the correct username and password |
| Tools not visible in Claude | Session was opened before the server started | Start a new Claude Code session |
| node: command not found | Node.js not installed or not on PATH | Install Node.js from nodejs.org |
| Unknown field '<name>' on <EntityType> | The configuration write used a field name that is not part of that entity's schema, for example a nested member field spelled with the name the flat variable table uses for the same setting | Call get_config_entity_type_schema for the entity type and use the exact field names it returns. The error names the item and the nested member the field was found on, and suggests the closest matching field names |
No rows match the filter.
Claude Chat
For Claude Chat, adjust the following file accordingly
C:\Users\stijn\AppData\Roaming\Claude\claude_desktop_config.json
{
"mcpServers": {
"EnvisionSCADA": {
"command": "C:\\PROGRA~1\\nodejs\\npx.cmd",
"args": [
"mcp-remote",
"https://localhost:7207/mcp",
"--transport",
"http-first",
"--header",
"Authorization:Basic QWRtaW46QWRtaW4="
],
"env": {
"NODE_TLS_REJECT_UNAUTHORIZED": "0"
}
}
},
...
}{
"mcpServers": {
"EnvisionSCADA": {
"command": "C:\\PROGRA~1\\nodejs\\npx.cmd",
"args": [
"mcp-remote",
"http://5.189.133.144/mcp",
"--transport",
"http-first",
"--allow-http",
"--header",
"Authorization:Basic QWRtaW46QWRtaW4="
]
}
}
...
}