Configuration Guide¶
This guide explains all supported authentication methods and configuration options for the Zscaler Integrations MCP Server.
Authentication¶
The server uses OneAPI authentication exclusively, providing unified authentication across all Zscaler services with a single set of OAuth2 credentials.
Required Environment Variables:
# OneAPI OAuth2 Credentials
export ZSCALER_CLIENT_ID="your_client_id" # OAuth client ID
export ZSCALER_CLIENT_SECRET="your_client_secret" # OAuth client secret
export ZSCALER_CUSTOMER_ID="your_customer_id" # Customer/tenant ID
export ZSCALER_VANITY_DOMAIN="your_vanity_domain" # Your vanity domain
Optional Environment Variables:
export ZSCALER_CLOUD="production" # Cloud environment (production, beta, zscalerone.net, etc.)
export ZSCALER_PRIVATE_KEY="path/to/key" # Path to private key for JWT authentication
Server Configuration¶
General Server Settings¶
# Transport Protocol
export ZSCALER_MCP_TRANSPORT="stdio" # stdio, sse, or streamable-http
# Service Selection
export ZSCALER_MCP_SERVICES="zpa,zia,zdx" # Comma-separated (empty = all services)
export ZSCALER_MCP_DISABLED_SERVICES="" # Comma-separated services to exclude
# Tool Selection
export ZSCALER_MCP_TOOLS="" # Comma-separated tool names (empty = all tools)
export ZSCALER_MCP_DISABLED_TOOLS="" # Comma-separated tools to exclude (supports wildcards)
# Logging
export ZSCALER_MCP_DEBUG="false" # Enable debug logging (true/false)
# HTTP Transport Settings (when using sse or streamable-http)
export ZSCALER_MCP_HOST="127.0.0.1" # Host to bind to
export ZSCALER_MCP_PORT="8000" # Port to listen on
# User Agent
export ZSCALER_MCP_USER_AGENT_COMMENT="My App" # Additional User-Agent info
MCP Client Authentication¶
Important
MCP Client Authentication applies only to HTTP transports (sse, streamable-http). The stdio transport does not support or require client authentication.
The MCP server supports three environment-variable-based authentication modes and a library-level auth= parameter for controlling which clients can connect:
1. API Key (Simple Shared Secret)
export ZSCALER_MCP_AUTH_ENABLED="true"
export ZSCALER_MCP_AUTH_MODE="api-key"
export ZSCALER_MCP_AUTH_API_KEY="sk-your-secret-key-here"
Clients authenticate with Authorization: Bearer sk-your-secret-key-here.
2. JWT (External Identity Provider via JWKS)
export ZSCALER_MCP_AUTH_ENABLED="true"
export ZSCALER_MCP_AUTH_MODE="jwt"
export ZSCALER_MCP_AUTH_JWKS_URI="https://your-idp.auth0.com/.well-known/jwks.json"
export ZSCALER_MCP_AUTH_ISSUER="https://your-idp.auth0.com/"
export ZSCALER_MCP_AUTH_AUDIENCE="zscaler-mcp-server"
export ZSCALER_MCP_AUTH_ALGORITHMS="RS256" # Optional, default: RS256
Supports Auth0, Okta, Azure AD, Keycloak, AWS Cognito, PingOne, and Google Cloud Identity. Tokens are validated locally using the IdP’s public keys.
3. Zscaler (OneAPI Credential Validation)
export ZSCALER_MCP_AUTH_ENABLED="true"
export ZSCALER_MCP_AUTH_MODE="zscaler"
Clients authenticate via Basic Auth (client_id:client_secret) or custom headers (X-Zscaler-Client-ID / X-Zscaler-Client-Secret). The server validates against Zscaler’s /oauth2/v1/token endpoint.
4. Library-Level OAuth 2.1 — OIDCProxy (auth= Parameter)
When using ZscalerMCPServer as a Python library, pass a fastmcp.server.auth.AuthProvider (e.g. OIDCProxy) directly to the constructor. This provides full MCP-spec-compliant OAuth 2.1 with Dynamic Client Registration (DCR) and works with any OIDC-compliant IdP (Auth0, Okta, Azure AD, Keycloak, Google, etc.).
import os
from fastmcp.server.auth.oidc_proxy import OIDCProxy
from zscaler_mcp.server import ZscalerMCPServer
auth = OIDCProxy(
config_url="https://your-tenant.auth0.com/.well-known/openid-configuration",
client_id=os.getenv("OIDCPROXY_CLIENT_ID"),
client_secret=os.getenv("OIDCPROXY_CLIENT_SECRET"),
base_url="http://localhost:8000",
audience="zscaler-mcp-server",
)
# Allow standard OIDC scopes for Dynamic Client Registration
if auth.client_registration_options:
auth.client_registration_options.valid_scopes = [
"openid", "profile", "email",
]
server = ZscalerMCPServer(auth=auth)
server.run("streamable-http", host="0.0.0.0", port=8000)
When auth= is provided, the env-var-based auth middleware (ZSCALER_MCP_AUTH_*) is automatically skipped. The server exposes standard OAuth endpoints (/.well-known/*, /register, /authorize, /token) and MCP clients handle the authorization flow automatically — no static tokens or shared secrets required.
IdP requirements: Your Identity Provider must have a Regular Web Application (not M2M) with the callback URL http://localhost:8000/auth/callback registered, and an API/resource server with an identifier matching the audience value.
See the Authentication & Deployment Guide for detailed IdP-specific setup instructions, Docker deployment, and troubleshooting.
Token Generation:
Use the --generate-auth-token CLI flag to generate a token for testing:
zscaler-mcp --generate-auth-token
Network Security¶
The server provides defense-in-depth network security controls for HTTP transports.
HTTPS / TLS Configuration:
export ZSCALER_MCP_TLS_CERT_FILE="/path/to/cert.pem"
export ZSCALER_MCP_TLS_KEY_FILE="/path/to/key.pem"
When both are set, the server starts with TLS enabled, serving over HTTPS.
HTTPS Policy Enforcement:
export ZSCALER_MCP_ALLOW_HTTP="false" # Default: false
When false (default), the server blocks plaintext HTTP on non-localhost interfaces if TLS is not configured. Set to true only if you have TLS termination handled upstream (e.g., a reverse proxy).
Host Header Validation:
export ZSCALER_MCP_ALLOWED_HOSTS="myhost.example.com,api.internal"
export ZSCALER_MCP_DISABLE_HOST_VALIDATION="false" # Default: false
Restricts accepted Host headers to prevent DNS rebinding attacks. Localhost variants (localhost, 127.0.0.1, ::1) are always allowed. Set ZSCALER_MCP_DISABLE_HOST_VALIDATION=true to disable (not recommended).
Source IP Access Control:
export ZSCALER_MCP_ALLOWED_SOURCE_IPS="10.0.0.0/8,192.168.1.0/24,203.0.113.42"
Restricts which client IP addresses can connect. Supports individual IPs and CIDR notation. When unset, all source IPs are allowed.
Write Operations Configuration (Security)¶
By default, the server operates in read-only mode for safety. To enable write operations:
# Step 1: Enable write tools globally
export ZSCALER_MCP_WRITE_ENABLED="true"
# Step 2: MANDATORY - Specify allowlist (no backdoor to "enable all")
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_*,zpa_delete_*,zia_update_*"
Security Note:
⚠️
ZSCALER_MCP_WRITE_TOOLSis MANDATORY whenZSCALER_MCP_WRITE_ENABLED=trueIf empty, 0 write tools will be registered (by design for security)
Supports wildcards:
zpa_create_*,zia_delete_*,zpa_*No backdoor exists to bypass the allowlist
Wildcard Examples:
# Allow all ZPA create operations
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_*"
# Allow ZPA create and delete
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_*,zpa_delete_*"
# Allow all ZPA write tools
export ZSCALER_MCP_WRITE_TOOLS="zpa_*"
# Allow specific tool (no wildcard)
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_application_segment"
# Allow multiple services
export ZSCALER_MCP_WRITE_TOOLS="zpa_*,zia_*,ztw_*"
Toolsets¶
Tools are grouped into named toolsets so you can load only the slice an agent actually needs (e.g. zia_url_filtering (5 tools) instead of every tool from every service (~280)). Toolsets reduce the agent’s context cost and improve tool-selection accuracy. They apply on every transport, including stdio.
# Load just two slices
zscaler-mcp --toolsets zia_url_filtering,zpa_app_segments
# Or use the curated default-on subset
zscaler-mcp --toolsets default
# Or load every registered toolset explicitly
zscaler-mcp --toolsets all
# Equivalent via environment variable
export ZSCALER_MCP_TOOLSETS="zia_url_filtering,zpa_app_segments"
When --toolsets is unspecified, every toolset whose service is enabled is loaded (preserves the historical default).
The meta toolset (server discovery) is always loaded regardless of selection. The agent can also enable additional toolsets at runtime through the always-on zscaler_list_toolsets, zscaler_get_toolset_tools, and zscaler_enable_toolset tools.
For the full catalog (29 toolsets across all services), filter precedence rules, and per-toolset agent guidance, see the dedicated Toolsets guide.
OneAPI Entitlement Filter¶
After your toolset selection resolves, the server reads the product entitlements from the OneAPI bearer token issued for your ZSCALER_CLIENT_ID and silently drops toolsets for products the credentials cannot call. If your OneAPI client is only entitled to ZIA and ZPA, every zdx_* / zcc_* / ztw_* / zid_* / zeasm_* / zins_* / zms_* toolset is filtered out at startup — even with --toolsets all.
This prevents an agent from discovering tools whose first call would only ever return 401 Unauthorized. The filter applies on every transport, including stdio.
When the filter runs you’ll see one log line at startup, for example:
entitlement filter applied: entitled services=['zia', 'zpa'], kept 12 toolset(s), removed 17 toolset(s)
The filter is non-fatal. If credentials are missing, the token endpoint is unreachable, the token doesn’t decode, or the token has no recognizable product entitlements, the server logs a single WARN line and starts normally with the user-selected toolsets unchanged.
To bypass the filter (for example, while diagnosing an unusual token shape):
zscaler-mcp --no-entitlement-filter
# or
export ZSCALER_MCP_DISABLE_ENTITLEMENT_FILTER=true
Only product entitlement is honoured — not role names. The server defers per-action permission enforcement to the live API; the entitlement filter only ensures the agent doesn’t discover tools for products the client has zero access to.
Complete Configuration Examples¶
Read-Only Mode (Default - Recommended)¶
# OneAPI Authentication - Read-Only
export ZSCALER_CLIENT_ID="your_client_id"
export ZSCALER_CLIENT_SECRET="your_client_secret"
export ZSCALER_CUSTOMER_ID="your_customer_id"
export ZSCALER_VANITY_DOMAIN="your_vanity_domain"
export ZSCALER_CLOUD="production"
# No write flags needed - read-only by default
# Only list_* and get_* operations available
Write Mode with Allowlist (Advanced)¶
# OneAPI Authentication + Write Operations
export ZSCALER_CLIENT_ID="your_client_id"
export ZSCALER_CLIENT_SECRET="your_client_secret"
export ZSCALER_CUSTOMER_ID="your_customer_id"
export ZSCALER_VANITY_DOMAIN="your_vanity_domain"
export ZSCALER_CLOUD="production"
# Enable write mode
export ZSCALER_MCP_WRITE_ENABLED="true"
# MANDATORY: Specify allowlist
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_*,zpa_update_*,zia_create_rule_label"
Security Best Practices¶
For Production:
# ✅ DO: Use read-only mode by default
# (No ZSCALER_MCP_WRITE_ENABLED needed)
# ✅ DO: Use specific allowlists when write mode needed
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_application_segment,zpa_update_application_segment"
# ❌ DON'T: Enable write mode without allowlist
# This will register 0 write tools (blocked by design)
export ZSCALER_MCP_WRITE_ENABLED="true" # ← Without allowlist = 0 tools
For Development:
# Safe: Read-only mode for exploration
export ZSCALER_MCP_DEBUG="true"
# When testing write operations:
export ZSCALER_MCP_WRITE_ENABLED="true"
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_*,zpa_delete_*" # Specific patterns
For CI/CD:
# Minimal permissions for automation
export ZSCALER_MCP_WRITE_ENABLED="true"
export ZSCALER_MCP_WRITE_TOOLS="zpa_create_application_segment" # Only what's needed
# Use service accounts with limited permissions
# Store credentials in secure secrets management
Environment Variables Reference¶
Complete List of All Supported Variables¶
Server Configuration:
ZSCALER_MCP_TRANSPORT- Transport protocol (stdio,sse,streamable-http)ZSCALER_MCP_SERVICES- Comma-separated service list (empty = all)ZSCALER_MCP_TOOLS- Comma-separated tool list (empty = all)ZSCALER_MCP_DISABLED_SERVICES- Comma-separated services to exclude (e.g.,zcc,zdx)ZSCALER_MCP_DISABLED_TOOLS- Comma-separated tools to exclude, supports wildcards (e.g.,zcc_*,zia_list_devices)ZSCALER_MCP_TOOLSETS- Comma-separated toolset ids to enable (e.g.zia_url_filtering,zpa_app_segments). Special values:default(curated default-on subset),all(every toolset). When unset, every toolset whose service is enabled is loaded. Themetatoolset is always loaded. See the Toolsets section below.ZSCALER_MCP_DISABLE_ENTITLEMENT_FILTER- Skip the OneAPI entitlement filter (default:false). The filter trims toolsets to the products the configuredZSCALER_CLIENT_IDis entitled to. It is non-fatal by default; set totrueonly as an emergency override.ZSCALER_MCP_DISABLE_OUTPUT_SANITIZATION- Disable defense-in-depth output sanitization (default:false). Sanitization strips invisible/BiDi/zero-width characters, raw HTML, dangerous Markdown link/image syntax, and suspicious code-fence info-strings from every tool response before it reaches the agent. Disabling removes a prompt-injection defense layer; only set totruefor diagnostics.ZSCALER_MCP_LOG_TOOL_CALLS- Enable per-tool-call audit logging (default:false)ZSCALER_MCP_DEBUG- Enable debug logging (true/false)ZSCALER_MCP_HOST- HTTP bind host (default:127.0.0.1)ZSCALER_MCP_PORT- HTTP port (default:8000)ZSCALER_MCP_USER_AGENT_COMMENT- Additional User-Agent info
Write Operations (Security):
ZSCALER_MCP_WRITE_ENABLED- Enable write mode (default:false)ZSCALER_MCP_WRITE_TOOLS- MANDATORY allowlist when write enabledZSCALER_MCP_SKIP_CONFIRMATIONS- Skip delete confirmations with HMAC token (advanced)ZSCALER_MCP_CONFIRMATION_TTL- Confirmation window in seconds (default:300)
MCP Client Authentication (HTTP transports only):
ZSCALER_MCP_AUTH_ENABLED- Enable client authentication (default:false)ZSCALER_MCP_AUTH_MODE- Authentication mode:api-key,jwt, orzscalerZSCALER_MCP_AUTH_API_KEY- Shared secret forapi-keymodeZSCALER_MCP_AUTH_JWKS_URI- JWKS endpoint URL forjwtmodeZSCALER_MCP_AUTH_ISSUER- Expected JWT issuer forjwtmodeZSCALER_MCP_AUTH_AUDIENCE- Expected JWT audience forjwtmodeZSCALER_MCP_AUTH_ALGORITHMS- Allowed JWT algorithms (default:RS256)
Network Security (HTTP transports only):
ZSCALER_MCP_TLS_CERT_FILE- Path to TLS certificate fileZSCALER_MCP_TLS_KEY_FILE- Path to TLS private key fileZSCALER_MCP_ALLOW_HTTP- Allow plaintext HTTP on non-localhost (default:false)ZSCALER_MCP_ALLOWED_HOSTS- Comma-separated list of allowed Host header valuesZSCALER_MCP_DISABLE_HOST_VALIDATION- Disable host header validation (default:false)ZSCALER_MCP_ALLOWED_SOURCE_IPS- Comma-separated list of allowed client IPs/CIDRs
OneAPI Authentication (Zscaler API credentials):
ZSCALER_CLIENT_ID- OAuth client ID (required)ZSCALER_CLIENT_SECRET- OAuth client secret (required)ZSCALER_CUSTOMER_ID- Customer/tenant ID (required for ZPA)ZSCALER_VANITY_DOMAIN- Vanity domain (required)ZSCALER_CLOUD- Cloud environment (optional)ZSCALER_PRIVATE_KEY- Private key path for JWT (optional)
CLI Flags Reference¶
--transport Transport protocol: stdio, sse, streamable-http (default: stdio)
--host Host to bind to for HTTP transports (default: 127.0.0.1)
--port Port for HTTP transports (default: 8000)
--services Comma-separated list of services to enable
--disabled-services Comma-separated list of services to exclude (e.g., zcc,zdx)
--tools Comma-separated list of specific tools to enable
--disabled-tools Comma-separated tool patterns to exclude (wildcards supported)
--toolsets Comma-separated toolset ids to enable (use 'default' or 'all' as keywords)
--no-entitlement-filter Skip the OneAPI entitlement filter (emergency override)
--enable-write-tools Enable write (create/update/delete) tools
--write-tools Mandatory allowlist of write tools (supports wildcards)
--log-tool-calls Enable per-tool-call audit logging
--generate-auth-token Generate an authorization token from configured credentials
--list-tools List all registered tools and exit
--user-agent-comment Additional comment appended to the User-Agent header
--version Show server version and exit
--debug Enable debug logging
Troubleshooting¶
Issue: Write tools not appearing
Check:
Is
ZSCALER_MCP_WRITE_ENABLED=trueset?Is
ZSCALER_MCP_WRITE_TOOLSprovided with patterns?Do patterns match tool names? (use
zscaler-mcp --list-toolsto see all tools)
Issue: Zscaler API authentication fails
Check:
ZSCALER_CLIENT_ID,ZSCALER_CLIENT_SECRET(orZSCALER_PRIVATE_KEY), andZSCALER_VANITY_DOMAINare all setZSCALER_CUSTOMER_IDis set when calling ZPA toolsCredentials are valid and not expired
The OneAPI client has the required scopes in the ZIdentity console
Issue: MCP Client Authentication fails
Check:
ZSCALER_MCP_AUTH_ENABLED=trueis setZSCALER_MCP_AUTH_MODEmatches your client’s authentication methodFor
api-key: Client sendsAuthorization: Bearer <key>with the correct keyFor
jwt: JWKS URI is reachable, issuer/audience match, token is not expiredFor
zscaler: Client sends valid Basic Auth orX-Zscaler-Client-ID/X-Zscaler-Client-Secretheaders
Issue: Connection refused on non-localhost
Check:
ZSCALER_MCP_ALLOW_HTTP— Iffalse(default) and TLS is not configured, HTTP is blocked on non-localhostEither configure TLS (
ZSCALER_MCP_TLS_CERT_FILE+ZSCALER_MCP_TLS_KEY_FILE) or setZSCALER_MCP_ALLOW_HTTP=true
Issue: 421 Misdirected Request (Host header rejected)
Check:
Add your server’s hostname to
ZSCALER_MCP_ALLOWED_HOSTSOr set
ZSCALER_MCP_DISABLE_HOST_VALIDATION=true(not recommended for production)
Issue: Client IP rejected
Check:
If
ZSCALER_MCP_ALLOWED_SOURCE_IPSis set, ensure the client’s IP is in the listUse CIDR notation for ranges (e.g.,
10.0.0.0/8)
Issue: Service not available
Check:
Service name is correct:
zpa,zia,zdx,zcc,zid,ztw,zeasm,zinsIf using
ZSCALER_MCP_SERVICES, service is included in the list