# Kindle Music

> Search 2M+ licensed production-music tracks, find similar ones by track or audio, share pick lists.

- name: cn.kindlemusic/kindlemusic
- version: 0.10.1
- connection class: R0 (autonomous)
- trust: 82/100 flags: no-repository
- quality: 77/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/cn.kindlemusic%2Fkindlemusic
- tools: https://api.protogrid.dev/v1/servers/cn.kindlemusic%2Fkindlemusic/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "kindlemusic": {
      "type": "http",
      "url": "https://share.kindlemusic.cn/mcp",
      "headers": {
        "Authorization": "Bearer ${KINDLEMUSIC_TOKEN}"
      }
    }
  }
}
```

Placeholders to fill: `${KINDLEMUSIC_TOKEN}`.

## Trust

- hygiene: 80
- liveness: 99
- freshness: 100
- provenance: 55
- drivers: +dns-namespace +website +reachable +uptime-98% +updated-22d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 77/100 (good)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: 83 (weight 15)

- pass `auth.prm`: Protected Resource Metadata (RFC 9728) published
- pass `auth.as_metadata`: authorization server metadata reachable
- warn `auth.cimd`: only Dynamic Client Registration, deprecated in 2026-07-28 in favour of CIMD
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 64 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 3 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- fail `tools.annotations`: no tool declares readOnlyHint or destructiveHint, so clients cannot tell safe calls from risky ones
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: km_resolve (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); km_vocabulary (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); km_search (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); …
- pass `tools.token_cost`: about 3,340 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 6, about 3,340 tokens to load them all
- tool set hash: 0f1a1495fc4ced8dc6bd033e4981018e
- badge: [![protogrid quality](https://protogrid.dev/badge/cn.kindlemusic/kindlemusic.svg)](https://protogrid.dev/servers/cn.kindlemusic/kindlemusic)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://share.kindlemusic.cn/mcp/oauth (streamable-http, auth oauth2, reachable true, uptime30d 0.9764706)
- https://share.kindlemusic.cn/mcp (streamable-http, auth none, reachable true, uptime30d 0.9764706)

## Packages

_none_

## Tools (6)

- `km_get_result_set`: 按 code 读回一份已发布的选曲清单（含分段、曲目与每首的状态）。
Reads back a published pick list by its code, including sections, tracks and each track status.

何时用 / When: 用户要在既有清单上继续增删改，或要确认清单里的曲目是否仍在架。
返回 / Returns: 清单全文；已过期或已撤销时 sections 为空数组（看 expired / revoked 字段）。

返回的 track_url 仅供试听/临时分析，见 audioNotice。
Returned track_url values are for audition / temporary analysis only; see audioNotice.
- `km_resolve`: 把用户手里的下载文件名、UPM 链接、本站链接（专辑 / 厂牌 / 选曲清单 / 歌单 / 搜索结果页）、外站链接或带连字符的专辑编号，定位成下一步可用的对象。
Resolves a download filename, UPM link, kindlemusic.cn link (album / label / pick list / playlist / search page), other web link or hyphenated album code into something the other km_* tools can act on.

何时用 / When: 用户贴的是 KM_PUC045_TK003_xxx.mp3、universalproductionmusic.com 链接、www.kindlemusic.cn/… 链接或 PUC-045 这类编号时，先调本工具；不要把它们当关键词丢进 km_search（会零结果）。

返回 / Returns: { q, resolved }。resolved 为 null 表示认不出或库里没有。按 kind 接下一步：
- kind="track"，source 为 upm / filename（文件名 / UPM 链接）：{ albumCode, trackNumber（主曲曲号）, trackIdentity, trackTitle, albumTitle }。剪辑版文件名一律映射到主版本；接着用 km_track_versions(albumCode, trackNumber) 取全部版本，或 km_search(searchField="album", keyword=albumCode) 拿曲目 id。
- kind="album"，source="code"（编号）：{ albumCode, albumTitle }。接着用 km_search(searchField="album", keyword=albumCode)。
- source="site"（本站链接）：
  - kind="track" 带 trackId：trackId 就是曲目 id，可直接喂 km_similar_by_track；带 trackNumber（专辑页 ?trackNumber=）：可直接喂 km_track_versions(albumCode, trackNumber)。
  - kind="album"：{ albumCode, trackId:null }，同上接 km_search(searchField="album")。
  - kind="label"：{ includeLabels:[厂牌名] }，原样放进 km_search 的 includeLabels 按厂牌收窄。
  - kind="resultSet"：{ code }，选曲清单（/picks/<code>），用 km_get_result_set(code) 读回。
  - kind="playlist"：{ playlistId } 或 { shareType, shareCode }，网站歌单 / 歌单分享链接，MCP 没有读取歌单的工具，请让用户在网站打开，或说出想要的风格改用 km_search。
  - kind="search"：{ tier, args }，网站搜索结果页的条件已还原成 km_search 入参，原样传给 km_search 即可复现用户看到的那次检索。
  - kind="page"：本站首页 / 列表页 / 场景页 / 指南，没有可直接检索的对象。
- kind="keywords"，source="slug"（外站链接、或本站认不出的路径）：{ keyword }，取自链接里的搜索参数或最后一段路径；可作为 km_search 的关键词（含中文时带 expand="fast"，或改用 searchField="ai"）。视频网站链接通常取不出曲名，有参考音频请走 km_similar_by_audio。
- `km_search`: 在 Kindle Music 正版曲库里检索曲目或专辑，支持关键词、facet 筛选、BPM 与时长区间。
Searches the Kindle Music production-music catalog: keyword + facet filters + bpm/duration ranges.

searchField 怎么选 / Choosing searchField:
- keywords：关键词匹配，默认值。多个词之间是 OR、按命中词数排序，所以加不同维度的词（用途 + 情绪 + 乐器）比堆近义词有用；英文加双引号是短语匹配（"epic trailer"）。不要写 AND/OR/NOT；开头的 -term 按字面匹配，不表示排除。
  剧情词和抽象词（逆袭、对峙、回忆、高级感）曲库标签里很少出现，会把排序带偏：先翻译成情绪 / 乐器 / 速度这类音乐描述再检索。
  expand="fast"：中文按词翻译 + 同义扩展（结果稳定，同一个词每次扩成一样）；expand="deep"：映射到曲库标准词，召回更窄、最慢约 1 分钟。不带 expand 时 keyword 必须是英文。
  带 expand 时中文否定从句（不要X / 去掉X / 避免X）会从 keyword 里剥离并映射成 exclude（「不要太X」这类程度否定映射成降权），一次最多 3 条，结果见 derivedNegations。
- ai：一句自然语言描述（可中文），后端整句理解改写后检索，结果看前排而不是总数。一两个词的需求用 keywords 更好。
- semantic：text→audio 语义检索（英文效果最好），适合"听感"类描述；不可用或 0 结果时自动降级 ai。
- track：按英文原曲名查（去掉前导序号与扩展名，中文译名搜不到）。album：按专辑编号/名查，编号不区分大小写、连字符、空格与前导零。
- lyrics：按歌词查（可中文）。composer：按作曲者查（只能英文）。
- 手里是下载文件名、UPM 链接、本站链接或 PUC-045 这类编号时，先用 km_resolve 定位，不要拿它当关键词。

⚠️ 硬约束 / Hard constraint: searchField=keywords（未带 expand）或 composer 时 keyword 只能是英文。
Passing Chinese with searchField=composer, or with keywords and no expand, is rejected up front (Solr matches literally → zero hits).

否定 / Negation:
- keywords：英文的 no / without X 不会被识别（反而把 X 当正向词召回），用 exclude*；中文否定需带 expand（见上）。客户的硬性排除任何模式都用 exclude* 兜底。
- ai：直接写进句子（不要/无/别/去掉/避免 X，no/not/without X），一次最多 4 项；「不要太X」只让 X 往后排不去掉；排除后 0 结果会自动放宽。
  响应里的 derivedNegations 说明每条否定被映射成了哪个 facet 值、是否被放宽——交付前核对它。

include*/exclude* 的取值必须先用 km_vocabulary 取，并原样回填。同一维度多个值是 AND（includeLabels / includeAlbums 例外，是 OR）；exclude* 命中任一即排除。
关键词不匹配厂牌名，按厂牌收窄用 includeLabels。
partition：independent = 网站「独立精选」分区，universal = 「环球UPM」分区；不传 = 两个分区合并检索（网站精选站默认只显示独立精选）。
bpmMin/bpmMax 与 durationMin/durationMax（秒）必须成对给出。

fields 怎么选 / Choosing fields:
- slim（默认）：每首 25 个字段（含 track_number、四维标签 + 中英文描述 + 可播放的 url），够直接做精排与交付。pageSize 上限 50。
- compact：每首只回 10 个字段（id / album_code / track_number / track_title / track_version / track_bpm / track_duration / library_name / library_type / web_url），pageSize 上限放宽到 200。
没有"按 id 批量取全字段"的端点：compact 结果需要中文描述与四维标签时，只能对收窄后的条件重跑一次 fields=slim。

⚠️ BPM 半速口径 / Half-time BPM: 本曲库 55/60 与 110/120 常常是同一个脉冲的两种记法（标注方按半速还是双速记没有统一）。
在架主曲落在 60–90 BPM 的有 12.6 万首，一刀切 bpmMin=95,bpmMax=125 会静默漏掉一大片听感完全对的曲子。
按 BPM 收窄时要把半速区间也检索一遍再合并，否则会漏召回。

返回 / Returns: { total, appliedSearchField, searchId, fields, tracks[]（字段集见 fields，含可直接打开的 web_url）, search_url（C 端复现本次检索的链接）}。
有扩展时另带 ai_keyword / expanded（实际检索用的英文词）；有否定时带 derivedNegations。
translation_failed:true 表示中文扩展失败、按空结果返回，不代表曲库里没有：换英文或改 searchField=ai 重试。
ai / lyrics / expand 受后端每日 LLM 配额；超额时返回 llmQuotaExceeded:true 且 appliedSearchField 降级为 keywords。

返回的 track_url 仅供试听/临时分析，见 audioNotice。
Returned track_url values are for audition / temporary analysis only; see audioNotice.
- `km_similar_by_track`: 以曲库里一首已有曲目为锚点，找音频听感相似的曲目（向量检索，不是关键词）。
Audio-similarity search anchored on an existing catalog track (vector search, not keywords).

何时用 / When: 用户说"再来一些像这首的"，或你已经命中一首合适的曲目、想扩出一组候选时。
接力用法：对"七八分像"的曲目取相似 → 挑出更像的一首再取相似，两三轮通常就能逼近目标。

入参 / Args: id = km_search 返回的曲目 id（不是 track_identity），须是主版本。limit 默认 12，上限 50。
不认 partition（独立精选 / 环球UPM 分区）；要按 BPM / 时长 / 标签收窄，拿结果在本地筛。
返回 / Returns: { searchId, total, tracks[] }，曲目字段与 km_search 一致。

返回的 track_url 仅供试听/临时分析，见 audioNotice。
Returned track_url values are for audition / temporary analysis only; see audioNotice.
- `km_track_versions`: 列出同一首曲子的全部剪辑版本（Full Length / 60 Sec / 30 Sec / 20 Sec / 15 Sec 等）。
Lists every cutdown version of one track (Full Length / 60 Sec / 30 Sec / 20 Sec / 15 Sec …).

⚠️ km_search 只索引主曲（Solr 里 track_is_main=Y），**剪辑版拿不到**，只能靠本工具取。
km_search only indexes main tracks; the shorter cutdowns are invisible to it and can ONLY be fetched here.

何时用 / When: 广告、TVC、预告片这类有硬性时长的项目，交付候选之前对每首都查一次——
有现成的 60s/30s/15s 版本，客户就不必自己剪；没有就要在交付说明里讲清楚需要自行剪辑。

入参 / Args: albumCode = 曲目的 album_code；trackNumber = **主曲**的 track_number（都取自 km_search 返回的曲目对象）。
libraryType 可选：原样透传 km_search 里那首曲子的 library_type，用来判定 web_url 的 essential / premium 段（本端点自身不返回该字段）。

返回 / Returns: { albumCode, trackNumber, total, versions[] }，versions 按时长从长到短排，字段与 km_search 的曲目对象同构。
看 track_version（版本名）、track_duration（秒）、orginal_time（mm:ss）、track_mixout（如 Backing Vocals Only，即去人声版）。
注意：剪辑版只有版本名 / 时长 / mixout / 英文描述，track_bpm 与四维标签（mood/genre/instrumentation/tempo）只有主曲那行有——它们本来就是同一首曲子，按主曲的值理解即可。
专辑号或曲目号不存在时返回空 versions[]，不报错。

返回的 track_url 仅供试听/临时分析，见 audioNotice。
Returned track_url values are for audition / temporary analysis only; see audioNotice.
- `km_vocabulary`: 列出曲库全部可用的筛选值（流派/情绪/乐器/速度/适用场景/厂牌）。
Lists every filterable facet value in the catalog (genre, mood, instrumentation, tempo, music-for, label).

何时用 / When: 在 km_search 里使用任何 include*/exclude* 筛选之前，先用本工具确认取值。
Call this BEFORE using any include*/exclude* filter in km_search.

入参 / Args: field（可选，facet 字段名子串，如 "genre"/"mood"/"library"）；query（可选，对取值与中文名做不区分大小写的子串过滤，中文也能查，如 query="悲伤"）。

返回 / Returns: 每个 facet 字段的 { param, values }，values 里每项是 { value, labelZh, count }。param 就是 km_search 里该字段对应的入参名。
顶层另有 labels[]：320 个厂牌的 { library_name, library_type, company, album_count, track_count }，可用来判断某个厂牌值不值得单独收窄。
⚠️ value 必须**原样**回填到 km_search，不要翻译、改大小写或去掉 "Parent;Leaf" 里的分号；改动过的值一律匹配不上。labelZh 只供你把中文 brief 映射到 canonical 值，不要回填。
count 用来防过度收窄：候选值 count < 200 时考虑放宽或换父级（例：`sad` 有 8.6 万首，而叶子 `sad;breakup` 只有 38 首，直接用叶子会把结果掐死）。
