Skip to main content
Glama
umsachde

commendation

by umsachde

commendation

새로운 노래만 추천하는 MCP 서버입니다. 이미 보관함에 있는 노래, 즉 '좋아요 표시한 음악'이나 플레이리스트에 이미 있는 노래는 절대 추천하지 않습니다. 시드를 뿌린 플레이리스트뿐 아니라 모든 플레이리스트가 대상입니다.

단일 블랙박스 알고리즘을 신뢰하는 대신, 여러 독립적인 발견 신호(라디오, 관련 콘텐츠, 아티스트 카탈로그 확장)를 모으고 후보가 얼마나 많은 신호에서 일치하는지로 순위를 매겨 스트리밍 서비스의 기본 라디오/자동 재생보다 더 나은 결과를 제공하도록 설계되었습니다.

백엔드: YouTube Music (v1). Commendation은 단일 서비스에 국한되지 않는 범용 추천 엔진으로 설계되었습니다. v1은 전적으로 YouTube Music(ytmusicapi 기반)을 대상으로 구축되었습니다. Spotify 지원은 두 번째 백엔드로 계획되어 있습니다. 이에 대한 설계 질문은 PLAN.md의 "v3 — Multi-provider support" 섹션을 참조하세요.

도구

도구

설명

recommend_from_song(video_id=None, song=None, artist=None, limit=20)

시드 곡과 유사한 새 노래를 추천합니다. video_id를 직접 전달하거나, song(선택적으로 artist 포함)을 전달하면 검색을 통해 시드를 해석합니다. 예를 들어 "songs that relate to Kryptonite by 3 Doors Down"은 별도의 조회가 필요 없습니다.

recommend_from_playlist(playlist_id, limit=20, seed_sample_size=5)

전체 플레이리스트를 기반으로 새 노래를 추천합니다(플레이리스트에서 시드 트랙을 샘플링).

songs_by_artist(artist, limit=10)

지정된 아티스트의 실제 노래를 반환합니다. 유사도 추천이 아닌 직접 카탈로그 조회입니다.

세 도구 모두 모든 결과가 '좋아요 표시한 음악' 그리고 (있는 경우) 시드를 뿌린 플레이리스트뿐만 아니라 모든 플레이리스트에 없다는 것을 보장합니다. recommend_from_song은 추가로 시드 곡 자체를 절대 반환하지 않으며, recommend_from_playlist는 시드 플레이리스트가 보관함 목록에 없더라도 해당 플레이리스트의 어떤 것도 절대 반환하지 않습니다.

songs_by_artist는 다른 두 도구와 성격이 다릅니다. 점수 매기기나 라디오/관련 신호 없이 해당 아티스트의 실제 카탈로그만을 동일한 보관함 전체 제외 규칙을 적용해 반환합니다. 이는 최선 노력(best-effort)이 아닌 엄격한 요구사항입니다. limit 개수보다 적은 수의 적격 노래만 존재하면 대체 항목으로 목록을 채우지 않고 발견된 만큼만(응답의 found) 반환합니다. 어디에도 아무것도 추가하지 않습니다.

포함되지 않은 기능 (v1): BPM/템포 기반 비교. YouTube Music은 템포 데이터를 제공하지 않으므로 두 번째 데이터 소스(예: 타사 BPM API)가 필요합니다. 이번 빌드에는 포함되지 않은 향후 버전의 확장 목표입니다. 전체 설계 근거는 PLAN.md를 참조하세요.

Related MCP server: youtube-music-mcp

설정

1. 의존성 설치

python3 -m venv .venv
source .venv/bin/activate
pip install -e .

2. 인증 (YouTube Music)

공식 YouTube Music API가 없으므로 ytmusicapi는 로그인된 브라우저 세션의 헤더를 재사용하여 인증합니다.

  1. 로그인한 상태에서 Firefox에서 music.youtube.com을 엽니다(권장 — 원시 헤더 복사가 Chrome보다 안정적입니다).

  2. DevTools(Cmd+Option+I / F12) → Network 탭 → browse로 필터링합니다.

  3. 플레이리스트를 클릭하거나 페이지를 새로고침하여 browse POST 요청을 트리거합니다.

  4. 해당 요청 클릭 → Headers 탭 → Raw headers 토글 → 전체 블록을 선택하여 복사합니다.

  5. 프로젝트 루트에 raw_headers.txt라는 새 파일에 붙여넣고 저장합니다.

  6. 실행:

    python scripts/setup_auth_from_file.py

    이렇게 하면 headers_auth.json이 생성되고 raw_headers.txt가 삭제됩니다.

또는 python scripts/setup_auth.py를 실행하면 파일 대신 대화형 터미널 프롬프트를 통해 동일한 작업을 수행하므로 직접 붙여넣는 것을 선호하는 경우 유용합니다.

headers_auth.json은 로그인 세션과 동일하므로 커밋하거나 공유하지 마세요. 이미 gitignore에 등록되어 있습니다.

더 진행하기 전에 인증이 작동하는지 확인하고 추천을 검증하세요:

python scripts/test_recommend.py

이 헤더는 주기적으로 만료/교체됩니다. 도구에서 인증 오류가 발생하기 시작하면 이 단계를 다시 수행하세요.

3. Claude Code에 추가

claude mcp add commendation -s user \
  -e COMMENDATION_AUTH_PATH="$(pwd)/headers_auth.json" \
  -- "$(pwd)/.venv/bin/python" "$(pwd)/server.py"

-s user를 사용하면 이 디렉터리뿐만 아니라 모든 Claude Code 세션에서 사용할 수 있습니다. 서버는 모든 작업 디렉터리에서 실행될 수 있으므로 python 인터프리터, server.py, COMMENDATION_AUTH_PATH에는 절대 경로를 사용하세요.

다른 MCP 클라이언트(Claude Desktop 등)의 경우 각자의 구성 형식을 사용하여 동일한 명령과 환경 변수를 가리키면 됩니다.

테스트

단위 테스트(tests/)는 수제 페이크 YTMusic 클라이언트를 대상으로 순수 로직(정규화, 점수 매기기, 순위 지정, 제외 필터링, 아티스트/노래 검색 해석, 오류 변환)과 세 도구 모두를 엔드투엔드(정상 경로, 신호 실패, 부족, 검증 오류)로 다룹니다. 네트워크 액세스나 headers_auth.json이 필요 없습니다.

pip install -e ".[dev]"
pytest

커버리지를 확인하려면:

pytest --cov=server --cov-report=term-missing

server.py는 98%의 라인 커버리지를 보입니다. 커버되지 않은 두 줄은 _client()의 실제 YTMusic() 생성과 if __name__ == "__main__" 진입점으로, 실제 인증 세션이나 서버를 프로세스로 실행하지 않고는 의미 있게 테스트할 수 없습니다.

scripts/test_recommend.py는 실제 계정(설정 2단계 참조)에 접속하여 인증과 실시간 추천이 실제로 작동하는지 확인하는 별도의 보완 스모크 테스트입니다.

추천 순위가 매겨지는 방식

각 시드 곡에 대해 세 가지 독립적인 신호에서 후보를 가져옵니다:

  1. Radio — 해당 곡에 대한 YouTube Music 자체의 자동 재생/라디오.

  2. Related — 라디오와 알고리즘적으로 구별되는 별도의 "관련 콘텐츠" 신호.

  3. Artist expansion — 시드 아티스트의 다른 노래와 관련 아티스트 몇 명의 인기 곡.

후보의 점수는 해당 후보를 표면화한 고유한 (시드, 신호) 조합의 수입니다. 독립적인 신호가 많이 일치할수록 순위가 높아집니다. 모든 결과에는 어떤 신호가 해당 곡을 표면화했는지 보여주는 sources 필드가 포함되어 있어 추천이 블랙박스가 아닌 설명 가능합니다.

'좋아요 표시한 음악'과 보관함의 모든 플레이리스트는 마지막에 항상 하드 필터로 제외됩니다. 추천에는 이미 좋아요를 표시했거나 어딘가에 저장한 노래가 절대 포함될 수 없습니다.

오류 처리

도구 호출은 원시 역추적 대신 일반적인 실패 모드를 명확한 메시지로 변환합니다:

  • 인증 누락/만료/손상 → scripts/setup_auth_from_file.py를 다시 실행하라는 메시지 표시.

  • 속도 제한(HTTP 429) → 잠시 기다렸다가 다시 시도하라는 메시지 표시.

  • 게이트/제한된 콘텐츠 → 충돌 대신 사용할 수 없음으로 보고.

  • 네트워크 오류 → 직접 보고.

  • 특정 시드에 대해 개별 신호(라디오, 관련, 아티스트 확장)가 실패하면 전체 추천을 실패시키는 대신 해당 시드에 대해 해당 신호를 자동으로 건너뜁니다.

라이선스

MIT — LICENSE 참조.

Available Tools

10 tools
explain_recommendationA

Explain why a song was recommended, in mood terms.

Reports the song's mood vector, which layer produced it (Claude reading the lyrics, YouTube mood-playlist membership, or the artist's own average), the named moods it sits closest to, and the mood it was last served against.

NameRequiredDescriptionDefault
video_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does disclose the internal mechanics: the mood vector, which of three source layers produced it, the nearest named moods, and the mood last served against. It stops short of stating error behavior (e.g., what happens if the song was never recommended) or confirming it is side-effect-free.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose in the first clause, followed by one sentence enumerating what is reported. No filler, no repetition of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only explanatory tool with an output schema present, the description need not restate return formats and is complete enough to call correctly. The only real gap is the undocumented video_id, which is minor given the output schema carries the result contract.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single required video_id, and the description never mentions it, so it adds no meaning beyond the bare property name. The parameter is fairly self-evident, which keeps this from being a 1, but the description does not compensate for the coverage gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Explain why a song was recommended') and scopes it to mood terms. This clearly separates it from the action-oriented siblings like recommend_from_song and recommend_from_playlist, which produce recommendations rather than explain them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: call this after a recommendation exists to understand its basis. There is no explicit when-to-use, no statement of prerequisites (e.g., must the song have been recommended?), and no routing to alternatives among the ten siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

index_statusA

Report how much of the mood index exists, so gaps are visible not silent.

Covers the mood-playlist crawl, how much of the listener's library carries a mood label and from which layer, and whether Claude-based labelling is configured. Low coverage means recommendations are ranking mostly on signal agreement rather than on mood -- worth saying out loud.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the behavioral burden, and it does reasonably well by disclosing exactly what the report contains and how to interpret low coverage (ranking on signal agreement rather than mood). It never explicitly states the operation is read-only or side-effect-free, which leaves one gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first sentence and the rest adds diagnostic meaning. A few phrases ('gaps are visible not silent', 'worth saying out loud') are stylistic flourishes that could be trimmed, but the passage stays short.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists and there are no parameters or annotations, the description supplies enough conceptual context to know what the report conveys and why it matters. It stops short of describing invocation conditions, but little else is needed for a no-arg diagnostic.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the rubric the baseline is 4. There is no parameter syntax to document and the description introduces none.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Report how much of the mood index exists') and enumerates the scope it covers (crawl coverage, labelled library layers, Claude-labelling config). This clearly separates it from all siblings, which are recommendation, retrieval, or mutation tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the tool exists to surface index gaps and the description notes the implication of low coverage for recommendations, which hints at when it's worth calling. But there is no explicit 'use this when...' instruction or contrast with alternatives like refresh_library.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_my_moodA

Infer the listener's current mood from recent listening, with evidence.

Returns the inferred vector, a plain-language described, a confidence, and evidence -- the specific observations behind it (a song on repeat, one artist dominating, valence drifting across the session).

Lead with the evidence, not the verdict. "You've had these three on loop since yesterday -- want something that sits there with you, or something that lifts?" is the point of this tool; asserting "you are sad" is not. Mood inference is often wrong, so offer it as a read the user can correct.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does well: it discloses the epistemic limits of the tool ('mood inference is often wrong'), instructs that the result be presented as correctable, and names the concrete signals used. It omits anything about latency, caching, or how much history is scanned, but the fallibility disclosure is unusually valuable context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then the return shape, then the interaction rule. The quoted example earns its space by encoding tone, though the enumeration of return fields partially duplicates the output schema and could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with a rich output schema and no annotations, this covers purpose, output framing, and the key caveat about unreliable inference. The only real gap is not routing the agent to the mood-recommendation siblings when the user actually wants a suggestion.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. There is nothing for the description to disambiguate, and it correctly avoids inventing input semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — infer the listener's current mood from recent listening — and frames it as an evidence-backed read, which cleanly separates it from the recommendation siblings (recommend_for_mood, recommend_from_playlist_for_mood). An agent can tell what this returns without opening the output schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear interaction guidance (lead with evidence, offer the inference as a correctable read) but never says when to call this instead of, or before, recommend_for_mood. The when-to-use case is only implied by the conversational framing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recommend_for_moodA

Recommend new songs that match how the listener actually feels right now.

Unlike recommend_from_song, the mood decides where candidates come from: seeds are drawn from the listener's OWN library nearest the target mood, then expanded through radio/related/artist signals and songs from YouTube's mood playlists. Results are still guaranteed absent from their library.

Describing the mood -- in priority order: vector The precise path, and the one to prefer. A dict with valence (-1..1, despairing->euphoric), energy (0..1, still->frantic), tension (0..1, resolved->anxious; this is what separates angry from excited) and depth (0..1, background ->lyric-forward). YOU should read the user's words and set these -- you understand "wistful but still wants to get things done" far better than any keyword list. feeling Their words verbatim, as a fallback when you'd rather not commit to numbers. Matched against a mood-word lexicon. context One of: Chill, Sleep, Focus, Commute, Feel good, Romance, Energize, Workout, Party, Gaming, Sad. If none are given, the mood is inferred from recent listening history.

arc shapes the sequence rather than returning a flat mood-matched set: mirror stay where they are and validate it (default) lift start where they are, rise gradually -- never jump straight to upbeat when someone is low, it reads as being told to cheer up settle descend to calm; an evening wind-down deepen go further in; sometimes you want to sit in it properly hold stay in a band with energy as a curve (workout: warmup/peak/cooldown)

genres optionally restricts the seeds to the listener's own genre playlists, e.g. ["Punjabi", "Hip-Hop & Rap"].

language / exclude_languages filter the RESULTS, e.g. language=["english"]. Strict by default: a candidate with no language label is dropped, because someone asking for English only wants a guarantee. The response says how many were dropped and why; pass allow_unlabelled_language=True to keep them.

bpm biases ranking toward a tempo (half- and double-time count as close). bpm_min/bpm_max bound it instead. Songs with no known BPM are KEPT and simply not scored on tempo -- Deezer has no tempo for much of the non-English catalogue, so dropping them would delete whole languages.

limit is a ceiling, not a guarantee. If fewer than limit songs genuinely fit the mood (rated, with a real fit -- not just an unrated placeholder score), the shortfall is NOT padded with weak filler to hit the number. Filler is capped at 25% of limit: asking for 100 with 7 genuine matches returns 32 (7 + 25), not 100. See match_quality in the result for the genuine/filler breakdown, and notes for the human-readable version.

If they also point at a specific playlist ("look at this playlist and recommend me songs for how I feel"), use recommend_from_playlist_for_mood instead -- it seeds from that playlist's own fitting tracks rather than from the whole library.

This is READ-ONLY. If they asked for a PLAYLIST rather than a list, this tool is step one of three: get the songs here, create the playlist from the returned videoIds with a playlist-management tool, then call refresh_library() so those tracks are excluded from later recommendations.

The result carries target (the mood aimed at), target_origin (where it came from), seeds (which of their songs it grew from), notes (caveats worth repeating to the user), match_quality (genuine vs. filler counts) and songs, each with its slot, mood fit and which signals surfaced it.

NameRequiredDescriptionDefault
arcNomirror
bpmNo
limitNo
genresNo
vectorNo
bpm_maxNo
bpm_minNo
contextNo
feelingNo
languageNo
exclude_languagesNo
allow_unlabelled_languageNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must carry the full behavioral burden and it does: declares READ-ONLY, guarantees results absent from library, discloses the strict language filter and the unlabelled-drop behavior, and explains the 25% filler cap with a concrete example (7 + 25 = 32). These are non-obvious traits an agent cannot infer elsewhere.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and organized under clear parameter headers, so it scans well despite its length. It is verbose and occasionally repetitive (the filler logic is restated in both `limit` and the result description), but nearly every sentence carries operational detail that would otherwise be missing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

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 values, yet it still previews `target`, `seeds`, `match_quality`, and `notes` to tell the agent what to surface to the user. Combined with the alternative routing and the playlist hand-off, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% and the schema has no enums, so the description compensates fully: it defines vector's four numeric dimensions with ranges and semantics, enumerates all eleven `context` values, documents each `arc` mode, and explains bpm_min/max biasing, language filtering, allow_unlabelled_language, and limit's ceiling-not-guarantee semantics. All 12 params gain meaning beyond the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('recommend new songs that match how the listener actually feels') and immediately contrasts its seed-selection mechanism against recommend_from_song. An agent can distinguish it from every sibling without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names when to switch: 'If they also point at a specific playlist ... use recommend_from_playlist_for_mood instead.' It also clarifies the multi-step playlist workflow (get songs here, create playlist, call refresh_library) and that this tool is not for building playlists directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recommend_from_playlistA

Recommend new songs based on an entire playlist.

Randomly samples up to seed_sample_size tracks from the playlist as seeds (the whole playlist if it's smaller), runs the same multi-signal candidate generation as recommend_from_song for each, and pools/ranks the results. Never returns a song already in Liked Music, already in the source playlist, or already in ANY other of the user's playlists.

The library exclusion set is cached for speed; newly liked songs are always honoured, but call refresh_library() after adding songs to a playlist by other means.

NameRequiredDescriptionDefault
limitNo
playlist_idYes
seed_sample_sizeNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses the sampling strategy (up to seed_sample_size random seeds), the pooling/ranking approach, and hard output guarantees (never returns songs in Liked Music, the source playlist, or any other playlist). It also flags a caching staleness risk and the refresh_library remedy, which is exactly the kind of behavioral caveat an agent needs before trusting results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose, then layers mechanism, guarantees, and the caching caveat in short paragraphs; every sentence carries information. Slightly verbose in restating the multi-signal pipeline, but no filler sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is unnecessary, and the description covers seeding, exclusions, and cache behavior. The main gap is the unexplained `limit` parameter and no mention of failure modes for an invalid playlist_id, but overall it is sufficient to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 three undocumented parameters. It explains seed_sample_size concretely (random seed count, with whole-playlist fallback) and implies playlist_id's role, but never explains what `limit` (default 20) controls. Partial compensation only.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Recommend new songs based on an entire playlist') and explicitly differentiates its mechanism from the sibling recommend_from_song ('runs the same multi-signal candidate generation as recommend_from_song for each, and pools/ranks'). An agent can distinguish it from recommend_from_song and recommend_from_playlist_for_mood without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when this tool applies (you have a whole playlist rather than one seed song) and an explicit follow-up call ('call refresh_library() after adding songs to a playlist by other means'), which routes the agent to a sibling when the cache is stale. It stops short of an explicit 'use recommend_from_song when you only have one track' exclusion, so it is strong but not fully enumerated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recommend_from_playlist_for_moodA

Recommend new songs from ONE playlist, shaped by how the listener feels.

For "I feel like this -- look at this playlist and find me songs". Use this over recommend_from_playlist whenever a mood is part of the ask, and over recommend_for_mood whenever a specific playlist is.

Unlike recommend_from_playlist, which samples a few tracks at random and ignores mood entirely: EVERY track in the playlist is read and scored for mood fit, and only genuine matches -- tracks whose own mood resolves and actually fits the target -- are used as seeds. An off-mood playlist therefore yields few seeds or none, which is reported rather than papered over by seeding from tracks that don't fit.

Seeding costs ~4 API calls per seed, so the best-fitting seeds are capped (default 20, override with seed_cap). seed_report in the result says how many tracks were considered, how many were genuine, and how many were capped away.

Mood arguments behave exactly as in recommend_for_mood (vector preferred, then feeling, then context; falls back to inferred mood). arc shapes the sequence the same way. Results are guaranteed absent from Liked Music, from this playlist, and from every other playlist -- and limit is a ceiling, not a guarantee: filler is capped at 25% of it, same as recommend_for_mood.

This is READ-ONLY -- it never creates a playlist or adds anything anywhere. To turn the result into a real playlist, pass the returned videoIds to a playlist-management tool, then call refresh_library() so the new tracks are excluded from later recommendations.

NameRequiredDescriptionDefault
arcNomirror
bpmNo
limitNo
vectorNo
bpm_maxNo
bpm_minNo
contextNo
feelingNo
languageNo
seed_capNo
playlist_idYes
exclude_languagesNo
allow_unlabelled_languageNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden and does so richly: read-only guarantee, ~4 API calls per seed with a default cap of 20, seed_report contents (considered/genuine/capped), the fact that off-mood playlists legitimately yield few or no seeds rather than being papered over, exclusion guarantees, and the 25% filler ceiling on `limit`. This is exactly the cost/side-effect/auth context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose and the routing rule before any internals, and every paragraph adds a distinct fact (contrast, cost/seed behavior, mood args, guarantees, read-only follow-up). It is long, and a couple of clauses ('same as recommend_for_mood') are mild repetition, but no paragraph is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present it correctly avoids re-describing return values while still flagging the meaningful `seed_report` field. For a 13-parameter, no-annotation, no-schema-description tool it covers behavior thoroughly, but the unaddressed bpm/language parameter family is a real completeness gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 and it only partially does. It clarifies vector>feeling>context precedence, arc's shaping role, seed_cap, and limit's ceiling semantics, but 13 parameters exist and bpm/bpm_min/bpm_max, language, exclude_languages, and allow_unlabelled_language are never addressed beyond their self-evident names.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+scope: 'Recommend new songs from ONE playlist, shaped by how the listener feels.' It explicitly contrasts itself with both closest siblings (recommend_from_playlist and recommend_for_mood) and names the distinguishing dimension (mood presence, playlist specificity).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing rules: 'Use this over recommend_from_playlist whenever a mood is part of the ask, and over recommend_for_mood whenever a specific playlist is,' plus a concrete user-facing trigger ('I feel like this -- look at this playlist and find me songs'). It also explains the follow-up workflow (pass videoIds to a playlist tool, then call refresh_library()).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

recommend_from_songA

Recommend new songs similar to a seed song.

Seed the search either with a known video_id, or with song (a free-text title, optionally narrowed with artist) to have the seed resolved via search internally -- e.g. "10 songs that relate to Kryptonite by 3 Doors Down" needs no separate lookup first. Exactly one of video_id or song must be given.

Combines YouTube Music's radio, its separate "related" signal, and the seed artist's own catalog plus related artists' catalogs, then ranks by how many independent signals agreed on each candidate. Never returns the seed song itself, and never returns a song already in Liked Music or in ANY of the user's playlists.

By default candidates can come from OTHER artists too (radio/related signals surface stylistically similar tracks, not just the seed artist's own catalog) -- pass same_artist_only=True to keep only songs credited to the seed's own artist(s), e.g. for "recommend songs BY artist X similar to song Y" requests.

language / exclude_languages filter the RESULTS independently of the seed, which is the point: seeding from a Punjabi song with language=["english"] returns English songs similar to it. Strict by default -- candidates with no language label are dropped, since a Punjabi-seeded pool is mostly Punjabi and keeping unlabelled ones would hand back exactly what was excluded. Pass allow_unlabelled_language=True to relax that; the response always reports what was dropped.

When a language filter leaves too few results -- seeding from a Punjabi song and asking for English usually does -- the surviving songs are used as fresh seeds to reach more of that language in the same neighbourhood, since filtering alone can only return what happened to be in the seed's own pool. Set expand_across_language=False to skip that and get the short list.

match_seed_tempo=True biases results toward the seed's own BPM (half- and double-time count as close). bpm sets a tempo target directly, and bpm_min/bpm_max bound it. Songs with no known BPM are kept and simply not scored on tempo.

Returns {"songs": [...], "notes": [...], "filters": {...}} -- notes carry anything the user should hear about, such as results dropped for having no language label.

The library exclusion set is cached for speed; newly liked songs are always honoured, but call refresh_library() after adding songs to a playlist by other means.

NameRequiredDescriptionDefault
bpmNo
songNo
limitNo
artistNo
bpm_maxNo
bpm_minNo
languageNo
video_idNo
max_per_artistNo
match_seed_tempoNo
same_artist_onlyNo
exclude_languagesNo
expand_across_languageNo
allow_unlabelled_languageNo

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses the multi-signal ranking strategy, that the seed song is never returned, exclusion of Liked Music and all playlists, the default cross-artist behaviour, language-filter strictness with allow_unlabelled_language escape hatch, and the response shape with notes. It even flags a cache-staleness behaviour and the refresh_library() remedy — exactly the kind of non-obvious trait annotations would normally supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and the required-argument rule are front-loaded, and essentially every sentence adds a distinct behavioural fact, so length is largely justified. A few conversational asides ('which is the point:') and repeated restatements of the language-filter rationale could be trimmed without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be re-explained, and the description nonetheless names the response keys and the role of `notes`. Combined with the mutual-exclusion rule, filter semantics, and the cache/refresh_library dependency, an agent has everything needed to call this 14-parameter tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% across 14 parameters, so the description is the only source of meaning, and it explains the semantics of most of them: video_id vs song mutual exclusion, artist narrowing, language/exclude_languages independence from the seed, allow_unlabelled_language, expand_across_language, same_artist_only, and match_seed_tempo/bpm/bpm_min/bpm_max including the half/double-time and missing-BPM cases. It leaves `limit` and `max_per_artist` (the default of 2) undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ('Recommend new songs similar to a seed song'), which cleanly separates it from the playlist- and mood-seeded siblings by seeding resource. It never names those siblings explicitly, so an agent must infer the routing from the resource noun rather than being told.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Strong in-scope guidance: exactly one of video_id or song must be given, with a worked example ('10 songs that relate to Kryptonite by 3 Doors Down'); it also explains when same_artist_only, language filters, and expand_across_language apply. It does not, however, compare itself against the sibling tools (recommend_from_playlist, recommend_for_mood), so the agent gets no explicit alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record_feedbackB

Record what the listener thought of a recommendation.

reaction is one of: loved, saved, skipped, wrong_mood.

wrong_mood is the valuable one -- it says the song was fine but the mood read was off, which is a different failure from simply not liking it. Anything marked skipped or wrong_mood is never recommended again.

NameRequiredDescriptionDefault
reactionYes
video_idYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It does disclose a meaningful system effect -- 'Anything marked skipped or wrong_mood is never recommended again' -- which is durable state change worth knowing. However, it omits idempotency, auth/permission needs, error behavior, and whether feedback can be changed after recording.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Short and front-loaded: purpose first, then the allowed values, then the consequence. Every sentence carries weight, though the sentimental framing of 'the valuable one' is mildly editorial rather than operational.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described, and the reaction semantics are covered well. The one gap is the undocumented required `video_id` and no statement of the recording's persistence or reversibility, which leaves the agent guessing on a required field.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate. It fully enumerates and interprets the `reaction` values, which the schema does not (no enum). But `video_id` is never explained -- the agent must infer where a video id comes from -- leaving half the parameters undocumented.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('Record what the listener thought of a recommendation'), making it a feedback sink that is easily distinguished from the sibling recommender tools. It does not explicitly name siblings, but 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Use is implied by the recommender sibling set (call this after a recommendation is consumed), and it hints at the value of one reaction type. There is no explicit when-to-use, when-not, or routing to alternatives such as explain_recommendation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

refresh_libraryA

Rebuild the cached library exclusion set from scratch, right now.

Every recommendation tool excludes songs already in Liked Music or any of your playlists. That set is expensive to build (~20s), so it's cached and reused. Liking a song is picked up immediately regardless, but adding a song to some other playlist is only seen once the cache is rebuilt.

Call this after adding songs to a playlist by other means (e.g. a playlist-management tool) if you want the next recommendation to account for them without waiting out the cache TTL.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses the ~20s build cost, that the result is cached and reused, and that the effect is only otherwise visible after a cache TTL. It also clarifies the incremental freshness rule (likes immediate, playlist adds deferred), which is non-obvious and directly affects whether the agent should call it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The action is front-loaded in the first sentence and each subsequent sentence adds real information (cost, cache semantics, call condition). The cache-economics paragraph is slightly more expansive than strictly needed, but it is not wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. For a zero-parameter maintenance tool, the description covers the why, the cost, the caching model, and the precise call condition, leaving no material gap for an agent deciding whether to invoke it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the baseline is 4 and there is no parameter syntax for the description to clarify. Nothing is missing, but there is also no opportunity to add semantic value here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Rebuild the cached library exclusion set') and immediately explains its relationship to the sibling recommendation tools, which all consume this set. An agent can distinguish this maintenance tool from recommend_* siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the exact trigger ('Call this after adding songs to a playlist by other means') and explicitly contrasts it with the case where it is unnecessary, since liking a song is already picked up immediately. It also names the alternative workflow (a playlist-management tool) that creates the need.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

songs_by_artistA

Return actual songs by a specific artist -- a direct catalog pull, not a similarity recommendation like recommend_from_song/recommend_from_playlist.

Resolves artist (a name) to its YouTube Music channel and pulls its real song catalog, excluding anything already in Liked Music OR in ANY of the user's playlists (not just one, unlike recommend_from_playlist's single-seed-playlist exclusion). Read-only: never adds results anywhere.

This is a hard requirement, not best-effort -- if fewer than limit qualifying songs exist after exclusion, this returns however many were actually found rather than padding the list. Check found vs requested in the result to see whether it fell short.

Remix/feature variants of the same underlying song (e.g. a track and its "(feat. ...)" credit under a different videoId) count once, not once per variant -- see variants_collapsed in the result.

The library exclusion set is cached for speed; newly liked songs are always honoured, but call refresh_library() after adding songs to a playlist by other means.

NameRequiredDescriptionDefault
limitNo
artistYes

Output Schema

NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses read-only behavior ('never adds results anywhere'), the exclusion set semantics (Liked Music OR any playlist), the hard requirement that it returns fewer than limit rather than padding, and the variant-collapsing behavior. It does not state auth/permission requirements or rate limits, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Multi-paragraph but front-loads the core purpose and sibling differentiation first, then layers in exclusion behavior, shortfall semantics, variant collapsing, and caching. Each paragraph earns its place, though some detail could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so return-value explanation is largely unnecessary, yet the description references result fields ('found' vs 'requested', 'variants_collapsed') to clarify semantics. Covers exclusion behavior, caching caveat, and refresh_library guidance. Could still note artist-resolution failure behavior, but is largely complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 'artist' is a name resolved to a YouTube Music channel and mentions 'limit' as a qualifying-songs count, adding real meaning. But it does not specify limit bounds, defaults effect, or exact artist-matching semantics, leaving gaps for a 0%-coverage schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Return actual songs by a specific artist -- a direct catalog pull') and explicitly distinguishes itself from siblings by contrasting with similarity recommendations like recommend_from_song/recommend_from_playlist. The direct-catalog-pull framing makes it unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly contrasts this tool with recommend_from_song and recommend_from_playlist, and clarifies the exclusion scope differs from recommend_from_playlist's single-seed-playlist exclusion. It also instructs when to call refresh_library(). Strong when-to-use guidance.

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.

  1. 10 tool updatesv0.2.0
    • First observedexplain_recommendation
    • First observedindex_status
    • First observedread_my_mood
    • First observedrecommend_for_mood
    • First observedrecommend_from_playlist
    • First observedrecommend_from_playlist_for_mood
    • First observedrecommend_from_song
    • First observedrecord_feedback
    • First observedrefresh_library
    • First observedsongs_by_artist

TDQS

A4.2/5.0

Scored across 10 tools

Disambiguation4/5

Tool names and descriptions clearly delineate purposes: recommend_from_song seeds by a song, recommend_from_playlist seeds by playlist, recommend_for_mood uses mood, recommend_from_playlist_for_mood combines both. songs_by_artist and explain_recommendation are distinct. Minor potential confusion between recommend_from_playlist_for_mood and recommend_for_mood, but descriptions explicitly guide selection.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (recommend_from_song, read_my_mood, record_feedback, etc.) with snake_case throughout, no deviations.

Tool Count5/5

10 tools provide a well-scoped set covering recommendation generation, library management, feedback, mood reading, explanation, and status—each earns its place without excess.

Completeness5/5

Comprehensive lifecycle coverage: multiple recommendation entry points (by song, playlist, mood, playlist+mood), library refresh, mood inference, feedback recording, explanation, and index status. No obvious gaps for a music recommendation system.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    An MCP server for managing YouTube Music playlists via Claude. Add and remove songs, create playlists, and ask Claude to suggest music — all through conversation.
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    A production-grade MCP server that connects YouTube Music to AI assistants, enabling music search, library management, playlist creation, and personalized recommendations through 15 tools, 3 resources, and 3 prompts.
    1
    -
  • A
    license
    Not graded
    quality
    D
    maintenance
    An MCP server that enables AI applications to search YouTube music videos and manage playlists via the YouTube Data API v3, with OAuth support for playlist and subscription management.
    3
    MIT