Remote development
graphmind serve binds 127.0.0.1 and has no --host option. Nothing can reach it from
another machine or another network namespace, which is the point. When your agent runs
somewhere other than your browser, the flow that works is:
-
Run
npx graphmind-aiwhere the agent runs: inside the container, the Codespace, the WSL distribution, or on the SSH host. The agent then reaches it on its own loopback, with no configuration. -
Forward port 4747 to the machine your browser is on, keeping the same port number.
-
Open
http://localhost:4747in your local browser.
The same port number matters. The server accepts a browser only when the page’s origin is on
the server’s own port. If the forward lands on a different local port, say localhost:8888,
every script the viewer loads is refused with 403 and the page stays blank. If you cannot
keep the port, tell the server which origin to expect:
# on the remote side, if your browser will use http://localhost:8888GRAPHMIND_ALLOWED_ORIGINS=http://localhost:8888 npx graphmind-aiBy environment
Section titled “By environment”Run npx graphmind-ai --no-open in the container’s terminal. VS Code offers to forward a port
it sees in terminal output. To make it explicit, add to .devcontainer/devcontainer.json:
{ "forwardPorts": [4747]}Check the Ports panel: the “Forwarded Address” should be localhost:4747. If VS Code
picked another local port because 4747 was busy on your machine, either free it or set
GRAPHMIND_ALLOWED_ORIGINS to that origin as above.
Publishing the port with docker run -p 4747:4747 does not work on its own. Docker
forwards to the container’s network interface, and the server listens only on the container’s
loopback. VS Code’s forwarding connects from inside the container, which is why it works.
Opened in VS Code desktop, a Codespace forwards ports to localhost on your machine. That
is the same flow as a devcontainer: run npx graphmind-ai --no-open, forward 4747, open
http://localhost:4747.
Opened in the browser, the forwarded address is a https://<name>-4747.app.github.dev URL.
That hostname is not a loopback name, so the server’s DNS-rebinding check refuses it with
403. Allowing that exact origin should let it through:
GRAPHMIND_ALLOWED_ORIGINS=https://<name>-4747.app.github.dev npx graphmind-ai --no-openThat is an unauthenticated control channel for your agent, reachable by anyone who can pass the forwarded port’s visibility setting. Keep the port Private.
Run the agent and npx graphmind-ai --no-open inside the same WSL distribution, then open
http://localhost:4747 in a Windows browser. WSL 2 forwards localhost from Windows into the
distribution by default, so the port number stays the same.
If the agent runs on Windows and the server in WSL (or the reverse), they are not on the same loopback. Run both on the same side.
Run the agent and npx graphmind-ai --no-open on the remote host, and forward the port with
the same number on both ends:
ssh -L 4747:127.0.0.1:4747 you@remote-hostThen open http://localhost:4747 locally. VS Code Remote-SSH does the same when you forward the
port from its Ports panel.
If 4747 is taken on your machine, forward another local port and allow that origin on the remote server:
ssh -L 8888:127.0.0.1:4747 you@remote-host# on the remote host:GRAPHMIND_ALLOWED_ORIGINS=http://localhost:8888 npx graphmind-ai --no-openWhen the server and the agent cannot share a machine
Section titled “When the server and the agent cannot share a machine”GRAPHMIND_URL tells an SDK where the server is, for example when you run the server on your
host and the agent in a container:
GRAPHMIND_URL=ws://host.docker.internal:4747/ingest node agent.jsTwo things stand in the way, and both are deliberate:
-
The Host check. The SDK’s connection arrives with
Host: host.docker.internal:4747, which is not a loopback name, and the server answers403. Allow that hostname on the server:Terminal window GRAPHMIND_ALLOWED_ORIGINS=http://host.docker.internal:4747 npx graphmind-ai -
The loopback bind. The server must be reachable at all from inside the container. Docker Desktop’s
host.docker.internalroutes to the host’s loopback. On Linux,--add-host=host.docker.internal:host-gatewaypoints at the bridge address, where a server bound to127.0.0.1is not listening.
Running the server inside the container, as above, avoids both.
What was tested
Section titled “What was tested”Tested on macOS on 2026-09-14 against the built CLI:
- A browser on the server’s own loopback port: the viewer loads and connects.
- A TCP port forward to a different local port, the same thing
ssh -Land VS Code do at the socket level: the page is blank, and the console shows403 (Forbidden)for the viewer’s scripts. - The same forward with
GRAPHMIND_ALLOWED_ORIGINSset to the forwarded origin: the viewer loads and connects. - An SDK connection whose
Hostishost.docker.internal:4747: refused with403. Accepted onceGRAPHMIND_ALLOWED_ORIGINS=http://host.docker.internal:4793named that hostname. The port in that setting does not have to match for theHostcheck. - A request with
Host: <name>-4747.app.github.dev: refused with403.
Described from how each environment forwards ports, but not run here: a real VS Code
devcontainer, a Codespace (in VS Code or in the browser), WSL 2, SSH, and Docker on Linux with
host-gateway. If one of these behaves differently for you,
open an issue with the Ports panel entry or
the 403 body; the server’s message names the header it refused.