MCPcopy Index your code
hub / github.com/MuhammadHananAsghar/wormhole

github.com/MuhammadHananAsghar/wormhole @v0.2.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.2.1 ↗ · + Follow
246 symbols 868 edges 28 files 93 documented · 38% updated 4mo agov0.2.1 · 2026-03-09★ 3143 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README
  █   █ █▀▀█ █▀▀█ █▀▄▀█ █  █ █▀▀█ █   █▀▀
  █▄█▄█ █  █ █▄▄▀ █ █ █ █▀▀█ █  █ █   █▀▀
  ▀ ▀ ▀ ▀▀▀▀ ▀ ▀▀ ▀   ▀ ▀  ▀ ▀▀▀▀ ▀▀▀ ▀▀▀
  

Expose your localhost to the internet. Instantly.

Release License Go Report


Wormhole is an open-source ngrok alternative that gives your local server a public HTTPS URL with a single command. No signup required. No config files. Just works.

wormhole http 3000
  █   █ █▀▀█ █▀▀█ █▀▄▀█ █  █ █▀▀█ █   █▀▀
  █▄█▄█ █  █ █▄▄▀ █ █ █ █▀▀█ █  █ █   █▀▀
  ▀ ▀ ▀ ▀▀▀▀ ▀ ▀▀ ▀   ▀ ▀  ▀ ▀▀▀▀ ▀▀▀ ▀▀▀
  v0.1.0

  ╭──────────────────────────────────────────────────╮
  │       Status  ● connected                        │
  │   Forwarding  https://k7x9m2.wormhole.bar → ...  │
  │    Inspector  http://localhost:4040               │
  ╰──────────────────────────────────────────────────╯

  Requests
  --------------------------------------------------------------
  GET     /                          200    12ms
  POST    /webhooks/stripe           200     8ms
  GET     /api/users                 200    34ms

Features

  • One commandwormhole http 3000 and you're live
  • HTTPS by default — TLS handled automatically by Cloudflare
  • Custom subdomainswormhole http 3000 --subdomain myapp (free with GitHub login)
  • Traffic inspector — Built-in dashboard at localhost:4040 with live request stream
  • Request replay — Re-send any captured request with one click
  • HAR export — Export captured traffic in standard HAR format
  • Color-coded terminal — Live request log with method + status code colors
  • Auto-reconnect — Exponential backoff, seamless recovery
  • WebSocket passthrough — Full WebSocket support through the tunnel
  • Zero config — No signup, no config file, no server to deploy
  • Open source — Fully open source, MIT licensed

Install

Quick install (macOS / Linux)

curl -fsSL https://wormhole.bar/install.sh | sh

Homebrew (macOS)

brew install MuhammadHananAsghar/tap/wormhole

Go install

go install github.com/MuhammadHananAsghar/wormhole/cmd/wormhole@latest

Build from source

git clone https://github.com/MuhammadHananAsghar/wormhole.git
cd wormhole
make build
# Binary: ./wormhole

Quick Start

Expose a local HTTP server

# Start your local server on any port
wormhole http 3000
# => https://k7x9m2.wormhole.bar -> http://localhost:3000

Custom subdomain (free)

# One-time login via GitHub
wormhole login

# Use your own subdomain
wormhole http 3000 --subdomain myapp
# => https://myapp.wormhole.bar -> http://localhost:3000

Traffic inspector

Every tunnel automatically starts a traffic inspector at http://localhost:4040:

  • Live request/response stream via WebSocket
  • Request detail view with headers and body
  • One-click request replay
  • Filter by method, status code, path
  • Export as HAR file
# Custom inspector port
wormhole http 3000 --inspect localhost:5050

# Disable inspector
wormhole http 3000 --no-inspect

CLI Reference

wormhole http <port>                    # Expose local HTTP server
wormhole http <port> --subdomain NAME   # Custom subdomain
wormhole http <port> --headless         # No TUI, plain log output
wormhole http <port> --inspect ADDR     # Custom inspector address
wormhole http <port> --no-inspect       # Disable inspector

wormhole login                          # Authenticate via GitHub
wormhole logout                         # Remove stored credentials
wormhole status                         # Show auth status
wormhole uninstall                      # Remove wormhole from system
wormhole uninstall --purge              # Also remove config (~/.wormhole/)
wormhole version                        # Print version

How It Works

YOUR LAPTOP                       CLOUDFLARE EDGE (300+ cities)
┌──────────────┐                 ┌─────────────────────────────┐
│              │   WebSocket     │                             │
│  wormhole    │◄───────────────►│  Worker (request router)    │
│  client      │  (encrypted)    │         ↕                   │
│              │                 │  Durable Object (tunnel)    │
│  localhost   │                 │  • Holds your WebSocket     │
│  :3000       │                 │  • Proxies HTTP to you      │
└──────────────┘                 │  • Hibernates when idle     │
                                 └──────────────┬──────────────┘
                                                │
                                   *.wormhole.bar (Cloudflare DNS)
                                                │
                                        Public Internet
  1. Client opens WebSocket to nearest Cloudflare edge
  2. Durable Object assigns a subdomain
  3. HTTP requests to *.wormhole.bar hit the Worker
  4. Worker routes to the correct Durable Object
  5. DO serializes the request over WebSocket to your client
  6. Client forwards to localhost:3000
  7. Response flows back the same path

Latency: client <-> nearest CF edge (~5-20ms) + localhost (~0ms) = fast.

Architecture

Component Technology
CLI Client Go, Cobra, Bubbletea, Lipgloss
Transport WebSocket (gorilla/websocket)
Edge Relay Cloudflare Workers + Durable Objects
Database Cloudflare D1 (SQLite)
DNS Cloudflare DNS (wildcard *.wormhole.bar)
TLS Cloudflare automatic SSL
Auth GitHub OAuth

Project Structure

wormhole/
├── cmd/wormhole/          # CLI entry point
├── internal/
│   ├── client/            # Tunnel client (connect, forward, display)
│   ├── transport/         # WebSocket transport layer
│   └── inspect/           # Traffic inspector (recorder, server, replay, HAR)
├── edge/                  # Cloudflare Worker + Durable Object relay
│   ├── src/
│   │   ├── index.ts       # Worker router + auth
│   │   └── tunnel.ts      # Durable Object tunnel proxy
│   └── migrations/        # D1 schema migrations
├── pkg/config/            # User config (~/.wormhole/config.json)
├── deployments/           # install.sh, Docker, etc.
├── Makefile
└── .goreleaser.yml

Development

# Run all Go tests
go test ./... -race

# Run edge tests
cd edge && npm test

# Build binary
make build

# Cross-compile all platforms
make dist

TDD Workflow

This project follows test-driven development. Write failing tests first, then implement.

# Run tests in watch mode
go test ./internal/inspect/ -v -count=1

# Coverage
go test ./... -cover

Comparison

Feature ngrok (free) Cloudflare Tunnel Wormhole
One-command setup Needs signup Needs CF account Just works
Custom subdomains Paid ($8/mo) Yes (complex) Free
HTTPS Yes Yes Yes
Traffic inspector Basic No Full (replay, HAR)
WebSocket support Yes Yes Yes
Open source No Client only Fully open source
Cost $0-$120/yr $0 (complex) $0

Roadmap

  • [x] Phase 1 — Core tunnel (wormhole http 3000 -> public URL)
  • [x] Phase 2 — HTTPS, custom subdomains, GitHub OAuth
  • [x] Phase 3 — Traffic inspector, replay, HAR export
  • [ ] Phase 4 — API keys, rate limiting
  • [ ] Phase 5 — Self-hosted relay + TCP tunnels
  • [ ] Phase 6 — P2P mode (direct connections, no relay)
  • [ ] Phase 7 — Polish (CI/CD, Homebrew, docs)

Author

Muhammad Hanan Asghar

License

MIT License. See LICENSE for details.


Built with Go + Cloudflare Workers. Runs on the edge.

Extension points exported contracts — how you extend this code

Transport (Interface)
Transport is the interface for client-relay communication. [1 implementers]
internal/transport/transport.go
SubdomainStore (Interface)
SubdomainStore manages subdomain reservations and active tunnel tracking. CF mode uses D1 (edge/src/tunnel.ts), self-hos [1 …
internal/server/subdomain.go
Env (Interface)
(no doc)
edge/src/index.ts
ProvidedEnv (Interface)
(no doc)
edge/__tests__/env.d.ts
PendingRequest (Interface)
(no doc)
edge/src/tunnel.ts
TunnelMessage (Interface)
(no doc)
edge/src/tunnel.ts
HttpResponseMessage (Interface)
(no doc)
edge/src/tunnel.ts

Core symbols most depended-on inside this repo

Record
called by 28
internal/inspect/recorder.go
Get
called by 27
internal/inspect/recorder.go
Reserve
called by 27
internal/server/subdomain.go
Close
called by 22
internal/transport/transport.go
fetch
called by 21
edge/src/tunnel.ts
NewRecorder
called by 19
internal/inspect/recorder.go
Close
called by 17
internal/inspect/server.go
Len
called by 13
internal/inspect/recorder.go

Shape

Function 116
Method 86
Struct 31
Interface 7
TypeAlias 4
Class 2

Languages

Go88%
TypeScript12%

Modules by API surface

internal/server/subdomain.go27 symbols
internal/server/subdomain_test.go25 symbols
edge/src/tunnel.ts20 symbols
internal/client/client.go19 symbols
cmd/wormhole/main.go16 symbols
internal/inspect/server.go13 symbols
internal/transport/protocol_test.go12 symbols
internal/inspect/recorder_test.go12 symbols
internal/inspect/recorder.go11 symbols
internal/client/display.go11 symbols
internal/inspect/har.go10 symbols
internal/transport/protocol.go9 symbols

For agents

$ claude mcp add wormhole \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page