cd /news/developer-tools/keep-it-local · home topics developer-tools article
[ARTICLE · art-45297] src=olafalders.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Keep It Local

Developer Simon Willison warns against accidentally exposing local apps to the internet, advocating for binding to localhost or private networks like Tailscale by default. He demonstrates how to secure tools such as his Claude Code dashboard clodhopper, air, Python's http.server, and App::HTTPThis by using explicit bind addresses instead of the default 0.0.0.0.

read3 min views15 publishedJun 30, 2026
Keep It Local
Image: Olafalders (auto-discovered)

Who wants to talk about networking today? I know I do. Two addresses do most of the heavy lifting here: 127.0.0.1

(aka localhost or the loopback address — only your own machine can reach it) and 0.0.0.0

(bind to this and you’re reachable on every network interface). See Localhost and 0.0.0.0 for a refresher.

clodhopper# #

Yesterday I talked about clodhopper, my personal Claude Code dashboard. It collects data from your running agents and spins up a read-only app to show their status. By default, it binds to localhost (127.0.0.1

), which means I don’t accidentally broadcast my workflows to the world. I also run it on my Tailscale network, which means I can view it on my own private network, but the world can’t. I was doing this by interpolating the Tailscale IP in the startup command: clodhopper serve --host "$(tailscale ip -4)"

. Today I added a --tailscale

arg, to make this a touch easier.

clodhopper serve

CLODHOPPER_HOST=0.0.0.0 clodhopper serve

clodhopper serve --tailscale

So, that’s all fine, but we are now living in a world where anyone can spin up a custom app on their machine and accidentally broadcast it to the world. Is this bad? Not always, but consider the following:

  • your app keeps secrets in .env

  • your app spins up a web server .env

somehow ends up in the path that your app is serving- random bot sniffs out your app and fetches .env

  • now you need to rotate your secrets and you may not even be aware that your secrets are in the hands of a bad actor

"Localhost" by Wesley Nitsckie is licensed under CC BY-SA 2.0.

Ideally you’d restrict access to your resources to only the audiences which require them. So, defaulting to localhost

and then expanding your reach from there is a good way to go. In my case I’ve been enjoying using a Tailscale tailnet. Only my own authenticated devices can connect. Internet creeping will have to take place elsewhere, because my apps are now for my eyes only.

Moving beyond clodhopper

, here are ways to apply the same principle to some open source apps.

air# #

airrunsfull_bin

through a shell, so you can interpolatetailscale ip -4

straight into your app’s host flag in.air.toml

— no hardcoded address:

[build]
full_bin = "./tmp/main -port 5003 -host 127.0.0.1"

full_bin = "./tmp/main -port 5003 -host $(tailscale ip -4)"

Python’s built-in file server# #

http.server

binds0.0.0.0

by default — pass an explicit--bind

.

python3 -m http.server 5000

python3 -m http.server 5000 --bind 127.0.0.1

python3 -m http.server 5000 --bind "$(tailscale ip -4)"

App::HTTPThis# #

App::HTTPThisserves the current directory over HTTP.- Use --host

to control the bind address.

http_this --host 127.0.0.1

http_this --host "$(tailscale ip -4)"

nota bene: the current version of http_this

binds to every interface but emits a message that implies that it is binding only to 127.0.0.1

.

$ http_this .
Exporting '.', available at:
   http://127.0.0.1:7007/

😬 Today I opened #13 to clarify the behaviour, but maybe take this as a reminder that it’s good to be explicit about the things that really matter, rather than relying on the defaults.

── more in #developer-tools 4 stories · sorted by recency
── more on @tailscale 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/keep-it-local] indexed:0 read:3min 2026-06-30 ·