claude-code - 💡(How to fix) Fix Stdio MCP server cwd field silently ignored on Windows (2.1.123) [1 participants]

Official PRs (…)
ON THIS PAGE

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…
GitHub stats
anthropics/claude-code#54786Fetched 2026-04-30 06:36:03
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
labeled ×4cross-referenced ×2

On Windows, the cwd field in a stdio MCP server config (.mcp.json or user-scope mcpServers in ~/.claude.json) is silently ignored when Claude Code spawns the server. The subprocess inherits the parent process's cwd instead of the configured value. This breaks any server that uses cwd-relative paths to locate its script file or its data directories.

The failure presents as ✗ Failed to connect in claude mcp list with no surface-level explanation. The real cause is only visible by running with DEBUG=true and inspecting the debug log, which shows the spawned Python interpreter reporting it cannot find server.py because it's looking in the wrong directory.

A second, compounding failure mode (covered partially by #46360): when working around the first by using absolute paths for both the interpreter AND the script, the recommended cmd /c <python> <script> Windows wrapper hits cmd.exe's "old-behavior" quote-stripping rule (≥2 quoted args triggers it), producing 'c:\Users\noahr\code' is not recognized as an internal or external command. The wrapper that's supposed to make Windows work makes Windows worse once both args have spaces. Dropping the wrapper (using direct interpreter + absolute script path with no cmd /c) is what works — same workaround as #46360 Bug 2, but the diagnostic path is different.

Root Cause

The failure presents as ✗ Failed to connect in claude mcp list with no surface-level explanation. The real cause is only visible by running with DEBUG=true and inspecting the debug log, which shows the spawned Python interpreter reporting it cannot find server.py because it's looking in the wrong directory.

Fix Action

Workaround

Drop the cmd /c wrapper, use bare interpreter + absolute path to the script:

{
  "command": "C:\full\path\python.exe",
  "args": ["C:\full\path\server.py"]
}

And ensure each server itself uses os.path.dirname(os.path.abspath(__file__)) for any data lookups, since cwd still won't be set on the spawned process.

Code Example

{
     "mcpServers": {
       "demo": {
         "type": "stdio",
         "command": "cmd",
         "args": ["/c", "C:\some\path with spaces\my-server\.venv\Scripts\python.exe", "server.py"],
         "cwd": "C:\some\path with spaces\my-server"
       }
     }
   }

---

Server stderr: python.exe: can't open file 'C:\<repo-root>\server.py': [Errno 2] No such file or directory

---

{
  "command": "C:\full\path\python.exe",
  "args": ["C:\full\path\server.py"]
}
RAW_BUFFERClick to expand / collapse

Description

On Windows, the cwd field in a stdio MCP server config (.mcp.json or user-scope mcpServers in ~/.claude.json) is silently ignored when Claude Code spawns the server. The subprocess inherits the parent process's cwd instead of the configured value. This breaks any server that uses cwd-relative paths to locate its script file or its data directories.

The failure presents as ✗ Failed to connect in claude mcp list with no surface-level explanation. The real cause is only visible by running with DEBUG=true and inspecting the debug log, which shows the spawned Python interpreter reporting it cannot find server.py because it's looking in the wrong directory.

A second, compounding failure mode (covered partially by #46360): when working around the first by using absolute paths for both the interpreter AND the script, the recommended cmd /c <python> <script> Windows wrapper hits cmd.exe's "old-behavior" quote-stripping rule (≥2 quoted args triggers it), producing 'c:\Users\noahr\code' is not recognized as an internal or external command. The wrapper that's supposed to make Windows work makes Windows worse once both args have spaces. Dropping the wrapper (using direct interpreter + absolute script path with no cmd /c) is what works — same workaround as #46360 Bug 2, but the diagnostic path is different.

Steps to Reproduce

  1. Windows 11 (10.0.26200), Claude Code 2.1.123 (CLI binary AND VS Code extension bundle).
  2. Create a Python MCP server at C:\some\path with spaces\my-server\server.py.
  3. Add to .mcp.json in some other directory (e.g. a repo root):
    {
      "mcpServers": {
        "demo": {
          "type": "stdio",
          "command": "cmd",
          "args": ["/c", "C:\some\path with spaces\my-server\.venv\Scripts\python.exe", "server.py"],
          "cwd": "C:\some\path with spaces\my-server"
        }
      }
    }
  4. Run DEBUG=true CLAUDE_CODE_DEBUG_LOGS_DIR=/tmp/log claude mcp list from the repo root (NOT the server dir).
  5. Observe ✗ Failed to connect and, in the debug log:
    Server stderr: python.exe: can't open file 'C:\<repo-root>\server.py': [Errno 2] No such file or directory

Expected Behavior

Claude Code should set the spawned subprocess's working directory to the cwd value from the config, so that relative server.py (and any cwd-relative data paths the server uses) resolve correctly. This matches how vanilla child_process.spawn(cmd, args, {cwd}) in Node behaves.

Actual Behavior

The subprocess inherits the parent's cwd. The cwd field in the config has no effect.

Workaround

Drop the cmd /c wrapper, use bare interpreter + absolute path to the script:

{
  "command": "C:\full\path\python.exe",
  "args": ["C:\full\path\server.py"]
}

And ensure each server itself uses os.path.dirname(os.path.abspath(__file__)) for any data lookups, since cwd still won't be set on the spawned process.

Environment

  • OS: Windows 11 Home 10.0.26200 (win32-x64)
  • Claude Code CLI: 2.1.123 (both ~/.local/bin/claude.exe and ~/.vscode/extensions/anthropic.claude-code-2.1.123-win32-x64/resources/native-binary/claude.exe)
  • VS Code extension: 2.1.123
  • Affected: every stdio MCP server defined with relative script path + cwd
  • Diagnostic-visibility prerequisite: DEBUG=true env var; otherwise claude mcp list reports only ✗ Failed to connect

Related

  • #46360 — Windows claude mcp add /c flag mangling + workaround (different root cause, same workaround shape)
  • #49133 — Silent-failure UX gap meta-issue (macOS-flagged but applies on Windows too — confirms the diagnostic-discoverability problem)

Suggested Labels

bug, area:mcp, platform:windows, has repro

extent analysis

TL;DR

The issue can be fixed by dropping the cmd /c wrapper and using the bare interpreter with an absolute path to the script in the mcp.json configuration.

Guidance

  • The cwd field in the mcp.json configuration is being ignored, causing the subprocess to inherit the parent process's working directory.
  • To fix this, update the command and args fields in the mcp.json configuration to use the bare interpreter and absolute path to the script, as shown in the provided workaround.
  • Ensure that each server uses os.path.dirname(os.path.abspath(__file__)) for data lookups, as the cwd field will still not be set on the spawned process.
  • Verify the fix by running claude mcp list with DEBUG=true and checking the debug log for any errors.

Example

{
  "command": "C:\\\\full\\\\path\\\\python.exe",
  "args": ["C:\\\\full\\\\path\\\\server.py"]
}

Notes

This fix assumes that the issue is specific to Windows and the cmd /c wrapper. The root cause of the issue is the cwd field being ignored, which is not directly addressed by this fix. However, the provided workaround should resolve the symptoms.

Recommendation

Apply the workaround by dropping the cmd /c wrapper and using the bare interpreter with an absolute path to the script, as this should resolve the issue and allow the subprocess to run correctly.

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

claude-code - 💡(How to fix) Fix Stdio MCP server cwd field silently ignored on Windows (2.1.123) [1 participants]