Your localhost,
on the internet — right now
One command gives your local dev server a public URL.
Share webhooks, demos, and APIs with anyone, instantly.
Why "Macha"?
Macha(மச்சா) is a Tamil word — the way you call your closest friends. "Macha, come look at this." "Macha, got a minute?" It's warm, casual, no-ceremony. That's the vibe this tool aims for: a close friend who opens a tunnel for you, no account, no credit card, no questions asked.
How it works
Three components, zero configuration. Your app never needs to change.
You run your app
Any server on localhost— Express, FastAPI, Rails, anything. Macha doesn't touch your code.
Agent opens a tunnel
The macha agent dials out to macha.live and registers your subdomain. From then on, it opens a fresh connection on demand for every incoming request.
Traffic flows through
Anyone visiting myapp.macha.live is transparently bridged to localhost:3000. No headers changed. WebSocket, gRPC, all protocols work.
The agent always dials out — so NAT and firewalls are never a problem.
Why it's built this way
A few deliberate choices explain almost everything about how Macha behaves — here's what each one buys you, and what the obvious alternative would have cost.
Why can't the internet reach my laptop?
Home and office networks sit behind NAT and a firewall that blocks unsolicited inbound connections — that's a security feature, not a bug. The macha agent never asks for an inbound connection. Instead it dials out to macha.live, the same way your browser dials out to any website. Outbound traffic is always allowed, so there's nothing to configure — no port forwarding, no router settings.
How does each request get a connection?
Earlier versions of macha kept a pool of pre-opened connections sitting idle, ready to go — but a fixed pool has a ceiling, and dev servers blow past it fast (HMR keeps a socket open forever, and a single page load can fire dozens of concurrent asset requests). Macha now opens a connection per request: when a visitor arrives, the server asks your agent to dial out a fresh connection just for that request, over the same outbound-only path. The dial takes milliseconds and runs in parallel for every request, so concurrency has no fixed ceiling to exhaust.
Why does macha.live handle HTTPS instead of my agent?
The alternative would be every agent managing its own TLS certificate — running an ACME client, renewing certs, and binding to port 443 on whatever machine it's running on. That's a lot of moving parts for something that should just work. Instead, one wildcard certificate for *.macha.live lives on the edge server, and every agent connects over a plain outbound TCP socket — no cert, no port 443, nothing to renew. The tradeoff: traffic is decrypted at macha.live before reaching the tunnel, so self-hosters who need end-to-end encryption all the way to their machine can run their own server with their own certs (see self-hosting).
Get started
Three steps from zero to a live public URL.
Install
Pick your platform. No dependencies, no runtime — just a single binary.
curl -fsSL https://macha.live/install.sh | bash
Downloads a pre-built binary for Apple Silicon or Intel Mac.
curl -fsSL https://macha.live/install.sh | bash
Statically linked binary — works on any Linux (x86-64, ARM64). No libc required.
# Run in PowerShell
irm https://macha.live/install.ps1 | iexInstalls to %LOCALAPPDATA%\macha\bin and adds it to your user PATH.
cargo install --git https://github.com/DhineshKrishnan1206/macha macha
Requires Rust. Compiles from source — takes about a minute.
Start your local app
Macha works with any server — it doesn't care what language or framework you use. Just make sure it's running.
# Node.js / Express node app.js # running on :3000 # Python / FastAPI uvicorn main:app # running on :8000 # Anything else ./my-server # running on :8080
Run Macha
Tell it which port your app is on and what subdomain you want — or skip the subdomain and get a random one.
macha --port 3000 --subdomain myapp
You'll see:
Dashboard → http://127.0.0.1:4040 ✓ Tunnel: https://myapp.macha.live
Share https://myapp.macha.live with anyone. Open localhost:4040 to watch requests in real-time.
Need more options? Auth tokens, TLS, library API, custom servers —
Full documentation →Everything you need
Production-grade internals, simple on the outside.
localhost:4040 — method, path, size, duration, in real time.*.macha.live subdomains are served over TLS. Your local app gets HTTPS for free.macha to Cargo.toml and embed tunneling directly in your app.Self-host on your own VPS
Full control, no trust required. Your traffic stays on your infrastructure.
Prerequisites
A VPS with Docker installed and a domain with a wildcard DNS record (*.tunnel.yourcompany.com → your-vps-ip). Caddy handles TLS automatically — no certificate management needed.
1 — Start the server
services:
macha:
image: ghcr.io/dhineshk/macha-server:latest
restart: unless-stopped
ports:
- "80:8080"
- "9000:9000"
- "9001:9001"
environment:
DOMAIN: tunnel.yourcompany.com
AUTH_TOKEN: change-me-to-a-long-random-secretdocker compose up -d
2 — Point your agents at it
macha --port 3000 --subdomain myapp \
--server tunnel.yourcompany.com \
--token your-secretThe tunnel URL will read https://myapp.tunnel.yourcompany.com — fully under your domain.
All server environment variables
| Variable | What it does | Default |
|---|---|---|
| DOMAIN | Base domain for tunnel URLs | macha.live |
| PUBLIC_SCHEME | http or https in tunnel URLs | https |
| AUTH_TOKEN | Agents must present this token to register | none (open) |
| PUBLIC_PORT | Port the public HTTP listener binds on | 8080 |
| CONTROL_PORT | Port agents use to register | 9000 |
| DATA_PORT | Port agents use for on-demand data connections | 9001 |
| TLS_CERT | Path to PEM certificate for ports 9000/9001 | none |
| TLS_KEY | Path to PEM private key for ports 9000/9001 | none |
Ready to go deeper?
Full CLI reference, library API, TLS configuration,
auth tokens, Caddy setup guides, and more.