Self-hosted push notifications for Bambu Lab printers

Your printer already knows when it's done.
Now your phone will too.

bambu-ntfy watches your Bambu Lab printer's local MQTT status feed and pushes a notification to your own ntfy server the moment something changes without needing the Bambu Lab cloud.

Bambu Lab printers expose a local MQTT broker over TLS once LAN mode is enabled. bambu-ntfy stays connected to it, watches every status report, and turns the changes that matter into a push notification through ntfy.

The problem

The printer knows exactly what's happening. You have to go look.

Bambu Handy will tell you what's going on if you use the bambu cloud, but that means trusting Bambu's servers with your data. If you use LAN-only / developer mode you lose Bambu Handy and it's notifications.

bambu-ntfy fixes that issue: it stays connected to the printer's local MQTT broker and turns the events that matter into a push notification, entirely on your own network.

01

One connection per printer

Each configured printer gets its own persistent MQTT connection, authenticated as bblp with the printer's access code. A dropped connection reconnects automatically with backoff.

02

Reports, not polling

On connect it asks the printer for a full status push, then just listens. Every subsequent report is diffed against the last known state in memory.

03

Only real changes notify

State transitions, new or cleared print errors, and new or cleared HMS conditions each fire exactly one notification, pushed to a topic on a self-hosted ntfy server you control.

What it does

Everything worth knowing about a print, pushed to your phone.

Full print state tracking

Follows the printer’s own state including idle, preparing, slicing, running, paused, finished, and failed, then notifies on every transition.

Print error codes

Surfaces print_error / mc_print_error_code as soon as the printer reports one, and logs when it clears.

HMS warnings, with severity

Decodes Health Management System entries into a readable code, severity (fatal/serious/common/info), and a friendly description where known, then notifies again when they clear.

Connection loss & recovery

Notifies you the moment the MQTT connection to a printer drops, and again once it reconnects, so silence never looks like "all is well".

Multiple printers, one instance

Configure up to nine printers with numbered environment variables. Each gets its own MQTT connection on its own thread, all sharing one ntfy target.

Bring your own ntfy

Notifications post to a topic on any self-hosted (or hosted) ntfy server you point it at. Both token or basic-auth are supported, and nothing routes through a third party.

Local network only

Talks to the printer over its LAN-mode MQTT broker with the on-device access code. Nothing about the printer connection touches Bambu's cloud.

Minimal container

A small non-root Alpine image with pip, setuptools, and wheel stripped from the final image after install; nothing but the app and its two dependencies at runtime.

Reference

Notification events

Every notification is prefixed with the printer's configured name and sent to your ntfy topic with an ntfy priority that matches how urgently it deserves your attention.

LowMonitor startedSent once, when bambu-ntfy connects to a printer for the first time.
DefaultState changedThe printer moved to a new gcode_state. Priority and tags depend on the specific state — see below.
UrgentPrint errorThe printer reported a non-zero print error code.
UrgentHMS error raisedA new Health Management System condition appeared on the printer.
DefaultHMS condition clearedA previously active HMS condition is no longer being reported.
HighConnection lostThe MQTT connection to a printer dropped. bambu-ntfy keeps retrying with backoff.
DefaultConnection restoredA previously lost connection reconnected successfully.

gcode_state → notification

IDLEIdle 2
PREPAREPreparing 3
SLICINGSlicing 3
RUNNINGPrint started 3
PAUSEPrint paused 4
FINISHPrint finished 3
FAILEDPrint FAILED 5

Unrecognized states still notify, using the raw state name and default priority.

Known HMS codes

0300-2000AMS communication error
0500-4000Heatbed temperature abnormal
0700-4000Nozzle temperature abnormal
0C00-2000Filament runout
0E00-2000Toolhead communication error
1200-8000Nozzle clog / extrusion abnormal

All other HMS code will still triggers a notification with the raw code and decoded severity but without a friendly description. Look codes up at wiki.bambulab.com/en/hms.

Under the hood

Technical info

Stack

  • Python 3.13python:3.13-alpine3.24 base image
  • paho-mqttMQTT client, TLS connection to the printer
  • requestsPosts notifications to the ntfy HTTP API
  • threadingOne daemon thread per configured printer

Container image

  • Runs as a non-root user on python:3.13-alpine3.24.
  • No exposed ports — the container only makes outbound MQTT and HTTPS connections.
  • pip, setuptools, and wheel are uninstalled after dependencies are installed, so the runtime image ships with no package manager at all.
  • Only two runtime dependencies: paho-mqtt and requests.

Configuration

NTFY_URLBase URL of your ntfy instance, e.g. https://ntfy.example.com. Required.
NTFY_TOPICTopic to publish notifications to. Required.
NTFY_TOKENBearer token for ntfy, if your instance requires auth. Alternative to username/password.
NTFY_USERNAME / NTFY_PASSWORDBasic auth for ntfy, used if no token is set.
PRINTER_IP / PRINTER_SERIAL / PRINTER_ACCESS_CODESingle-printer connection details. Serial and access code come from the printer's network settings screen.
PRINTER_NAME / PRINTER_PORTOptional for single printer use. Friendly name for notifications, and MQTT port (defaults to 8883).
PRINTER_1_IP … PRINTER_9_IP (+ _SERIAL, _ACCESS_CODE, _NAME, _PORT)Numbered variables for multiple printers. Can be combined with the single-printer set above.
LOG_LEVELPython logging level. Defaults to INFO.
Get running

Installation

First, enable LAN Only Mode (or Developer Mode, depending on firmware) on the printer under Settings → Network. That screen also shows the 8-digit Access Code and the printer's Serial Number you'll need below.

  1. Run the container:

    docker run -d \
      --name bambu-ntfy \
      -e NTFY_URL=https://ntfy.example.com \
      -e NTFY_TOPIC=bambu-printer \
      -e PRINTER_IP=192.168.1.50 \
      -e PRINTER_SERIAL=00M00A000000000 \
      -e PRINTER_ACCESS_CODE=12345678 \
      -e PRINTER_NAME="Bambu X1C" \
      pocketsized/bambupushnotifier

No ports to be published as bambu-ntfy only makes outbound connections to the printer and to your ntfy server. Add NTFY_TOKEN or NTFY_USERNAME /NTFY_PASSWORD if your ntfy instance requires auth.

  1. Run the container:

    services:
      bambu-ntfy:
        image: pocketsized/bambupushnotifier
        container_name: bambu-ntfy
        restart: unless-stopped
        environment:
          # --- ntfy (shared across all printers) ---
          NTFY_URL: "https://ntfy.example.com"
          NTFY_TOPIC: "bambu-printer"
          NTFY_TOKEN: ""          # or use NTFY_USERNAME / NTFY_PASSWORD
          # NTFY_USERNAME: ""
          # NTFY_PASSWORD: ""
    
          # --- One printer ---
          PRINTER_IP: "192.168.1.50"
          PRINTER_SERIAL: "00M00A000000000"
          PRINTER_ACCESS_CODE: "12345678"
          PRINTER_NAME: "Bambu X1C"
    
          # --- Or multiple printers (numbered, up to _9) ---
          # PRINTER_1_IP: "192.168.1.50"
          # PRINTER_1_SERIAL: "00M00A000000000"
          # PRINTER_1_ACCESS_CODE: "12345678"
          # PRINTER_1_NAME: "X1C Upstairs"
          #
          # PRINTER_2_IP: "192.168.1.51"
          # PRINTER_2_SERIAL: "00M00B000000000"
          # PRINTER_2_ACCESS_CODE: "87654321"
          # PRINTER_2_NAME: "P1S Garage"
    
          LOG_LEVEL: "INFO"

The single-printer and numbered variables can be combined — a plainPRINTER_* set plus any number of PRINTER_1_*PRINTER_9_*sets all run side by side.

Transparency

About the AI use here

I understand the reservations surrounding AI-generated software. Relying on a tool to write code without fully understanding either the tool or the output is risky and many wish to avoid it. However, developer assistance tools like autocomplete or online reference platforms have been standard practice for years before AI came on the scene.

Both the notifier and this website were developed with the help of AI coding assistants. Depending on the task, this assistance ranged from simple word completion to refactoring functions for modern best practices. Crucially, every line of code was individually reviewed, vetted, and thoroughly tested by me.

Finally, AI involvement is strictly confined to the build process: bambu-ntfy itself contains no embedded AI features or runtime models.