Cowork: mcp__workspace__bash and web_fetch permanently denied — host passes Bash/WebFetch in --disallowedTools, which aliases onto the workspace tools

Status Open
Reported on v2.1.258
Maintainer reply None cached
Activity 0 comments · opened Sep 2, 2026

Summary

In Cowork on Claude Desktop for Windows, every call to mcp__workspace__bash and mcp__workspace__web_fetch is denied, in every session, permanently. No other tool is affected.

The cause is visible in the command line the desktop host uses to spawn the Claude Code child: it puts mcp__workspace__bash in --allowedTools and Bash + WebFetch in --disallowedTools in the same spawn. The SDK expands those two built-in names onto their workspace equivalents, so the deny list cancels the allow list. Deny outranks allow, and the call is refused by rule.

The apparent intent is to stop Cowork using the local shell so execution goes through the workspace sandbox. The alias expansion carries the denial onto the sandbox tools as well.

Environment

Claude Desktop : 1.44121.1.0  (MSIX, Windows 11 Pro 10.0.26200)
Bundled CLI    : claude-code 2.1.258
Plan           : personal account, no organization
Permission mode: auto (also reproduced under bypassPermissions)

Evidence

1. The spawned child's command line (captured from Win32_Process, abridged; paths and identifiers redacted):

claude-code\2.1.258\claude.exe
  --allowedTools     Task,…,mcp__cowork__present_files,…,mcp__workspace__bash
  --disallowedTools  Bash,PowerShell,NotebookEdit,REPL,JavaScript,WebFetch
  --permission-mode  auto
  --allow-dangerously-skip-permissions
  --setting-sources=user

mcp__workspace__bash is allowed and Bash is denied, on the same line.

2. The alias map, in app.asar and in the CLI binary:

{ Bash: "mcp__workspace__bash", WebFetch: "mcp__workspace__web_fetch" }

with an expander that, for each built-in name present in a set, adds the workspace tool id to that set. Applied to the deny set, denying Bash also denies mcp__workspace__bash.

Note mcp__workspace__web_fetch is not in --allowedTools at all, yet is denied identically — consistent with expansion of WebFetch, and not with a hand-written rule.

3. The session's audit record:

{"type":"system","subtype":"permission_denied",
 "tool_name":"mcp__workspace__bash",
 "decision_reason_type":"rule",
 "message":"Permission to use mcp__workspace__bash has been denied."}

with "non_execution_kind":"permission-rule" on the tool result. It is a rule decision, not a declined prompt — no approval dialog is ever raised.

4. The workspace MCP server is healthymcpServerStatus reports {"name":"workspace","status":"connected","toolCount":2}, and both tools appear in the session's tool list (197 tools). They are provisioned and refused at call time.

Reproduction

  1. Cowork session on Claude Desktop 1.44121.1.0 (Windows).
  2. Ask it to run any shell command.
  3. Error: Permission to use mcp__workspace__bash has been denied.

To see the cause, poll for the child process while sending a message — it lives only for the turn:

$deadline=(Get-Date).AddMinutes(3); $seen=@{}
while((Get-Date) -lt $deadline){
  Get-CimInstance Win32_Process -Filter "Name='claude.exe'" |
    Where-Object { $_.ExecutablePath -like '*Roaming\Claude\claude-code*' -and -not $seen[$_.ProcessId] } |
    ForEach-Object { $seen[$_.ProcessId]=$true; $_.CommandLine }
  Start-Sleep -Milliseconds 150
}

Expected vs actual

Expected: mcp__workspace__bash and mcp__workspace__web_fetch run in the workspace sandbox. Denying the local Bash/WebFetch built-ins should not affect them.

Actual: both are denied by rule, permanently, with no user-visible cause.

Why the usual remedies do not apply

A deny rule outranks all of these; each was tried and failed:

  • Starting new conversations, and quitting/relaunching the app
  • Signing out and back in
  • Changing permission mode, including "skip all approvals" (bypassPermissions) — the argv already carries --allow-dangerously-skip-permissions and the call is still denied
  • Editing ~/.claude/settings.json — Cowork does not read it; CLAUDE_CONFIG_DIR points at a per-session directory
  • Every on-device policy source is empty: user/project/local settings, C:\ProgramData\ClaudeCode\managed-settings.json, HKLM/HKCU policy keys, MDM (device is unmanaged), and mcp-user-tool-toggles.json (no workspace entry)

The desktop host's own tool-disabling code paths all log when they run, and none of them fired — so the --disallowedTools list is being assembled somewhere that does not log.

Scope

  • Cloud Cowork sessions are unaffected — in a browser session the tools are the plain Bash/WebFetch built-ins, both work, and mcp__workspace__bash does not exist. The account and code-execution capability are fine.
  • Claude Code outside Cowork on the same machine has a working Bash.
  • File, browser and subagent tools in desktop Cowork are unaffected.

Regression note

The bundled CLI 2.1.255 (previous version, still on disk) contains the same alias map, so the expander is not new. The change appears to be host-side — Claude Desktop newly passing Bash and WebFetch in --disallowedTools. On this machine the tools worked in every session before the 1.44121.1.0 update and in none since.

Suggested fix

Exclude the workspace tool ids from alias expansion when building the deny set, or stop passing Bash/WebFetch in --disallowedTools when the workspace equivalents are being granted. At minimum, an explicit entry in --allowedTools should not be silently overridden by an aliased deny derived from a different tool name.

View original on GitHub ↗