What feature would you like to see?
When [tools].disabled (or [tools].enabled) contains a name that matches no built-in tool and no MCP tool, fail loudly — exit with an error or refuse to start the session — instead of only printing a warning.
Matching is case-sensitive today, so disabled = ["agent"] does not disable Agent, and the tool silently stays available.
Concretely: keep the current warning text, but make it a hard failure for the three shapes the docs already say never match:
- a wildcard that is not an
mcp__ pattern,
- an
mcp__ name missing the tool segment,
- any name that no registered tool has.
Additional information
The configuration docs (tools section) say those shapes "are reported with a warning" and that matching is case-sensitive. A denylist that is silently inert after a one-character case mistake is exactly how a session keeps a tool the operator tried to turn off — including Agent and AgentSwarm.
Behaviour that should keep working: exact names such as disabled = ["Agent", "AgentSwarm"], and an empty enabled list still meaning "no allowlist constraint", as documented.
Suggested acceptance check: with disabled = ["agent"] the process refuses to run and the message suggests the exact built-in name Agent; with disabled = ["NoSuchTool"] it refuses and names the unmatched entry.
What feature would you like to see?
When
[tools].disabled(or[tools].enabled) contains a name that matches no built-in tool and no MCP tool, fail loudly — exit with an error or refuse to start the session — instead of only printing a warning.Matching is case-sensitive today, so
disabled = ["agent"]does not disableAgent, and the tool silently stays available.Concretely: keep the current warning text, but make it a hard failure for the three shapes the docs already say never match:
mcp__pattern,mcp__name missing the tool segment,Additional information
The configuration docs (
toolssection) say those shapes "are reported with a warning" and that matching is case-sensitive. A denylist that is silently inert after a one-character case mistake is exactly how a session keeps a tool the operator tried to turn off — includingAgentandAgentSwarm.Behaviour that should keep working: exact names such as
disabled = ["Agent", "AgentSwarm"], and an emptyenabledlist still meaning "no allowlist constraint", as documented.Suggested acceptance check: with
disabled = ["agent"]the process refuses to run and the message suggests the exact built-in nameAgent; withdisabled = ["NoSuchTool"]it refuses and names the unmatched entry.