bubbles

Open source · Windows, macOS, Linux & Docker · one binary

Chat for everyone on your network.

Channels, DMs, files and alerts for the whole LAN, from one server and no internet connection.

Run bubbles on any computer that stays on. Phones, laptops and desktops join in the browser over HTTPS, signed by a certificate authority bubbles creates for you. netdiag and your own scripts post alerts that everyone sees.

Free · Apache-2.0 · Works offline · No cloud account · Self sign-up

1 fileserver for Windows, macOS, Linux and Pi
~200people on one server
2.2 msp95 delivery to 200 clients in load tests
0cloud accounts or internet needed

For everyone

Join in three steps.

People join from a laptop or a phone in under a minute. No admin needed while sign-up is open.

  1. Find it. The tray app lists the bubbles servers on your network. On a phone, scan the QR code or open the address.
  2. Trust it once. Compare the fingerprint and install the certificate. That is one prompt from your system.
  3. Pick a name and a password. Any password works, and you are in.
Find. The tray app lists servers on your network.
Trust. Compare the fingerprint once.
Join. Pick a name and a password.
On a phone. Open the onboarding page and tap Create your account.
Your name, any password. Then you are in.

For the host

Running in two minutes.

One file to run, one password to read, and your people can join. No wizard, no token to copy.

  1. Download and run one file on a computer that stays on.
  2. Read the console. It prints the address and the admin password.
  3. Sign in, change the password, and people join. Sign-up closes by itself after a day.
bubbles
bubbles v0.3.0 is running Open: https://192.168.1.20:28225/ Onboarding: http://192.168.1.20:28226/ CA fingerprint (SHA-256), compare it on each device: A29F 73CA 36DA C90A 6905 A6D5 64AC E368 BF74 3EAD E54B 9A0B E449 0278 25CA 3A24 Sign in as: admin Password: k7mq-x4pz-9vbd-h2nc (also saved in C:\Users\you\AppData\Local\bubbles\admin-password.txt; deleted when you change the password)

Sign-up

Open for a day, then it closes itself.

Sign-up closes by itself. Reopen it for the next party or add people yourself.

  • auto-close
  • reopen any time
  • invites still work
Admin settings. See when sign-up closes, close it now or reopen it.

Sign in

Everyone else just taps Create an account.

While sign-up is open, the login page shows a Create an account link, so nobody has to wait for an invite.

Login. A Create an account link appears while sign-up is open.

What it does

Everything you expect from a modern chat app.

Without an account on someone else's server: messages, files and people all live on one computer on your network.

Channels and DMs

Public and private channels, direct messages and group DMs. Presence, typing, unread counts and drafts that follow you between devices.

Threads, reactions, pins

Reply in a thread without derailing the channel, react with any emoji, pin what everyone needs, and edit or delete your own messages.

Emoji and mentions

A full emoji picker plus autocomplete for :emoji:, @people and #channels. @channel and @here reach everyone.

Files and photos

Upload by button, drag and drop or paste. Images, video and audio show inline, and GPS location is stripped from photos.

Search

Full-text search across the channels and DMs you can see, narrowed with from:, in: and has:image.

Phones and desktops

An installable web app for phones and computers, opt-in push notifications, and a desktop tray app for Windows, macOS and Linux.

Invite by QR code

Sign-up is open for a day after the first start, then closes by itself. After that the admin makes an invite with a role, people scan the QR code, pick a name and they are in.

Admin tools

Settings, roles, an audit log, encrypted backups, certificate management and a reset for starting over.

Alerts

When the network breaks, everyone hears about it.

bubbles is the companion to netdiag. When netdiag sees a printer drop off, an IP conflict or a failed health check, it posts an alert, and everyone on the local network sees it in one channel. Any other tool can do the same.

  1. detectnetdiag noticesThe Brother printer at 192.168.1.50 stops answering.
  2. postWarning alertIt lands in #netdiag-alerts, with a push notification for anyone who opted in.
  3. acknowledgeSomeone is on itOne click shows who took it, so nobody else walks over to the printer.
  4. resolveAll clearnetdiag sends the all-clear and the same alert updates in place.

Three severities

info, warning and critical. Each person chooses which levels notify them, per channel.

One alert, not fifty

A repeat with the same dedupe key updates the existing alert instead of flooding the channel. Optional re-notify for anything left open.

Acknowledge and resolve

People acknowledge in the app; the sender resolves when the problem clears. Each app can only touch its own alerts.

Survives restarts

The Go SDK queues alerts and retries through server restarts and rate limits, so a flapping network does not lose the message.

A tour

Real screens from the app.

Captured from a running server by the same browser test harness that checks bubbles' layout and accessibility.

Threads

Side conversations stay on the side.

Open a thread from any message and reply there. The channel shows one reply count instead of the whole back-and-forth.

  • replies
  • reactions
  • pins

Emoji

Every emoji, no third-party code.

The picker is built into bubbles and works offline, with search, categories and skin tones. Type : in the composer for quick autocomplete.

  • :pizza:
  • :tada:
  • skin tones

Files and photos

Drop a screenshot, it shows up inline.

Paste or drag images, video, audio and documents into any channel or DM. Pictures open full size, and location data is removed from JPEG, PNG and WebP before anyone else sees them.

  • drag & drop
  • paste
  • GPS stripped

Search

Find it again.

Full-text search across everything you can see. Narrow it down with from:, in:#channel and has:file, has:image or has:link, then jump straight to the message.

  • from:
  • in:
  • has:

On the phone

Built for the phone in your pocket.

The same app on a phone, laid out for one hand. Add it to the home screen to install it, and turn on push notifications if you want alerts while it is closed.

  • installable
  • push (opt-in)
  • light & dark

Invites

Scan to join.

The admin creates an invite with a role and an expiry. bubbles shows a link and a QR code, drawn in the browser so the secret never travels in a request URL. Point a phone camera at it and pick a name.

  • member or admin
  • expires
  • single or multi-use

Administration

See who is on, at a glance.

People, open connections, storage and free disk space, and the addresses to share, each with a QR code. Settings, roles, apps, webhooks, the audit log and encrypted backups are one click away.

  • audit log
  • backups
  • certificates

Integrations

Anything that can call a URL can talk to the LAN.

Four ways in, from a one-line curl to a full two-way bot. Every app gets its own token with only the scopes it needs, and each can be revoked on its own.

Incoming webhooks

A URL per channel. Native JSON alerts, or point anything that posts to Slack at it: text, attachments and blocks work.

REST API and events

Messages, alerts, files and slash commands with a scoped app token, plus a realtime WebSocket event stream for two-way bots.

Go SDK

pkg/bubblesclient finds the server over mDNS, pairs with admin approval and pins the CA. The alert queue retries for you.

MCP for AI agents

Claude and other agents can read channels, search, post messages and raise or resolve alerts through eight MCP tools.

Terminal · post an alert
$ curl --cacert bubbles-ca.pem https://192.168.1.20:28225/hooks/bwh_XXXX \ -H 'Content-Type: application/json' \ -d '{"alert": {"severity": "warning", "title": "Backup is late", "text": "Last success 3 days ago", "dedupe_key": "backup:nas"}}'
ok
$ claude mcp add bubbles -e BUBBLES_CONN="bubbles://192.168.1.20:28225/?token=bub_XXXX&fp=sha256:AB12…" -- bubbles mcp
> Summarise what happened in #netdiag-alerts today and resolve anything that has cleared.

Webhook posts never mention anyone, and every app is rate limited. Full reference: integrations, MCP and OpenAPI.

MCP tools

  • list_channels Channels the token can see
  • read_messages Recent messages in a channel
  • search_messages Full-text search
  • post_message Say something
  • post_alert Raise or update an alert
  • ack_alert Acknowledge it
  • resolve_alert Clear it
  • list_alerts What is still open

Security

Real HTTPS on a network with no internet.

Browsers only give a web app notifications, offline mode and camera access over HTTPS. bubbles makes that work on a LAN without a public domain or a cloud service.

Onboarding. Each device installs the local CA once, with steps for iPhone, Android, Windows, macOS and Linux.
  • Its own certificate authority. bubbles creates an ECDSA P-256 CA on first start and issues the server certificate for its IP addresses and bubbles.local.
  • Accounts you control. argon2id passwords, login lockout, secure cookies, and an admin password that is printed only on the server console and saved owner-only on disk.
  • Locked-down web app. A strict Content Security Policy, origin checks, rate limits, and no scripts, fonts or images from anywhere else.
  • Privacy by default. Photo location data is removed, push notifications carry no message text by default, and the server refuses clients from outside private address ranges.
  • Encrypted backups. One command writes an age-encrypted archive; restore it on any host.

Open sign-up, honestly: for the first day anyone on the network can create an account, and any password works. That suits a trusted LAN. Close sign-up, or switch to invites, at any time from the admin settings.

What it does not do: there is no end-to-end encryption. Whoever runs the server can read the messages on it. The full threat model is in docs/security.md.

Reset

Pack up after the LAN party.

bubbles travels. Bring it to a LAN party, a workshop or an event, then wipe it clean for the next one, from the admin Danger zone or the console.

Clear content

bubbles reset --content
  • Every message, thread, reaction and pin
  • All files, pictures and alerts
  • People, channels, apps and settings
  • Everyone stays signed in

Same crew, fresh start: the next session begins with empty channels.

Factory reset

bubbles reset --factory
  • All users, channels, DMs, messages and files
  • Sessions, tokens, apps, webhooks, invites, logs
  • The CA, so trusted devices stay trusted (or rotate it)
  • Server settings, if you choose to keep them

Back to a fresh start: bubbles creates a new admin account with a new password, as if just installed.

Danger zone

Hard to do by accident.

Both resets need the admin password and the instance name typed exactly, show a preview of what will go, and can save an encrypted backup first. Web resets are limited to three tries an hour and written to the audit log; admins can turn them off and keep reset console-only.

  • typed confirmation
  • audited
  • console always works

Download

Unzip it, run it, sign in.

One server binary per platform, no installer and no runtime to add. First time? HOW-TO-OPEN.txt in the zip covers the SmartScreen (Windows) and Gatekeeper (macOS) warnings for unsigned programs.

Server

Windows, macOS, Linux
  • amd64 and arm64
  • Linux arm64 runs on a Raspberry Pi
  • Checksums in SHA256SUMS

Docker

$ docker run -d --network host -v bubbles-data:/data ghcr.io/donaldsteele/bubbles

Multi-arch, distroless, runs as non-root. Host networking keeps bubbles.local working.

Tray app

Windows, macOS, Linux

Optional desktop companion: sign in once, get notifications and open bubbles from the tray.

  1. Run bubbles on a computer that stays on. The console prints the address to open and a generated admin password.
  2. Sign in as admin with the printed password and change it. Sign-up is open for a day, so people can already join.
  3. People create their accounts. Phones open the onboarding page, trust the CA once, then pick a name and a password.

Default ports: 28225 for the app (BUBBL on a phone keypad) and 28226 for onboarding, picked to stay clear of other servers and games. All releases: github.com/donaldsteele/bubbles/releases · Build from source: bash scripts/build.sh · Guides: onboarding, admin