[BUG] --allowedTools no working reliably

Resolved 💬 19 comments Opened Mar 19, 2025 by TomDigitalDavid Closed Mar 20, 2025
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Environment

  • Platform (select one):
  • [x] Anthropic API
  • [ ] AWS Bedrock
  • [ ] Google Vertex AI
  • [ ] Other: <!-- specify -->
  • Claude CLI version: 0.2.49
  • Operating System: Windows (Windows Server 2022 Datacenter)
  • Terminal: WSL2

Bug Description

I am trying to run Claude Code from a script using a command like claude -p "test the application and fix any errors you encounter" --allowedTools "Bash(dotnet:*)" Edit.
Claude Code will always reply that it needs permissions for the Edit tool, when it encounters an error. When prompting Claude Code to simply edit a file with the same --allowedTools specification it can edit files.

Steps to Reproduce

  1. Open WSL terminal in a .NET project
  2. Prompt it something like claude -p "test the application and fix any errors you encounter" --allowedTools "Bash(dotnet:*)" Edit
  3. It runs the tests and then you get a reply that it needs permissions to edit files (if it encounters errors)
  4. Prompt something like claude -p "Check which files you have access to and give me list of the files' names. Then write 'test' at the end of README.md. If you require permissions stop your task and reply with a message explaining what permissions you need." --allowedTools Edit
  5. Result: Claude Code can execute Bash (ls) and edit the file.

Expected Behavior

I would expect Claude Code to work the same in interactive mode and non-interactive mode, i.e. either use the allowedTools as defined in the project's claude config or correctly apply the --allowedTools flag with its parameters.
When using --allowedTools I expect Claude Code to use all tools defined with the command.

Actual Behavior

Claude Code cannot use all tools that were defined with --allowedTools

Additional Context

I'm running Claude Code in WSL on a virtual machine.
I played around with different prompts and different --allowedTools configurations. I could not find an explanation as to why this happens. When giving Claude Code a task like claude -p "Write 'hello' to README.md" --allowedTools Edit it worked. The same when I used a prompt that required it to run a bash command like "ls" and then edit a file.
I also added more allowed tools to the prompt and it still worked. Somehow, it failed once the prompt got a bit more complex, i.e. run "dotnet test" and then, if there are error during the build, editing files.

View original on GitHub ↗

19 Comments

maschwenk · 1 year ago

Can repro this as well, and can also confirm that claude -p "Write 'hello' to README.md" --allowedTools Edit DOES seem to work.

Reproing on a Mac talking to Bedrock. 0.2.49 (Claude Code)

maschwenk · 1 year ago

Maybe it has nothing to do with the prompt, but more that --allowedTools is not accepting a list properly? Or it's not working with --print mode specifically?

I tried providing the arguments a few different ways like --allowedTools X --allowedTools Y and still didn't work.

maschwenk · 1 year ago

Ok I figured it out. The docs are wrong.

export ANTHROPIC_API_KEY=sk_...
claude -p "update the README with the latest changes" --allowedTools "Bash(git diff:*)" "Bash(git log:*)" Edit

https://docs.anthropic.com/en/docs/agents-and-tools/claude-code/overview#automate-ci-and-infra-workflows

but actually if you look at claude --help you can see the correct format is:

--allowedTools <tools> Comma-separated list of tool names to allow (e.g. "Bash(git*),Edit,Replace")

e.g.

claude -p "update the README with the latest changes" --allowedTools "Bash(git diff:*),Bash(git log:*),Edit"

bcherny collaborator · 1 year ago

Fix incoming

TomDigitalDavid · 1 year ago

@maschwenk You are right. I tested my workflow with --allowedTools "Bash(dotnet:*),[...some other tools...],Edit" and it worked fine. Thanks for your help!

@bcherny Thanks for your quick response!

maschwenk · 1 year ago

@bcherny Awesome! Just also noting using --print mode in CI makes it super hard to understand when permissions are failing. It'll say "I had permissions issues doing X" but it doesn't really call out what command it ran so it's really hard to build the --allowedTools list. I've tried adding things like

As you work on this, please print any output to the file and well as a summary of each command you execute to ./.git/claude-code-output.txt with a timestamp.

or

if you run into any issues please tell me which command failed and why

but never works

bcherny collaborator · 1 year ago

Fixed in the latest!

bcherny collaborator · 1 year ago
maschwenk · 1 year ago

@bcherny For sure. Can you clarify exactly what you changed here though? Did you update the docs to match the code? Or change the code to match the docs?

ijohnson-coursera · 1 year ago

@bcherny This is still an issue in 0.2.53. Still getting permission issues when I run Claude Code with the following. It seems to work most of the time, but about 20% of the time it will say it doesn't have access to write or commit/push.

CLAUDE_CODE_USE_BEDROCK=1 DISABLE_PROMPT_CACHING=1 claude -p "/init" --allowedTools "Bash(git diff:*),Bash(git status:*),Bash(git log:*),Bash(git show:*),Bash(git blame:*),Bash(git add:*),Bash(git commit:*),Bash(git checkout:*),Bash(git branch:*),Bash(git push:*),Bash(gh pr:*),Bash(gh auth:*),Bash(./gradlew build:*),Bash(./gradlew clean build:*),Bash(./gradlew test:*),Bash(./gradlew checkstyleMain:*),Bash(./gradlew idea:*),Bash(./gradlew eclipse:*),Bash(./gradlew generateProto:*),Edit,Write"
ijohnson-coursera · 1 year ago

Seems like doing "--allowedTools Bash Edit Replace" and not specifying the bash command works

Connoropolous · 1 year ago

Really confused, because people are throwing around Edit, and Write, but if you look at the list of tools, it's these:

!Image

acron0 · 1 year ago

Sorry to hijack this, but is it possible to grant permission to use MCPs this way?

claude --allowedTools "playwright" -p $(echo e2e/INSTRUCTIONS.md) I need your permission to use the Playwright browser automation tool to visit the webpage mentioned in the instructions.
TomDigitalDavid · 1 year ago

Yes, you can add MCPs to the allowedTools. However, you have to provide the whole MCP function name in this format: mcp__{your-MCP-server-name}__{MCP-function-name}, e.g. mcp__perplexity__search.

your-MCP-server-name would be the name provided to Claude Code when you added the MCP server.

Note: From my experience, you have to add each MCP function separately. mcp_perplexity:* or mcp_perplexity__:* or similar variations did not work for me.

tino · 1 year ago

@bcherny this seems to be still an issue on 0.2.90 (Claude Code)

❯ claude --allowedTools 'Edit Write' --print --verbose --output-format=json 'add "works" to ./afile.txt'
[
  {
    "role": "user",
    "content": "add \"works\" to ./afile.txt"
  },
  {
    "id": "msg_01QkufEES2W5kkTicZwbTkNB",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "tool_use",
        "id": "toolu_012uHWPsXUSNEbV7YCv35jDE",
        "name": "Read",
        "input": {
          "file_path": "/Users/tino/Dev/solarmonkey/app/code/afile.txt"
        }
      }
    ],
    "stop_reason": "tool_use",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 4,
      "cache_creation_input_tokens": 147,
      "cache_read_input_tokens": 32567,
      "output_tokens": 73
    }
  },
  {
    "role": "user",
    "content": [
      {
        "tool_use_id": "toolu_012uHWPsXUSNEbV7YCv35jDE",
        "type": "tool_result",
        "content": ""
      }
    ]
  },
  {
    "id": "msg_014PmD3Y5r7CA2t5fuphBreq",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "tool_use",
        "id": "toolu_01X2oJsGZMpvdhzKG73pHujp",
        "name": "Write",
        "input": {
          "file_path": "/Users/tino/Dev/solarmonkey/app/code/afile.txt",
          "content": "works"
        }
      }
    ],
    "stop_reason": "tool_use",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 7,
      "cache_creation_input_tokens": 195,
      "cache_read_input_tokens": 32714,
      "output_tokens": 91
    }
  },
  {
    "role": "user",
    "content": [
      {
        "type": "tool_result",
        "content": "Claude requested permissions to use Write, but you haven't granted it yet.",
        "is_error": true,
        "tool_use_id": "toolu_01X2oJsGZMpvdhzKG73pHujp"
      }
    ]
  },
  {
    "id": "msg_015j7AjEJ2hCJVTDpSx9QYGL",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "tool_use",
        "id": "toolu_0164yLRYCeHoF1ws9RQW3dLH",
        "name": "Read",
        "input": {
          "file_path": "/Users/tino/Dev/solarmonkey/app/code/afile.txt"
        }
      }
    ],
    "stop_reason": "tool_use",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 7,
      "cache_creation_input_tokens": 124,
      "cache_read_input_tokens": 32909,
      "output_tokens": 74
    }
  },
  {
    "role": "user",
    "content": [
      {
        "tool_use_id": "toolu_0164yLRYCeHoF1ws9RQW3dLH",
        "type": "tool_result",
        "content": ""
      }
    ]
  },
  {
    "id": "msg_01NZmy6ukqdHoRctFYf3bJqZ",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "text",
        "text": "The file appears to be empty. I'll add \"works\" to it."
      }
    ],
    "stop_reason": "tool_use",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 7,
      "cache_creation_input_tokens": 99,
      "cache_read_input_tokens": 33033,
      "output_tokens": 108
    }
  },
  {
    "id": "msg_01NZmy6ukqdHoRctFYf3bJqZ",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "tool_use",
        "id": "toolu_01UvgawKTQ8daoKJNwo7jhFw",
        "name": "Write",
        "input": {
          "file_path": "/Users/tino/Dev/solarmonkey/app/code/afile.txt",
          "content": "works"
        }
      }
    ],
    "stop_reason": "tool_use",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 7,
      "cache_creation_input_tokens": 99,
      "cache_read_input_tokens": 33033,
      "output_tokens": 108
    }
  },
  {
    "role": "user",
    "content": [
      {
        "type": "tool_result",
        "content": "Claude requested permissions to use Write, but you haven't granted it yet.",
        "is_error": true,
        "tool_use_id": "toolu_01UvgawKTQ8daoKJNwo7jhFw"
      }
    ]
  },
  {
    "id": "msg_01Bdo16MCkxDQGPd5pEYgVTN",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-7-sonnet-20250219",
    "content": [
      {
        "type": "text",
        "text": "I need permission to write to the file. Please grant Write permission and I'll try again."
      }
    ],
    "stop_reason": "end_turn",
    "stop_sequence": null,
    "usage": {
      "input_tokens": 7,
      "cache_creation_input_tokens": 141,
      "cache_read_input_tokens": 33132,
      "output_tokens": 23
    }
  },
  {
    "role": "system",
    "cost_usd": 0.057585,
    "duration_ms": 23860,
    "duration_api_ms": 23861,
    "result": "I need permission to write to the file. Please grant Write permission and I'll try again."
  }
]

And I'd like to echo the confusion from @Connoropolous. The tool name isn't what's written there but without "Tool" suffix. So how to read that?

ronnyli · 1 year ago

I've tried --allowedTools "AgentTool" "BatchTool", --allowedTools AgentTool,BatchTool, --allowedTools "AgentTool,BatchTool", --allowedTools "AgentTool BatchTool", and --allowedTools AgentTool BatchTool and none of them are working.

I can confirm they aren't doing anything by using --output-format stream-json because the init message prints out the list of tools and no matter what I do the list of initialized tools is unchanged.

(Note that AgentTool and BatchTool are just placeholder examples. I've also tried removing them and replacing with mcp__alpaca__get_account_info which I know works because I can use the tool when I run Claude Code in interactive mode)

jybp · 1 year ago

From @TomDigitalDavid

Yes, you can add MCPs to the allowedTools. However, you have to provide the whole MCP function name in this format: mcp__{your-MCP-server-name}__{MCP-function-name}, e.g. mcp__perplexity__search.

your-MCP-server-name would be the name provided to Claude Code when you added the MCP server.
Note: From my experience, you have to add each MCP function separately. mcp_perplexity: or mcp_perplexity__: or similar variations did not work for me.

Would it be possible to update claude code to allow to configure all the functions of an mcp server at once in allowed tools? For example by just specifying: mcp__{your-MCP-server-name} ?

Connoropolous · 1 year ago
I've tried --allowedTools "AgentTool" "BatchTool", --allowedTools AgentTool,BatchTool, --allowedTools "AgentTool,BatchTool", --allowedTools "AgentTool BatchTool", and --allowedTools AgentTool BatchTool and none of them are working. I can confirm they aren't doing anything by using --output-format stream-json because the init message prints out the list of tools and no matter what I do the list of initialized tools is unchanged. (Note that AgentTool and BatchTool are just placeholder examples. I've also tried removing them and replacing with mcp__alpaca__get_account_info which I know works because I can use the tool when I run Claude Code in interactive mode)

I have some experience. Take a look at the following:

**Command**
claude -p --allowedTools="[\"Bash\", \"Edit\"]" "what allowed tools do you have?"

**Response**
I have access to the following tools:

- **Task** - Launch agents for searching keywords/files across the codebase
- **Bash** - Execute shell commands with proper quoting and timeout handling
- **Glob** - Fast file pattern matching (e.g., `**/*.js`, `src/**/*.ts`)
- **Grep** - Search file contents using regex patterns
- **LS** - List files and directories with optional ignore patterns
- **Read** - Read file contents with optional line offset/limit
- **Edit** - Make exact string replacements in files
- **MultiEdit** - Make multiple edits to a single file in one operation
- **Write** - Write/overwrite files (requires reading existing files first)
- **NotebookRead/NotebookEdit** - Read and edit Jupyter notebooks
- **WebFetch** - Fetch and analyze web content with AI processing
- **WebSearch** - Search the web for up-to-date information
- **TodoRead/TodoWrite** - Manage structured task lists for complex work
- **exit_plan_mode** - Exit planning mode when ready to implement code
github-actions[bot] · 11 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.