You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Any settings.tools.core value (even []) emits a wildcard DENY that silently excludes all MCP tools – breaks run-gemini-cli's shipped pr-review example #28361
Setting any value for tools.core in settings – including the empty array [] – causes the policy engine to emit a wildcard * DENY rule that statically excludes every MCP tool (plus non-allowlisted built-ins such as activate_skill) from the tool registry. The exclusion is active in YOLO mode, and no MCP allow mechanism (mcpServers.<name>.trust: true, mcp.allowed, mcp.autoAllowInHeadless) can override it.
Symptom chain observed with that example as shipped (gemini-cli-extensions/code-review extension + github-mcp-server v0.27.0, GitHub Actions non-interactive mode):
Startup logs Refresh for 'github' discovered 3 tools – the MCP server connects and discovery works.
But the excluded tools are filtered out of ToolRegistry.getFunctionDeclarations(), so the model receives no MCP tool declarations and blind-guesses tool names.
getTool() excludes them too, so every guess fails with Tool "<name>" not found. Did you mean "activate_skill"?.
The model burns through maxSessionTurns trying 22+ name variants (get_pull_request, github.get_pull_request, pull_request_read, prefixed/unprefixed FQNs, ...) and the run dies with FatalTurnLimitedError.
The net effect: anyone deploying the pr-review example as documented gets a green workflow that never reviews anything, with no error surfaced anywhere.
Root cause
At tag v0.50.0, packages/core/src/policy/config.ts lines 545–562: any truthy settings.tools.core (an empty array is truthy) adds a wildcard DENY one notch below the core allowlist's ALLOW priority:
if(settings.tools?.core){mapToolsToRules(settings.tools.core,CORE_TOOLS_FLAG_PRIORITY,'Settings (Core Tools)',nonPlanModes,);// If core tools are restricted, we should add a default DENY rule for everything else// at a slightly lower priority than the explicit allows.rules.push({toolName: '*',decision: PolicyDecision.DENY,priority: CORE_TOOLS_FLAG_PRIORITY-0.01,source: 'Settings (Core Tools Allowlist Enforcement)',modes: nonPlanModes,});}
With the priority constants from the same file (lines 75–81), the resulting ranking is:
Every MCP allow mechanism ranks below the wildcard DENY; only tools.allowed and explicit tools.core entries outrank it. And because PolicyEngine.getExcludedTools() converts static DENYs into registry exclusions consumed by ToolRegistry.getActiveTools(), the tools are not merely denied at execution time – their declarations are never sent to the model, which is what produces the blind-guessing loop instead of a clean policy error.
This also contradicts the documentation: docs/reference/configuration.md describes tools.core as "Restrict the set of built-in tools with an allowlist" – nothing indicates it also disables all MCP tools regardless of MCP trust/allow settings.
What did you expect to happen?
tools.core: [] should restrict built-in tools (as documented) while leaving MCP tools governed by the MCP policy mechanisms – or at minimum fail loudly rather than silently stripping tool declarations.
Suggested fixes, in descending order of preference:
Scope the core-allowlist wildcard DENY to built-in tools (exclude mcp_* / declared MCP server tools from the * match), so tools.core matches its documented semantics and trust/mcp.allowed/autoAllowInHeadless keep working.
Failing that, fix the shipped run-gemini-cli pr-review example settings so they don't ship a config that disables the very MCP server the workflow depends on (I'm filing a linked issue on google-github-actions/run-gemini-cli).
At minimum, document the interaction in docs/reference/configuration.md and consider warning at startup when tools.core is set and MCP servers are configured but end up fully excluded.
Steps to reproduce
Minimal, generic repro (no GitHub Actions needed):
gemini --approval-mode yolo -p "Call any tool from the github MCP server"
Expected: MCP tools callable (server is trusted, YOLO mode).
Actual: discovery logs the server's tools, but the model gets no declarations for them and any attempted call returns Tool "<name>" not found.
As-shipped repro: deploy examples/workflows/pr-review/gemini-review.yml from run-gemini-cli unmodified and open a PR – the review run exhausts maxSessionTurns and posts nothing while the workflow stays green.
Verified workarounds (end-to-end):
add "mcp_github_*" (and/or exact FQNs) to tools.core, or use "tools": { "allowed": ["mcp_github_*"] } (4.3 outranks the 4.24 DENY);
also allowlist "activate_skill" – the code-review extension's mandatory skill activation is a built-in tool call that "core": [] denies.
What happened?
Setting any value for
tools.corein settings – including the empty array[]– causes the policy engine to emit a wildcard*DENY rule that statically excludes every MCP tool (plus non-allowlisted built-ins such asactivate_skill) from the tool registry. The exclusion is active in YOLO mode, and no MCP allow mechanism (mcpServers.<name>.trust: true,mcp.allowed,mcp.autoAllowInHeadless) can override it.This silently breaks run-gemini-cli's own shipped
examples/workflows/pr-reviewexample, whose settings contain:Symptom chain observed with that example as shipped (gemini-cli-extensions/code-review extension + github-mcp-server v0.27.0, GitHub Actions non-interactive mode):
Refresh for 'github' discovered 3 tools– the MCP server connects and discovery works.ToolRegistry.getFunctionDeclarations(), so the model receives no MCP tool declarations and blind-guesses tool names.getTool()excludes them too, so every guess fails withTool "<name>" not found. Did you mean "activate_skill"?.maxSessionTurnstrying 22+ name variants (get_pull_request,github.get_pull_request,pull_request_read, prefixed/unprefixed FQNs, ...) and the run dies withFatalTurnLimitedError.--output-format json, the CLI embedsINVALID_STREAM/FatalTurnLimitedErrorin stdout while exiting 0, so the surrounding action reports success and simply posts no review (the action-side half of that is Silent success when multiple auth methods are provided (zero review output, no error) google-github-actions/run-gemini-cli#519).The net effect: anyone deploying the pr-review example as documented gets a green workflow that never reviews anything, with no error surfaced anywhere.
Root cause
At tag v0.50.0,
packages/core/src/policy/config.tslines 545–562: any truthysettings.tools.core(an empty array is truthy) adds a wildcard DENY one notch below the core allowlist's ALLOW priority:With the priority constants from the same file (lines 75–81), the resulting ranking is:
tools.allowedtools.coreentries*mcpServers.<name>.trust: truemcp.allowed/mcp.autoAllowInHeadless(#27215)Every MCP allow mechanism ranks below the wildcard DENY; only
tools.allowedand explicittools.coreentries outrank it. And becausePolicyEngine.getExcludedTools()converts static DENYs into registry exclusions consumed byToolRegistry.getActiveTools(), the tools are not merely denied at execution time – their declarations are never sent to the model, which is what produces the blind-guessing loop instead of a clean policy error.Behaviour introduced in v0.41.0 by #25720.
This also contradicts the documentation:
docs/reference/configuration.mddescribestools.coreas "Restrict the set of built-in tools with an allowlist" – nothing indicates it also disables all MCP tools regardless of MCP trust/allow settings.What did you expect to happen?
tools.core: []should restrict built-in tools (as documented) while leaving MCP tools governed by the MCP policy mechanisms – or at minimum fail loudly rather than silently stripping tool declarations.Suggested fixes, in descending order of preference:
mcp_*/ declared MCP server tools from the*match), sotools.corematches its documented semantics andtrust/mcp.allowed/autoAllowInHeadlesskeep working.docs/reference/configuration.mdand consider warning at startup whentools.coreis set and MCP servers are configured but end up fully excluded.Steps to reproduce
Minimal, generic repro (no GitHub Actions needed):
settings.json:{ "mcpServers": { "github": { "command": "github-mcp-server", "args": ["stdio"], "trust": true } }, "tools": { "core": [] } }Run non-interactively:
gemini --approval-mode yolo -p "Call any tool from the github MCP server"Expected: MCP tools callable (server is trusted, YOLO mode).
Actual: discovery logs the server's tools, but the model gets no declarations for them and any attempted call returns
Tool "<name>" not found.As-shipped repro: deploy
examples/workflows/pr-review/gemini-review.ymlfrom run-gemini-cli unmodified and open a PR – the review run exhaustsmaxSessionTurnsand posts nothing while the workflow stays green.Verified workarounds (end-to-end):
"mcp_github_*"(and/or exact FQNs) totools.core, or use"tools": { "allowed": ["mcp_github_*"] }(4.3 outranks the 4.24 DENY);"activate_skill"– the code-review extension's mandatory skill activation is a built-in tool call that"core": []denies.Client information
ubuntu-latestrunner), non-interactive mode via google-github-actions/run-gemini-cliLogin information
API key (
GEMINI_API_KEY) in CI.Anything else we need to know?
Related issues that compound this one in the pr-review workflow:
.errorfrom stderr only, so theINVALID_STREAM/FatalTurnLimitedErrorembedded in stdout with exit 0 is reported as success.