@ewanc26/malachite
v0.19.7
Published
Import your music listening history to AT Protocol from Last.fm, Spotify, Apple Music, YouTube Music, or ListenBrainz, with deduplication and rate limiting
Downloads
519
Maintainers
Readme
malachite
Import your music listening history to AT Protocol as fm.teal.feed.play records, from Last.fm, Spotify, Apple Music, YouTube Music, or ListenBrainz. Web interface at malachite.croft.click.
Full documentation at docs.ewancroft.uk.
Deduplication & sync guarantees
Malachite treats two play records as the same listen using a single shared key
(@ewanc26/croft-click-core): the normalized artist, normalized track,
and a canonical timestamp. Normalization is case-insensitive,
punctuation-insensitive, and applies Unicode NFKC equivalence first, so
Dagames/DAGames, jack stauber's/jack stauber's (curly vs straight
apostrophe), and Bru-C/Bru-C (non-breaking vs regular hyphen) all collapse
onto one key without rewriting the casing of the stored record.
Timestamps are parsed and re-emitted as canonical ISO 8601, so the same instant
scrobbled as 2026-07-17T11:39:14Z and 2026-07-17T11:39:14.000Z hashes to one
record key and publishes a byte-identical playedTime.
Beyond exact keys, the sync and cleanup paths also fold together records that
share artist + track within a ±60 second window — the conservative
"cross-source overlap / double-fire" tolerance (a deliberate replay of a short
track after the window is preserved as a real listen). This window is
configurable via the windowMs/--dedup-window option.
The historical deduplicate mode (--mode deduplicate) is dry-run first:
it fetches your repo via CAR, builds a reviewable plan that keeps the richest
copy of each duplicate cluster (MusicBrainz IDs, ISRC, duration preferred) and
marks the rest for deletion, then prompts for confirmation before deleting
anything with com.atproto.repo.deleteRecord.
Related projects
Part of the croft.click toolkit — free, browser-based tools for moving your data onto the AT Protocol:
- Opal — Convert Twitter, Mastodon, Threads, and Nostr posts to Bluesky.
- Jasper — Import Instagram photos, stories, and videos to Grain or Spark.
- Bismuth — Convert ATProto richtext-block documents to Markdown.
- Tourmaline — Analyse your Teal.fm scrobbles and find your listener archetype.
Support
This is free and open source, built and maintained in my spare time. If it's useful to you, a one-off tip on Ko-fi or a monthly sponsorship helps keep it maintained. A star on the repo or a mention to someone who'd use it helps just as much.
Trademark
“AT Protocol”, “atproto”, and “atprotocol” are trademarks of Bluesky Social PBC. This project is independent and is not affiliated with or endorsed by Bluesky Social PBC; the terms are used only to describe compatibility. See the AT Protocol trademark policy and this repository's TRADEMARKS.md.
Licence
AGPL-3.0-only.
