Ctrl K
ComunidadGuías…

README.md

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<div align="center">

<img src="docs/moongate-icon.png" width="96" alt="Moongate logo"/>

# Moongate

### One app. Your Klipper printer. Anywhere.

[![Latest release](https://img.shields.io/github/v/release/PEEKYPAUL/Moongate?label=latest%20release&color=6C63FF)](https://github.com/PEEKYPAUL/Moongate/releases/latest)
[![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial-blue)](LICENSE)
[![Platform](https://img.shields.io/badge/platform-iPhone%20%7C%20Android-6C63FF)](#quick-start)
[![App Store](https://img.shields.io/badge/iPhone-on%20the%20App%20Store-0D96F6?logo=apple&logoColor=white)](https://apps.apple.com/gb/app/moongate-klipper-control/id6785038887)
[![Google Play](https://img.shields.io/badge/Android-on%20Google%20Play-34A853?logo=googleplay&logoColor=white)](https://play.google.com/store/apps/details?id=com.moongate.app.moongate)
[![Website](https://img.shields.io/badge/website-peekypaul.github.io%2FMoongate-6C63FF)](https://peekypaul.github.io/Moongate/)

<img src="docs/screenshots/generated/hero-ios.png" width="820" alt="Moongate on iPhone and Android - fleet dashboard with per-printer console and file tools, the full Mainsail UI in-app, and printing straight from stored G-code"/>

Free, source-available **iPhone and Android** control for your **Klipper 3D printer** - live webcam, print controls, temperatures, and the complete Mainsail/Fluidd UI - over home WiFi and **automatically over the internet** when you're away. Zero setup, no port forwarding, no subscriptions.

**Prefer your own infrastructure? Run it your way.** The cloud-free **Direct (LAN/VPN)** mode talks straight to your printer over your network - or your own **WireGuard / Tailscale VPN** when you're out - and never touches the internet. [See how the two modes compare ›](#run-it-your-way)

<a href="https://apps.apple.com/gb/app/moongate-klipper-control/id6785038887"><img src="https://img.shields.io/badge/Download%20on%20the%20App%20Store-0D96F6?style=for-the-badge&logo=apple&logoColor=white" alt="Download on the App Store"/></a>
<a href="https://play.google.com/store/apps/details?id=com.moongate.app.moongate"><img src="https://img.shields.io/badge/Get%20it%20on%20Google%20Play-34A853?style=for-the-badge&logo=googleplay&logoColor=white" alt="Get it on Google Play"/></a>
<a href="https://github.com/PEEKYPAUL/Moongate/releases/latest"><img src="https://img.shields.io/badge/%E2%AC%87%20APK%20%E2%80%A2%20early%20access-6C63FF?style=for-the-badge&logo=android&logoColor=white" alt="Download the APK - early access channel"/></a>

**📱 Now on both stores.** Moongate is live on the [App Store](https://apps.apple.com/gb/app/moongate-klipper-control/id6785038887) and [Google Play](https://play.google.com/store/apps/details?id=com.moongate.app.moongate), built from one codebase. The stores carry the **stable releases**; the [GitHub APK](https://github.com/PEEKYPAUL/Moongate/releases/latest) is the **early-access channel** - every release lands there first, and it updates itself in-app.

</div>

---

## Contents

- [Features](#features)
- [Screenshots](#screenshots)
- [Quick start](#quick-start)
- [Run it your way](#run-it-your-way)
- [How it works](#how-it-works)
- [Documentation](#documentation)
- [Buy me a coffee](#buy-me-a-coffee)
- [License](#license)

---

## Features

- **Fleet dashboard** - every printer on one screen: live webcam, progress and time left, temperatures (hold the chamber reading to pick which sensor it shows), status. Sort by activity or drag your own order.
- **Single-printer dashboard** - one printer full screen: camera, job, temperatures, macros, console, files and live X Y Z. Arrows step through your printers.
- **Full Mainsail / Fluidd** - tap a tile for the complete web UI, kept loaded so it opens instantly, even over the tunnel.
- **Home and away, automatically** - home WiFi first, the secure tunnel when you're out. No port forwarding, no setup.
- **Direct (LAN/VPN) mode** - cloud-free: the app talks straight to Moonraker, and away from home over your own WireGuard or Tailscale. [Compare the two modes ›](#run-it-your-way)
- **Print controls** - pause, resume, stop, firmware restart, a double-tap emergency stop, and a power button for printers with a power device or power macro.
- **Control panel** - arrange temperature, motion and macro modules per printer, and turn any Klipper macro into a labelled button.
- **Console and config editor** - a live G-code console with command completions, and a Klipper-aware `printer.cfg` editor with a backup and one-tap restore.
- **Print from the printer** - browse the G-code already on it, with slicer thumbnails, and start a print. No re-upload.
- **Print queue** - line up stored files, see what is up next on the tile, and start or pause the queue, without opening Mainsail.
- **G-code layer viewer** - open any stored file as a 3D layer stack you spin with a finger, coloured like Orca's preview: temperature, flow rate, layer time, speed, fan speed, or the filament colours of a multi-material print with a key per tool (and, on an MMU, a switch to what is loaded in the gates right now), layer by layer, then start the print from there, or save the file to your phone.
- **Cameras** - Mainsail cameras auto-detected, go2rtc included; add an external IP camera; full-screen view with pinch-to-zoom; switch between several on one printer.
- **Multi-toolhead** - IDEX and tool changers show every hotend as its own chip, active tool highlighted, preheat for all at once.
- **Notifications** - opt-in start / finish / pause / error alerts with the reason, live progress in the shade, heat-soak and "cool enough to remove" alerts, and a `MOONGATE_NOTIFY` macro for your own gcode.
- **Lighting** - a bulb on the tile drives your light macros and shows the real on/off state.
- **App lock** - PIN or biometric, auto-lock, screenshot protection. Off by default.
- **Themes and layout** - light, dark or custom colours and background, Material You on Android, a 36-font picker, 1-3 columns, landscape.
- **9 languages** - English, German, French, Spanish, Italian, Chinese, Russian, Polish and Brazilian Portuguese.
- **Backup and restore** - move to a new phone and your printers come back with no re-pairing.
- **In-app updates** - the early-access APK updates itself, and a tile badge updates the printer's plugin from your phone.
- **Guided tour** - an optional walkthrough that points out each part of the app on your first printer.
- **Hardened remote access** - every internet request needs a short-lived signed token; a leaked tunnel URL gives an attacker only `401`s. [How it works ›](#how-it-works)

Every feature in depth, with the version it arrived in: **[Feature guide ›](docs/features.md)**

---

## Screenshots

<div align="center">
  <img src="docs/screenshots/generated/framed-single-printer.png" width="31%" alt="The Single-printer dashboard - one printer full screen with the camera, the print job, temperatures, the tool buttons and live X Y Z"/>
  <img src="docs/screenshots/generated/framed-pairing.png" width="31%" alt="Secure LAN pairing"/>
  <img src="docs/screenshots/generated/framed-drawer.png" width="31%" alt="Menu"/>
</div>

<div align="center">
  <img src="docs/screenshots/generated/framed-icon-guide.png" width="31%" alt="Icon guide - what every dashboard icon means"/>
  <img src="docs/screenshots/generated/framed-custom-theme.png" width="31%" alt="Custom theme editor"/>
  <img src="docs/screenshots/generated/framed-layer-viewer.png" width="31%" alt="G-code layer viewer - a stored file as a 3D layer stack, coloured by fan speed with Orca's ramp, with the layer rail and a Start print button"/>
</div>

<div align="center">
  <img src="docs/screenshots/generated/framed-console.png" width="31%" alt="Per-printer G-code console - history pre-filled, quick-command chips"/>
  <img src="docs/screenshots/generated/framed-file-system.png" width="31%" alt="File System - browse the printer's configuration folder"/>
  <img src="docs/screenshots/generated/framed-config-editor.png" width="31%" alt="Structured printer.cfg editor - names fixed, values editable, backup before the first change"/>
</div>

<div align="center">
<br/>
<img src="docs/screenshots/notification.png" width="640" alt="Print notifications in the Android notification shade"/>
<br/><sub><em>Optional print notifications - live fleet status &amp; start / finish / error alerts, right in your notification shade.</em></sub>
</div>

---

## Quick start

Three steps: install the Pi plugin, install the app, pair.

### 1. Install the Pi plugin

SSH into your Pi and run:

```bash
curl -fsSL https://raw.githubusercontent.com/PEEKYPAUL/Moongate/master/klipper-plugin/install.sh | bash
```

The installer asks how your phone will connect: **1) Moongate cloud** (the default - remote access from anywhere) or **2) Direct (LAN/VPN)** (cloud-free; [see how the two compare](#run-it-your-way)). With the default it installs the plugin, the `MOONGATE_PAIR` macro, the QR pairing page, the auth proxy, and the Cloudflare tunnel, then restarts Moonraker. Future updates appear in **Mainsail → Software Updates → Moongate**.

> **Using a 3rd-party printer instead?** (e.g. an Elegoo Centauri Carbon on OpenCentauri COSMOS) - this installer targets Raspberry-Pi-style machines and won't run on embedded vendor firmware. Follow [3rd-party printer support](docs/third-party-printers.md) instead: a one-file install, no installer needed.

<details>
<summary><b>Requirements &amp; custom HTTP port</b></summary>

<br>

**Requirements:** a Raspberry Pi running Klipper + Moonraker + Mainsail or Fluidd (standard KIAUH / MainsailOS / FluiddPI). Tested on aarch64 (Pi 4/5) and armv7l (Pi 3).

**Non-standard port?** Moonraker usually serves on port 80 (the installer's default). If yours is elsewhere, tell the installer:

```bash
MOONGATE_PORT=8080 bash -c "$(curl -fsSL https://raw.githubusercontent.com/PEEKYPAUL/Moongate/master/klipper-plugin/install.sh)"
```

In the app's pair screen, set the **Port** field to match (leave it blank for 80).

**Other things talk to Moonraker at this Pi's IP?** A cloud install moves Moonraker onto localhost so only Moongate's gated tunnel is exposed. An on-Pi client like KlipperScreen then needs pointing at `127.0.0.1`, and a central "farm" Mainsail/Fluidd on another machine should target port 80 (this Pi's nginx serves the full Moonraker API there) - see [Troubleshooting](TROUBLESHOOTING.md) for both. If something genuinely needs raw `<pi-ip>:7125`, keep the bind exactly as it is:

```bash
MOONGATE_KEEP_BIND=1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/PEEKYPAUL/Moongate/master/klipper-plugin/install.sh)"
```

**LAN-only (own VPN, no tunnel)?** If you reach your printer over your own VPN / WireGuard and don't want an outbound Cloudflare tunnel or external exposure, install in LAN-only mode. It keeps Moonraker on the LAN (`0.0.0.0`) and skips cloudflared, the auth proxy, and the tunnel service. The plugin, `MOONGATE_PAIR` macro, and mDNS advertisement are still installed, and a later cloud re-install enables remote access.

**The installer asks.** Run it interactively (the normal `curl | bash` one-liner counts) and it offers the choice - answer `2` for Direct (LAN/VPN):

```
How will your phone connect to this printer?
    1) Moongate cloud   - remote access from anywhere (secure tunnel)
    2) Direct (LAN/VPN) - home network / your own VPN only, no cloud
```

On a box that already runs LAN-only the default keeps it LAN-only, so pressing Enter never converts your mode. To preselect an answer and skip the question (scripts, headless installs):

```bash
# LAN-only, piped
MOONGATE_LAN_ONLY=1 bash -c "$(curl -fsSL https://raw.githubusercontent.com/PEEKYPAUL/Moongate/master/klipper-plugin/install.sh)"
# LAN-only, from a local checkout
bash install.sh --lan-only
# cloud, never prompt (automation)
MOONGATE_LAN_ONLY=0 bash -c "$(curl -fsSL https://raw.githubusercontent.com/PEEKYPAUL/Moongate/master/klipper-plugin/install.sh)"
```

Choosing LAN-only on a box that already has the tunnel stack retires it (disables the tunnel + auth proxy) and converges to LAN-only.

In the app, add a LAN-only printer with **Add printer → Direct (LAN/VPN)** - scan the QR from `MOONGATE_PAIR` or type the printer's address. A LAN-only box can also be paired through the cloud as normal (while it has internet); Direct mode is for the fully cloud-free / internet-isolated case. Two networking notes:

- **`trusted_clients` must cover your phone.** The app talks to Moonraker directly, so the phone's subnet needs to be in Moonraker's `[authorization] trusted_clients`. Home WiFi and WireGuard's usual `10.x` range typically already are; **Tailscale's `100.64.0.0/10` usually is not** - add it or Moonraker answers 401 before Moongate ever runs.
- **Give the Pi a fixed address.** The app stores the address a Direct printer was added with, so use a DHCP reservation (or static IP) - if the Pi's IP changes you'd have to re-add it.

Direct-mode printers work fully offline, but skip everything cloud-backed: no print notifications, and away from home the app only reaches them through your own VPN.

</details>

### 2. Install the app

[![Download on the App Store](https://img.shields.io/badge/iPhone-App%20Store-0D96F6?style=for-the-badge&logo=apple&logoColor=white)](https://apps.apple.com/gb/app/moongate-klipper-control/id6785038887)
[![Get it on Google Play](https://img.shields.io/badge/Android-Google%20Play-34A853?style=for-the-badge&logo=googleplay&logoColor=white)](https://play.google.com/store/apps/details?id=com.moongate.app.moongate)
[![Download Moongate APK](https://img.shields.io/badge/%E2%AC%87%20APK-early%20access-6C63FF?style=for-the-badge&logo=android&logoColor=white)](https://github.com/PEEKYPAUL/Moongate/releases/latest)

**iPhone** - get it on the [App Store](https://apps.apple.com/gb/app/moongate-klipper-control/id6785038887).

**Android** - get it on [Google Play](https://play.google.com/store/apps/details?id=com.moongate.app.moongate) (recommended - stable releases, updated automatically by the store).

**Android early access** - want each release the day it ships? Grab the APK from the [Releases page](https://github.com/PEEKYPAUL/Moongate/releases) instead: enable **Install from unknown sources** for your browser or file manager, then open the APK. From then on it updates itself in-app. It's signed with the same key as the Play build, so you can move between the two channels later without losing your printers.

### 3. Pair

1. Run **`MOONGATE_PAIR`** in the Klipper / Mainsail console.
2. On a device on the **same WiFi as your Pi**, open `http://<your-pi-ip>/moongate-pair.html` - a QR appears.
3. In the app, tap **+ → Scan QR** and point the camera at it. Done - your printer lands on the dashboard.

No working camera? Type the **`GATE-XXXX-XXXX`** code shown in the console instead. And if you opened the pair page on the phone the app is on, just **tap the link under the QR** (v0.9.59+) - the app opens straight into pairing.

> **How quickly does it connect? Scanning the QR is instant.**
> - ✅ **Scan the QR (recommended)** - an **instant local connection**: your printer is on the dashboard in about a second, because the QR hands the app your Pi's local address directly. Remote access over the secure tunnel keeps **building in the background** - you never wait on it.
> - ⚠️ **GATE code** - there's no instant local hand-off, so the printer doesn't appear until the **Cloudflare tunnel** has finished building (that's what carries the connection). Usually under a minute - a little longer right after a Pi reboot. It isn't stuck; give it a moment, or scan the QR for an instant connection.

> Pairing is LAN-only by design: nothing to port-forward, no URL to share. Reinstalling or switching phones? **Back up your config first** - restoring it brings your printers back online without re-pairing. See **[Updating &amp; removing](docs/managing-moongate.md)**.

---

## Run it your way

Moongate gives every printer a choice of two connections - and you can mix them freely on one dashboard.

| | ☁️ Moongate cloud (default) | 🔌 Direct (LAN/VPN) |
|---|---|---|
| Setup | pair once with the QR / GATE code | pick **Direct** when the installer asks, add by QR or address |
| Away from home | automatic - secure tunnel, zero config | through **your own VPN** (WireGuard, Tailscale) |
| Print notifications | ✅ | ❌ (no cloud to send them) |
| What touches the cloud | pairing, a heartbeat, short-lived tokens | **nothing - zero calls, ever** |
| Needs internet | to pair and for the tunnel | **never - works fully offline** |
| Best for | most people - it just works | VPN owners, isolated networks, zero-cloud setups |

Switch an existing printer between modes anytime from its edit dialog - no re-pairing. If you later want a Direct printer on the cloud, re-run the installer normally and pair it; the app absorbs the old tile automatically. Networking notes for Direct mode (Moonraker's `trusted_clients`, give the Pi a fixed address) are in the [LAN-only install section](#quick-start) above.

Direct mode isn't picky about the host, either: from plugin 0.6.17 it needs **zero extra Python packages**, so machines that were never a Raspberry Pi - embedded boards, vendor printers on community firmware - can join the dashboard with a one-file install. See [3rd-party printer support](docs/third-party-printers.md).

---

## How it works

<div align="center">
<img src="docs/how-it-works.svg" width="820" alt="Moongate's two connection routes: route 1, Moongate cloud - the app gets a short-lived signed token from the access broker and reaches the Raspberry Pi over the LAN at home or through Cloudflare's tunnel away, with the Pi's auth proxy admitting only broker-signed requests so a leaked tunnel URL returns only 401s; route 2, Direct - the app talks straight to Moonraker over home WiFi or the user's own WireGuard/Tailscale VPN, gated by trusted_clients, with zero cloud involvement.">
</div>

**Route 1 - Moongate cloud.** Your Pi runs Klipper, Moonraker, the Moongate plugin, and an **auth proxy** that gates everything reachable from the internet. A minimal **access broker** handles anonymous sign-in (no email, no password) and tracks the current tunnel URL; the app fetches a fresh signed token before each request and tries home WiFi first, then the tunnel.

**The headline:** leaking the tunnel URL alone gives an attacker nothing - every path through it returns `401` without revealing what's underneath. Full threat model in [SECURITY.md](SECURITY.md); code-level detail in [ARCHITECTURE.md](ARCHITECTURE.md).

**Route 2 - Direct (LAN/VPN).** No broker, no tunnel, no heartbeats: the app talks straight to Moonraker on your network - or across your own VPN - gated by Moonraker's `trusted_clients`, exactly like Mainsail in a desktop browser. The Pi makes **zero outbound calls** and the whole thing works with no internet at all.

---

## Documentation

| Document | What's inside |
|---|---|
| [Moongate website](https://peekypaul.github.io/Moongate/) | The features, screenshots and setup steps on one page - the friendliest place to send someone new |
| [Feature guide](docs/features.md) | Every feature in depth, with the version it arrived in and the plugin it needs |
| [Updating &amp; removing](docs/managing-moongate.md) | Updating the app &amp; plugin, reinstalling / moving to a new phone, full uninstall |
| [3rd-party printer support](docs/third-party-printers.md) | Direct (LAN/VPN) mode on non-Pi hosts - the one-file install, supported machines, VPN notes |
| [DEVELOPMENT.md](DEVELOPMENT.md) | Building from source, repo layout, debugging, release signing, CI |
| [ARCHITECTURE.md](ARCHITECTURE.md) | Code structure, state management, data-flow walkthroughs, design decisions |
| [SECURITY.md](SECURITY.md) | Threat model, what the tunnel does and doesn't expose, the empirical verification, vulnerability reporting |
| [TROUBLESHOOTING.md](TROUBLESHOOTING.md) | Common failure modes - offline tiles, tunnel issues, pairing failures - each with copy-paste diagnostics |
| [CHANGELOG.md](CHANGELOG.md) | Every release as a few short bullets: what is new, what was fixed |
| [Privacy policy](https://peekypaul.github.io/Moongate/privacy-policy.html) | What data the app handles and why - anonymous, no analytics, no tracking, no data sold |

> **Building from source?** `cd mobile && flutter pub get && flutter build apk --release --flavor github --dart-define=MOONGATE_CHANNEL=github`. Full developer workflow in [DEVELOPMENT.md](DEVELOPMENT.md).

---

## Buy me a coffee

Moongate is free, source available, and built in my spare time for the Klipper community - no ads, no subscriptions, no data harvesting. If it's earned a spot on your phone, you can buy me a coffee on [Ko-fi](https://ko-fi.com/peekypaul) (or tip via PayPal) to say thanks. Every contribution goes straight back into the project: test hardware, the cloud service that keeps remote access working, and the time to keep shipping features.

Thank you for being part of it 💜

<p align="center">
  <a href="https://ko-fi.com/peekypaul">
    <img src="https://img.shields.io/badge/%E2%98%95%20Buy%20me%20a%20coffee%20on%20Ko--fi-FF5E5B?style=for-the-badge&logo=ko-fi&logoColor=white" alt="Buy me a coffee on Ko-fi"/>
  </a>
  <a href="https://www.paypal.com/donate/?hosted_button_id=WCWAZKQ7WKQB4">
    <img src="https://img.shields.io/badge/Donate%20with%20PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white" alt="Donate with PayPal"/>
  </a>
</p>

---

## License

**PolyForm Noncommercial License 1.0.0** - see [LICENSE](LICENSE) for the full text.

- ✅ Free to read, build, self-host, modify, and share for **non-commercial** use - including charities, schools, and public / research / government institutions.
- ❌ Selling Moongate, charging for access, or bundling it in a paid product needs a **separate written licence**.

Want to use Moongate commercially? [Open an issue](https://github.com/PEEKYPAUL/Moongate/issues/new) or contact [@PEEKYPAUL](https://github.com/PEEKYPAUL) to discuss terms.

---

<div align="center">
<sub>Created by <a href="https://github.com/PEEKYPAUL">Paul Sharman</a></sub>
</div>