---
title: "WSL & containers"
description: "Connect an agent that runs in WSL, a devcontainer or on another machine to a Scalebrowser daemon on Windows: why localhost does not reach it, and what does."
canonical: "https://scalebrowser.net/docs/agents/wsl-and-containers"
---

> ## Documentation Index
> Fetch the complete documentation index at: https://scalebrowser.net/llms.txt
> Use this file to discover all available pages before exploring further.

# WSL & containers

> Connect an agent that runs in WSL, a devcontainer or on another machine to a Scalebrowser daemon on Windows: why localhost does not reach it, and what does.

An agent in WSL cannot reach the Windows daemon on `127.0.0.1`, and the failure looks like a
dead daemon rather than a network boundary. This page is the way across.

## Why the HTTP entry does not connect

WSL 2 runs as a virtual machine behind a network adapter of its own. Inside it, `127.0.0.1`
is the Linux side. Windows forwards the other way (a service in WSL is reachable from
Windows on localhost) and not this way, so the entry that works in a Windows terminal fails
in a WSL one:

```bash
$ curl http://127.0.0.1:8787/health
curl: (7) Failed to connect to 127.0.0.1 port 8787: Connection refused
```

Mirrored networking mode makes localhost shared, and it does fix this. It is a
machine-wide change with its own trade-offs, so nothing here assumes it.

## What works: start the daemon across the boundary

WSL can run Windows programs directly. Instead of reaching the daemon over the network, let
your agent start it over stdio: the process attaches to the daemon the app is already
running and relays to it, owning no browser of its own. Nothing is opened on the network,
and no token goes into the file.

```json ~/.claude.json
{
  "mcpServers": {
    "scalebrowser": {
      "command": "/mnt/c/Users/<you>/AppData/Local/Programs/Scalebrowser/resources/daemon/scalebrowser-daemon.exe",
      "args": ["--mcp-stdio", "--data-dir", "C:/Users/<you>/AppData/Local/Scalebrowser"]
    }
  }
}
```

Two details decide whether this works:

**The program is named with a Linux path, the data directory with a Windows one.** WSL
resolves `command` on the Linux side, which is why it needs `/mnt/c/...`. The daemon that
starts is a Windows process and reads `--data-dir` with Windows rules. Forward slashes are
fine there; backslashes inside a JSON string are not, unless you double them.

**`/mnt/c` assumes the default mount point.** If you set `automount.root` in
`/etc/wsl.conf`, use yours.

The app fills both paths in for you under **Settings → General → Connect an agent**, on the
"From WSL" tab.

<Warning>

**`--data-dir` is what makes this land on the right daemon.** Without it the process looks
in `%ProgramData%\Scalebrowser`, which is not where the desktop app keeps anything. It then
either attaches to whatever holds the address named in an old `runtime.json` there and
answers `unauthorized` to every call, or starts a second, empty daemon that responds
normally and knows none of your profiles. Since 0.9 it stops and names both directories
instead.

</Warning>

## Devcontainers and other machines

A container has no access to the Windows filesystem, so it cannot start the program. The
stdio route is out, and the daemon deliberately binds loopback only, so there is no address
to point at either.

That case is what [remote access](/docs/agents/mcp-server) is for: the daemon opens an
outbound tunnel and your agent reaches it through a relay, wherever it runs. It is off until
someone switches it on at the machine, in **Settings → General → Remote access**.

## Checking which daemon you reached

One machine can hold more than one installation, and they are told apart by data directory,
never by address. Ask the daemon which one it is:

```bash
curl -H "Authorization: Bearer $SCALEBROWSER_TOKEN" \
  http://127.0.0.1:8787/v1/connection
```

```json
{
  "native_addr": "127.0.0.1:8787",
  "data_dir": "C:\\Users\\you\\AppData\\Local\\Scalebrowser",
  "executable": "C:\\Users\\you\\AppData\\Local\\Programs\\Scalebrowser\\resources\\daemon\\scalebrowser-daemon.exe"
}
```

If `data_dir` is not the one you meant, the port is being held by another installation. The
app moves up a port when something already holds 8787, so its real address is the
`native_addr` field of `runtime.json` in its own data directory.
