serato-dj-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@serato-dj-mcpFind tracks in 8A or 9A between 122 and 126 BPM."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
serato-dj-mcp
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.
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.
What you can ask
Once the server is connected, you talk to your assistant as usual:
"Find tracks between 122 and 126 BPM in 8A or 9A that I added this year."
"Give me tracks that mix harmonically out of 8A, around 124 BPM."
"Show me what's in my Warm Up crate, in order."
"Audit my library: duplicates, missing files, tracks that aren't in any crate."
"Which tracks in my library have no BPM or no key?"
With crate writing switched on:
"Build a crate called Friday Opening from the twenty tracks you just found, and show me the list before writing anything." Then, once you have closed Serato: "Apply the staged crate."
The assistant does the searching; the server answers from your library and, when asked, writes only what you approved.
Related MCP server: lexicon-mcp
Install
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.
Claude Desktop
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.
{
"mcpServers": {
"serato": {
"command": "npx",
"args": ["-y", "serato-dj-mcp"]
}
}
}Claude Code
claude mcp add serato -- npx -y serato-dj-mcpAdd --scope user before serato to have it in every project. The repository is also a Claude
Code plugin that starts the same command.
Cursor
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.
VS Code
Install in VS Code, or from a terminal:
code --add-mcp '{"name":"serato","type":"stdio","command":"npx","args":["-y","serato-dj-mcp"]}'Options for any client
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 holdingmaster.sqlite). Not needed on macOS, where the library in~/Library/Application Support/Seratoand on mounted drives is found automatically.--allow-writes— crate writing, see below.--allow-raw-sql— addsrun_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.
From source, for developers
git clone https://github.com/Venut-Technologies/serato-dj-mcp.git
cd serato-dj-mcp
npm ci
npm run buildThen 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.
Compatibility
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 |
Serato DJ 3.x | Detected and reported, not read (it keeps a binary |
macOS | Supported. This is where the project is developed, and CI runs on it. |
Windows | Untested. The server has no Windows-specific handling: pass |
Linux | Serato does not run on Linux; the test suite runs there in CI on synthetic fixtures. |
Node.js | 22.16 or newer, because |
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 |
Everything this server assumes about the Serato library is written down in docs/serato-4x-notes.md, with the measurement behind each claim.
Read-only by default, writes on request
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-sqladdsrun_sql: read-onlySELECTagainst the snapshot, returning raw rows.--allow-writesaddsstage_crate,preview_changes,apply_changesanddiscard_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.
Tools
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, andkey_sourcesays 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 idssearch_tracksreturned. Unknown ids come back inmissingrather 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.duplicatesreports groups instead of loose ids, because which track duplicates which is the part you can act on.broken_pathsreads Serato's own missing flag by default; passcheck_filesystem: trueto 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-onlySELECTagainst 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, withformat: "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.
Options
--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.
Writing to the library
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:
Quit Serato.
In the library folder, delete
root.sqlite-journalif present, and deletemaster.sqlite-walandmaster.sqlite-shm.Copy the backed-up
root.sqliteandmaster.sqliteinto the library folder, replacing the current ones.Delete
~/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.
Privacy
The same, as a standalone policy with the source file behind each statement: PRIVACY.md.
Everything runs on your computer. The server is a local process your MCP client starts. It sends no telemetry, has no analytics, and makes no network requests. The only other program it runs is
ps, to check whether Serato is running before a write.What it reads: Serato's library databases, always read-only except for
apply_changes; withaudit_library'scheck_filesystem: true, the file metadata of your tracks on disk.What it writes, and where:
--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.With
--allow-writes,apply_changeswrites new crates into Serato'sroot.sqlite.
What leaves your computer is up to your MCP client. Tool results — track titles, artists, crate names, file paths — go to your assistant, and from there to whichever model provider the client uses. Track paths under your home folder are shortened to
~;list_libraries,run_sqland the backup paths returned byapply_changesare full paths. Check your client's data policy if that matters to you.
Limitations
Read this before deciding what to trust.
Serato DJ 3.x is not supported. It is recognised and reported as
version: "3.x", but nothing reads it — it stores a binarydatabase V2rather than SQLite. No tool will return data from a 3.x library.Reads go through a snapshot, so an answer reflects the library as of the last snapshot, not the current instant. A snapshot is reused for up to two seconds, so while Serato is writing an answer can be that far behind. Only the current snapshot of each library is kept in
--cache-dir; older ones are deleted as soon as a newer one is published.Two audit checks rest on column semantics this project has not confirmed.
stalereadsis_staleandstreaming_onlyreadsthird_party_type; both were zero on every track of the reference library, so their counts are reported without any claim about what they mean.ratingand the streaming flag are passed through uninterpreted.ratingwas 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_flagsbit 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 asflags.analyzed, whichsearch_trackscan 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.Free-text search is not Serato's search. Serato normalises text with a function only its own process has, so
qmatches both the normalised columns and the raw ones and can differ from what the application would find.A page taken while Serato is writing can straddle two snapshots. Pagination is keyset, so it continues from the same position on the newer copy and says so in
warnings: snapshot_advanced; a few rows may be repeated or skipped at the seam.Crate writing is new and experimental. The write protocol was worked out against a live Serato DJ Lite 4.0.9 library, but it has not been exercised across Serato updates, on large libraries, or on libraries spread over external drives. Keep your own backups as well.
Writes are narrow on purpose.
apply_changescreates 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.A crate can only hold tracks from the library's own disk. Streaming tracks, and tracks that live in another drive's Serato store, are refused by
stage_crate, naming each one.Serato must be closed to apply, and restarted to see the result. New crates show up in Serato, and in this server's read tools, only after Serato has started and synced.
Staging reads Serato's live database.
stage_cratereadsroot.sqlitewhile 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.There is no undo tool. Undoing a write means restoring the backups by hand, as described above.
Principles
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.
Security
Please report vulnerabilities privately — see SECURITY.md. Do not open a public issue for them.
Contributing
Issues and pull requests are welcome; start with CONTRIBUTING.md. Changes are recorded in CHANGELOG.md.
License
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.
Available Tools
6 toolsaudit_libraryAudit the Serato libraryARead-onlyIdempotent
Diagnose the library. All checks run by default: missing_bpm, missing_key, key_unreadable_by_serato, stale, not_in_any_crate, streaming_only, duplicates, broken_paths. broken_paths reads Serato's own missing flag by default and ALSO walks the filesystem with check_filesystem: true -- opt-in because a stat against a disconnected drive blocks for seconds. Each check reports a count and up to 10 example track ids; duplicates reports groups instead, since which track duplicates which is the actionable part. missing_key counts tracks with no key at all, while key_unreadable_by_serato counts tracks whose key this server can read but Serato itself cannot display.
| Name | Required | Description | Default |
|---|---|---|---|
| checks | No | ||
| check_filesystem | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| checks | Yes | |
| warnings | No | |
| generation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations, the description discloses default behavior, per-check output shape, the special duplicates grouping, and the subtle distinction between missing_key and key_unreadable_by_serato. It also explains the filesystem-walk performance caveat.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: scope, defaults, the opt-in flag with rationale, output format, and an important distinction between two similar checks. It is dense but well-organized and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool does, what each check means, how the optional flag behaves, output structure, and safety profile via annotations. Even with an output schema present, this description leaves nothing material missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description fully compensates by naming every valid check value, explaining that checks are optional via 'all checks run by default', and describing what check_filesystem: true actually does. This adds meaning the raw schema lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Diagnose the library' and then enumerates the eight concrete checks, giving a precise verb-resource-scope statement. This clearly differentiates it from sibling tools that list, search, or fetch tracks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explains that all checks run by default and that the filesystem walk is opt-in due to a real blocking risk on disconnected drives. It does not explicitly name sibling alternatives, but the diagnostic-vs-access distinction is clear enough from context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_crate_tracksGet the tracks of a crateARead-onlyIdempotent
List the tracks of one crate, in the crate's own order -- the order the DJ arranged, not the order they were added to the library. Only crates in the Serato Library space can be given. Give the crate by id or by exact name; an unknown name comes back with the list of names that exist. Default fields: id, artist, title, bpm, key, key_source, genre, rating, length. Paths are redacted to ~.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| cursor | No | ||
| fields | No | ||
| crate_id | No | ||
| crate_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| crate | Yes | |
| tracks | Yes | |
| warnings | No | |
| generation | Yes | |
| next_cursor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral details: the ordering (DJ-arranged vs library-added), path redaction to ~, default fields, and unknown-name error behavior. These go beyond the annotations and help an agent anticipate response characteristics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. It front-loads the core purpose and ordering, then adds constraints, input methods, defaults, and redaction in a logical sequence. Every sentence adds value with no fluff. It is easy to read and digest.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 5 parameters and an output schema, the description covers identification, default fields, redaction, and error behavior. It does not mention pagination (limit/cursor) behavior, which is relevant for large crates, but the output schema and annotations provide additional context. Overall it is almost complete, missing only pagination details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It explains crate_id and crate_name (by id or exact name) and implies the fields parameter via default fields. However, it does not explain the limit and cursor parameters, which are pagination controls. It provides partial parameter semantics but leaves out important ones, so it does not fully compensate for the low coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a specific resource ('the tracks of one crate'), and a distinguishing feature (the crate's own order, not addition order). It also clarifies scope ('Only crates in the Serato Library space') and input methods (id or exact name), making it unmistakable what the tool does and how it differs from siblings like list_crates or search_tracks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear guidance on how to specify the crate (by id or exact name) and what happens on an unknown name (returns list of names). It states a constraint (Serato Library space). However, it does not explicitly mention alternatives or when to prefer this over sibling tools like get_tracks or search_tracks, though the scope is implicit from the name and wording.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tracksGet Serato tracks by idARead-onlyIdempotent
Fetch tracks by the ids search_tracks returned. Unknown ids come back in missing rather than being dropped silently, and found is in the order the ids were given. Default fields: id, artist, title, bpm, key, key_source, genre, rating, length. Paths are redacted to ~.
| Name | Required | Description | Default |
|---|---|---|---|
| ids | Yes | ||
| fields | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| found | Yes | |
| missing | Yes | |
| warnings | No | |
| generation | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover readonly, idempotent, and non-destructive behavior. The description adds significant extra context: unknown ids are returned in 'missing' rather than silently dropped, 'found' preserves input order, default fields are listed, and paths are redacted. These details go well beyond annotations and help an agent anticipate responses.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences, each adding distinct value: the action, the error-handling/ordering details, and the default-field/redaction note. The main action is front-loaded, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The output schema covers return structure; the description fills in everything an agent needs: error handling (missing), ordering, default fields, and redaction. Given the tool's simplicity (fetch by ids) and annotations, nothing is missing for a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema coverage, the description compensates by explaining that ids come from search_tracks and listing default fields, which implies the 'fields' parameter overrides defaults. It doesn't explicitly name the parameters but provides enough semantic intent for both ids and fields.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action ('Fetch tracks') and resource ('tracks'), and specifies the source of ids ('search_tracks returned'). This distinguishes it clearly from siblings like search_tracks (which searches) and get_crate_tracks (which targets a crate). The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It indicates this is the follow-up to search_tracks by saying 'ids search_tracks returned', but does not explicitly name alternatives or state when not to use this tool. The context is clear, though it could be more explicit about differentiating from search-driven workflows.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_cratesList Serato cratesARead-onlyIdempotent
List the crates in the Serato Library space, with their display path and how many distinct tracks each holds. Only crates in that space are listed: smart crates, space roots and Serato's other internal spaces (such as the Prepare panel) are excluded.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| cursor | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| crates | Yes | |
| warnings | No | |
| generation | Yes | |
| next_cursor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, destructiveHint, and idempotentHint, so the safety profile is covered. The description adds value beyond these by revealing the exact output content (display path and distinct track count) and the filtering rule (exclusion of smart crates and internal spaces). It does not contradict annotations and gives concrete behavioral expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, no filler. The core function and output detail are front-loaded, followed by the scope exclusion. Every clause contributes meaning; there is no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a paginated list tool, the description covers the key aspects: what is returned, what is excluded, and the space it operates in. Pagination behavior is not described, but the output schema exists and the limit/cursor parameters are enough for a capable agent to infer. The description is adequate, though a brief note on pagination would have made it fully self-sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate for parameter meanings. It does not mention `limit` or `cursor` at all, nor does it explain that the tool is paginated. An agent would have to infer pagination behavior from the schema alone, which is a substantial gap given the tool's listing purpose.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List'), a precise resource ('crates in the Serato Library space'), and the output detail (display path and track count). It also distinguishes itself from siblings by explicitly excluding smart crates and internal spaces, so an agent can differentiate it from get_crate_tracks or audit_library without opening their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clarifies what is and isn't included ('Only crates in that space... excluded'), which is useful context. However, it never explicitly states when to prefer this tool over the sibling tools (e.g., 'use get_crate_tracks to inspect tracks within a crate'). Usage timing is implied by the resource named but not contrasted with alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_librariesList Serato librariesARead-onlyIdempotent
List the Serato libraries this server can see, with their version, schema and locations. Paths here are NOT redacted: copy one into --library to pin the server to it.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| active | Yes | |
| warnings | No | |
| libraries | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, so safety profile is known. The description adds valuable behavioral context: paths are not redacted, and it lists only libraries 'this server can see,' which scopes the output. These go beyond what annotations state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no fluff. The main purpose is front-loaded, followed by a critical usage warning. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, the description need not explain return format. It covers what the tool does, the non-redaction caveat, and how to use the output. Nothing missing for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Tool has zero parameters, so schema coverage is trivially 100%. Description adds no parameter details, but none are needed. Baseline of 4 applies due to no parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (List), the resource (Serato libraries), and the specific details returned (version, schema, locations). It distinguishes itself from sibling tools like list_crates and get_tracks by focusing on library discovery. No ambiguity about what it does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides a concrete usage instruction: copy a path into --library to pin the server. This implicitly tells when to use it (to discover and select a library) without explicitly listing alternatives. Lacks explicit 'when not to use' but the context is clear given siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tracksSearch Serato tracksARead-onlyIdempotent
Search the Serato library. Free text q matches every whitespace-separated token against title, artist, album, genre and comments. Tonality is Camelot (8A); tracks whose key Serato itself could not parse are included, and key_source says where each key came from. bpm.around cannot be combined with bpm.min/bpm.max. key.compatible_with expands to the four mixable cells of the wheel. rating is a 0 to 1 scale, not 0 to 5 stars. Sort is one of bpm, added, artist, title, rating, relevance with an optional :asc/:desc; relevance needs a q. Default fields: id, artist, title, bpm, key, key_source, genre, rating, length. Paths are redacted to ~.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | ||
| bpm | No | ||
| key | No | ||
| sort | No | ||
| added | No | ||
| crate | No | ||
| flags | No | ||
| genre | No | ||
| limit | No | ||
| cursor | No | ||
| fields | No | ||
| rating | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| tracks | Yes | |
| warnings | No | |
| generation | Yes | |
| next_cursor | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses several important behaviors beyond the annotations: tracks with unparsed keys are included and key_source indicates origin, paths are redacted to ~, and rating is 0-1 not 0-5. These add meaningful context to the read-only/idempotent hints and help set expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a dense but efficient paragraph. Each sentence adds a distinct piece of information, and it front-loads the core purpose. It is not overly verbose for a tool with 12 parameters, though it could benefit from light structuring.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex search tool, it covers the most critical behaviors (matching, key, bpm, rating, sort, defaults, redaction). With an output schema present, return format is covered. Pagination (cursor) and some filters are not explained, but the overall context is sufficient for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema coverage at 0%, the description compensates for several parameters: explains q matching semantics, the bpm combination restriction, key.compatible_with expansion, rating scale, sort options, and default fields. However, it does not explain added, crate, flags, genre, limit, or cursor, though their names are somewhat suggestive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action ('Search the Serato library') with a clear resource. It distinguishes itself from siblings like get_crate_tracks and get_tracks by describing free-text matching semantics and its scope. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit usage constraints (e.g., 'bpm.around cannot be combined with bpm.min/bpm.max', 'relevance needs a q', rating scale is 0-1). It does not explicitly compare with sibling tools or state when not to use it, but the context is clear enough that an agent would know this is the search tool for broad queries.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.1- First observed
audit_library - First observed
get_crate_tracks - First observed
get_tracks - First observed
list_crates - First observed
list_libraries - First observed
search_tracks
TDQS
Scored across 6 tools
Each tool targets a distinct resource and action: crates, libraries, tracks by search, tracks by ID, and diagnostics. No two tools have overlapping purposes.
All tool names follow the same verb_noun snake_case pattern: list_crates, get_tracks, search_tracks, audit_library, etc. The convention is uniform and predictable.
Six tools is well-scoped for a Serato library inspection and audit server. Each tool earns its place and covers a distinct workflow.
The surface fully covers the stated domain: discover libraries, list crates, read crate contents, search tracks, fetch tracks by ID, and run diagnostics. There are no obvious dead ends for the intended read/audit use case.
Maintenance
Related MCP Connectors
The media memory layer for AI agents and their humans. Your AI client gets 29 tools to search your collection, add items, update ratings, preview music, and find patterns across everything you've read, watched, and listened to.
Builds narrated, playable music stories, explores sample lineage, and saves verified playlists.
Browse, search, rename, and favorite your Tolstoy media library from any AI client.
Manage SRG+ hubs, channels, content, assets, users, and workspaces from any MCP-aware AI agent.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI assistants to control Spotify playback, manage playlists, and plan DJ sets using BPM, key, and energy data.37MIT
- AlicenseAqualityBmaintenanceEnables MCP-aware AI clients to read, query, and modify a Lexicon DJ library through structured tool calls, including searching tracks, managing tags, and curating playlists or smartlists.13MIT
- AlicenseNot gradedqualityBmaintenanceEnables DJs to retrieve BPM, key/Camelot, energy, and other track metadata with provider provenance, score transitions, plan setlists, and control Spotify playlists and playback with staged, revalidated writes for safety.MIT
- FlicenseNot gradedqualityBmaintenanceConnects AI assistants to a local music library for full-text search and filtering of tracks, albums, artists, genres, composers, and lyrics, plus listening analytics and metadata hygiene audits. Also lets users generate and populate playlists and control playback (play, pause, seek, volume) in a running player instance.-