Troubleshooting Guide¶
This guide covers common issues and solutions when using the Zscaler Integrations MCP Server.
Tip
For the most up-to-date troubleshooting information, see the Troubleshooting Guide on GitHub.
Installation Issues¶
“Command not found: zscaler-mcp”
Install uv and use uvx to run the server:
curl -LsSf https://astral.sh/uv/install.sh | sh
uvx zscaler-mcp
Or install directly:
uv tool install zscaler-mcp
If installed but not found, update your shell PATH.
“.env file not found”
Use absolute paths, not relative paths, when specifying the
.envfile locationVerify the file exists:
ls -la /path/to/.envCheck file permissions (should be readable)
Zscaler API Authentication¶
“Authentication failed” / 401 Unauthorized
Verify all 4 required OneAPI variables are set:
ZSCALER_CLIENT_IDZSCALER_CLIENT_SECRETZSCALER_CUSTOMER_IDZSCALER_VANITY_DOMAIN
Check that credentials are not expired
Ensure the API client has the necessary scopes in the ZIdentity console
“ZSCALER_CUSTOMER_ID required”
ZSCALER_CUSTOMER_ID is required for ZPA operations. If you only use ZIA/ZDX/ZCC, this can be omitted.
MCP Client Authentication¶
Client receives 401 when connecting over HTTP
Check
ZSCALER_MCP_AUTH_ENABLEDistrueVerify
ZSCALER_MCP_AUTH_MODEmatches the client’s authentication methodFor
api-keymode: Client must sendAuthorization: Bearer <key>with the correct keyFor
jwtmode: Verify the JWKS URI is reachable, issuer/audience match, and the token is not expiredFor
zscalermode: Client must send valid Basic Auth orX-Zscaler-Client-ID/X-Zscaler-Client-Secretheaders
JWT token validation fails
Ensure
ZSCALER_MCP_AUTH_JWKS_URIpoints to a reachable JWKS endpointVerify
ZSCALER_MCP_AUTH_ISSUERexactly matches theissclaim in your tokensVerify
ZSCALER_MCP_AUTH_AUDIENCEexactly matches theaudclaimCheck that
ZSCALER_MCP_AUTH_ALGORITHMSincludes the algorithm used by your IdP (default:RS256)
Generate a test token:
zscaler-mcp --generate-auth-token
Network Security¶
Connection refused on non-localhost
By default, the server blocks plaintext HTTP on non-localhost interfaces. Either:
Configure TLS: Set
ZSCALER_MCP_TLS_CERT_FILEandZSCALER_MCP_TLS_KEY_FILEOr allow HTTP explicitly: Set
ZSCALER_MCP_ALLOW_HTTP=true(only if TLS is handled upstream)
421 Misdirected Request / “Invalid Host header”
The server validates Host headers to prevent DNS rebinding attacks. Fix:
Add your hostname to
ZSCALER_MCP_ALLOWED_HOSTS:export ZSCALER_MCP_ALLOWED_HOSTS="myserver.example.com"Or disable validation (not recommended):
export ZSCALER_MCP_DISABLE_HOST_VALIDATION=trueLocalhost variants (
localhost,127.0.0.1,::1) are always allowed
Client IP rejected / 403 Forbidden
If ZSCALER_MCP_ALLOWED_SOURCE_IPS is configured:
Ensure the client’s IP is in the allowed list
Use CIDR notation for ranges:
10.0.0.0/8,192.168.1.0/24Check if the client is behind a proxy (the server sees the proxy’s IP)
Write Operations¶
Write tools not appearing
Is
ZSCALER_MCP_WRITE_ENABLED=trueset?Is
ZSCALER_MCP_WRITE_TOOLSprovided? This is mandatory — if empty, 0 write tools are registeredDo patterns match tool names? Use
zscaler-mcp --list-toolsto see all registered toolsWildcards are supported:
zpa_create_*,zia_*,zpa_delete_application_segment
Delete operations require confirmation
All 33 delete operations require double confirmation:
AI agent permission dialog (
destructiveHint)Server-side confirmation via hidden
kwargsparameter
To skip confirmations (advanced/CI use only): Set ZSCALER_MCP_SKIP_CONFIRMATIONS with an HMAC-SHA256 token. The confirmation window is controlled by ZSCALER_MCP_CONFIRMATION_TTL (default: 300 seconds).
Tool Filtering¶
These checks apply on every transport (stdio, sse, streamable-http).
A specific tool isn’t loaded
Walk down this list in order — each item rules out one filter the server applies at startup.
Was the service explicitly disabled? Check
--disabled-services/ZSCALER_MCP_DISABLED_SERVICES. A service in this list contributes zero tools.Was the tool’s pattern explicitly disabled? Check
--disabled-tools/ZSCALER_MCP_DISABLED_TOOLS. This list supports wildcards (e.g.zcc_*) and wins over every other filter.Is it a write tool with no allowlist? Write tools (
*_create_*,*_update_*,*_delete_*) require both--enable-write-toolsAND a matching pattern in--write-tools. With write mode disabled (the default), no write tool is registered.Was the tool’s toolset filtered out? If you set
--toolsets(orZSCALER_MCP_TOOLSETS), only tools that belong to a listed toolset are registered. Callzscaler_list_toolsetsfrom your client to see what’s currently active and what’s available.Did the OneAPI entitlement filter drop the tool’s product? Look for a startup log line of the form
entitlement filter applied: entitled services=[...], kept N toolset(s), removed M toolset(s). If the product (e.g. ZDX) isn’t in the entitled list, every toolset for that product was filtered out. Either grant the OneAPI client the missing product entitlement in ZIdentity, or — for a quick diagnostic — restart the server with--no-entitlement-filterto confirm the filter is the cause.
If the agent reports a tool that genuinely doesn’t exist (typo, hallucination), zscaler_list_toolsets and zscaler_get_available_services are the right introspection tools to call. Use name_contains / description_contains on zscaler_list_toolsets to scope the search to a single area before drilling in with zscaler_get_toolset_tools.
How do I see what the entitlement filter dropped?
The OneAPI entitlement filter logs one INFO line at startup with the result, for example:
entitlement filter applied: entitled services=['zia', 'zpa'], kept 12 toolset(s), removed 17 toolset(s)
To see which specific toolsets were removed, compare two startup runs:
Start the server normally and call
zscaler_list_toolsets— note which toolsets show as currently enabled.Restart with
--no-entitlement-filter(orZSCALER_MCP_DISABLE_ENTITLEMENT_FILTER=true), callzscaler_list_toolsetsagain — anything new is what the filter was hiding.
If you see a WARN entitlement filter skipped (...) line instead, the filter never ran — the parenthesized reason tells you why (missing OneAPI credentials, the ZIdentity token endpoint was unreachable, the token didn’t decode, or the token had no recognizable product entitlements). Your tool list in that case is whatever your other filters produced.
Agent/Editor Issues¶
Claude Desktop: “MCP server not found”
Verify the
.envfile path is absolute and correctCheck Claude Desktop logs: Help → View Logs
Restart Claude Desktop completely (quit and reopen)
Claude Desktop: Extension not working on Windows
The one-click extension bundles macOS/Linux binaries. Use manual configuration with uvx instead:
{
"mcpServers": {
"zscaler-mcp-server": {
"command": "uvx",
"args": ["--env-file", "C:\\Users\\You\\.env", "zscaler-mcp"]
}
}
}
Windows: “‘C:\Program’ is not recognized” (npx path issue)
Paths with spaces break npx when called directly. Use cmd /c:
{
"mcpServers": {
"zscaler-mcp-server": {
"command": "cmd",
"args": ["/c", "npx", "-y", "mcp-remote", "http://server:8000/mcp"]
}
}
}
“Non-HTTPS URLs are only allowed for localhost” (mcp-remote)
mcp-remote enforces HTTPS for non-localhost URLs. Add --allow-http to the args:
{
"args": ["-y", "mcp-remote", "http://server:8000/mcp", "--allow-http", "--header", "Authorization: Bearer sk-key"]
}
Self-signed certificate rejected (mcp-remote)
When using self-signed certificates, add to the MCP server config:
{
"env": { "NODE_TLS_REJECT_UNAUTHORIZED": "0" }
}
Cursor: Tools not appearing
Check Cursor’s MCP logs: View → Output → MCP
Verify the
.envfile path is absoluteConfig file location:
~/.cursor/mcp.json(macOS/Linux) or%USERPROFILE%\.cursor\mcp.json(Windows)
Docker Issues¶
“Server connection timeout” with Docker
When using HTTP transports in Docker, always bind to 0.0.0.0:
docker run --rm -p 8000:8000 --env-file /path/to/.env \
zscaler/zscaler-mcp-server:latest --transport streamable-http --host 0.0.0.0
Port conflicts
Change the port with --port:
docker run --rm -p 8001:8001 --env-file /path/to/.env \
zscaler/zscaler-mcp-server:latest --transport streamable-http --host 0.0.0.0 --port 8001
Debugging¶
Enable debug logging:
export ZSCALER_MCP_DEBUG="true"
zscaler-mcp
List all registered tools:
zscaler-mcp --list-tools
Test the server manually:
# Start server with HTTP transport
zscaler-mcp --transport streamable-http --host 127.0.0.1 --port 8000
# Test health (in another terminal)
curl http://127.0.0.1:8000/mcp