Skip to main content
Local development is comfortable right up until something outside your machine needs to hit your agent. A webhook provider, a teammate, or a quick external test all run into the same wall: localhost does not exist anywhere except your own machine.

Why Tunneling Matters

Bindu ships a built-in FRP-based tunnel so a local agent can be reached from the public internet without a deploy step. The agent process stays on your machine; only the network path changes.
Tunneling is for local development and testing only. Do not use it in production. Production deployments should sit behind proper hosting, certificates, and auth — not a shared FRP relay.

What A Reverse Tunnel Actually Does

If you’ve never used FRP or ngrok before, the trust model is the important part. A normal server listens for incoming connections. That doesn’t work from a laptop behind NAT or a corporate firewall: nothing on the public internet can route a packet to 127.0.0.1. A reverse tunnel flips the direction. Your agent opens an outbound connection to a public FRP server. That connection stays open. When a request hits the public URL, the FRP server pushes it down the already-open socket to your agent, which responds back through the same pipe.
Your laptop never accepts a new inbound connection. It only keeps one outbound TCP connection open to the FRP server. That is why this works through NAT and most corporate firewalls, and it is the reason the agent — not the user — is the side that initiates the tunnel.
Trust model in one line: anyone with the public URL can call your agent. Treat the URL as a development secret, and use Bindu’s auth (Hydra, DID, x402) the same way you would in production if you’re testing auth-protected flows.

How Bindu Tunneling Works

Bindu uses FRP (Fast Reverse Proxy) to relay traffic between a public URL and your local agent.
The first time you enable tunneling, Bindu downloads the official frpc client binary (currently v0.61.0) from the FRP GitHub releases and caches it under ~/.bindu/frpc/. Subsequent runs reuse the cached binary. If your OS or firewall prompts about a new executable making outbound network connections, that is expected.

The Public Address Model

Tunneling is enabled with launch=True in bindufy():
When the agent starts, the logs look like this:
The URL maps back to the local agent for as long as the process is alive.

Local First

Your agent still runs locally on localhost:3773. Nothing about the handler changes.

Public URL

A random 12-character subdomain is generated under tunnel.getbindu.com — one lowercase letter followed by 11 alphanumerics.

Development Only

This is meant for testing, webhooks, and demos — not production traffic.

The Lifecycle: Start, Tunnel, Forward

Under the hood, tunneling moves through three practical stages.
1

Start

bindufy() constructs a TunnelConfig(enabled=True), the binary is downloaded if missing, and a TunnelManager spawns frpc as a subprocess that connects to the Bindu FRP server.
2

Tunnel

frpc registers a subdomain on the server. The subdomain is either:
  • Random (default) — 12 characters: 1 lowercase letter + 11 lowercase letters or digits, e.g. abc12def3456.
  • Custom — whatever you set via TUNNEL_SUBDOMAIN env var, the tunnel.subdomain config key, or by calling TunnelManager.create_tunnel(subdomain="my-agent").
On success, the server replies start proxy success and Bindu logs the public URL.
3

Forward

For every public request, frpc reads it off the already-open socket and forwards it to 127.0.0.1:<your_port>. Responses go back the same way. The agent has no idea it’s being tunneled — to the handler it looks like a normal local request.When the agent process exits, atexit terminates the frpc subprocess and the public URL stops resolving.

Configuration

TunnelConfig

The dataclass in bindu.tunneling.config controls every knob.

Custom Subdomain

The default subdomain is random and changes every restart. To pin it, set TUNNEL_SUBDOMAIN:
Or pass a tunnel block in your config:
Custom subdomains are first-come, first-served on the shared tunnel.getbindu.com domain. If someone else already holds it, frpc will fail with a registration error and Bindu falls back to running local-only.

Environment Variables

Every TunnelConfig field has an env-var equivalent that create_tunnel_config_from_env() reads:

DID-Derived Subdomains

TunnelManager._generate_subdomain_from_did() converts an agent DID into a DNS-safe label (strips did:, replaces colons with hyphens, lowercases, truncates to 63 chars). It exists for future stable per-agent URLs, but the default create_tunnel() path uses the random generator — wire it in yourself if you want DID-stable URLs today:

Programmatic Use

bindufy(..., launch=True) is the common path. For tests, scripts, or anything that isn’t a full agent, TunnelManager can be used directly as a context manager — it handles frpc cleanup on exit.
A more explicit config:
TunnelManager allows exactly one active tunnel per instance — calling create_tunnel() twice raises RuntimeError. The process also registers an atexit hook globally, so even hard exits clean up the frpc subprocess.

Local Testing Through The Tunnel

Basic Development Test

End-To-End Webhook Test

A common reason to tunnel: an external service (Stripe, GitHub, a partner agent) needs to POST into your local agent during development.
The tunneled agent is still your local process. If python my_agent.py stops, the public URL keeps resolving for a moment but returns 404 — there’s nothing behind it.

Use Cases

Test your agent without deploying it. The agent runs on your machine, but the public URL makes it reachable for quick external checks.
Let an external service call back into your local agent during development. Pin a custom subdomain so the upstream URL doesn’t change every restart.
Share the public URL so someone else can hit the agent without you having to deploy it first. Combine with auth if the agent handles anything sensitive.
Use the tunnel for demos where local iteration matters more than production deployment. Combine with expose: True in your deployment block so the agent card advertises the public URL.
Point another agent at your tunnel URL to test A2A flows (negotiation, task send) end-to-end without standing up shared infrastructure.

Limits And Troubleshooting

Tunneling is intentionally narrow in scope. It solves development reachability, not production hosting.

Current Limits

  • Development only — not suitable for production traffic.
  • Shared relaytunnel.getbindu.com is operated as a convenience, not as guaranteed infrastructure. No SLA.
  • Temporary URLs by default — the random 12-character subdomain changes every restart unless you pin one.
  • One tunnel per TunnelManager — start a second bindufy(launch=True) in the same process and you’ll get a RuntimeError.
  • No persistence — when the agent stops, frpc is terminated and the URL stops resolving.

Troubleshooting

frpc couldn’t reach the FRP server within the default 30-second timeout. Check network egress first:
Corporate firewalls often block arbitrary outbound TCP ports. Port 7000 is the one to allowlist.
If you pinned a subdomain via TUNNEL_SUBDOMAIN and someone else already holds it, frpc exits non-zero. Bindu logs the failure and continues local-only. Pick something less generic (alice-agent-dev beats agent).
On first run Bindu fetches frpc_<os>_<arch> from the official FRP GitHub release. If your platform isn’t in the release matrix, you’ll see a 404 from bindu.tunneling.binary. Download frpc manually from https://github.com/fatedier/frp/releases and drop it at ~/.bindu/frpc/frpc_<os>_<arch>_v0.61.0 with executable permissions.
Bindu registers an atexit hook to terminate frpc. If the parent dies in a way that skips atexit (kill -9, OOM kill), the subprocess can linger. Kill it manually:

For Production

Do not use tunneling in production. Use proper hosting with your own certificates and ingress — Cloudflare, a managed load balancer, or whatever your platform offers — and keep launch=False in deployed environments.

Practical Boundaries

Good Fit

Tunneling is a good fit when you need quick public access to a local agent for testing, demos, or webhook development.

Wrong Fit

It’s the wrong fit for production traffic, persistent public infrastructure, or anything that depends on strong uptime guarantees.
Sunflower LogoBindu tunneling makes a local agentreachable for development without pretending to be production, so testing can move faster without changing where you build.