Skip to content

Repository files navigation

ClipMesh

ClipMesh is a self-hosted, end-to-end encrypted clipboard and file-transfer mesh. It pairs a Chrome Manifest V3 extension or native Rust client with a Rust/SQLite server and synchronizes plain text, PNG images, and encrypted files through password-protected channels.

Canonical repository: https://github.com/YiPrograms/ClipMesh

Development

Requirements: Rust 1.85 or newer, Node.js 20 or newer, and npm.

cargo test --workspace
cd extension
npm install
npm test
npm run build

Run the server with:

CLIPMESH_PUBLIC_URL=http://127.0.0.1:8787 cargo run -p clipmesh-server

The development server listens on 127.0.0.1:8787 and stores state under server/data. TLS is mandatory for non-loopback deployments; terminate TLS at a trusted reverse proxy or configure the server deployment accordingly.

Open http://127.0.0.1:8787 for onboarding. To load the extension during development, open chrome://extensions, enable Developer mode, choose Load unpacked, and select extension/dist. Create a pairing code on the onboarding page, open the extension popup while that tab is active, confirm the origin permission, and pair the device.

Tagged GitHub releases also contain clipmesh-extension-vVERSION.zip and SHA256SUMS. The server automatically presents the release matching its compiled version with accurate manual installation and update instructions. Chrome requires users to extract the ZIP and load the folder through Developer mode; a ZIP is not a one-click extension installer.

Docker Compose

The public image supports Linux x86-64 and ARM64. Save this as compose.yaml:

services:
  clipmesh:
    image: ghcr.io/yiprograms/clipmesh:latest
    container_name: clipmesh
    restart: unless-stopped
    ports:
      - "127.0.0.1:8787:8787"
    env_file:
      - .env
    volumes:
      - ./data:/var/lib/clipmesh

Put the server options in .env:

CLIPMESH_LISTEN=0.0.0.0:8787
CLIPMESH_PUBLIC_URL=http://127.0.0.1:8787
CLIPMESH_INSTANCE_NAME=Home ClipMesh
# CLIPMESH_CHROME_STORE_URL=https://chromewebstore.google.com/detail/replace-with-unlisted-id
CLIPMESH_DATABASE_URL=sqlite:///var/lib/clipmesh/clipmesh.db
CLIPMESH_BLOB_DIR=/var/lib/clipmesh/blobs
CLIPMESH_MAX_FILE_BYTES=2GiB
CLIPMESH_FILE_RETENTION=7d
CLIPMESH_FILE_STORAGE_QUOTA=50GiB
CLIPMESH_FILE_CHANNEL_QUOTA=10GiB
CLIPMESH_INCOMPLETE_UPLOAD_RETENTION=1h
RUST_LOG=clipmesh_server=info

Create the bind-mount directory for the container's UID 10001 and start it:

mkdir -p data
sudo chown 10001 data
docker compose up -d
docker compose logs -f clipmesh

For a public deployment, change CLIPMESH_PUBLIC_URL to the HTTPS URL served by your reverse proxy. No registry login is required. See the deployment guide for backups, upgrades, quotas, and reverse-proxy examples.

Native client

Build and launch the native client with:

cargo run -p clipmesh-client

Running clipmesh with no arguments starts the foreground TUI and owns clipboard synchronization for that session. Pair from the TUI with p, or use the scriptable command:

clipmesh pair --server https://clipmesh.example.com --name "Workstation"
clipmesh channel list
clipmesh channel create --name Personal
clipmesh route CHANNEL_ID --send=true --receive=true
clipmesh send-file ./report.pdf
tar cz ./project | clipmesh send-file --filename project.tar.gz --media-type application/gzip

Background sync is opt-in and uses the current user's native service manager:

clipmesh service install
clipmesh service start
clipmesh service status
clipmesh service stop

Stop the service before opening the foreground TUI. Device tokens, signing keys, channel secrets, and the local outbox key are stored in Windows Credential Manager, macOS Keychain, or Linux Secret Service. Linux clipboard support uses Wayland's data-control protocol when available and X11/XWayland otherwise.

Files are encrypted locally in independently authenticated 4 MiB chunks, uploaded to the server, and announced only after finalization. Receiving devices get a small encrypted manifest and download file content only when requested. Use the browser Download button or:

clipmesh history list
clipmesh history export LOCAL_ID --output ~/Downloads/

The server defaults to a 2 GiB maximum file, seven-day retention, 50 GiB instance quota, and 10 GiB per-channel quota. All are configurable; quota exhaustion rejects new files rather than deleting unexpired transfers.

Repository map

  • server/: Axum API, WebSocket relay, SQLite migrations, embedded onboarding assets, and encrypted clipboard/file retention.
  • client/: Rust foreground TUI, headless sync engine, CLI administration, native clipboard adapters, local encrypted history, and user-service installers.
  • crates/clipmesh-protocol/: Shared protocol v1 crypto, wire DTOs, clipboard encodings, and routing invariants.
  • extension/: Chrome MV3 extension with browser adapters, offscreen clipboard access, Argon2id/AES-GCM protocol, routing, local outbox/history, popup, and full page.
  • protocol/: Frozen binary encodings, WebSocket behavior, and OpenAPI 3.1 contract.
  • deploy/: Container, Compose/Caddy, and systemd deployment examples.
  • docs/: Operations, testing, privacy, and release guidance.

No channel password, channel root key, membership private key, device token, pairing code, WebSocket ticket, clipboard plaintext, filename, or file media type is intentionally logged. Local history stores authenticated ciphertext; previews and files are decrypted only when requested.

See implementation status, deployment, testing, security reporting, and Chrome Web Store release for verification and release workflows.

License

ClipMesh is available under the MIT License.

About

Cross-platform clipboard synchronization, with browser extension or CLI.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages