How to use the filesystem mcp with WSL and Docker

When setting up the filesystem mcp server for Claude Desktop, I found a few issues with the standard recommendations.

As of writing this article, the instructions at https://modelcontextprotocol.io/quickstart/user recommend using node/npx to interact with the file system.

This seemed a bit too risky to me as it meant the LLM potentially had access to any files on my machine if for some reason the mcp didn’t respect it’s stated

Use docker

Hence, I chose to use the docker variation described in the official setup instructions which would give me the ability to use docker as the abstraction layer to limited access to just the locations I needed, with a robust, trusted tool.

Next though, I found a few issues with the default/recommended setup, particularly on Windows, namely:

  • It was not clear how to mount projects from WSL
  • Naively mounting directories into docker would result in write actions creating files owned by root

so I’m sharing the solutions I found

How to correctly mount projects in WSL

{
  "mcpServers": {
    "filesystem": {
      "command": "wsl.exe",
      "args": [
        "docker",
        "run",
        "-i",
        "--rm",
        "--user", "1000:1000",
        "--mount", "type=bind,src=/path/within/wsl,dst=/projects/path/as/mcp/server/sees/it",
        "mcp/filesystem",
        "/projects"
      ]
    }
  }
}

Note the differences from the official setup instructions (as of publishing this article)

Firstly, we set the command to wsl.exe to run in the context of WSL, and move the docker call into the args list

Secondly, we add "--user", "1000:1000", (switch these user and group values to whatever your user uses, which can be found with id -u and id -g respectively) to ensure that the files written via the mount are owned by you, rather than root

Enhanced security

Optionally, you can set the docker mount to readonly, by appending the ,ro suffix to the mount config

"--mount", "type=bind,src=/path/within/wsl,dst=/projects/path/as/mcp/server/sees/it,ro",

if you only want your LLM to be able to see the context of the locations, and not make changes.

Without this it’s potentially possible for the LLM to escape the bounds you’ve placed on it via the creation of symlinks