Repository navigation
Releases
v2.1.0
Migrate a whole Microsoft 365 tenant from one screen, connected in two clicks, and clean up duplicates afterwards.
✨ Highlights
- Microsoft 365 tenant migration. Add a tenant once in Settings, Servers, then pick its mailboxes on one screen, side by side with the target mailboxes. Each mailbox shows its state (ready, linked, missing on the target, conflict…) and what will be carried: mail, calendar, contacts, tasks. Start a batch and run the final resync from the same screen. Mailboxes are linked by Entra object ID, so the final resync still works after the domain has left the tenant.
- Connect with Microsoft. A Global Administrator signs in with a device code. mccb then creates the "mccb migration" application in the client tenant, grants admin consent, adds a one-year secret and tests the tenant. You no longer register an app by hand (that option is still there). Self-hosters can use their own bootstrap app with
M365_BOOTSTRAP_CLIENT_ID. - Choose the destination by hand. On the tenant screen, send a mailbox to another account of the target server, or to a new one typed with its password.
- Duplicates tab. Finds duplicate messages, events and contacts folder by folder, using strict criteria. The analysis only reads; removal is permanent, needs a confirmation and always keeps one copy of each group. See Remove duplicates.
- Calendars keep their shape on CalDAV and CardDAV. Each source calendar, address book and task list goes to its own collection, found by name or created; the default one goes to the default collection. Read-only calendars that Outlook or Google generate (holidays, birthdays) are skipped.
🛠️ Fixed
- The final resync from Microsoft 365 no longer fails with HTTP 400 "Parsing OData Select and Expand failed", including the first resync after a full copy.
- Events written to MDaemon are found by the final check.
- A collection the server lists but refuses to open is reported clearly, instead of being "created" again as "PST Import".
- A folder that could not be created now ends the job as done with errors.
- The copy button works inside dialogs and over plain HTTP. The server test no longer reports DAV as working when it is disabled, and offers to enable it.
⬆️ Upgrading
The project moved to the selfhostr organisation. In your docker-compose.yml, change ghcr.io/yetysw/mccb to ghcr.io/selfhostr/mccb, back up ./data, then run docker compose pull && docker compose up -d. The database is upgraded automatically. Details: upgrade guide.
🐳 Get it
docker pull ghcr.io/selfhostr/mccb:2.1.0Full changelog: v2.0.0...v2.1.0
v2.0.0
Migrate mail, calendars and contacts between almost any source and target, plan it, script it, and repair what other tools broke.
✨ Highlights
- Repair tab. Analyse a list of mailboxes read-only, then repair the damage other migration tools leave (accents replaced by U+FFFD, mojibake, nameless attachments, detached signature images). Each message is verified before it is written; originals are kept and can be restored.
- Exchange in both directions.
exchange_ewsfor Exchange on premises andm365_graphfor Exchange Online, with mail, calendar, contacts and tasks. Impersonation, app-only and master-user access cover many mailboxes with one credential. Tested against simulated servers, not real Exchange. - More sources and targets. JMAP, Google (Gmail, Calendar, People), CalDAV and CardDAV, plus files: mbox, Maildir,
.eml,.msg,.ics,.vcfand zip. - Planning and control. Dry run, folder mapping in nine languages, per-server and per-account policies, allowed hours, bandwidth limits, named batches, final resync and source/target comparison.
- Command line and API tokens. The
mccbCLI uploads with resume, runs, watches and plans migrations. - Server-side intake. Drop folder, or fetch over HTTP(S), SFTP or S3, with notifications by ntfy, webhook or e-mail.
- New web interface. Side panel for job details, live updates that change only what moved, explicit selection, dark and light themes, nine languages, and a static demo.
- Scales further. Auto mode uses up to 32 mailboxes at once, and recovers from network errors and server overload instead of throttling for good.
⬆️ Upgrading from 1.x
Back up ./data, then docker compose pull && docker compose up -d. Remove the WORKER_CONCURRENCY line from an existing .env to get auto mode. Old links redirect to the new interface, old three-column mailbox CSV files are still read, and API routes and the mccb accounts command keep their names. CSV downloads are now mailboxes.csv and mailboxes-export.csv; upload chunk PUT no longer returns the received list (use received_count in the upload event). Details in the upgrade guide and the changelog.
🐳 Get it
docker pull ghcr.io/selfhostr/mccb:2.0.0Installation guide: https://github.com/selfhostr/mccb/blob/main/docs/install.md
Moved: the project now lives at github.com/selfhostr/mccb and the image at
ghcr.io/selfhostr/mccb. Existing installs should switchghcr.io/yetysw/mccbtoghcr.io/selfhostr/mccbindocker-compose.yml.
📦 Dependencies
cryptography 50.0.0, python-multipart 0.0.31; tests on pytest 9.0.3.
Full changelog: v1.1.2...v2.0.0
v1.1.2
Changes
- The product is now MCCB (Mail Contact Calendrier Bridge): tab title, sidebar, login screen, logs, image title and the PRODID of exported vCards and events.
- README and documentation restructured per the yety guidelines: pages in
docs/, CONTRIBUTING, SECURITY, CODE_OF_CONDUCT, issue templates.
Upgrade
docker compose pull && docker compose up -dThe session cookie is renamed: everyone signs in again once after the upgrade. No data migration.
v1.1.1
- Mail order and IMAP INTERNALDATE now share one date rule (Date header only if plausible and timezone-aware, else MAPI submit/delivery/creation/modification time), so newest-first order matches INTERNALDATE.
- Finished jobs show average items/s and MB/s.
- Docs refreshed; added CHANGELOG.
Upgrade: docker compose pull && docker compose up -d
🤖 Generated with Claude Code
v1.1.0
What's new
- Faster: messages are built in parallel worker processes, about 2–6× faster.
- Newest first: mail is imported newest-first across all folders, and so are calendar and contacts.
- Auto-tuning of builder processes and IMAP connections, with a manual override per server.
- Version shown in the UI.
- MB/s rate and a size-based ETA.
- Quieter cid warnings.
Upgrade
- Pause running jobs.
docker compose pull && docker compose up -d- Resume the jobs. Already-imported messages are not duplicated.
Servers created with the default settings switch to Auto tuning. Servers with custom values stay Manual; you can switch them in Servers.
v1.0.0
Features
- Migrate PST/OST to IMAP mail, CalDAV calendars and CardDAV contacts
- Web dashboard
- Resumable uploads, built for 50 GB+ PSTs
- Every message verified
- Pause, resume and retry without duplicates
- Multilingual charset handling
- Auto-generated admin password on first start
Quick start
mkdir mccb && cd mccb
curl -fsSLO https://raw.githubusercontent.com/yetysw/mccb/main/docker-compose.yml
docker compose up -d
docker compose logs web | grep -A2 "Admin password"Open http://HOST:22362 and sign in with the printed password.
Image: ghcr.io/yetysw/mccb:1.0.0 (also :1.0, :latest).
Known limitations
- Single administrator, SQLite on a local disk: one host, no high availability.
- UI is in French only.
- A corrupted PST can crash libpff; affected items are skipped and reported.