diff --git a/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.ini b/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.ini
new file mode 100644
index 00000000..fc4e6e46
--- /dev/null
+++ b/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.ini
@@ -0,0 +1,13 @@
+; MokoSuiteClient Backup Bridge Plugin
+; Copyright (C) 2026 Moko Consulting. All rights reserved.
+; License: GPL-3.0-or-later
+
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP="System - MokoSuiteClient Backup"
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC="Detects MokoSuiteBackup and includes backup status in heartbeat payloads sent to MokoSuiteHQ."
+
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC="Backup Monitoring"
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_FIELDSET_BASIC_DESC="Configure backup status collection for heartbeat reporting."
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_LABEL="Include in Heartbeat"
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_HEARTBEAT_DESC="Include MokoSuiteBackup status data in heartbeat payloads sent to MokoSuiteHQ."
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_LABEL="Stale Backup Threshold (days)"
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_STALE_DAYS_DESC="Number of days without a backup before status is marked as degraded. Default: 7."
diff --git a/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.sys.ini b/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.sys.ini
new file mode 100644
index 00000000..07da83a8
--- /dev/null
+++ b/source/packages/plg_system_mokosuiteclient_backup/language/en-GB/plg_system_mokosuiteclient_backup.sys.ini
@@ -0,0 +1,3 @@
+; MokoSuiteClient Backup Bridge Plugin - System strings
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP="System - MokoSuiteClient Backup"
+PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC="MokoSuiteBackup detection and heartbeat integration."
diff --git a/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml b/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml
new file mode 100644
index 00000000..c0f05aeb
--- /dev/null
+++ b/source/packages/plg_system_mokosuiteclient_backup/mokosuiteclient_backup.xml
@@ -0,0 +1,48 @@
+
+
+ System - MokoSuiteClient Backup
+ mokosuiteclient_backup
+ Moko Consulting
+ 2026-06-18
+ Copyright (C) 2026 Moko Consulting. All rights reserved.
+ GPL-3.0-or-later
+ hello@mokoconsulting.tech
+ https://mokoconsulting.tech
+ 02.34.84-dev
+ PLG_SYSTEM_MOKOSUITECLIENT_BACKUP_DESC
+ Moko\Plugin\System\MokoSuiteClientBackup
+
+
+ src
+ services
+ language
+
+
+
+ en-GB/plg_system_mokosuiteclient_backup.ini
+ en-GB/plg_system_mokosuiteclient_backup.sys.ini
+
+
+
+
+
+
+
+
diff --git a/source/packages/plg_system_mokosuiteclient_backup/services/provider.php b/source/packages/plg_system_mokosuiteclient_backup/services/provider.php
new file mode 100644
index 00000000..4ea63861
--- /dev/null
+++ b/source/packages/plg_system_mokosuiteclient_backup/services/provider.php
@@ -0,0 +1,34 @@
+set(
+ PluginInterface::class,
+ function (Container $container) {
+ $dispatcher = $container->get(DispatcherInterface::class);
+ $plugin = new Backup($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuiteclient_backup'));
+ $plugin->setApplication(Factory::getApplication());
+
+ return $plugin;
+ }
+ );
+ }
+};
diff --git a/source/packages/plg_system_mokosuiteclient_backup/src/Extension/Backup.php b/source/packages/plg_system_mokosuiteclient_backup/src/Extension/Backup.php
new file mode 100644
index 00000000..6eee0741
--- /dev/null
+++ b/source/packages/plg_system_mokosuiteclient_backup/src/Extension/Backup.php
@@ -0,0 +1,219 @@
+ 'onCollectHeartbeat',
+ ];
+ }
+
+ /**
+ * Collect backup status data for the heartbeat payload.
+ *
+ * Triggered by the monitor plugin before sending a heartbeat.
+ * Appends a 'backup' key to the heartbeat data array.
+ */
+ public function onCollectHeartbeat($event): void
+ {
+ if (!$this->params->get('heartbeat_enabled', 1))
+ {
+ return;
+ }
+
+ try
+ {
+ $data = $this->getBackupStatus();
+ $event->addResult('backup', $data);
+ }
+ catch (\Throwable $e)
+ {
+ Log::add('Backup bridge: ' . $e->getMessage(), Log::WARNING, 'mokosuiteclient');
+ }
+ }
+
+ /**
+ * Check if MokoSuiteBackup is installed.
+ *
+ * Queries the extensions table for the component, which is more
+ * reliable than checking for database tables alone.
+ */
+ public function isBackupInstalled(): bool
+ {
+ try
+ {
+ $db = Factory::getContainer()->get(DatabaseInterface::class);
+
+ $query = $db->getQuery(true)
+ ->select('COUNT(*)')
+ ->from($db->quoteName('#__extensions'))
+ ->where($db->quoteName('element') . ' = ' . $db->quote('com_mokosuitebackup'))
+ ->where($db->quoteName('type') . ' = ' . $db->quote('component'));
+
+ $db->setQuery($query);
+
+ return (int) $db->loadResult() > 0;
+ }
+ catch (\Throwable $e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * Get backup status summary from MokoSuiteBackup.
+ *
+ * @return array Backup status data for heartbeat inclusion.
+ */
+ public function getBackupStatus(): array
+ {
+ if (!$this->isBackupInstalled())
+ {
+ return [
+ 'installed' => false,
+ ];
+ }
+
+ $db = Factory::getContainer()->get(DatabaseInterface::class);
+ $tables = $db->getTableList();
+ $prefix = $db->getPrefix();
+ $statsTable = $prefix . 'mokosuitebackup_records';
+
+ if (!in_array($statsTable, $tables, true))
+ {
+ return [
+ 'installed' => true,
+ 'status' => 'degraded',
+ 'message' => 'Backup tables not found',
+ ];
+ }
+
+ // TODO: Query MokoSuiteBackup records table for latest backup status.
+ //
+ // This is a placeholder — the actual column names and table structure
+ // depend on MokoSuiteBackup's schema. Once that component is available
+ // locally, update this query to match its database layout.
+ //
+ // Expected return shape:
+ // [
+ // 'installed' => true,
+ // 'status' => 'ok' | 'degraded',
+ // 'last_backup' => '2026-06-18 10:30:45',
+ // 'last_status' => 'complete' | 'failed' | 'partial',
+ // 'last_size_mb' => 512,
+ // 'days_since' => 2,
+ // 'total_backups'=> 42,
+ // 'recent_7d' => 5,
+ // 'destination' => 'local' | 's3' | 'remote',
+ // 'description' => 'Full site backup',
+ // ]
+
+ return $this->queryBackupRecords($db);
+ }
+
+ /**
+ * Query MokoSuiteBackup records for the latest backup summary.
+ *
+ * @param DatabaseInterface $db Database driver.
+ *
+ * @return array Backup status array.
+ */
+ private function queryBackupRecords(DatabaseInterface $db): array
+ {
+ $staleDays = (int) $this->params->get('stale_days', 7);
+
+ // Get the most recent backup record
+ $query = $db->getQuery(true)
+ ->select('*')
+ ->from($db->quoteName('#__mokosuitebackup_records'))
+ ->order($db->quoteName('id') . ' DESC');
+
+ $db->setQuery($query, 0, 1);
+ $latest = $db->loadObject();
+
+ if (!$latest)
+ {
+ return [
+ 'installed' => true,
+ 'status' => 'degraded',
+ 'message' => 'No backups found',
+ ];
+ }
+
+ // Count total and recent backups
+ $db->setQuery(
+ $db->getQuery(true)
+ ->select('COUNT(*)')
+ ->from($db->quoteName('#__mokosuitebackup_records'))
+ );
+ $totalBackups = (int) $db->loadResult();
+
+ $db->setQuery(
+ $db->getQuery(true)
+ ->select('COUNT(*)')
+ ->from($db->quoteName('#__mokosuitebackup_records'))
+ ->where($db->quoteName('created') . ' >= DATE_SUB(NOW(), INTERVAL 7 DAY)')
+ );
+ $recentBackups = (int) $db->loadResult();
+
+ // Determine status
+ $lastDate = $latest->created ?? '';
+ $daysSince = $lastDate ? (int) ((time() - strtotime($lastDate)) / 86400) : 999;
+ $lastStatus = $latest->status ?? 'unknown';
+
+ $status = 'ok';
+
+ if ($lastStatus !== 'complete')
+ {
+ $status = 'degraded';
+ }
+ elseif ($daysSince > $staleDays)
+ {
+ $status = 'degraded';
+ }
+
+ $sizeMb = !empty($latest->total_size)
+ ? round($latest->total_size / 1048576)
+ : null;
+
+ return [
+ 'installed' => true,
+ 'status' => $status,
+ 'last_backup' => $lastDate,
+ 'last_status' => $lastStatus,
+ 'last_size_mb' => $sizeMb,
+ 'days_since' => $daysSince,
+ 'total_backups' => $totalBackups,
+ 'recent_7d' => $recentBackups,
+ 'destination' => $latest->destination ?? null,
+ 'description' => $latest->description ?? null,
+ ];
+ }
+}
diff --git a/source/pkg_mokosuiteclient.xml b/source/pkg_mokosuiteclient.xml
index f79089f3..613d4d30 100644
--- a/source/pkg_mokosuiteclient.xml
+++ b/source/pkg_mokosuiteclient.xml
@@ -25,6 +25,7 @@
mod_mokosuiteclient_cache.zip
mod_mokosuiteclient_categories.zip
+ plg_system_mokosuiteclient_backup.zip
plg_webservices_mokosuiteclient.zip
plg_task_mokosuiteclientdemo.zip
plg_task_mokosuiteclientsync.zip