claude-code - 💡(How to fix) Fix Feature request: exclusive-allowlist mode for --allowedTools (currently additive on top of built-in default safe-list)

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Without it, every Claude Code release that adds a built-in tool potentially breaks downstream agentic harnesses. We've already hit this twice in the past month — Skill and ScheduleWakeup showed up in subprocesses that hadn't asked for them. The maintenance burden falls on each caller to keep their --disallowedTools list in sync with the CLI's tool catalogue across versions.

A strict-mode flag would let callers express the constraint they actually mean ("only these tools, please") and stay forward-compatible.

Fix Action

Fix / Workaround

Workaround (today)

Code Example

claude --print --output-format stream-json \
  --allowedTools Write \
  --disallowedTools Bash,PowerShell,Edit,MultiEdit,NotebookEdit,Glob,Grep,Task,ToolSearch,WebFetch,WebSearch \
  --strict-mcp-config --mcp-config <per-run-config>.json \
  --model claude-opus-4-7 \
  ...

---

AskUserQuestion, CronCreate, CronDelete, CronList,
EnterPlanMode, EnterWorktree, ExitPlanMode, ExitWorktree,
ListMcpResourcesTool, Monitor, PushNotification, Read,
ReadMcpResourceTool, RemoteTrigger, ScheduleWakeup,
Skill, TaskOutput, TaskStop, TodoWrite, Write

---

--strict-tools          # symmetric to --strict-mcp-config

---

--default-tools none    # disable all built-in tools by default

---

Bash,PowerShell,Edit,MultiEdit,NotebookEdit,Glob,Grep,Task,ToolSearch,
WebFetch,WebSearch,Read,Skill,TodoWrite,AskUserQuestion,EnterPlanMode,
ExitPlanMode,EnterWorktree,ExitWorktree,ScheduleWakeup,CronCreate,
CronDelete,CronList,Monitor,PushNotification,RemoteTrigger,TaskOutput,
TaskStop,ListMcpResourcesTool,ReadMcpResourceTool
RAW_BUFFERClick to expand / collapse

Problem

--allowedTools is documented and intuitive as a whitelist, but at runtime it behaves additively — it appends to the Claude CLI's default safe-list of built-in tools rather than replacing it. The only way to truly restrict a subprocess to a specific tool set today is to enumerate everything else in --disallowedTools, which means tracking every new built-in tool Claude Code ships.

Reproduction

Spawn a Claude Code subprocess with:

claude --print --output-format stream-json \
  --allowedTools Write \
  --disallowedTools Bash,PowerShell,Edit,MultiEdit,NotebookEdit,Glob,Grep,Task,ToolSearch,WebFetch,WebSearch \
  --strict-mcp-config --mcp-config <per-run-config>.json \
  --model claude-opus-4-7 \
  ...

The intent is "this subprocess should only call Write." In the agent_session_init event, the subprocess actually has 20 built-in tools available:

AskUserQuestion, CronCreate, CronDelete, CronList,
EnterPlanMode, EnterWorktree, ExitPlanMode, ExitWorktree,
ListMcpResourcesTool, Monitor, PushNotification, Read,
ReadMcpResourceTool, RemoteTrigger, ScheduleWakeup,
Skill, TaskOutput, TaskStop, TodoWrite, Write

In our case the agent auto-invoked Skill('init') (the built-in /init skill that generates CLAUDE.md from codebase analysis), then re-read its own output file twice, ballooning a 130 s / $0.85 step into 255 s / $1.94 with 9 turns instead of the expected 3.

Use case context

We run Claude Code as a non-interactive subprocess from a Python orchestrator ("agent step in a multi-step pipeline"). Each step has a narrow contract — e.g., "read inline-injected inputs, emit two files, exit." We've already done:

  • Fake HOME with only .credentials.json copied (no ~/.claude.json, no user skills, no CLAUDE.md memory)
  • Scrubbed CLAUDE_* and CLAUDECODE env vars
  • --strict-mcp-config with a per-run config listing only the MCP servers the step needs
  • --allowedTools listing only what the step's prompt requires

User-installed state (skills, MCP servers, settings) is correctly isolated. But built-in tools ship inside the claude binary itself — filesystem isolation can't strip them, so they leak into every subprocess.

Proposed solution

A flag like:

--strict-tools          # symmetric to --strict-mcp-config

Semantics: --allowedTools becomes an exclusive whitelist. Built-in tools not in --allowedTools are unavailable (same effect as listing them in --disallowedTools), without callers having to enumerate them.

Alternatively, a complementary flag:

--default-tools none    # disable all built-in tools by default

So callers can opt out of the default safe-list once instead of subtracting each tool by name.

Why this matters

Without it, every Claude Code release that adds a built-in tool potentially breaks downstream agentic harnesses. We've already hit this twice in the past month — Skill and ScheduleWakeup showed up in subprocesses that hadn't asked for them. The maintenance burden falls on each caller to keep their --disallowedTools list in sync with the CLI's tool catalogue across versions.

A strict-mode flag would let callers express the constraint they actually mean ("only these tools, please") and stay forward-compatible.

Workaround (today)

Enumerate every current built-in in --disallowedTools:

Bash,PowerShell,Edit,MultiEdit,NotebookEdit,Glob,Grep,Task,ToolSearch,
WebFetch,WebSearch,Read,Skill,TodoWrite,AskUserQuestion,EnterPlanMode,
ExitPlanMode,EnterWorktree,ExitWorktree,ScheduleWakeup,CronCreate,
CronDelete,CronList,Monitor,PushNotification,RemoteTrigger,TaskOutput,
TaskStop,ListMcpResourcesTool,ReadMcpResourceTool

This works but is fragile — every new built-in is silently opt-in until it breaks something.

Related

  • --strict-mcp-config already exists and solves the exact same problem for MCP servers; the same pattern for built-in tools would be a natural extension.

Thanks for considering!

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING