DXT ${__dirname} resolves to MSIX-virtualized path, breaking external process spawns

Resolved 💬 3 comments Opened Apr 14, 2026 by CptPirx Closed Apr 18, 2026

Summary

When Claude Desktop is installed as an MSIX package on Windows, DXT extensions that spawn external processes (e.g. py.exe for Python MCP servers) fail because ${__dirname} resolves to a path inside the MSIX virtual filesystem that external processes cannot see.

Environment

  • Windows 11 Pro
  • Claude Desktop (MSIX-packaged, Claude_pzs8sxrjxfjjc)
  • DXT extension with type: "python" using ${__dirname} in mcp_config.args

Steps to Reproduce

  1. Install Claude Desktop on a fresh Windows machine (no prior Claude Desktop installation)
  2. Install a DXT extension (.mcpb) that uses a Python MCP server with this manifest:

``json
"server": {
"type": "python",
"entry_point": "server.py",
"mcp_config": {
"command": "py",
"args": ["${__dirname}/server.py"]
}
}
``

  1. Claude Desktop extracts the bundle and spawns py.exe with the resolved ${__dirname} path

Expected Behavior

py.exe finds and runs server.py at the path provided by ${__dirname}.

Actual Behavior

C:\Program Files\Python312\python.exe: can't open file
'C:\Users\<user>\AppData\Roaming\Claude\Claude Extensions\<extension-id>/server.py':
[Errno 2] No such file or directory

The file actually exists at the MSIX-virtualized path:

C:\Users\<user>\AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\Claude\Claude Extensions\<extension-id>\server.py

Root Cause

MSIX filesystem virtualization redirects AppData\Roaming\ writes to AppData\Local\Packages\Claude_pzs8sxrjxfjjc\LocalCache\Roaming\. Claude Desktop (inside the sandbox) resolves ${__dirname} to the virtual path (AppData\Roaming\...), but the spawned external process (py.exe) runs outside the MSIX sandbox and cannot see files at that path.

Per Microsoft's MSIX docs, on Windows 10 1903+:

  • Newly created files/folders in AppData are written to the per-app virtualized location
  • Child processes spawned by MSIX apps do not inherit the package context
  • Command-line argument paths are not automatically rewritten from virtual to real paths

This only affects fresh installations where Claude Extensions\ didn't previously exist at the real AppData\Roaming\ path. Machines with a pre-existing folder (from an earlier non-MSIX install) are unaffected because MSIX writes to pre-existing real paths.

Workaround

Manually create the real directory before installing the extension, so MSIX doesn't virtualize it:

New-Item -ItemType Directory -Path "$env:APPDATA\Claude\Claude Extensions" -Force

Then reinstall the .mcpb extension.

Suggested Fix

When resolving ${__dirname}, Claude Desktop should detect MSIX packaging and resolve to the real filesystem path (AppData\Local\Packages\...\LocalCache\Roaming\...) rather than the virtual path, since spawned child processes run outside the sandbox.

Alternatively, Claude Desktop could write extensions to a non-AppData location (MSIX only virtualizes AppData paths), or declare unvirtualizedResources / FilesystemWriteVirtualization=disabled in its MSIX manifest for the extensions directory.

Related Issues

  • #25579 — MSIX virtualization redirects app.getPath("userData"); documents the core path mismatch
  • #26073 — "Edit Config" opens wrong claude_desktop_config.json due to MSIX path
  • #29302 — Windows-MCP extension fails because executable in MSIX virtualized path is blocked
  • #35037 — MSIX causes rename() EXDEV errors crossing virtual/real boundary

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗