MCP allow and deny policy entries now expand ${VAR} references, skipping allowlist entries whose expansion looks unsafe.
What's wrong with this entry?
allowedMcpServers and deniedMcpServers predicates are no longer matched literally; stdio serverCommand entries and remote serverUrl patterns go through environment-variable expansion first, with a safety analysis that discards allowlist entries whose expansion changes what the pattern means.
- Denylist expansion uses a merged env drawn from global config, user, flag and policy settings as fallbacks; the allowlist path uses the settings-derived env.
- Substituted values are normalised through a placeholder that returns the constant
zzenvsubzz(or a digit-zeroed form for numeric values,::for IPv6-looking ones) so the expanded URL can be re-parsed and compared against the original. - Flagged as unsafe: an injected value that adds wildcard semantics, changes the URL's structure or hostname, or introduces traversal or query/fragment characters.
- Allowlist URL entries with an unsafe expansion are skipped, so they fail closed; denylist entries still apply.
- Missing variables emit a debug warning that the predicate references environment variables not present in the policy expansion env; unsafe expansions log that the expansion was unsafe.
- Neither the placeholder nor the wildcardVars analysis exists in v2.1.218, and the settings schema descriptions were not updated to mention any of it.
zzenvsubzz, MCP policy URL predicate expansion was unsafe
Strings lifted out of the shipped bundle, so the claim above can be checked against them.
Related
Other releases about the same thing. Found by shared names or similar wording; neither means one caused the other.
-
v2.1.248
MCP server allow and deny lists get settings keys
Both mention allowed server denied
-
v2.1.221
New MCP policy-predicate telemetry for allowedMcpServers matching
Both mention allowed server
-
v2.1.242
Eval runs fail loudly when managed policy blocks the mock servers
Both mention allowed server denied