Skip to main content
Glama
umsachde

commendation

by umsachde

recommend_for_mood

Recommend new songs that match how the listener feels right now, using their own library and mood signals, while ensuring nothing is already liked or playlisted.

Instructions

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.

Input Schema

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

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.2.0

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.