Sync agent workspace with cloud storage (Dropbox, Google Drive, S3, etc.) using rclone.
---
name: workspace-sync
description: Sync agent workspace with cloud storage (Dropbox, Google Drive, S3, etc.) using rclone.
metadata: {"openclaw":{"emoji":"☁️","requires":{"bins":["rclone"]}}}
---
# workspace-sync
Sync the agent workspace with cloud storage. `mode` is required — choose `mailbox` (inbox/outbox, safest), `mirror` (remote->local), or `bisync` (bidirectional, advanced).
## Trigger
Use this skill when the user asks to:
- Sync workspace to/from cloud
- Back up workspace files
- Check sync status
- Fix sync issues
- Send files to the agent workspace
## Sync modes
| Mode | Direction | Description |
|------|-----------|-------------|
| `mailbox` (recommended) | Push + inbox/outbox | Workspace pushes to cloud; `_outbox` sends files up to the agent's `_inbox`. Safest. |
| `mirror` | Remote → Local | One-way: workspace mirrors down. Safe — local can never overwrite remote. |
| `bisync` | Bidirectional | Two-way sync. Powerful but requires careful setup. |
### Mailbox mode
Each sync cycle: (1) pushes workspace to cloud excluding `_inbox/` and `_outbox/`, (2) drains cloud `_outbox/` into workspace `_inbox/` via `rclone move` (deletes from cloud after transfer). On startup, bootstraps `cloud:_outbox` and local `_inbox/`.
Users drop files in the local `_outbox/` folder (created by the cloud provider's desktop app). Files arrive in the agent's `_inbox/`. The agent or a skill processes them from there.
With `notifyOnInbox: true`, the agent is woken when files land in `_inbox`. A system event lists the new filenames so the agent can process them. Off by default — each notification costs an agent turn.
### Mirror mode with ingest
With `ingest: true`, a local `inbox/` folder syncs one-way **up** to the remote workspace (additive only). For a more robust pattern, use `mailbox` mode instead.
## Commands
### Check sync status
```bash
openclaw workspace-sync status
```
Shows: provider, mode, last sync time, sync count, error count, running state.
### Trigger manual sync
```bash
openclaw workspace-sync sync
```
In `mailbox` mode: pushes workspace and drains `_outbox`. In `mirror` mode: pulls latest from remote. In `bisync` mode: runs bidirectional sync.
### Preview changes
```bash
openclaw workspace-sync sync --dry-run
```
### One-way sync (explicit direction)
```bash
openclaw workspace-sync sync --direction pull # remote -> local
openclaw workspace-sync sync --direction push # local -> remote
```
### Force re-establish bisync baseline (destructive)
```bash
openclaw workspace-sync sync --resync
```
**WARNING: `--resync` is destructive (bisync only).** It copies ALL files from both sides to make them identical — deleted files come back, and it transfers everything. Only use when you explicitly need to re-establish the bisync baseline. The plugin never auto-resyncs.
### View remote files
```bash
openclaw workspace-sync list
```
Lists files in the configured cloud storage path.
## Configuration
Workspace sync is configured via the plugin entry in `openclaw.json`. The preferred format uses nested `sync` and `backup` blocks (flat config at root level is also supported):
```json
{
"plugins": {
"entries": {
"openclaw-workspace-sync": {
"enabled": true,
"config": {
"sync": {
"provider": "dropbox",
"mode": "mailbox",
"remotePath": "",
"localPath": "/",
"interval": 60,
"timeout": 1800,
"onSessionStart": true,
"onSessionEnd": true,
"exclude": [".git/**", "node_modules/**", "*.log"]
}
}
}
}
}
}
```
### Config keys
These keys live under `sync` in the nested format, or at the config root in flat format.
| Key | Default | Description |
|-----|---------|-------------|
| `provider` | `"off"` | `dropbox`, `gdrive`, `onedrive`, `s3`, `custom`, or `off` |
| `mode` | **required** | `mailbox` (inbox/outbox, safest), `mirror` (remote->local), or `bisync` (bidirectional) |
| `ingest` | `false` | Enable local inbox for sending files to the agent (mirror mode only) |
| `ingestPath` | `"inbox"` | Local subfolder name for ingestion |
| `notifyOnInbox` | `false` | Wake the agent when files arrive in `_inbox` (mailbox mode). Costs credits per notification. |
| `remotePath` | `"openclaw-share"` | Folder name in cloud storage |
| `localPath` | `"shared"` | Subfolder within workspace to sync |
| `interval` | `0` | Background sync interval in seconds (0 = manual only, min 60) |
| `timeout` | `1800` | Max seconds for a single sync operation (min 60) |
| `onSessionStart` | `false` | Sync when an agent session begins |
| `onSessionEnd` | `false` | Sync when an agent session ends |
| `conflictResolve` | `"newer"` | `newer`, `local`, or `remote` (bisync only) |
| `exclude` | `**/.DS_Store` | Glob patterns to exclude from sync |
## Automatic sync
When configured, sync runs automatically:
- **On session start**: Pushes workspace and drains outbox (mailbox), pulls latest (mirror), or runs bisync
- **On session end**: Syncs changes after conversation ends
- **Periodic interval**: Background sync every N seconds (no LLM cost)
## Safety notes
- **Mailbox mode is the safest.** Workspace pushes to cloud; users send files via `_outbox`. Streams never overlap.
- **Mirror mode is safe by design.** Remote workspace is the authority. Local is a read-only copy.
- **Bisync requires careful setup.** Both sides must agree. If state is lost, `--resync` is needed and it copies everything.
- **On container platforms** (Fly.io, Railway), bisync state is ephemeral — use `mailbox` or `mirror` mode instead.
- **When changing config** (remotePath, localPath, mode), disable periodic sync first, verify, then re-enable.
## Auto-recovery
- **Stale lock files**: Detected and cleared before retrying (lock files older than 15 min are expired automatically)
- **Interrupted syncs**: Uses `--recover` and `--resilient` flags to resume after interruptions (bisync only)
- **Resync never automatic**: If bisync state is lost, the plugin logs a message but does NOT auto-resync
## Troubleshooting
### "rclone not configured"
First, install `rclone` via your OS package manager:
```bash
# macOS
brew install rclone
# Debian/Ubuntu
sudo apt-get install rclone
# Fedora
sudo dnf install rclone
# Arch
sudo pacman -S rclone
# Alpine
sudo apk add rclone
```
For other platforms, see https://rclone.org/install/
**Security note:** This skill never pipes remote install scripts to your shell. Install rclone via your OS package manager, then run the setup wizard:
```bash
openclaw workspace-sync setup
```
The setup wizard will only attempt installation via your detected OS package manager (brew/apt/dnf/yum/pacman/apk) — it will never use `curl | sudo sh`.
### "requires --resync" (bisync only)
Bisync state was lost. **Before running `--resync`, verify both sides are correct**:
```bash
openclaw workspace-sync sync --resync
```
### Sync times out
Increase the `timeout` in your config (default is 1800 seconds / 30 min):
```json
{ "timeout": 3600 }
```
### Check rclone directly
```bash
rclone lsd cloud:/
rclone ls cloud:openclaw-share
```
## Notes
- `mode` is **required** — set `mailbox` (inbox/outbox, safest), `mirror` (remote→local), or `bisync` (bidirectional)
- Mailbox mode bootstraps `_outbox` on cloud and `_inbox` on workspace at startup
- Bisync is available for power users who need bidirectional sync
- Ingest inbox (mirror mode only) is additive only — cannot delete remote files
- Only `**/.DS_Store` excluded by default — add your own excludes in config
- Sync operations run in background (no LLM tokens used)
- All rclone activity is logged at info level for visibility
## Encrypted backups
Add a `backup` block to the plugin config for automated encrypted snapshots to your own cloud storage (S3, R2, B2, etc.). Backups stream directly (`tar | rclone rcat`) — no local temp files, so they work even when disk space is tight.
### Backup commands
```bash
openclaw workspace-sync backup now # Create a snapshot immediately
openclaw workspace-sync backup list # List available snapshots
openclaw workspace-sync backup restore # Restore latest snapshot
openclaw workspace-sync backup status # Check backup service status
```
### Backup config
```json
{
"backup": {
"enabled": true,
"provider": "s3",
"bucket": "my-backups",
"prefix": "agent-name/",
"interval": 86400,
"encrypt": true,
"passphrase": "${BACKUP_PASSPHRASE}",
"include": ["workspace", "config", "cron", "memory"],
"retain": { "daily": 7, "weekly": 4 }
}
}
```
| Key | Default | Description |
|-----|---------|-------------|
| `enabled` | `false` | Enable scheduled backups |
| `provider` | parent provider | Cloud provider (can differ from sync provider) |
| `bucket` | — | S3/R2 bucket name |
| `prefix` | `""` | Path prefix within the bucket |
| `interval` | `86400` | Backup interval in seconds (clamped to min 300) |
| `encrypt` | `false` | AES-256 client-side encryption |
| `passphrase` | — | Encryption passphrase (use env var) |
| `include` | `["workspace", "config", "cron", "memory"]` | What to back up |
| `retain` | `7` | Keep N snapshots, or `{ daily: N, weekly: N }` |
don't have the plugin yet? install it then click "run inline in claude" again.