The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Serato DJ library listing page.
Ask Claude about your Serato DJ library: find tracks that mix harmonically by BPM and Camelot key, browse your crates, audit the library for duplicates and missing files, and have new crates built for you, shown to you before anything is written. It works through the Model Context Protocol (MCP), the standard way AI apps such as Claude Desktop, Claude Code, Cursor and VS Code connect to tools on your computer: this is a small local server that answers from your library and sends nothing anywhere itself.
Status: experimental. Pre-1.0 and actively developed: a minor version may change behaviour or break compatibility, a patch never does.
[!IMPORTANT] Not affiliated with, endorsed by, or supported by Serato. Serato and Serato DJ are trademarks of their respective owner. This project reads a reverse-engineered database layout and can stop working after any Serato update.
Once the server is connected, you talk to your assistant as usual:
With crate writing switched on:
The assistant does the searching; the server answers from your library and, when asked, writes only what you approved.
Works on macOS. Tested with Serato DJ Lite 4.0.9 on macOS; the test suite runs in CI on macOS and Linux with Node.js 22.16 and 24. Windows is untested — see Compatibility. The Claude Desktop extension and the Claude Code setup below were tried by hand on macOS; the Cursor and VS Code setups follow those editors' documentation and have not been tried.
Every setup starts the server read-only. Crate writing is a separate switch, described below.
As an extension (no Node.js needed). Download serato-dj-mcp-<version>.mcpb from the
latest release (attached
from version 0.1.1 on) and open it; Claude Desktop shows what it contains and installs it. Its
settings let you point it at a library folder and switch on crate writing or raw SQL; all three
can stay as they are.
Or by hand, with Node.js 22.16 or newer installed: open Settings →
Developer → Edit Config and add the server to claude_desktop_config.json, then restart Claude
Desktop.
Add --scope user before serato to have it in every project. The repository is also a Claude
Code plugin that starts the same command.
Add to Cursor,
or add the same mcpServers entry as for Claude Desktop to ~/.cursor/mcp.json. The link opens
cursor://anysphere.cursor-deeplink/mcp/install?name=serato&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInNlcmF0by1kai1tY3AiXX0=,
which asks Cursor to add {"command":"npx","args":["-y","serato-dj-mcp"]} under the name serato.
Install in VS Code, or from a terminal:
Add options after serato-dj-mcp in args, for example
"args": ["-y", "serato-dj-mcp", "--allow-writes"]:
--library <path> — the Serato library folder (the one holding master.sqlite). Not needed on
macOS, where the library in ~/Library/Application Support/Serato and on mounted drives is
found automatically.--allow-writes — crate writing, see below.--allow-raw-sql — adds run_sql, read-only SQL for developers.All options are listed under Options.
node:sqlite is an experimental Node API and prints a warning to stderr; that is expected and
harmless, because the MCP protocol travels over stdout.
Then use "command": "node" with "args": ["/absolute/path/to/serato-dj-mcp/dist/index.js"], or
claude mcp add serato -- node /absolute/path/to/serato-dj-mcp/dist/index.js.
What the server reads, writes and sends is in PRIVACY.md: it makes no network requests and has no telemetry.
| Serato DJ 4.x | Supported. Developed and tested against Serato DJ Lite 4.0.9 (library schema 202). Other 4.x schema versions are read with a schema_unknown warning. Serato DJ Pro 4.x is expected to use the same library format but has not been tested. |
| Serato DJ 3.x | Detected and reported, not read (it keeps a binary database V2 instead of SQLite). |
| macOS | Supported. This is where the project is developed, and CI runs on it. |
| Windows | Untested. The server has no Windows-specific handling: pass --library explicitly, because automatic discovery only knows the macOS layout, and expect macOS-style cache and state directories under your user folder. The "is Serato running" check uses ps, which Windows does not have, so apply_changes may refuse to write rather than guess. |
| Linux | Serato does not run on Linux; the test suite runs there in CI on synthetic fixtures. |
| Node.js | 22.16 or newer, because backup() from node:sqlite lands there. Not assumed: CI runs the whole suite on 22.16 and on 24, on macOS and on Ubuntu. |
| Claude Desktop extension | Runs in Claude Desktop's own Node.js, not yours. Checked by hand on 2026-09-24 with Claude Desktop 2.7032.0 on macOS, whose built-in Node.js is 24.21: installed, then list_libraries and list_crates answered with the library's data. |
Everything this server assumes about the Serato library is written down in docs/serato-4x-notes.md, with the measurement behind each claim.
By default the server never writes to Serato's files. Every read goes through a snapshot
copy of the library database in --cache-dir, so a question from the assistant cannot change your
library, whether Serato is open or not.
Two flags widen that, and each registers extra tools only when it is given — a tool that does not exist cannot be called by mistake:
--allow-raw-sql adds run_sql: read-only SELECT against the snapshot, returning raw rows.--allow-writes adds stage_crate, preview_changes, apply_changes and discard_changes.
Writing is split in two: crates are staged first, which never touches the library, and are
applied only when you confirm and Serato is closed. Both databases are backed up before every
write. The details are in Writing to the library.list_libraries — the libraries this server can see, with version, schema
version and locations. Paths here are not redacted, so you can copy one into
--library.search_tracks — search by free text, BPM, key, genre, rating, date added, crate
membership and flags. Tonality is Camelot; a track whose key Serato itself could not
parse is still matched, and key_source says where the key came from. Paginated with an
opaque cursor; the default page is 25 tracks and nine fields.get_tracks — fetch tracks by the ids search_tracks returned. Unknown ids come back in
missing rather than being dropped.list_crates — the crates in the Serato Library space, with their display path and how many
distinct tracks each holds. Smart crates, space roots and Serato's other internal spaces
(such as the Prepare panel) are not listed.get_crate_tracks — the tracks of one crate, in the crate's own order. Only crates in the
Serato Library space can be given.audit_library — diagnose the library. Every check runs by default and reports a count plus
up to ten example track ids: tracks with no BPM, with no key at all, with a key Serato itself
cannot display, marked stale, in no crate, streaming-only, duplicated, and with broken paths.
duplicates reports groups instead of loose ids, because which track duplicates which is the
part you can act on. broken_paths reads Serato's own missing flag by default; pass
check_filesystem: true to also look on disk, which is opt-in because a stat against a
disconnected drive blocks for seconds. A drive that is not mounted is reported as such rather
than having all its tracks declared missing.run_sql — one read-only SELECT against a snapshot copy. Registered only
with --allow-raw-sql, because it returns raw rows with no path redaction.With --allow-writes:
stage_crate — stage a new crate from track ids. Nothing is written yet; the response lists
every staged track by title and artist, so check it.preview_changes — show what is staged, with format: "detail" down to each track.apply_changes — write everything staged, all or nothing. Refused while Serato is running.discard_changes — drop one staged crate, or all of them.--library <path>, --root <dir> (repeatable), --cache-dir <dir>,
--state-dir <dir>, --allow-raw-sql, --allow-writes, --help,
--version. SERATO_LIBRARY_PATH is an alternative to --library;
the flag wins. An unknown option is an error, not a no-op.
Writes need --allow-writes and happen in two steps, because Serato must be closed while its
database is written and the model usually works while it is open. stage_crate can run at any
time; apply_changes refuses while Serato is running. Start Serato afterwards and the new crates
appear within a few seconds.
What a write does: it creates new crates at the top level of the Serato Library, in
root.sqlite, and nothing else. It never changes or deletes an existing crate, never edits a
track, never touches master.sqlite, database V2 or the Subcrates folder — Serato regenerates
those itself.
Before every write both databases are backed up under
<state-dir>/backups/<library-id>/<timestamp>/ (default state-dir:
~/Library/Application Support/serato-dj-mcp), and the last ten are kept. A backup is taken on
every apply_changes attempt that reaches the backup step, including attempts that are then
refused inside the transaction (a name conflict, for example) — so "the last ten" means the last
ten attempts, not ten successful writes, and the newest one may already contain the write you
are trying to undo.
There is no undo tool. To undo a specific write, first find the right backup: use the
backup_paths returned by that apply_changes call, or open
<state-dir>/manifests/<library-id>.jsonl and take the backup_paths of the line whose
"commit_state" is "committed". <library-id> is the uuid reported by list_libraries. Then,
with that pair of paths in hand:
root.sqlite-journal if present, and delete
master.sqlite-wal and master.sqlite-shm.root.sqlite and master.sqlite into the library folder, replacing the
current ones.~/Music/_Serato_/Subcrates/<crate name>.crate — Serato exported it after it synced
the crate, and copying the databases back does not remove it.Restoring these files also rolls back anything Serato itself recorded in the library after that backup was taken.
Nested crates are not supported: a crate created this way inside another crate is deleted by Serato when it next syncs, so every crate goes to the top level.
The same, as a standalone policy with the source file behind each statement: PRIVACY.md.
ps, to check whether Serato is running before a write.apply_changes;
with audit_library's check_filesystem: true, the file metadata of your tracks on disk.--cache-dir (default ~/Library/Caches/serato-dj-mcp) holds a snapshot copy of your library
database. Safe to delete at any time.--state-dir (default ~/Library/Application Support/serato-dj-mcp) holds staged crates, a
manifest of every write, lock files, and backups of your library databases. Only used with
--allow-writes. Deleting it deletes those backups.--allow-writes, apply_changes writes new crates into Serato's root.sqlite.~; list_libraries,
run_sql and the backup paths returned by apply_changes are full paths. Check your client's
data policy if that matters to you.Read this before deciding what to trust.
version: "3.x", but nothing reads it — it stores a binary database V2
rather than SQLite. No tool will return data from a 3.x library.--cache-dir; older ones
are deleted as soon as a newer one is published.stale reads
is_stale and streaming_only reads third_party_type; both were zero on every track of the
reference library, so their counts are reported without any claim about what they mean.rating and the streaming flag are passed through uninterpreted. rating was NULL or 0 on
all 118 tracks of the reference library, so the top of the scale is unconfirmed. No meaning
beyond the raw column value is claimed for the streaming flag.analysis_flags bit 2 is claimed, though the rest of the field is not.
It is read as "Serato ran its own analysis" — not the same as "has a BPM",
since a BPM can come from the file's tags — and exposed as
flags.analyzed, which search_tracks can filter on. Measured 2026-09-06
on 118 tracks: 106 have bit 2 set, of which 104 have a BPM; twelve have it
clear — six sound effects and six tracks whose BPM came from tags rather
than Serato's own analysis.q matches both the normalised columns and the raw ones and can
differ from what the application would find.warnings: snapshot_advanced; a few rows may be repeated or skipped at the seam.apply_changes creates new top-level crates and nothing
else: no nested crates, no smart crates, no renaming, reordering or deleting crates, no edits
to tracks, cue points or other metadata.stage_crate, naming each one.stage_crate reads root.sqlite while Serato may be
running. Measured on 2026-09-16: three stagings of 50 tracks each, 8 to 41 ms apiece, with
nothing in Serato's own log for those seconds. That is evidence, not a guarantee — a busier
library, or a Serato in the middle of its own write, has not been tried.What this server guarantees about your library, and what it refuses to do, is stated in PRINCIPLES.md — each guarantee with the code that enforces it and the tests that would fail if it stopped being true.
Please report vulnerabilities privately — see SECURITY.md. Do not open a public issue for them.
Issues and pull requests are welcome; start with CONTRIBUTING.md. Changes are recorded in CHANGELOG.md.
MIT. Maintained by Venut Technologies.
Serato and Serato DJ are trademarks of their respective owner. This project is independent and is not affiliated with, endorsed by, or supported by Serato.