The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Zscaler Zero Trust Exchange listing page.
zscaler-mcp-server is a Model Context Protocol (MCP) server that connects AI agents with the Zscaler Zero Trust Exchange platform. By default, the server operates in read-only mode for security, requiring explicit opt-in to enable write operations.
-> Disclaimer: Please refer to our General Support Statement before proceeding with the use of this provider. You can also refer to our troubleshooting guide for guidance on typical problems.
[!IMPORTANT] 🚧 Public Preview: This project is currently in public preview and under active development. Features and functionality may change before the stable 1.0 release. While we encourage exploration and testing, please avoid production deployments. We welcome your feedback through GitHub Issues to help shape the final release.
The Zscaler Integrations MCP Server brings context to your agents. Try prompts like:
[!WARNING] 🔒 READ-ONLY BY DEFAULT: For security, this MCP server operates in read-only mode by default. Only
list_*andget_*operations are available. To enable tools that can CREATE, UPDATE, or DELETE Zscaler resources, you must explicitly enable write mode using the--enable-write-toolsflag or by settingZSCALER_MCP_WRITE_ENABLED=true. See the Security & Permissions section for details.
[!TIP] Writing effective prompts: This server exposes 402 tools across multiple Zscaler services. Most MCP clients (Claude Desktop, Cursor, etc.) use deferred tool loading and will search for relevant tools based on your prompt. For best results, be specific about the service and action in your prompts:
- Good: "List my ZPA application segments" — targets the right service and tool directly
- Good: "Show ZIA firewall rules" — clear service (
zia) and action (list)- Less effective: "Show me my devices" — ambiguous; multiple services expose device-related tools
When a service is disabled, its tools are fully removed from the server. However, the AI agent may still attempt to find related tools in other services. If you get unexpected results, refine your prompt with the specific service name (e.g.
zpa,zia,zdx,zcc,zcell,zms).
The Zscaler MCP Server implements a security-first design with granular permission controls and safe defaults:
By default, the server operates in read-only mode, exposing only tools that list or retrieve information:
list_* and get_* operations are available (110+ read-only tools)create_*, update_*, and delete_* operations are disabled by defaultWhen the server starts in read-only mode, you'll see:
💡 Read-only tools are ALWAYS registered by the server regardless of any flags. You never need to enable them server-side. Note: Your AI agent UI (like Claude Desktop) may require you to enable individual tools before use.
To enable tools that can create, modify, or delete Zscaler resources, you must provide BOTH flags:
--enable-write-tools - Global unlock for write operations--write-tools "pattern" - MANDATORY explicit allowlist🔐 SECURITY: Allowlist is MANDATORY - If you set
--enable-write-toolswithout--write-tools, 0 write tools will be registered. This ensures you consciously choose which write operations to enable.
When you try to enable write mode without an allowlist:
The allowlist provides two-tier security:
--enable-write-tools must be set (global unlock)Allowlist Examples:
Or via environment variable:
Wildcard patterns supported:
zpa_create_* - Allow all ZPA creation toolszpa_delete_* - Allow all ZPA deletion toolszpa_* - Allow all ZPA write tools*_application_segment - Allow all operations on application segmentszpa_create_application_segment - Exact match (no wildcard)When using a valid allowlist, you'll see:
Each operation is a separate, single-purpose tool with explicit naming that makes its intent clear:
This design allows AI assistants (Claude, Cursor, GitHub Copilot) to:
A read tool returns the Zscaler API record unchanged. The server does not trim, rename, or re-declare a resource's attributes — that attribute set belongs to the API, so a field Zscaler adds in future reaches you with no server upgrade.
To keep responses small, you control what comes back rather than the server guessing. Two levers:
--toolsets — load only the slice of tools you need, so the tool catalog
stays small (see Toolsets).
query — every list tool accepts an optional JMESPath
expression applied to the results, so the agent projects exactly what it wants:
Field names are exactly what the Zscaler API returns. Omit query to get the
full records.
The server implements multiple layers of security (defense-in-depth). The first nine apply on every transport, including stdio — they govern which tools are exposed and how dangerous calls are confirmed. The remaining HTTP-only layers (TLS, host-header validation, source-IP ACL, MCP client authentication) are described in the Network-Level Controls section further down.
list_* and get_* operations are always available (254 tools).--enable-write-tools.--write-tools allowlist (wildcard support).--toolsets zia_url_filtering,zpa_app_segments). See the Toolsets section below.list, get, create, update, delete).readOnlyHint or destructiveHint for AI agent frameworks.destructiveHint=True trigger permission dialogs in AI assistants.ZSCALER_MCP_WRITE_ENABLED, ZSCALER_MCP_WRITE_TOOLS, ZSCALER_MCP_TOOLSETS, ZSCALER_MCP_DISABLE_ENTITLEMENT_FILTER, and the disable lists can all be managed centrally without code changes.bleach), Markdown link/image syntax is neutralised so embedded URLs cannot be smuggled to the agent, and Markdown code-fence info-strings containing role-impersonation tokens (system, assistant, tool, ignore, …) are collapsed to a neutral text tag. This defends against prompt-injection payloads that an attacker — or a careless admin — might embed in editable Zscaler resources (rule descriptions, location names, label descriptions, etc.). On by default. Opt-out with ZSCALER_MCP_DISABLE_OUTPUT_SANITIZATION=true (use only for diagnostics).--log-tool-calls / ZSCALER_MCP_LOG_TOOL_CALLS=true is set, every tool invocation is logged with its arguments (sensitive values redacted), duration, and a result summary.This multi-layered approach ensures that even if one security control is bypassed, others remain in place to prevent unauthorized operations. Layers 1-12 above apply equally to stdio, sse, and streamable-http.
Tools are grouped into 63 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 (402)). Toolsets reduce the agent's context cost and improve tool-selection accuracy.
When --toolsets is unspecified, every toolset whose service is enabled is loaded (preserves the historical default).
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, per-toolset agent guidance, and the complete reference, see docs/guides/toolsets.md.
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:
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):
Only product entitlement is honoured — not role names. The server defers per-action permission enforcement to the live API; the entitlement filter only ensures we don't advertise tools for products the client has zero access to.
Delete operations are never executed on the first call. What happens instead depends on the client:
There is no way to turn this off. Deletes are irreversible against a live tenant, so the server ships no flag or environment variable that skips the gate. If you don't want an agent deleting anything, don't allowlist the delete tools: write tools are off by default and --write-tools takes explicit patterns (see Write Mode).
The next four subsections — TLS, source-IP allowlist, host-header validation, and the .env plaintext-secret scanner — apply only to the HTTP transports (sse, streamable-http). They control who can reach the server over the network. They are independent of the tool-level controls listed in Security Layers above (read-only mode, write allowlist, toolsets, entitlement filter, HMAC confirmations), which apply on every transport including stdio.
The corresponding MCP client authentication (Bearer / Basic / OAuth 2.1) is a fifth network-level layer covered in detail in the MCP Client Authentication section further below.
HTTPS is required by default for non-localhost deployments. The server will refuse to start on a non-localhost interface without TLS certificates unless you explicitly set ZSCALER_MCP_ALLOW_HTTP=true.
When running with HTTP transports (sse or streamable-http), provide TLS certificates:
When TLS is configured, the server automatically starts with HTTPS. This works with both public (CA-signed) and private (self-signed) certificates. Generate a self-signed certificate for testing:
You can restrict which client IPs are allowed to connect using ZSCALER_MCP_ALLOWED_SOURCE_IPS. When unset (the default), source IP filtering is disabled and deferred to upstream controls (firewall rules, AWS Security Groups, etc.).
Supports individual IPv4/IPv6 addresses, CIDR notation, and the wildcard 0.0.0.0/0. Health-check endpoints (/health, /healthz, /ready) are exempt so load-balancer probes continue to work. Requests from disallowed IPs receive 403 Forbidden.
When starting with HTTP transports, the server automatically scans any .env file in the working directory for plaintext secrets (values containing SECRET, PASSWORD, KEY, or TOKEN). If detected, a security warning is logged recommending the use of a secrets manager or environment variables instead.
On startup, the server logs a consolidated Security Posture Banner summarizing the active security configuration — transport mode, host validation status, authentication mode, TLS status, and any active warnings. This makes it easy to verify the security state at a glance.
Key Security Principles:
destructiveHint)--write-tools allowlist when enabling write mode--write-tools "zpa_create_application_segment")ZSCALER_MCP_WRITE_ENABLED=true without a corresponding ZSCALER_MCP_WRITE_TOOLS allowlistzpa_create_*) or operation-level control (e.g., *_create_*)📖 Full Documentation: Authentication & Deployment Guide
When running the MCP server over HTTP (sse or streamable-http transports), you can enable authentication to control who is allowed to connect to the server. This is independent from the Zscaler API credentials, which control how the server authenticates to Zscaler APIs.
For HTTP transports, the server auto-detects and enables authentication when auth-related environment variables are present. For stdio transport, authentication is not applicable (the operating system's process isolation provides security).
The server supports four authentication modes, configured via environment variables:
| Mode | Description | Best For |
|---|---|---|
api-key | Simple shared secret — client sends Authorization: Bearer <key> | Quick setup, internal environments, development |
jwt | External Identity Provider via JWKS — tokens validated locally using public keys | Enterprise SSO, multi-tenant deployments (Auth0, Okta, Azure AD, Keycloak, AWS Cognito, PingOne, Google) |
zscaler | Zscaler OneAPI credential validation — client sends Basic Auth with client_id:client_secret | Environments already using Zscaler API credentials |
oidc | OAuth 2.1 against your own IdP — the server is an OAuth 2.0 protected resource (RFC 9728) and clients authenticate with the IdP directly | Browser-based login for human operators, any OIDC provider |
Enable authentication by setting these environment variables in your .env file:
Then start the server with an HTTP transport:
Clients must include the key in the Authorization header:
Authentication is implemented as ASGI middleware that wraps the HTTP transport layer:
ZSCALER_MCP_AUTH_* variables — validates the incoming requestZSCALER_CLIENT_ID, ZSCALER_CLIENT_SECRET, etc. — authenticates the server to Zscaler APIsThese two layers are completely independent. You can enable one, both, or neither.
Clients authenticate with Basic Auth (client_id:client_secret) or custom headers (X-Zscaler-Client-ID / X-Zscaler-Client-Secret).
For HTTP transports (sse, streamable-http), the server auto-detects and enables authentication if auth-related environment variables are present (e.g., ZSCALER_MCP_AUTH_JWKS_URI, ZSCALER_MCP_AUTH_API_KEY, or ZSCALER_VANITY_DOMAIN). If no auth configuration is detected and ZSCALER_MCP_AUTH_ENABLED is not explicitly set, the server logs a security warning but continues without authentication.
To explicitly disable authentication, set:
Authentication does not apply to stdio transport (process isolation provides security).
oidc mode)oidc mode makes the server an OAuth 2.0 protected resource (RFC 9728). The server publishes /.well-known/oauth-protected-resource naming your Identity Provider; the client reads that, runs the OAuth flow against the IdP directly, and presents the resulting token. The server's only job is verifying the token signature against the IdP's published public keys.
It is configured entirely through environment variables — no code, no extra packages:
Notes:
OIDCPROXY_CLIENT_SECRET is ignored if set.OIDCPROXY_BASE_URL is this server's public URL, which clients use as the resource identifier — not the IdP's.OIDCPROXY_AUDIENCE defaults to OIDCPROXY_CLIENT_ID. Entra ID puts the client ID in aud; Auth0 uses the API identifier./authorize, /token or /register — clients need a client ID issued by the IdP and cannot self-register.IdP requirements: an application with the callback URL your client uses (http://localhost:3334/oauth/callback for mcp-remote, with the port pinned) registered, and an API/resource identifier matching OIDCPROXY_AUDIENCE.
📖 For detailed setup instructions — including Microsoft Entra ID step-by-step guide, IdP-specific JWKS configuration, Docker deployment examples, client configuration for Claude/Cursor/VS Code, and troubleshooting — see the Authentication & Deployment Guide.
The Zscaler Integrations MCP Server provides 402 tools for all major Zscaler services:
| Service | Description | Tools |
|---|---|---|
| ZIA | Zscaler Internet Access — Security policies | 166 read/write |
| ZPA | Zscaler Private Access — Application access | 109 read/write |
| ZDX | Zscaler Digital Experience — Monitoring & analytics | 31 read/write |
| ZCell | Zscaler Cellular — SIM inventory, usage analytics & anomaly policies | 20 read-only |
| ZMS | Zscaler Microsegmentation — Agents, resources, policies | 20 read-only |
| ZTW | Zscaler Workload Segmentation | 19 read/write |
| Z-Insights | Z-Insights analytics — Web traffic, cyber incidents, shadow IT | 16 read-only |
| ZIdentity | ZIdentity — Identity & access management | 10 read-only |
| EASM | External Attack Surface Management | 7 read-only |
| ZCC | Zscaler Client Connector — Device management | 4 read-only |
📖 View Complete Tools Reference →
Note: All write operations require the
--enable-write-toolsflag and an explicit--write-toolsallowlist. See the Security & Permissions section for details.
uv or pipCopy the example environment file and configure your credentials:
Then edit .env with your Zscaler API credentials:
Required Configuration (OneAPI):
ZSCALER_CLIENT_ID: Your Zscaler OAuth client IDZSCALER_CLIENT_SECRET: Your Zscaler OAuth client secretZSCALER_CUSTOMER_ID: Your Zscaler customer IDZSCALER_VANITY_DOMAIN: Your Zscaler vanity domainOptional Configuration:
ZSCALER_CLOUD: (Optional) Zscaler cloud environment (e.g., beta) - Required when interacting with Beta Tenant ONLY.ZSCALER_PRIVATE_KEY: (Optional) PEM-encoded private key for JWT-based OneAPI auth, used in place of ZSCALER_CLIENT_SECRET.ZSCALER_MCP_SERVICES: Comma-separated list of services to enable (default: all services)ZSCALER_MCP_TRANSPORT: Transport method - stdio, sse, or streamable-http (default: stdio)ZSCALER_MCP_DEBUG: Enable debug logging - true or false (default: false)ZSCALER_MCP_HOST: Host for HTTP transports (default: 127.0.0.1)ZSCALER_MCP_PORT: Port for HTTP transports (default: 8000)Alternatively, you can set these as environment variables instead of using a .env file.
Important: Ensure your API client has the necessary permissions for the services you plan to use. You can always update permissions later in the Zscaler console.
Note: This will open VS Code and prompt you to configure the MCP server. You'll need to replace the placeholder values (
<YOUR_CLIENT_ID>, etc.) with your actual Zscaler credentials.
Remote deployment: When running on EC2/VM, activate the project venv before starting:
source .venv/bin/activate. See Remote MCP Deployment.
[!TIP] If
zscaler-mcp-serverisn't found, update your shell PATH.
For installation via code editors/assistants, see the Using the MCP Server with Agents section below.
[!NOTE] Default Security Mode: All examples below run in read-only mode by default (only
list_*andget_*operations). To enable write operations (create_*,update_*,delete_*), add the--enable-write-toolsflag to any command, or setZSCALER_MCP_WRITE_ENABLED=truein your environment.
Run the server with default settings (stdio transport, read-only mode):
Run the server with write operations enabled:
Run with SSE transport:
Run with streamable-http transport:
Run with streamable-http transport on custom port:
The Zscaler Integrations MCP Server supports multiple ways to specify which services to enable:
Specify services using comma-separated lists:
Set the ZSCALER_MCP_SERVICES environment variable:
If no services are specified via command line or environment variable, all available services are enabled by default.
Service Priority Order:
--services argument (overrides all)ZSCALER_MCP_SERVICES environment variable (fallback)When you want to keep most tools available but exclude a few, use --disabled-tools or --disabled-services instead of listing every tool you want to include.
Both flags support wildcards via fnmatch patterns.
Environment variables:
Precedence: --disabled-tools takes precedence over --tools (include list). A tool that matches both the include list and the exclude list will be excluded.
For all available options:
Available command-line flags:
--transport: Transport protocol (stdio, sse, streamable-http)--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 list of tools to exclude, supports wildcards (e.g., zcc_*,zdx_list_devices)--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 unspecified, every toolset whose service is enabled is loaded. See docs/guides/toolsets.md.--no-entitlement-filter: Skip the OneAPI entitlement filter that trims toolsets to the products the configured ZSCALER_CLIENT_ID is entitled to. Emergency override only — the filter is non-fatal by default.--enable-write-tools: Enable write operations (disabled by default for safety)--write-tools: Mandatory allowlist of write tool patterns (e.g., "zpa_create_*,zpa_delete_*")--log-tool-calls: Enable per-tool-call audit logging (tool name, redacted arguments, duration, result summary)--debug: Enable debug logging--host: Host for HTTP transports (default: 127.0.0.1)--port: Port for HTTP transports (default: 8000)--user-agent-comment: Additional text appended to User-Agent header--generate-auth-token: Generate a client auth token snippet and exit--list-tools: List all available tools and exit--version: Show server version and exitThe Zscaler Integrations MCP Server uses OneAPI authentication exclusively. A single set of credentials authenticates the server to every Zscaler product (ZIA, ZPA, ZCC, ZDX, Zscaler Cellular, ZTW, ZIdentity, ZMS, Z-Insights, EASM).
Zscaler Cellular (ZCell) needs one extra credential — your Zscaler Cellular customer ID via
ZCELL_CUSTOMER_ID— which is separate fromZSCALER_CUSTOMER_ID(used by ZPA). See the environment-variable table below.
clientId, clientSecret (or privateKey for JWT), customerId, and vanityDomain.Create a .env file in your project root (or wherever you start the MCP server):
⚠️ Security: Do not commit .env to source control. Add it to your .gitignore.
| Environment Variable | Required | Description |
|---|---|---|
ZSCALER_CLIENT_ID | Yes | OneAPI client ID from the ZIdentity console |
ZSCALER_CLIENT_SECRET | Yes (or ZSCALER_PRIVATE_KEY) | OneAPI client secret |
ZSCALER_CUSTOMER_ID | Yes (for ZPA tools) | Zscaler customer/tenant ID |
ZCELL_CUSTOMER_ID | Yes (for Zscaler Cellular tools) | Zscaler Cellular customer ID (distinct from ZSCALER_CUSTOMER_ID; also accepted as the zcellCustomerId config key) |
ZSCALER_VANITY_DOMAIN | Yes | Your organization's vanity domain (e.g., acme) |
ZSCALER_CLOUD | No | Cloud override (e.g., beta, zscalertwo); omit for production |
ZSCALER_PRIVATE_KEY | No | PEM-encoded private key for JWT auth (used in place of ZSCALER_CLIENT_SECRET) |
After populating .env, start the server:
If credentials are valid, the server starts cleanly. The Zscaler SDK client is created lazily on the first tool call, so missing or rotating credentials surface as a clear error message at call time rather than blocking server startup.
| Symptom | Likely cause | Fix |
|---|---|---|
Zscaler SDK failed to initialize due to missing OneAPI credentials: [...] | One or more of ZSCALER_CLIENT_ID, ZSCALER_VANITY_DOMAIN, or (for ZPA) ZSCALER_CUSTOMER_ID is unset or empty. | Set the listed env vars in .env or your shell. |
You must provide either ZSCALER_CLIENT_SECRET or ZSCALER_PRIVATE_KEY for the OneAPI client. | Both auth materials are absent. | Set one of ZSCALER_CLIENT_SECRET or ZSCALER_PRIVATE_KEY. |
| 401/403 from a Zscaler API at tool-call time | API client lacks the scope for that product, or credentials are revoked. | Verify the OneAPI client's permissions in the ZIdentity console; rotate credentials if necessary. |
The following environment variables control MCP server behavior (not authentication):
| Environment Variable | Default | Description |
|---|---|---|
ZSCALER_MCP_TRANSPORT | stdio | Transport protocol to use (stdio, sse, or streamable-http) |
ZSCALER_MCP_SERVICES | "" | Comma-separated list of services to enable (empty = all services). Supported values: zcc, zdx, zia, zid, zpa, ztw |
ZSCALER_MCP_TOOLS | "" | Comma-separated list of specific tools to enable (empty = all tools) |
ZSCALER_MCP_DISABLED_SERVICES | "" | Comma-separated list of services to exclude (e.g., zcc,zdx). Takes precedence over ZSCALER_MCP_SERVICES. |
ZSCALER_MCP_DISABLED_TOOLS | "" | Comma-separated list of tools to exclude. Supports wildcards (e.g., zcc_*,zia_list_devices). Takes precedence over ZSCALER_MCP_TOOLS. |
ZSCALER_MCP_WRITE_ENABLED | false | Enable write operations (true/false). When false, only read-only tools are available. Set to true or use --enable-write-tools flag to unlock write mode. |
ZSCALER_MCP_WRITE_TOOLS | "" | MANDATORY comma-separated allowlist of write tools (supports wildcards like zpa_*). Requires ZSCALER_MCP_WRITE_ENABLED=true. If empty when write mode enabled, 0 write tools registered. |
ZSCALER_MCP_DEBUG | false | Enable debug logging (true/false) |
ZSCALER_MCP_HOST | 127.0.0.1 | Host to bind to for HTTP transports |
ZSCALER_MCP_PORT | 8000 | Port to listen on for HTTP transports |
ZSCALER_MCP_DISABLE_HOST_VALIDATION | false | Disable Host header validation when exposing on EC2/public IP (true/false). Alternatively, use --host 0.0.0.0 which auto-disables. |
ZSCALER_MCP_ALLOWED_HOSTS | "" | Comma-separated allowed Host values for remote deployment (e.g. 34.201.19.115:*,localhost:*). Preferred over disable for production. |
ZSCALER_MCP_TLS_CERTFILE | "" | Path to TLS certificate file (PEM format) for HTTPS. |
ZSCALER_MCP_TLS_KEYFILE | "" | Path to TLS private key file (PEM format) for HTTPS. |
ZSCALER_MCP_TLS_KEYFILE_PASSWORD | "" | Password for encrypted TLS private key (if applicable). |
ZSCALER_MCP_TLS_CA_CERTS | "" | Path to CA certificate bundle for mutual TLS or custom CA chains. |
ZSCALER_MCP_ALLOW_HTTP | false | Allow plaintext HTTP on non-localhost interfaces. HTTPS is required by default for remote deployments. Set to true only when TLS is terminated upstream (reverse proxy, ZPA, VPN). |
ZSCALER_MCP_ALLOWED_SOURCE_IPS | "" | Comma-separated list of allowed client IPs/CIDRs (e.g. 10.0.0.0/8,172.16.0.5). When unset, source IP filtering is disabled (defer to firewall/security groups). Set to 0.0.0.0/0 to allow all. |
ZSCALER_MCP_CONFIRMATION_TTL | 300 | HMAC fallback token lifetime in seconds. Does not apply to the sealed requestState used by elicitation-capable clients (SDK envelope TTL, default 600s). There is no variable that skips the confirmation itself. |
ZSCALER_MCP_REQUEST_STATE_KEYS | (unset) | Shared key ring for the SEP-2322 requestState. JSON array or comma-separated; each key ≥32 bytes (python -c "import secrets; print(secrets.token_hex(32))"). Required for multi-replica HTTP deployments with write tools enabled — unset uses a per-process key, so a confirmation issued by one replica cannot be validated by another. First key seals, all unseal (rotate [old,new] → [new,old] → [new]). |
ZSCALER_MCP_DISABLE_OUTPUT_SANITIZATION | false | Disable defense-in-depth output sanitization (BiDi / zero-width / HTML / Markdown / code-fence stripping). Sanitization is on by default; only set this for diagnostics — disabling it removes a prompt-injection defense layer. |
ZSCALER_MCP_USER_AGENT_COMMENT | "" | Additional information to include in User-Agent comment section |
The MCP server automatically includes a custom User-Agent header in all API requests to Zscaler services. The format is:
Example:
With Custom Comment:
You can append additional information (such as the AI agent details) using the ZSCALER_MCP_USER_AGENT_COMMENT environment variable or the --user-agent-comment CLI flag:
This results in:
The User-Agent helps Zscaler identify API traffic from the MCP server and can be useful for support, analytics, and debugging purposes.
You can use the Zscaler Integrations MCP Server as a Python library in your own applications:
Example with write operations enabled:
Available Services: zcc, zdx, zcell, zia, zid, zeasm, zins, zms, zpa, ztw
Example with Environment Variables:
The Zscaler Integrations MCP Server is available as a pre-built container image for easy deployment:
For development or customization purposes, you can build the image locally:
Note: When using HTTP transports in Docker, always set --host 0.0.0.0 to allow external connections to the container.
You can integrate the Zscaler Integrations MCP server with your editor or AI assistant. Here are configuration examples for popular MCP clients:
uvx (recommended)Note: The published PyPI package is
zscaler-mcp(notzscaler-mcp-server). When integrating as a Claude Code plugin, use${CLAUDE_PLUGIN_ROOT}/.envinstead of an absolute path; for Gemini extensions, use${extensionPath}${pathSeparator}.env.
When deploying the MCP server on a remote host (EC2, VM, internal server) so clients connect over HTTP from another machine:
Server setup:
Install and configure credentials (see Installation and Environment Configuration).
If using an editable install (uv pip install -e .), you must activate the project venv before running—otherwise an older or different installation may run:
Use --host 0.0.0.0 to bind on all interfaces. This automatically disables Host header validation (required when clients send the server's public IP in the Host header). For production, consider ZSCALER_MCP_ALLOWED_HOSTS in .env to restrict to known hostnames.
Ensure the firewall allows inbound traffic on the chosen port (e.g. 8000).
Client configuration (Claude Desktop):
Claude Desktop expects a command that spawns a process. For remote HTTP, use mcp-remote which supports custom authentication headers.
macOS / Linux:
Windows:
On Windows, paths with spaces (e.g., C:\Program Files\...) cause npx to fail when invoked directly. Wrap the call through cmd /c:
--allow-http: Required when connecting to a non-localhost HTTP endpoint.mcp-remoteenforces HTTPS by default for non-localhost URLs. Omit this flag when connecting over HTTPS or tolocalhost.
Using Zscaler auth mode (Basic Auth):
Replace the Authorization header with Basic Auth credentials. The value is the Base64 encoding of client_id:client_secret:
Then use "Authorization: Basic <base64_value>" in place of the Bearer header above.
Prerequisites on the client: Node.js (for npx) must be installed.
📖 Full remote deployment details (venv usage, 421 troubleshooting, security, TLS): Remote Deployment · 421 Misdirected Request · Troubleshooting
Deploy the Zscaler MCP Server to Azure with your choice of deployment target:
| Target | Description | Runtime | Status |
|---|---|---|---|
| Container Apps | Managed, serverless | Docker Hub image | GA |
| Virtual Machine | Ubuntu 22.04, self-managed | Python library (PyPI) | GA |
| Azure Kubernetes Service (AKS) | Kubernetes Deployment + LoadBalancer | Docker Hub image | Preview |
The script will prompt you for:
.env file path or manual entryContainer Apps and VM store all secrets in Azure Key Vault (mandatory) and auto-configure Claude Desktop / Cursor. AKS Preview injects credentials as Kubernetes environment variables on the Deployment — Workload Identity Federation + Key Vault CSI driver integration is planned.
Foundry Agent: Optionally create an Azure-hosted AI agent that wraps the MCP server. The agent is accessible via CLI chat (with spinner, token tracking, and timing), the Azure AI Foundry portal playground, REST APIs, or Microsoft 365 Copilot integrations.
📖 Full Azure deployment guide: integrations/azure/README.md
Google Cloud deployments cover both the standalone MCP Server and the Gemini-powered ADK Agent. A complete video walkthrough is available here:
Zscaler Integration MCP Server in GCP — Video Demo
Two interactive Python scripts manage all five Google Cloud deployment targets:
| Script | Deployment Targets |
|---|---|
integrations/google/gcp/gcp_mcp_operations.py | Cloud Run, GKE, Compute Engine VM (standalone MCP server) |
integrations/google/adk/adk_agent_operations.py | Local, Cloud Run, Vertex AI Agent Engine, Agentspace (ADK agent) |
Standalone MCP Server — Automated Deployment:
The script prompts for deployment target, credentials, and auth mode. It:
.env)zscaler authentication modeAuthorization: Basic headers from your Zscaler OneAPI credentialsclaude_desktop_config.json) and Cursor (~/.cursor/mcp.json).gcp-deploy-state.json) for subsequent status / logs / destroy operationsADK Agent — Interactive Deployment:
Manual Deployment:
With GCP Secret Manager (recommended for production):
The Docker image includes a built-in GCP Secret Manager loader. Store credentials as individual secrets (e.g., zscaler-client-id, zscaler-client-secret) and enable with a single env var:
The loader also works on GKE and Compute Engine — anywhere GCP Application Default Credentials are available.
📖 Full Google Cloud deployment guide (all five targets, IAM roles, authentication modes, enterprise patterns): integrations/google/README.md
📖 Secret Manager deep-dive (GKE manifests, credential rotation, loader internals): GCP Secret Manager Integration
Deploy the Zscaler MCP Server to any Kubernetes cluster via Helm — EKS, GKE, AKS, OpenShift, Rancher, k3s, Talos, or kind / minikube for local dev. The chart is cluster-vendor-agnostic and never calls aws, az, or gcloud. Use this when the cluster is already a fact and your operating model treats every workload as a Helm release; if you instead need to stand up brand-new cloud infra, use the Azure / GCP / AWS deployment sections above.
The deployment script materialises a Kubernetes Secret from your existing .env (no translation into values.yaml), runs helm upgrade --install, waits for the rollout with live per-pod feedback (detects ImagePullBackOff / CreateContainerConfigError / CrashLoopBackOff and exits with a tailored recovery hint), starts a background kubectl port-forward when no Ingress is configured, and auto-configures Claude Desktop + Cursor with the right Authorization: Basic header.
Five credential-setup paths are supported (interactive script, kubectl create secret --from-env-file, inline --set, pre-existing Secret for GitOps, and External Secrets Operator). All five converge on the same chart contract — the Deployment does envFrom: secretRef: so every ZSCALER_MCP_* / ZSCALER_* key in your secret flows into the container untouched.
For the full chart reference (values.yaml keys, Ingress / HTTPRoute / cert-manager / HPA / PDB toggles, ExternalSecret examples), see integrations/helm-chart/README.md.
[!IMPORTANT] One image, no AWS fork. Bedrock AgentCore used to be served by a separate build. It no longer is — the standard image runs on AgentCore as-is, configured entirely through environment variables. AgentCore's
containerConfigurationaccepts only an ECR URI (Docker Hub is not a legal value) and requireslinux/arm64, so the published multi-arch image still needs to be copied into ECR — or pulled from the AWS Marketplace listing, which is the same image already in ECR for you.
🚀 Quick Start with AWS Marketplace:
The easiest way to deploy the Zscaler Integrations MCP Server to Amazon Bedrock AgentCore is through the AWS Marketplace listing. What you get on this path:
linux/arm64 image — the two things AgentCore validatesZSCALER_SECRET_NAME and credentials never appear as environment variablesZSCALER_MCP_TRANSPORT / _HOST / _PORT, because ContainerConfiguration has no command override📚 Full Deployment Guide:
For detailed deployment instructions, IAM configuration, and troubleshooting, please refer to the comprehensive Amazon Bedrock AgentCore deployment guide.
The deployment guide covers:
🔐 AWS Secrets Manager (built in):
The image includes an AWS Secrets Manager loader, so credentials never have to appear as environment variables on the runtime. Store them as one JSON secret and point the deployment at it:
Then set ZSCALER_SECRET_NAME=zscaler/mcp/credentials on the runtime — its presence is the entire opt-in, there is no second flag. Grant the execution role secretsmanager:GetSecretValue (and kms:Decrypt if the secret uses a customer-managed key). Values from the secret override the container environment, so rotating the secret beats a stale value in a task definition, and a failure to read it stops the server at startup rather than surfacing later as an opaque Zscaler API error. Works the same on ECS Fargate, EKS and EC2. For a PyPI (non-container) install, boto3 rides the optional extra: pip install 'zscaler-mcp[aws]'.
ZSCALER_MCP_TRUST_PLATFORM_AUTH=true is an AgentCore-specific escape hatch: it lets api-key / zscaler auth modes accept a request carrying no credential, falling back to the container's own. It is safe only behind an authenticating ingress (AgentCore's customJwtAuthorizer consumes the Authorization header for its own token, leaving no envelope for ours). Never set it where the container is directly reachable.
[!NOTE] Earlier releases shipped a separate Bedrock image with a FastAPI wrapper (
web_server.py) that bypassed MCP session initialization. That wrapper is gone: the server speaks vanillastreamable-http, and clients on the2026-07-28revision are self-contained POSTs with no session handshake at all. The Marketplace image is recommended purely because it satisfies AgentCore's ECR + arm64 requirements out of the box — not because it runs different code.
This section provides instructions for configuring the Zscaler Integrations MCP Server with popular AI agents. Before starting, ensure you have:
.env file with credentialsYou can install the Zscaler MCP Server in Claude Desktop using either method:
Windows users: The one-click extension bundles macOS/Linux binaries and will not work on Windows. Use Option 2: Manual Configuration instead—it uses
uvxto install platform-appropriate packages at runtime. See Troubleshooting: Windows for details.
The easiest way to get started—one-click install with a user-friendly UI in Claude Desktop and low barrier to entry.
Prerequisites: uv must be installed (provides uvx). The extension uses uvx to run the server from PyPI at runtime—no manual pip install zscaler-mcp required. Install uv: curl -LsSf https://astral.sh/uv/install.sh | sh
zscaler.env file path when prompted (or edit the configuration after installation)Important: Replace
/absolute/path/to/your/.envwith the absolute path to your.envfile. On Windows, use a path likeC:\Users\You\.env. Relative paths will not work.
Troubleshooting:
.env file path is absolute and correct.env file contains valid credentialsModuleNotFoundError (rpds, pydantic_core, etc.): The extension bundles macOS/Linux binaries. Use Option 2 (Manual Configuration) instead. See Troubleshooting guide.~/.cursor/mcp.json. Add the following configuration:Alternative: You can also use Docker instead of
uvx:
Troubleshooting:
.env file path is absolute and credentials are correct~/.cursor/mcp.json (or %USERPROFILE%\.cursor\mcp.json on Windows)The Zscaler MCP Server ships with native integrations for several AI development platforms. Each integration includes platform-specific configuration files, 19 guided skills, and setup instructions.
| Platform | Type | Quick Start | Details |
|---|---|---|---|
| Claude Code | Plugin | claude plugin install zscaler | integrations/claude-code-plugin/ |
| Cursor | Plugin | Settings → Tools & MCP → New MCP Server | integrations/cursor-plugin/ |
| Gemini CLI | Extension | Register gemini-extension.json | integrations/gemini-extension/ |
| Kiro IDE | Power | Powers panel → Add Custom Power | integrations/kiro/ |
| Azure (Container Apps / VM) | Deployment + Agent | python azure_mcp_operations.py deploy | integrations/azure/ |
| Google Cloud (Cloud Run / GKE / VM) | Deployment | python gcp_mcp_operations.py deploy | integrations/google/ |
| Google ADK Agent | Agent | python adk_agent_operations.py deploy | integrations/google/adk/ |
| Kubernetes (Helm Chart) | Deployment | python helm_mcp_operations.py deploy | integrations/helm-chart/ |
| GitHub MCP Registry | Registry | mcp-publisher publish | integrations/github/ |
For full documentation on all integrations, see the Platform Integrations Guide.
Common Issues:
"Command not found: uvx"
uv: curl -LsSf https://astral.sh/uv/install.sh | shuvx with docker run --rm --env-file /path/to/.env zscaler/zscaler-mcp-server:latest".env file not found"
"Authentication failed"
.env"Tools not appearing"
"Server connection timeout"
uvx --env-file /absolute/path/to/.env zscaler-mcpWindows: ModuleNotFoundError: No module named 'rpds.rpds' (Claude Desktop extension)
uvx zscaler-mcp instead.Windows: 'C:\Program' is not recognized (Remote MCP with npx)
npx when called directly. Use "command": "cmd" with "args": ["/c", "npx", ...] instead.Non-HTTPS URLs are only allowed for localhost (mcp-remote)
mcp-remote enforces HTTPS for non-localhost URLs by default. Add "--allow-http" to the args array before --header.self-signed certificate / DEPTH_ZERO_SELF_SIGNED_CERT (mcp-remote with TLS)
"env": { "NODE_TLS_REJECT_UNAUTHORIZED": "0" } to the MCP server entry in your client config.Getting Help: