Claude Code MCP Permissions 5 min read

Claude Code Permission Denied — How to Diagnose and Fix It

"Permission denied" in Claude Code (and MCP-based agents generally, including Cursor's agent mode) can mean three completely different things — the CLI's own approval prompt, an OS-level filesystem error, or a sandboxed subprocess that can't reach the files it needs. This guide walks through each layer and how to fix it.

Not sure if it's your setup or an outage?

Prismix tracks live status for Anthropic, OpenAI, and 80+ AI services · Check live AI status →

Check now →

What causes "permission denied" in Claude Code?

"Permission" is overloaded here — it can refer to Claude Code's own trust prompt, a real OS-level file permission error, a restricted MCP subprocess, or a session running in a stricter mode than you expect. Telling them apart is most of the fix:

Symptom Cause Fix
"Do you want to proceed?" y/n prompt Claude Code's own approval gate Approve once, or allowlist the tool/command
EACCES: permission denied OS-level file/directory ownership chmod/chown, or use a dir you own
MCP server exits or "spawn" fails Subprocess inherited restricted permissions Check parent app / sandbox launch context
No prompt at all, action just refused Session in a stricter permission mode Check/adjust the session's mode
Only fails inside WSL or under /mnt/c WSL <-> Windows permission bit mismatch Keep project on WSL's native filesystem

5 steps to fix permission-denied issues

1

Understand the prompt, then grant per-session or persistent approval

Claude Code is an agent that can run shell commands, edit files, and call MCP tools on your behalf. By default it asks before anything with real side effects — running Bash, writing a file, calling certain MCP tools — because an autonomous agent taking an irreversible action without a human glancing at it first is exactly the failure mode the prompt exists to prevent. That's the trust model: you are the approval step, not a bug in the tool.

You don't have to re-approve the same thing forever. Two ways to reduce repeat prompts:

  • Per-session: at the prompt itself, choose the "always allow for this session" option if offered — it stops re-asking until you exit.
  • Persistent: add the specific tool/command to an allow list in your project's or user's settings.json, scoped narrowly (a specific command pattern, not a blanket allow-everything).

A narrowly-scoped allowlist entry looks roughly like this (check your installed version's docs or run /permissions in a session for the exact current syntax):

{
  "permissions": {
    "allow": [
      "Bash(npm run test:*)",
      "Bash(git diff:*)"
    ]
  }
}

Scope allowlist entries to the exact command or tool you actually trust to run unattended — a broad "allow everything" entry defeats the point of the prompt in the first place.

2

Diagnose OS-level EACCES errors — this is not the CLI prompt

If you already approved the action and it still fails with something like EACCES: permission denied, open '/path/to/file', that's coming from the operating system, not from Claude Code's approval system. The process you're running as genuinely doesn't have read/write/execute rights on that path. Common root causes: the directory is owned by a different user (often root, if something was previously run with sudo), the path is on a read-only mount, or you're running Claude Code as a different user than the one who owns the project directory.

Diagnose before fixing:

# Who am I actually running as?
whoami

# Who owns this file/directory, and what are the permission bits?
ls -l /path/to/file
ls -ld /path/to/directory

Then fix ownership or permissions directly, rather than escalating privileges:

# Give yourself ownership of a directory you should own
chown -R $(whoami) /path/to/directory

# Or fix the permission bits directly
chmod u+rw /path/to/file

Don't reach for sudo as the fix. Running Claude Code (or any agent) as root papers over the ownership mismatch instead of correcting it, and hands an AI agent unrestricted write access to your whole system. Fix the actual ownership, or work from a directory you already own.

3

Check for a sandboxed or restricted MCP server subprocess

MCP servers launched locally (via npx or uvx) run as a child process of whatever launched them. That child inherits the permissions — and the restrictions — of its parent, not of your interactive shell. Two situations cause permission failures here that look identical to a config problem but aren't:

  • Restricted parent launch context: if the app that spawned the MCP server itself has limited filesystem access (e.g. it was granted access to only specific folders), every server it spawns is bound by the same limit, regardless of what the MCP config's args say.
  • Sandboxed environments: a corporate-managed machine (MDM-enforced sandboxing on macOS, for example) or a containerized dev environment can block subprocess file access outright — the server process starts, but every file operation it attempts fails, no matter how the tool call itself is configured.

If a locally-spawned MCP server can read/write fine when you run the exact same command by hand in your terminal, but fails only when the client (Claude Code, Claude Desktop, Cursor) launches it, the sandbox or launch-context permissions of the parent app — not your MCP config — is the thing to investigate.

4

Check the session's permission mode

A Claude Code session runs at a trust level, and that level determines both how often you get prompted and, at the strict end, whether an action is silently refused instead of asked about. Concretely, sessions can range from "confirm nearly everything" up through modes that auto-accept file edits, and further up to more autonomous modes intended for sandboxed or CI-style runs. If a session feels like it's prompting far more — or far less — than you expect, or an action is being denied with no prompt at all, the session may simply be in a different mode than the one you think it's in.

The exact flag names and mode labels have changed across Claude Code releases, so rather than assert a specific one here, check the current mechanism directly: run claude --help for startup flags, look for an in-session permissions command (commonly something like /permissions), or check your project's and user's settings.json for a mode field. Whichever surface your installed version uses, the concept is the same: the session has a configured trust level, and it's worth confirming what it's actually set to before assuming a permission is broken.

5

Windows: fix WSL vs native filesystem permission mismatches

This is the most common Windows-specific cause of "permission denied" and it's easy to miss because everything looks configured correctly. When a project lives on the Windows filesystem and is accessed from inside WSL through the /mnt/c/... mount (or, less commonly, a WSL path is referenced from native Windows), permission bits get translated across the two very different permission models rather than mapped 1:1. The result: chmod can report success without actually changing what's enforced, and Claude Code (or an MCP server it spawns) can hit permission denied on a file that looks perfectly readable in Explorer.

Fix: work inside WSL's native filesystem

# Slow AND permission-fragile — Windows drive mounted into WSL
cd /mnt/c/Users/you/projects/my-app

# Fast AND permission-sane — native WSL ext4 filesystem
cd ~/projects/my-app

Move (or re-clone) the project into WSL's own home directory rather than working across the /mnt/c/ boundary. This also sidesteps the well-known WSL performance penalty on cross-filesystem file access, not just the permission mismatch.

If you must keep the project on the Windows side, running Claude Code from native Windows (rather than from inside WSL against the same path) avoids the translation layer entirely — the tradeoff is you lose access to WSL-only tooling for that session.

FAQ

Why does Claude Code ask for permission before every command?

It can execute shell commands, edit files, and call MCP tools on your behalf, and those actions can be destructive or irreversible. It prompts for explicit approval unless you've pre-approved that exact action — a safety boundary, not a bug.

How do I stop it from asking permission for the same command every time?

Approve "for this session" at the prompt if offered, or add a narrowly-scoped entry to the allow list in settings.json (e.g. a specific command pattern, not a blanket allow). Run /permissions in a session or check claude --help for the exact current mechanism — it has changed across versions.

What causes "EACCES: permission denied" from Claude Code or an MCP server?

An OS-level filesystem permission error, separate from the CLI's own prompt — the process's user account lacks rights on that path. Check with ls -l and whoami, then fix ownership/permissions with chown/chmod rather than escalating privileges.

Should I run Claude Code with sudo to fix permission errors?

No. It removes the permission boundary protecting your system instead of fixing the ownership mismatch, and gives an AI agent unrestricted write access to your machine. Fix ownership on the affected directory, or work from one you already own.

Why do I only get permission denied errors inside WSL?

Files under /mnt/c/... use a translated permission model that doesn't map cleanly onto native Linux permission bits, so chmod can appear to succeed without changing effective access. Keep the project on WSL's native filesystem (e.g. ~/projects/...) instead of the Windows-mounted path.

Related guides