25 min read

Install Bulwark Webmail and Publish with Localtonet

Install Bulwark Webmail with Docker Compose, connect it to Stalwart, verify it locally, and publish its web interface through Localtonet.

Self-Hosting ยท Bulwark Webmail ยท Docker Compose ยท Localtonet ยท 2026

Deploy a private JMAP web client, verify every local layer, and publish only the finished interface

Bulwark Webmail provides a self-hosted browser interface for mail, calendars, contacts, and files stored by Stalwart Mail Server. This guide uses Bulwark's official Docker Compose definition, applies a safer loopback-only port binding for a same-host Localtonet client, completes the setup wizard, and verifies the application before public access is enabled. It also covers persistence expectations, backups, release pinning, provenance verification, updates, rollback, and troubleshooting. Once Bulwark works locally, we publish it through a Localtonet HTTP tunnel without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.

๐Ÿ”’ Loopback-only binding for the recommended same-host layout ๐ŸŒ JMAP connection to Stalwart with public HTTPS access through Localtonet โšก Official Compose workflow with update and rollback planning
Remote browser reaching Docker-hosted Bulwark Webmail through a Localtonet tunnel while Stalwart remains a separate private service.
Bulwark runs locally as the browser client, Stalwart remains the mail server, and Localtonet publishes the verified web interface.

Understand the Bulwark, Stalwart, and Localtonet architecture

Bulwark Webmail is a self-hosted JMAP client designed for Stalwart Mail Server. It places mail, calendars, contacts, and files in one browser application. The full edition runs as a Node.js service and adds a setup wizard, administration dashboard, OAuth support, plugins, settings synchronization, web push, and update notices.

Bulwark is not a mail server. Stalwart remains responsible for accounts, messages, SMTP mail handling, spam processing, calendars, address books, and file storage. Bulwark connects to Stalwart over JMAP and presents that data to users. Installing the Bulwark container alone does not create mail accounts, configure mail-domain DNS, or produce a complete mail delivery system.

Localtonet has a separate responsibility. Our HTTP tunnel carries browser requests from a public HTTPS address to Bulwark's local HTTP listener. It does not replace Bulwark authentication, configure Stalwart, or turn an unhealthy local application into a healthy one.

Confirm Stalwart compatibility first

Bulwark's current compatibility guidance requires an existing Stalwart server running version 0.16.6 or newer. Verify the current compatibility requirement in the Bulwark documentation before changing either component in a production environment.

โœ‰๏ธ Mail Bulwark supports threaded conversations, unified and cross-account views, full-text search, Sieve filters, templates, scheduled sending, and S/MIME.
๐Ÿ“… Calendars Calendar functions include month, week, day, and agenda views, recurring events, invitations, free and busy information, and CalDAV subscriptions.
๐Ÿ‘ฅ Contacts Users can work with multiple address books and groups, including vCard import and export.
๐Ÿ“ Files Bulwark presents Stalwart's JMAP file storage with previews, sharing, and folder uploads.
๐Ÿ” Shared account experience The client supports single sign-on, two-factor authentication, multiple accounts, themes, keyboard shortcuts, a progressive web app experience, and 27 languages.
๐Ÿ”„ JMAP synchronization JMAP lets the client request changes while server-side services handle functions such as threading, search, and change tracking.

How the components fit together

Component Primary responsibility What it does not replace
Stalwart Mail Server Stores accounts and user data, performs mail-server functions, and provides the JMAP service It does not provide Bulwark's full-edition interface by itself
Bulwark Webmail Provides the browser interface for mail, calendars, contacts, and files It is not a standalone SMTP server and does not replace Stalwart
Docker Compose Defines and operates the Bulwark container on the host It does not configure Stalwart accounts, mail DNS, or delivery policy
Localtonet HTTP tunnel Connects a public HTTPS address to Bulwark's reachable local HTTP endpoint It does not create the application or replace its authentication

Full Bulwark compared with Bulwark Lite

This tutorial uses the full edition because it provides the setup wizard, administration dashboard, OAuth support, plugins, and settings synchronization. Bulwark Lite is built from the same client code but is exported as static files. With Lite, the browser communicates directly with Stalwart, and Stalwart must permit the required cross-origin requests.

Deployment Best fit Important characteristics
Full Bulwark container Docker or Node.js installations needing the complete server edition Includes the wizard, admin console, OAuth, plugins, settings sync, web push, and update notices
Bulwark Lite Static hosting where password sign-in is sufficient Has no setup wizard or admin console and requires appropriate Stalwart CORS configuration
Manual full-edition installation Administrators intentionally operating the Node.js application without Docker Use Bulwark's current manual-install instructions rather than translating the container workflow

Prerequisites and network-layout decisions

A Docker host with Compose

Use a system with Docker Engine or Docker Desktop installed and running. The current Compose plugin uses docker compose. Confirm that the daemon is available and that your account can operate it:

docker --version
docker compose version
docker info

If the first two commands work but docker info fails, start Docker or correct the current account's Docker permissions before continuing.

A working Stalwart deployment

Record the Stalwart address that Bulwark should use. Confirm that Stalwart is compatible, that the intended accounts exist, and that its JMAP endpoint is reachable from the Bulwark deployment. If Stalwart is on another host, account for routing, DNS, certificates, and firewall rules between the systems.

A release-selection policy

Bulwark's quick start uses ghcr.io/bulwarkmail/webmail:latest. That is convenient for an initial evaluation, but latest is mutable. For a reproducible deployment, select an explicit tag from the Bulwark releases page, read its notes, and keep the tag in your deployment record.

Release history matters. For example, Bulwark 1.11.2 replaced 1.11.1 because the earlier Docker image and standalone tarballs did not start. This is why operators should read the Bulwark changelog rather than selecting a version solely by its number.

A same-host or LAN-client Localtonet layout

Decide where our client will run before selecting the Docker port binding:

Layout Recommended host binding Localtonet target
Localtonet and Docker on the same host 127.0.0.1:3000:3000 127.0.0.1, port 3000
Localtonet on another LAN device A deliberately selected LAN-reachable host binding The Docker host's reachable LAN address and published port
Default broad Docker publication 3000:3000 Depends on the client location

A mapping written as 3000:3000 can publish port 3000 on every host interface, depending on the Docker environment. That may make Bulwark reachable from the LAN or other attached networks. For the recommended same-host layout, bind explicitly to 127.0.0.1. Use a LAN-reachable binding only when our client genuinely runs on another device, then restrict access with the host's normal security controls.

This tutorial uses the same-host layout

Docker and the Localtonet client run on the same machine. Bulwark listens on 127.0.0.1:3000, so the host does not need to publish the service to the LAN merely to make it available through Localtonet.

Install Bulwark with its official Docker Compose definition

Docker Compose starting the Bulwark container, which then connects to a separate Stalwart Mail Server.
Use the Compose definition maintained by the Bulwark project rather than translating the docker run example by hand.

Bulwark maintains an official Docker Compose definition in its repository and links to dedicated Docker, configuration, and updating documentation from the project README. Use that maintained definition as the baseline. Do not copy an unofficial reconstruction that can drift away from the project's supported service name, image settings, or future deployment changes.

1

Select a Bulwark release

Review current releases and choose either the current quick-start tag or an explicit tested release for a reproducible installation.

2

Obtain the official Compose definition

Download or clone the file maintained in the Bulwark repository. For a pinned deployment, obtain it from the same release tag you selected.

3

Apply the intended image tag and port binding

Pin the image when reproducibility is required and change the published port to 127.0.0.1:3000:3000 for the same-host Localtonet layout.

4

Validate the effective configuration

Run Compose validation and inspect the rendered image, service, port binding, and any settings supplied by the official file.

5

Start and inspect Bulwark

Launch the project in detached mode, confirm that its service remains running, and inspect recent logs before opening the wizard.

1. Create a project directory

mkdir bulwark-webmail
cd bulwark-webmail

Either download the official file from the repository or clone the repository and check out your selected release tag. Cloning is useful when you want the Compose definition, release history, and associated files together:

git clone https://github.com/bulwarkmail/webmail.git
cd webmail
git tag --list
git checkout <selected-release-tag>

Replace <selected-release-tag> with the exact tag chosen from the releases page. Do not type the angle brackets as part of the tag.

2. Review the official file before starting it

Open docker-compose.yml and inspect its image and ports entry. If the image uses latest and you require a reproducible installation, replace only the tag with the explicit release you selected. Do not guess unsupported environment variables, volume destinations, container commands, or health checks.

For a same-host Localtonet client, change the port publication from a broad mapping such as:

ports:
  - "3000:3000"

to the loopback-only form:

ports:
  - "127.0.0.1:3000:3000"

Preserve the rest of the official Compose definition. If the current file has changed its service structure or port, follow the current Bulwark Docker documentation and apply the same principle to the documented HTTP port.

Do not use the loopback bind for a separate LAN client

A Localtonet client on another computer cannot reach the Docker host's 127.0.0.1. In that layout, publish Bulwark on a deliberately selected interface reachable from the client, test the route from that device, and understand that the service may also become reachable to other systems on that network.

3. Validate and start the project

docker compose config
docker compose config --services

Check the rendered configuration carefully. Confirm the selected image tag and verify that the published host address is 127.0.0.1 for the same-host layout. Then start the project:

docker compose up -d
docker compose ps
docker compose logs --tail=100

The container should remain running. If it exits or repeatedly restarts, diagnose that condition before configuring Localtonet.

Persistence and backup expectations

Bulwark describes itself as a client that stores no mail, calendar, contact, or file data of its own. Stalwart remains the source of truth for that data. The project also states that the full edition provides administration and synchronized settings, but its current general installation guidance does not prescribe a separate Bulwark application-data backup archive that can replace a Stalwart backup.

Back up Stalwart according to Stalwart's own supported procedure. Separately retain the exact Bulwark Compose definition, selected release tag or image digest, external configuration, custom branding, and any deployment-specific proxy or hostname settings. Do not invent a volume mount or back up an arbitrary container directory unless the current Bulwark Docker documentation explicitly identifies it as persistent state.

Container recreation and mailbox data are separate concerns

Recreating the Bulwark client does not constitute a backup or restore of Stalwart. Protect the mail server independently, and test restoration procedures before relying on them.

Complete the Bulwark setup wizard

Open the loopback endpoint from a browser on the Docker host:

http://localhost:3000

The first-launch wizard asks for the Stalwart server and an administration password. Enter the actual JMAP-capable Stalwart address for this environment. Use a unique administration password and store it in an appropriate password manager.

1

Open the local interface

Visit http://localhost:3000 on the Docker host and confirm that the response comes from the container you started.

2

Enter the Stalwart server

Supply the real server requested by the wizard and confirm that it runs a compatible Stalwart version.

3

Set the administration password

Use a password that is not shared with the Docker host, a mailbox account, or the Localtonet device token.

Most installations can be configured through the wizard and changed later in the administration dashboard. Bulwark also supports environment-based configuration for immutable deployments. Documented examples include JMAP_SERVER_URL and APP_NAME.

Saved administration configuration has priority when both it and an environment variable define the same key. An environment variable fills a value only when the admin configuration leaves that value unset. If an environment change appears to have no effect, inspect the corresponding setting in the dashboard before assuming that Compose failed to pass it.

Finish local setup before publishing the service

Do not expose an incomplete first-run wizard. Configure the administration password, verify the Stalwart connection, and test a non-privileged account before starting the Localtonet tunnel.

Verify the complete local service

Docker Compose reporting a running Bulwark service while the web interface loads through localhost.
Verify the container, HTTP endpoint, setup, and Stalwart-backed account behavior before creating a public tunnel.

1. Check the container state

docker compose ps
docker compose logs --tail=200

If the service is unstable, follow new output while reproducing the problem:

docker compose logs -f

Press Ctrl+C to leave the log viewer. This does not stop a detached container.

2. Check the local HTTP endpoint

Open http://localhost:3000 from the Docker host. A command-line request can provide an additional reachability check:

curl -I http://127.0.0.1:3000

An HTTP response shows that a service is listening. The exact status can depend on application state and redirects, so complete functional verification in a browser.

3. Verify setup and administration

Confirm that the wizard accepted the intended Stalwart server and that the administration interface can be reopened with the password you set. Merely seeing a logo or sign-in page does not prove that the JMAP connection works.

4. Test a normal Stalwart account

Sign in with a non-privileged account intended for testing. Check the functions your deployment needs, such as opening the inbox, reading a message, displaying a calendar, viewing contacts, and browsing available files. Reserve server-wide administrator credentials for operations that actually require them.

5. Confirm the loopback-only bind

Test http://127.0.0.1:3000 on the host where our client will run. If you intentionally selected the LAN-client architecture, test the Docker host's LAN address from the separate client device instead. A failure here is a local binding, routing, or firewall problem.

A healthy page and a healthy mailbox are different checks

Bulwark can answer HTTP while its connection to Stalwart is misconfigured. Verify the local web listener and the complete account workflow separately.

Operate, back up, update, and roll back Bulwark

Routine commands

Run Compose commands from the directory containing the official definition:

docker compose ps
docker compose logs --tail=200
docker compose restart
docker compose stop
docker compose start

A restart reuses the selected image and configuration. It can recover from a transient problem, but it should not conceal a recurring configuration or compatibility failure.

Behavior after a host reboot

Automatic recovery depends on Docker starting and on the restart policy in the current official Compose definition. Inspect the file instead of assuming that a policy exists. If Bulwark does not return automatically, enter the project directory and run:

docker compose up -d

Also confirm that the Localtonet client is connected and that the tunnel is running. These are independent services.

Record a recoverable deployment state

Before an update, record the currently selected release and resolved image information:

docker compose config
docker compose images
docker image inspect ghcr.io/bulwarkmail/webmail:<current-version>

Keep a protected copy of the effective Compose definition and deployment notes. Back up Stalwart using its supported backup process. Bulwark does not prescribe a universal application-data backup command in its general container guidance, so do not claim that copying an arbitrary container directory protects mailbox data or administrative state.

Verify release provenance

Container images and release files from Bulwark 1.12.0 onward include signed build provenance attestations. With the GitHub CLI installed, verify a selected container image with the project's documented command:

gh attestation verify oci://ghcr.io/bulwarkmail/webmail:<version> --owner bulwarkmail

For a downloaded release file, use:

gh attestation verify <file> --repo bulwarkmail/webmail

Release files also have an adjacent .sha256 file. Download the artifact and its matching checksum, then use the SHA-256 verification tool appropriate for your operating system. A checksum confirms that the downloaded bytes match the published checksum. Provenance verification additionally checks that the artifact was built by the expected repository workflow.

Do not apply the 1.12.0 provenance statement to older releases

Bulwark documents signed build provenance for container images and release files from version 1.12.0 onward. Checksum and attestation availability must be evaluated for the exact release you selected.

Update a pinned Compose deployment

Read the release notes and the current updating guide before changing the image. Then update the image tag in the Compose definition to the selected release and validate it:

docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200

Test http://127.0.0.1:3000, reopen the administration interface, and verify a normal Stalwart account. Keep the Localtonet tunnel stopped during the change if you do not want users to reach an unverified build.

Roll back to the previous release

Rollback should be planned before the update. Retain the previous explicit image tag and Compose definition. If the new release fails, stop public access, restore the previous tag, and recreate the service:

docker compose config
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=200

Those commands are intentionally the same as the update commands. The difference is that the Compose definition now identifies the previous tested release. Verify the local interface and Stalwart-backed account behavior before restarting the tunnel.

Bulwark does not publish a universal guarantee that every configuration change made by a newer release is backward-compatible with every older release. Review release-specific migration and rollback notes. If a release says rollback requires additional action, follow that release's instructions instead of assuming that changing the image tag is sufficient.

Publish Bulwark with a Localtonet HTTP tunnel

Localtonet HTTP tunnel routing a public browser to loopback-bound Bulwark while Stalwart remains a separate service.
The same-host client can reach loopback-bound Bulwark without publishing port 3000 to the local network.

Once Bulwark and its Stalwart connection work locally, configure an HTTP tunnel. The exact order matters: select the HTTP Process Type, choose the client device token, choose an available relay, enter the local target, start the tunnel, and verify the assigned public address.

Review the current interface in our HTTP tunnel documentation. Relay availability, regions, options, and plan applicability can change, so select current values from the dashboard instead of copying a server code from an article.

1

Install and run the Localtonet client

Run our client on the Bulwark Docker host for the loopback-only layout. The client must remain connected while the public endpoint is needed.

2

Select the HTTP Process Type

Choose Random Sub Domain, Custom Sub Domain, or Custom Domain according to the hostname workflow available in the current dashboard.

3

Select the device authentication token

Select the device-specific token belonging to the client running on the Docker host. Keep the token private and never place it in Bulwark's Compose or application configuration.

4

Select an available relay server

Choose a server or region currently offered in your dashboard. Do not hardcode an old relay code.

5

Enter the local Bulwark target

For the same-host layout, enter local IP 127.0.0.1 and port 3000. For a separate client device, enter the Docker host address and port that are reachable from that device.

6

Start the tunnel

Creating the configuration does not start it. Use the Start control and confirm that the selected device and tunnel report a connected state.

7

Verify the assigned public address

Open the public HTTPS URL in a separate browser session. Test sign-in and the Stalwart-backed functions required by your deployment.

Choose the appropriate Process Type

Process Type Typical use Important consideration
Random Sub Domain Initial testing or temporary remote access Uses a generated public HTTPS address
Custom Sub Domain A selected Localtonet subdomain where supported Check current availability and plan applicability in the dashboard
Custom Domain An organization-controlled hostname Follow current Localtonet DNS instructions rather than guessing DNS records

All three Process Types serve the same local Bulwark content through a public HTTPS address. If Bulwark authentication, OAuth, or another integration depends on an externally visible hostname, align that integration with the selected public origin according to Bulwark's current configuration documentation.

Understand the tunnel lifecycle

The endpoint works only while the selected Localtonet client is connected, the tunnel is running, and Bulwark is answering on the configured target. Stop the tunnel when remote access is no longer needed. Delete it if the public configuration will not be used again.

Secure the published webmail interface

Webmail contains sensitive account and message data. A tunnel provides connectivity, not authorization. Treat the assigned public address as internet-facing even if you share it with only a small group.

๐Ÿ”‘ Independent credentials Use unique passwords for Bulwark administration and Stalwart accounts. A Localtonet device token must never be reused as an application credential.
๐Ÿ›ก๏ธ Least privilege Test ordinary mail access with a normal Stalwart user and reserve administrative accounts for administrative operations.
โœ… Account protection Enable appropriate two-factor authentication and account-security controls rather than relying on an unlisted public URL.
๐Ÿ”’ Limited host exposure Keep port 3000 bound to loopback when Docker and Localtonet run on the same host.
โฌ†๏ธ Verified releases Review release notes, select an explicit tag when reproducibility matters, and verify checksums and provenance where provided.
โน๏ธ Controlled exposure Stop the tunnel during maintenance and whenever public access is no longer required.
Do not treat the public URL as an access-control mechanism

Anyone who obtains the URL can attempt to reach Bulwark. Keep application authentication enabled, protect administrative accounts, and apply access restrictions required by your organization.

Protect tokens and configuration

Do not place Localtonet tokens, mailbox passwords, or Bulwark administration credentials in screenshots, public repositories, shell examples, issue reports, or the Compose file unless a project's documented secret-management procedure specifically requires and protects them.

Report Bulwark security issues privately

Bulwark asks users to report vulnerabilities privately to dev@bulwarkmail.org or through a private GitHub security advisory. Do not post vulnerability details or active credentials in a public issue.

Troubleshoot Bulwark and Localtonet

Bulwark maintains a troubleshooting guide in its documentation portal. Use the checks below to identify which layer is failing before escalating the problem.

The container exits or repeatedly restarts

docker compose config
docker compose ps
docker compose logs --tail=200

Check for invalid Compose syntax, an image-download failure, an unsupported architecture, missing Docker access, or an application startup error. Confirm that the selected release does not have a known startup problem in its release notes.

Docker reports that port 3000 is already allocated

Another process or container is using the host port. Run docker ps and inspect the host's active listeners. Stop or reconfigure only a service you recognize. If you select another host port, keep the container destination at its documented port and use the new host port consistently in local tests and the Localtonet target.

Localhost does not open Bulwark

Confirm that the browser is running on the Docker host. localhost always identifies the current device. Then check the Compose state, rendered port binding, and logs. If the mapping is loopback-only, another LAN computer is not expected to reach it.

The page loads, but login or mailbox data fails

The HTTP layer is healthy, but the Bulwark-to-Stalwart path may not be. Check the Stalwart version, JMAP server address, account credentials, account status, DNS resolution, routing, and certificate validity. If an environment variable appears to be ignored, remember that saved administration configuration takes priority for the same key.

Bulwark works locally but the public URL fails

  1. Confirm that http://127.0.0.1:3000 still works on the Localtonet client host.
  2. Confirm that the selected Localtonet device is connected.
  3. Confirm that the tunnel has been started, not merely created.
  4. Confirm that the target is 127.0.0.1 and port 3000 for the same-host layout.
  5. Confirm that you are opening the public address assigned to the active tunnel.

A separate Localtonet client cannot reach Bulwark

A loopback-only Docker bind is intentionally unreachable from another device. Either move our client to the Docker host or change the deployment to a controlled LAN-reachable binding. After changing it, test the Docker host's LAN address directly from the client device before troubleshooting the tunnel.

The public page opens, but OAuth or another hostname-sensitive function fails

Reproduce the action through the local URL. If it works locally but fails through the public hostname, review Bulwark's authentication and configuration documentation for origin, callback, proxy, and hostname requirements. Do not guess callback paths or environment-variable names.

An update caused a failure

Stop the tunnel, inspect the logs, identify the exact image tag or digest, and review that release's notes. If rollback is supported without additional migration steps, restore the previous pinned tag and recreate the service. Restore Stalwart data only through Stalwart's documented recovery process.

The service did not return after a reboot

Confirm that Docker started, then run docker compose ps. Start the project with docker compose up -d if needed. Separately confirm that the Localtonet client is connected and that the tunnel is running.

Frequently asked questions

Is Bulwark a complete mail server?

No. Bulwark is the browser client. Stalwart owns the accounts, messages, SMTP functions, spam processing, calendars, contacts, and files. Configure Bulwark to use an existing compatible Stalwart JMAP service.

Why use Bulwark's repository Compose file?

It is maintained with the application and can evolve with supported deployment requirements. A hand-written translation of the quick-start docker command can omit changes made to the official Compose workflow.

Why bind port 3000 to 127.0.0.1?

When Docker and Localtonet run on the same host, a loopback bind lets our client reach Bulwark without publishing the port to the LAN or every host interface. A separate client device requires a deliberately configured LAN-reachable bind instead.

Should I use the latest image tag?

The quick start uses latest, but it can change when a new image is published. Use an explicit tested release tag when reproducibility and predictable rollback matter.

What should I back up?

Back up Stalwart through its supported procedure because it remains the source of truth for user data. Also retain the Bulwark Compose definition, release selection, external configuration, and deployment notes. Do not assume that copying an arbitrary container directory is a supported Bulwark backup.

How do I verify a Bulwark release?

Review the release notes, use the adjacent SHA-256 checksum for release files, and verify signed provenance where available. Bulwark documents provenance attestations for container images and release files from version 1.12.0 onward.

Does Localtonet replace Bulwark authentication?

No. Our HTTP tunnel provides connectivity to the local application. Keep Bulwark and Stalwart authentication enabled, use strong unique credentials, and enable suitable account-security controls.

Do I need router port forwarding or a public IP address?

No. The Localtonet client establishes an outbound connection to our relay server. The running tunnel provides a public address without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.

Why is the public address unavailable after I created the tunnel?

Creation does not start a Localtonet tunnel. The selected client device must be connected, the tunnel must be started, and Bulwark must be running on the configured local IP address and port.

Publish your verified Bulwark interface with Localtonet

Run Bulwark from its official Compose definition, verify the Stalwart-backed workflow locally, and then create an HTTP tunnel to 127.0.0.1:3000 from the same host. Keep authentication enabled and stop the tunnel whenever public access is no longer required.

Get Started Free โ†’

Corrections & updates

Substantive changes approved by the Localtonet editorial team are listed transparently below.

Remove the outer article wrapper; move the opening figure so the hero is first and the guide navigation remains immediately after it; validate and, if necessary, replace the hand-written Compose file with the current official Bulwark Compose workflow; document verified persistence, backup, restart, update, rollback, release pinning, checksum, and provenance procedures; remove internal research language about 'supplied evidence'; make loopback binding the safer same-host example and explain when a LAN-reachable bind is required; align

Localtonet is a secure multi-protocol tunneling and proxy platform designed to expose localhost, devices, private services, and AI agents to the public internet supporting HTTP/HTTPS tunnels, TCP/UDP forwarding, mobile proxy infrastructure, file server publishing, latency-optimized game connectivity, and developer-ready AI agent endpoint exposure from a single unified control plane.

support