Skip to content

feat: add Syncthing monitor type#7314

Open
baquilla wants to merge 1 commit intolouislam:masterfrom
baquilla:feature/syncthing-monitor-type
Open

feat: add Syncthing monitor type#7314
baquilla wants to merge 1 commit intolouislam:masterfrom
baquilla:feature/syncthing-monitor-type

Conversation

@baquilla
Copy link
Copy Markdown

@baquilla baquilla commented Apr 24, 2026

Summary

Adds a new Syncthing monitor type that checks a Syncthing instance via its REST API (X-API-Key authentication).

In this pull request, the following changes are made:

File Change
README.md Add link to monitor-types folder
db/knex_migrations/2026-04-23-0000-add-syncthing-monitor.js DB migration (7 new columns)
server/model/monitor.js Expose fields in toJSON
server/monitor-types/syncthing.js New monitor type implementation
server/server.js Persist fields on save
server/uptime-kuma-server.js Register monitor type
src/lang/en.json English translation strings
src/pages/EditMonitor.vue UI form for the new monitor
test/backend-test/monitors/test-syncthing.js 32 backend tests
I've followed this checklist to avoid unnecessary back and forth
  • ⚠️ If there are Breaking change (a fix or feature that alters existing functionality in a way that could cause issues) I have called them out
  • 🧠 I have disclosed any use of LLMs/AI in this contribution and reviewed all generated content.
    I understand that I am responsible for and able to explain every line of code I submit.
  • 🔍 Any UI changes adhere to visual style of this project.
  • 🛠️ I have self-reviewed and self-tested my code to ensure it works as expected.
  • 📝 I have commented my code, especially in hard-to-understand areas (e.g., using JSDoc for methods).
  • 🤖 I added or updated automated tests where appropriate.
  • 📄 Documentation updates are included (if applicable).
  • 🧰 Dependency updates are listed and explained.
  • ⚠️ CI passes and is green.

AI disclosure: The implementation was developed with Claude (Anthropic) as a coding assistant, working from a specification I defined. I have manually reviewed every changed file, run the tests locally, and verified the monitor against a real Syncthing instance. I own and can explain all the code submitted here.

Further details

Check modes

Health

Checks overall system health: API reachability, active system errors, and folder sync status. A folder stuck in syncing/scanning state beyond a configurable threshold is treated as a failure.

Peers

Checks device connectivity. Devices that are disconnected for longer than the configured peer timeout (default: 24 h / 86 400 s) are reported. Devices that have never connected are always reported.

Common features to both modes

  • Glob filter (comma-separated patterns, * and ? wildcards, case-insensitive) on folder labels/IDs or device names/IDs
  • Filter mode: include (only check matching items) or exclude (skip matching items)
  • Duration fields allow for timeout events fine tuning.
  • Paused folders and paused devices are silently skipped

Security note: API key is write-only

The Syncthing API key always grants full, unrestricted access to the Syncthing instance — there is no read-only scope or per-capability restriction. Returning it to the frontend would mean that anyone who gains access to an Uptime Kuma session also obtains credentials capable of reconfiguring or disrupting Syncthing entirely.

For this reason the key is excluded from toJSON() under all circumstances and is never sent to the browser. The edit form shows a placeholder ("API key saved — leave blank to keep it") when a key is already stored, and omits the required validation in that case. Submitting the form without changing the field leaves the existing key untouched in the database.

This is a deliberate departure from how other credentials are handled in Uptime Kuma, justified by the unusually broad access the Syncthing API key provides.

Known limitation - no re-notification on partial recovery or degradation

Because this monitor reports multiple peers/folders as a single UP/DOWN status, Uptime Kuma only notifies on the first failure and on full recovery. Intermediate changes — a second peer going down, or one peer coming back while others remain down — do not trigger a new notification, even though the failure message changes.

As a workaround, create one monitor per peer or folder using the include filter with a single name/ID.

This is a core Kuma limitation, not specific to this monitor. A proper fix would require like a notifyOnMessageChange hook in the heartbeat processor. Tracked for a future PR.

Test plan

  • 32 unit tests pass (node --test test/backend-test/monitors/test-syncthing.js)
  • npm run lint passes (no new errors)
  • npm run fmt applied
  • Manual: create/clone a Health monitor pointing at a in-use Syncthing — verify system and folder errors are flagged
  • Manual: create/clone a Peers monitor — verify disconnected peer is flagged
  • Manual: verify glob filter (include / exclude) filters folders/devices correctly
  • Manual: verify API key error shows "Invalid Syncthing API key"
  • Manual: verify syncthing not reachable error is properly detected
  • Manual: build container with podman and replace my production instance to perform an in field test

Screenshots

Event Screenshot
UP/DOWN (health) Health monitor UP
UP/DOWN (peers) Peers monitor UP
Editor Syncthing monitor editor

  Adds a native Uptime Kuma monitor type for Syncthing instances, accessed via the Syncthing REST API.

  Two check modes:
  - health: verifies API reachability, active system errors, and folder sync state (idle/syncing/error). A folder stuck syncing/scanning beyond a configurable threshold is reported as a failure.
  - peers: checks device connectivity. Disconnected peers are reported if their last-seen time exceeds a configurable timeout (default 24h). Peers that have never connected are always reported.

  Both modes support a unified glob filter (comma-separated patterns) with include/exclude semantics. Paused folders and paused devices are silently ignored in both modes.

  Syncthing API key is intentionally never returned to the frontend.

  The Syncthing API key always grants full, unrestricted access to the instance — there is no read-only scope or capability restriction. Returning it to the frontend (even behind includeSensitiveData) creates unnecessary exposure: anyone who gains access to a Kuma session would also obtain credentials that can reconfigure or disrupt Syncthing. Once saved, the key is excluded from toJSON() entirely. On save, the key is only overwritten if the client sends a non-empty value, so editing a monitor without touching the key field preserves the existing one. The edit form reflects this with a conditional placeholder and a conditional required attribute.

  New columns in the monitor table:
    syncthing_url, syncthing_api_key, syncthing_check_type,
    syncthing_filter, syncthing_filter_mode,
    syncthing_peer_timeout, syncthing_folder_sync_threshold
@github-actions
Copy link
Copy Markdown
Contributor

Hello and thanks for lending a paw to Uptime Kuma! 🐻👋
As this is your first contribution, please be sure to check out our Pull Request guidelines.
In particular: - Mark your PR as Draft while you’re still making changes - Mark it as Ready for review once it’s fully ready
If you have any design or process questions, feel free to ask them right here in this pull request - unclear documentation is a bug too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant