Skip to main content
Glama

mcp-bideetmusique

npm CI license MCP Registry Glama M8ven LobeHub Install in Cursor Install in VS Code

Bide & Musique is a French web radio and the collection of records it plays, catalogued by hand by the volunteer association that runs it. Its subject is the forgotten song: the flop, the novelty record, the television theme, the single nobody reissued. A record's page carries the performer, the writers and composers, the year, the label and its catalogue reference, the sleeve, the duration, the station's own chart placings, and the words when a listener transcribed them.

This server connects a chat client to that collection. You can search it along one axis at a time, by performer, title, writer, lyrics, label or year; read one record in full; read what the site holds about an artist with their discography; draw a record at random; and see what has just been catalogued. It needs no API key and no account.

Version française


Install

One-click install

Install in Cursor Install in VS Code

Claude Code

claude mcp add bideetmusique -- npx -y mcp-bideetmusique

Claude Desktop, Cursor, and any client using the standard config format

{
  "mcpServers": {
    "bideetmusique": {
      "command": "npx",
      "args": ["-y", "mcp-bideetmusique"]
    }
  }
}

Node 24 or later is required, and no environment variable has to be set.

With Docker

{
  "mcpServers": {
    "bideetmusique": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-bideetmusique:2.1.0"]
    }
  }
}

-i keeps stdin open, which is where the protocol travels, and -t is left out because a TTY rewrites the stream. The container needs outbound HTTPS to www.bide-et-musique.com, and nothing else: no volume, no port, no credential.

Bundle, without npm

Download mcp-bideetmusique-2.1.0.mcpb from the latest release and open it. A client that supports MCP bundles installs it on its own, with no npm and no configuration file to edit. The bundle carries its dependencies, so nothing is fetched at install time.

Related MCP server: mcp-gouv-fr

What you can ask

  • « Qu'est-ce que Bide & Musique a de Jacques Dutronc ? »

  • "Which songs mention a submarine in their words?"

  • "Read me that record: the label, the year, who wrote it."

  • "Play me something at random from the collection."

  • "What has been catalogued lately?"

The ordinary path runs from a search to a record: a row carries a song_id, and get_song reads it.

Tools

Tool

What it does

search_songs

Searches the collection along one axis at a time.

get_song

Reads one record in full, words included.

get_artist

Reads an artist and the records the collection holds of theirs.

get_random_song

Draws a record nobody chose.

list_new_songs

Reads what the collection has just catalogued.

search_songs

Searches along one axis, which has to be named: each asks a different question, and an answer on one says nothing about the others. A name that returns nothing as a performer may still be a title.

Argument

Type

Required

What it does

query

string, up to 200 characters

yes

What to look for on that axis.

search_type

performer, title, writer, lyrics, label or year

yes

The axis to search along.

page

integer, 1 to 200, default 1

no

Which page of rows.

limit

integer, 1 to 50, default 20

no

Rows to serve.

search_type

Finds

performer

the artist credited on the record

title

the name of the song

writer

who wrote or composed it

lyrics

the words sung in it

label

the label it came out on

year

the year printed on it

The year axis takes one four-digit year and nothing else: the site drops any other word there instead of filtering on it. Several keywords are combined with AND and each is matched inside words, so every extra word narrows the search, and a quoted phrase returns nothing whatever the site's own form offers.

In return: rows carrying song_id, which get_song takes; title; url; and the artist. total_matches is the number the site prints, counting matching songs across every page, so it exceeds the rows of one page. page_served is the page the site actually served, since it answers a page past the last one with the last page and no error: read it rather than assuming the page asked for. page_count and has_more_pages are null where the site printed neither.

get_song

Reads one record in full.

Argument

Type

Required

What it does

song_id

string, up to 20 characters

yes

The id a search row carries.

include_lyrics

boolean, default true

no

Carry the transcribed words when the page has them.

In return: title, artist, credited_performer, year, writers, duration with the text exactly as the record prints it and its precision, labels with one entry per label, catalogue_reference, presentation, sleeve_credits, image_url, added_on as an ISO date, the station's chart placings, favourites and comments. The title, the artist and the duration are always stated; the rest is absent on some records and comes back null rather than guessed, and a counter the page prints nothing for is unknown rather than zero. lyrics.available says whether the page carries a transcription, and lyrics.text holds the words with the transcriber who wrote them down.

get_artist

Reads what the collection holds about one artist, with the records it has of theirs.

Argument

Type

Required

What it does

artist_id

string, up to 20 characters

yes

The artist id a record carries.

limit

integer, 1 to 200, default 100

no

Records of theirs to serve.

In return: name, aliases, surname, first_name, nationality, birth_date, presentation, see_also, links and photo_url, each null or empty where the page states nothing. discography carries their records, each with its song_id for get_song, its title, url, year and how often the station programmed it. discography_count counts the records served and songs_on_page the records the page held, so a truncated discography is visible.

get_random_song

Draws a record nobody chose, over the ids the site serves. It is for browsing the collection when no particular song is being asked about.

Argument

Type

Required

What it does

include_lyrics

boolean, default true

no

Carry the transcribed words when the page has them.

In return: the record get_song returns.

list_new_songs

Reads what the collection has just catalogued.

Argument

Type

Required

What it does

limit

integer, 1 to 50, default 20

no

Rows to serve.

In return: rows carrying song_id, title read off the line the feed publishes, artist_name, listed_as, url and published_at. entries_in_feed is the number of entries the feed holds, which is a fixed number and says nothing about how many records the collection holds.

Configuration

Every variable is optional. Set them in the env block of your client config.

Variable

Default

What it does

BIDE_USER_AGENT

the project identity

Names your application to the site, with an address where a person can be reached.

BIDE_MIN_INTERVAL_MS

3000

Gap between two requests, from 2000 to 60000.

BIDE_TIMEOUT_MS

20000

Deadline for one request, from 1000 to 120000.

BIDE_MAX_RETRIES

3

Attempts after a transient failure, from 0 to 10.

BIDE_CACHE_TTL_MS

900000

How long a page stays in memory, from 0 to 86400000.

BIDE_CACHE_MAX_ENTRIES

200

Pages held in memory at once, from 0 to 10000.

BIDE_LOG_LEVEL

error

silent, error, info or debug, written to stderr.

A value outside its range falls back to the default, and the reason is written to stderr.

Errors

Every failure carries one of six codes, a message, and where it helps a hint naming the next move.

Code

What happened

What to do

not_found

The site answered, and holds no such record.

Check the id with search_songs.

invalid_input

The arguments were refused before any request went out.

Read the message, which names the argument.

rate_limited

The site asked this client to slow down.

Wait the number of seconds the hint names and call again with the same arguments. The record is still there.

parse_failure

The page loaded and the expected content was absent.

Report it at the issue tracker.

network_error

The request did not complete.

Try again shortly.

timeout

The request passed its deadline.

Raise BIDE_TIMEOUT_MS, or ask for fewer rows.

As a library

The layer reading the site is published on its own, with its pacing, its cache and its errors, and with no protocol attached.

import { BideEtMusiqueClient } from "mcp-bideetmusique/client";

const client = new BideEtMusiqueClient();
const { data, cached } = await client.getSong("1234");
console.log(data.title, data.labels, cached);

search, getSong, getArtist and getNewSongs each answer { data, cached }, and throw an error carrying one of the six codes. The two-second floor between two requests holds here as well.

Pacing and attribution

Requests go out one at a time with at least three seconds between them, and the floor of two seconds holds however the server is configured. Bide & Musique is run by a volunteer association on its own means, and this pacing is what the collection is owed. The User-Agent always ends with the project identity and an address where a person can be reached.

Every result carries the address of the record's page. The catalogue is the work of the association and of the listeners who built it, transcriptions included.

This MCP server is an unofficial project, with no affiliation to Bide & Musique.

Privacy

This server collects nothing about you and sends nothing to its author. It runs on your machine, contacts www.bide-et-musique.com and nothing else, holds its answers in memory while it runs, and writes nothing to disk. PRIVACY.md states what a request carries and which settings change any of it.

Development

npm install
npm run build:fixtures
npm test
npm run check

Tests run against generated fixtures and make no network request. The live suite, npm run test:live, makes one request per route and runs nightly against the site itself.

Contributing

Bugs, questions and ideas belong in the issue tracker. Pull requests are welcome; opening an issue first helps agree on the shape of the change. See CONTRIBUTING.md.

License

MIT, see LICENSE. The catalogue belongs to Bide & Musique and to the listeners who built it.


mcp-bideetmusique (français)

English version

Bide & Musique est une radio web française et la collection de disques qu'elle diffuse, cataloguée à la main par l'association bénévole qui la tient. Son sujet est la chanson oubliée : le bide, le disque de fantaisie, le générique de télévision, le 45 tours que personne n'a réédité. La page d'un disque porte l'interprète, les auteurs et compositeurs, l'année, le label et sa référence de catalogue, la pochette, la durée, les classements du hit-parade de la station, et les paroles quand un auditeur les a transcrites.

Ce serveur relie un client de conversation à cette collection. On peut y chercher selon un axe à la fois, par interprète, titre, auteur, paroles, label ou année ; lire une fiche en entier ; lire ce que le site contient sur un artiste avec sa discographie ; tirer un disque au hasard ; et voir ce qui vient d'être catalogué. Aucune clé d'API, aucun compte.

Installation

Installation en un clic

Install in Cursor Install in VS Code

Claude Code

claude mcp add bideetmusique -- npx -y mcp-bideetmusique

Claude Desktop, Cursor, et tout client au format de configuration standard

{
  "mcpServers": {
    "bideetmusique": {
      "command": "npx",
      "args": ["-y", "mcp-bideetmusique"]
    }
  }
}

Node 24 ou plus récent est nécessaire, et aucune variable d'environnement n'est à renseigner.

Avec Docker

{
  "mcpServers": {
    "bideetmusique": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "ghcr.io/smeet666/mcp-bideetmusique:2.1.0"]
    }
  }
}

-i garde l'entrée standard ouverte, qui est le canal du protocole, et -t est omis parce qu'un TTY réécrit le flux. Le conteneur a besoin d'un accès HTTPS sortant vers www.bide-et-musique.com, et de rien d'autre : aucun volume, aucun port, aucun identifiant.

Bundle, sans npm

Téléchargez mcp-bideetmusique-2.1.0.mcpb depuis la dernière publication et ouvrez-le. Un client qui gère les bundles MCP l'installe seul, sans npm et sans fichier de configuration à modifier. Le bundle emporte ses dépendances, donc rien n'est téléchargé à l'installation.

Ce qu'on peut demander

  • « Qu'est-ce que Bide & Musique a de Jacques Dutronc ? »

  • « Quelles chansons parlent d'un sous-marin dans leurs paroles ? »

  • « Lis-moi cette fiche : le label, l'année, qui l'a écrite. »

  • « Fais-moi écouter quelque chose au hasard dans la collection. »

  • « Qu'est-ce qui a été catalogué récemment ? »

Le chemin ordinaire va d'une recherche à une fiche : une ligne porte un song_id, et get_song la lit.

Les outils

Outil

Ce qu'il fait

search_songs

Cherche dans la collection selon un axe à la fois.

get_song

Lit une fiche en entier, paroles comprises.

get_artist

Lit un artiste et les disques que la collection a de lui.

get_random_song

Tire un disque que personne n'a choisi.

list_new_songs

Lit ce que la collection vient de cataloguer.

search_songs

Cherche selon un axe, qu'il faut nommer : chacun pose une question différente, et une réponse sur l'un ne dit rien des autres. Un nom qui ne rend rien comme interprète peut très bien être un titre.

Argument

Type

Requis

Ce qu'il fait

query

chaîne, jusqu'à 200 caractères

oui

Ce qu'on cherche sur cet axe.

search_type

performer, title, writer, lyrics, label ou year

oui

L'axe de recherche.

page

entier, 1 à 200, défaut 1

non

Quelle page de lignes.

limit

entier, 1 à 50, défaut 20

non

Lignes à servir.

search_type

Trouve

performer

l'artiste crédité sur le disque

title

le nom de la chanson

writer

qui l'a écrite ou composée

lyrics

les mots qui y sont chantés

label

le label qui l'a publiée

year

l'année imprimée dessus

L'axe year prend une année à quatre chiffres et rien d'autre : le site laisse tomber tout autre mot au lieu de filtrer dessus. Plusieurs mots-clés sont combinés par ET et chacun est cherché à l'intérieur des mots, donc chaque mot supplémentaire resserre la recherche, et une expression entre guillemets ne rend rien, quoi qu'en propose le formulaire du site.

En retour : des lignes portant song_id, que get_song reprend ; title ; url ; et l'artist. total_matches est le nombre que le site imprime, comptant les chansons correspondantes sur toutes les pages, donc il dépasse les lignes d'une page. page_served est la page que le site a réellement servie, puisqu'il répond à une page au-delà de la dernière par la dernière page et sans erreur : lisez-la plutôt que de supposer la page demandée. page_count et has_more_pages valent null là où le site n'a imprimé ni l'un ni l'autre.

get_song

Lit une fiche en entier.

Argument

Type

Requis

Ce qu'il fait

song_id

chaîne, jusqu'à 20 caractères

oui

L'identifiant que porte une ligne.

include_lyrics

booléen, défaut true

non

Porter les paroles transcrites quand la page en a.

En retour : title, artist, credited_performer, year, writers, duration avec le texte exactement comme la fiche l'imprime et sa precision, labels avec une entrée par label, catalogue_reference, presentation, sleeve_credits, image_url, added_on en date ISO, les classements du hit-parade de la station, favourites et comments. Le titre, l'artiste et la durée sont toujours indiqués ; le reste est absent sur certaines fiches et revient null plutôt que deviné, et un compteur que la page n'imprime pas est inconnu plutôt que nul. lyrics.available dit si la page porte une transcription, et lyrics.text contient les mots avec le transcriber qui les a notés.

get_artist

Lit ce que la collection contient sur un artiste, avec les disques qu'elle a de lui.

Argument

Type

Requis

Ce qu'il fait

artist_id

chaîne, jusqu'à 20 caractères

oui

L'identifiant d'artiste que porte une fiche.

limit

entier, 1 à 200, défaut 100

non

Disques de lui à servir.

En retour : name, aliases, surname, first_name, nationality, birth_date, presentation, see_also, links et photo_url, chacun null ou vide là où la page n'indique rien. discography porte ses disques, chacun avec son song_id pour get_song, son title, url, year et le nombre de fois où la station l'a programmé. discography_count compte les disques servis et songs_on_page ceux que la page contenait, si bien qu'une discographie tronquée se voit.

get_random_song

Tire un disque que personne n'a choisi, parmi les identifiants que le site sert. Il sert à parcourir la collection quand aucune chanson précise n'est en question.

Argument

Type

Requis

Ce qu'il fait

include_lyrics

booléen, défaut true

non

Porter les paroles transcrites quand la page en a.

En retour : la fiche que rend get_song.

list_new_songs

Lit ce que la collection vient de cataloguer.

Argument

Type

Requis

Ce qu'il fait

limit

entier, 1 à 50, défaut 20

non

Lignes à servir.

En retour : des lignes portant song_id, title lu sur la ligne que le flux publie, artist_name, listed_as, url et published_at. entries_in_feed est le nombre d'entrées que le flux contient, qui est un nombre fixe et ne dit rien du nombre de disques que la collection contient.

Configuration

Chaque variable est facultative. Elles se posent dans le bloc env de la configuration du client.

Variable

Défaut

Ce qu'elle fait

BIDE_USER_AGENT

l'identité du projet

Nomme votre application auprès du site, avec une adresse où joindre une personne.

BIDE_MIN_INTERVAL_MS

3000

Écart entre deux requêtes, de 2000 à 60000.

BIDE_TIMEOUT_MS

20000

Délai d'une requête, de 1000 à 120000.

BIDE_MAX_RETRIES

3

Tentatives après un échec passager, de 0 à 10.

BIDE_CACHE_TTL_MS

900000

Durée pendant laquelle une page reste en mémoire, de 0 à 86400000.

BIDE_CACHE_MAX_ENTRIES

200

Pages gardées en mémoire à la fois, de 0 à 10000.

BIDE_LOG_LEVEL

error

silent, error, info ou debug, écrit sur la sortie d'erreur.

Une valeur hors de sa plage retombe sur le défaut, et la raison est écrite sur la sortie d'erreur.

Erreurs

Chaque échec porte un des six codes, un message, et quand cela aide une indication du geste suivant.

Code

Ce qui s'est passé

Que faire

not_found

Le site a répondu, et n'a pas cette fiche.

Vérifiez l'identifiant avec search_songs.

invalid_input

Les arguments ont été refusés avant toute requête.

Lisez le message, qui nomme l'argument.

rate_limited

Le site demande à ce client de ralentir.

Attendez les secondes indiquées et rappelez avec les mêmes arguments. La fiche est toujours là.

parse_failure

La page a chargé et le contenu attendu est absent.

Signalez-le sur le suivi d'incidents.

network_error

La requête n'a pas abouti.

Réessayez sous peu.

timeout

La requête a dépassé son délai.

Augmentez BIDE_TIMEOUT_MS, ou demandez moins de lignes.

Comme bibliothèque

La couche qui lit le site est publiée seule, avec son rythme, son cache et ses erreurs, sans protocole attaché.

import { BideEtMusiqueClient } from "mcp-bideetmusique/client";

const client = new BideEtMusiqueClient();
const { data, cached } = await client.getSong("1234");
console.log(data.title, data.labels, cached);

search, getSong, getArtist et getNewSongs répondent chacun { data, cached }, et lèvent une erreur portant un des six codes. Le plancher de deux secondes entre deux requêtes tient également ici.

Rythme et attribution

Les requêtes partent une à une avec au moins trois secondes entre elles, et le plancher de deux secondes tient quelle que soit la configuration. Bide & Musique est tenu par une association bénévole sur ses propres moyens, et ce rythme est ce qu'on doit à la collection. Le User-Agent se termine toujours par l'identité du projet et une adresse où joindre une personne.

Chaque résultat porte l'adresse de la page de la fiche. Le catalogue est l'œuvre de l'association et des auditeurs qui l'ont bâti, transcriptions comprises.

Ce MCP est un projet non officiel, sans affiliation à Bide & Musique.

Confidentialité

Ce serveur ne collecte rien sur vous et n'envoie rien à son auteur. Il tourne sur votre machine, ne joint que www.bide-et-musique.com, garde ses réponses en mémoire le temps qu'il tourne, et n'écrit rien sur le disque. PRIVACY.md dit ce qu'une requête emporte et quels réglages changent cela.

Développement

npm install
npm run build:fixtures
npm test
npm run check

Les tests s'exécutent sur des fixtures engendrées et n'émettent aucune requête. La suite en direct, npm run test:live, émet une requête par route et tourne chaque nuit contre le site lui-même.

Contribuer

Les anomalies, les questions et les idées ont leur place dans le suivi d'incidents. Les propositions de modification sont bienvenues ; ouvrir un ticket d'abord aide à s'accorder sur la forme du changement. Voir CONTRIBUTING.md.

Licence

MIT, voir LICENSE. Le catalogue appartient à Bide & Musique et aux auditeurs qui l'ont bâti.

Available Tools

5 tools
get_artistRead an artist's pageA
Read-onlyIdempotent

Read an artist's page on Bide & Musique: the names they recorded under, what the catalogue notes about them, and every song of theirs the collection holds, each with its year. Takes the 'artist_id' that search_songs, get_song and get_random_song return. An artist page is a way into a discography rather than a biography: half of them state nothing beyond the name, and the median artist has one record here. Fields the page does not state come back null or empty, which is the ordinary state of this catalogue rather than a failed read. The date of birth comes back exactly as written, since the catalogue states a full date, a bare year, or a date with a death beside it. Nationality is free text for the same reason. Rows come in the site's order, by year of release, never by importance. When you show an artist to a user, credit Bide & Musique and link the page.

NameRequiredDescriptionDefault
limitNoMaximum songs of the discography to return.
artist_idYesThe artist id returned by search_songs, get_song or get_random_song, digits only, for example '290'.

Output Schema

NameRequiredDescription
urlYes
nameYes
linksYesAddresses off the site, with the label the page gave them.
notesYes
sourceYes
aliasesYesOther names this artist recorded under, as the page stacks them.
surnameYes
see_alsoYes
artist_idYes
photo_urlYes
birth_dateYesExactly as published, which may be a day, a bare year, a month and a year, or a date with a death beside it. Nothing here is parsed into a date.
first_nameYes
discographyYes
nationalityYesAs the catalogue writes it, in its own words: 'suisse', 'franco-espagnole'.
presentationYes
songs_on_pageYesSongs the page held, before 'limit'.
discography_countYesSongs returned, after 'limit'.

TDQS

A4.5/5.0
Behavior5/5

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

Beyond the read-only annotations, the description discloses important data quirks: absent fields return null or empty rather than indicating failure, dates come through exactly as written, nationality is free text, and rows are ordered by release year rather than importance. It also states the attribution and linking requirement when presenting an artist to a user.

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?

The description is front-loaded with the core action and then adds only relevant caveats about missing fields, date formats, ordering, and attribution. Despite its length, each sentence contributes useful context for invoking and presenting the tool correctly.

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?

Given that an output schema exists, the description does not need to spell out return values. It still provides enough behavioral context—null/empty fields, free-text dates, ordering, and attribution—for an agent to use the tool correctly in this catalogue.

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 100%, and the schema already documents both 'artist_id' and 'limit', including examples and bounds. The description reinforces where 'artist_id' comes from but does not add meaning for 'limit' or other parameter behaviors beyond what the schema provides, so the baseline of 3 is appropriate.

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: read an artist's page on Bide & Musique, including recorded names, catalogue notes, and held songs with years. It distinguishes the artist page from a biography and explains that it is an entry point into a discography, making its role clear against sibling lookup tools.

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?

It clearly says the tool takes an 'artist_id' returned by search_songs, get_song, and get_random_song, which gives the agent a concrete usage path. It also frames the page as a discography entry rather than a biography, though it does not explicitly state when not to use this tool or name an alternative for artist search.

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

get_random_songRead a record drawn at randomA
Read-only

Read one record drawn at random from the Bide & Musique collection: same answer as get_song, on a record nobody chose. Use it to browse the collection. For a question about a particular song, use get_song. The draw runs over the ids the site serves, from the first to the newest one its feed of new entries names, and an id the collection does not serve is drawn again. Records whose page carries a transcription come back with the words themselves, as published. When you show a record to a user, credit Bide & Musique and link the page.

NameRequiredDescriptionDefault
include_lyricsNoWhether to return the transcription the drawn record's page carries. Browsing chains many calls, and a record with one runs to a few thousand characters.

Output Schema

NameRequiredDescription
urlYes
yearYes
notesYes
titleYes
top50Yes
artistYes
labelsYesOne entry per label, two when a record was co-released.
lyricsYes
sourceYes
song_idYes
writersYesWriters and composers as credited, one entry each, empty when the record credits none. A few records name the part someone took, and the entry then reads as the site prints it, for example 'Paroles : Jean-Pierre Lang'.
added_onYesThe day the collection catalogued it, as an ISO date.
commentsYes
durationYes
see_alsoYesOther artists the record links to.
image_urlYes
favouritesYesHow many people keep it as a favourite. Null when the page prints no counter.
presentationYesWhat the catalogue wrote about the record.
thumbnail_urlYes
sleeve_creditsYesWho is credited for the sleeve, when anyone is.
credited_performerYesA performer the sleeve credits apart from the artist page, when the record names one.
catalogue_referenceYesThe reference printed on the record. A reference of four digits is not a year.

TDQS

A4.6/5.0
Behavior4/5

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

Annotations already declare readOnly, non-destructive, non-idempotent and open-world, but the description adds real context on top: the draw runs over the ids the site serves, up to the newest entry in the new-entries feed, and a non-served id is drawn again. It also explains that transcriptions are returned as published and imposes an attribution/link obligation when surfacing a record to a user. It stops short of describing what the response envelope looks like, but the output schema covers that.

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 definition and the alternative routing up front, followed by sampling mechanics and the attribution rule. Slightly redundant to say 'same answer as get_song' and then again to defer particular-song questions to get_song, but the repetition serves clarity rather than padding.

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?

For a single optional-parameter read tool with an output schema and full annotation coverage, the description supplies everything an agent needs: what is drawn, over what domain, what happens on a miss, how lyrics behave, and the credit/link requirement. Return-value shape is legitimately left to the output schema.

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 coverage is 100% and the single parameter already carries a description, so the baseline is 3. The description adds meaning beyond it by clarifying that only records whose page carries a transcription return words, as published, which tells the agent what include_lyrics actually varies. It adds no default or format detail beyond the 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 and resource (read one record drawn at random from the Bide & Musique collection) and immediately distinguishes it from the sibling get_song: same answer, on a record nobody chose. An agent can tell it apart from search_songs and get_song 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?

Gives explicit when-to-use ('Use it to browse the collection') and when-not ('For a question about a particular song, use get_song'), naming the alternative directly. No inference is required to route between this tool and get_song.

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

get_songRead a song's recordA
Read-onlyIdempotent

Read one song's record on Bide & Musique: the year, the writers and composers, the duration, the label and its catalogue reference, the sleeve, when the collection catalogued it, how it ranked in the station's own chart, and how many people kept it as a favourite. Takes the 'song_id' that search_songs returns. Three things are always there: the title, the artist and the duration. Everything else is absent on some records, and comes back null or empty rather than guessed; a counter the record does not print is unknown, not zero. Records whose page carries a transcription come back with the words themselves, as published, along with who typed them. A record whose page carries none says so. When you show a record to a user, credit Bide & Musique and link the page.

NameRequiredDescriptionDefault
song_idYesThe song id returned by search_songs, digits only, for example '1734'.
include_lyricsNoWhether to return the transcription the page carries. A record whose page has one runs to a few thousand characters, so ask for false when the question is about the record: the year, the label or the writers. 'lyrics.available' still says whether the page has one.

Output Schema

NameRequiredDescription
urlYes
yearYes
notesYes
titleYes
top50Yes
artistYes
labelsYesOne entry per label, two when a record was co-released.
lyricsYes
sourceYes
song_idYes
writersYesWriters and composers as credited, one entry each, empty when the record credits none. A few records name the part someone took, and the entry then reads as the site prints it, for example 'Paroles : Jean-Pierre Lang'.
added_onYesThe day the collection catalogued it, as an ISO date.
commentsYes
durationYes
see_alsoYesOther artists the record links to.
image_urlYes
favouritesYesHow many people keep it as a favourite. Null when the page prints no counter.
presentationYesWhat the catalogue wrote about the record.
thumbnail_urlYes
sleeve_creditsYesWho is credited for the sleeve, when anyone is.
credited_performerYesA performer the sleeve credits apart from the artist page, when the record names one.
catalogue_referenceYesThe reference printed on the record. A reference of four digits is not a year.

TDQS

A4.7/5.0
Behavior5/5

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

Annotations already declare read-only, idempotent, open-world, but the description adds substantive behavior: null/empty means absent rather than zero, unknown counters are not zero, lyrics come back verbatim with their transcriber or an explicit 'no transcription' signal, and results require attribution and a link. None of that is in the structured fields.

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 purpose, then input provenance, then null semantics and lyric behavior. It is dense but long, and the opening field enumeration partly duplicates what the output schema already declares, so a little could be trimmed.

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 document return values, yet it adds the interpretive rules an agent needs (null vs zero, lyrics availability) plus the attribution obligation. Nothing required to call it correctly is missing.

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 coverage is 100% and the description still adds meaning: it reinforces that song_id must come from search_songs and explains why include_lyrics=false is the right choice for record-level questions, matching the schema's own rationale.

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?

Opens with a specific verb and resource ('Read one song's record') and enumerates the fields the record carries, which lets an agent distinguish it from search_songs, get_artist, get_random_song and list_new_songs at a glance.

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?

Explicitly ties its input to a sibling ('Takes the song_id that search_songs returns') and gives a concrete condition for the include_lyrics flag ('ask for false when the question is about the record'). It never states exclusions, e.g. that it is the wrong tool for bulk or by-artist lookups, but the workflow context is clear.

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

list_new_songsRead what was just cataloguedA
Read-onlyIdempotent

Read the records Bide & Musique has just catalogued. The collection is built by hand and grows a few records at a time, so this answers what has been added lately rather than what the station is playing. The feed carries a fixed number of entries and offers no second page, so the count is what it holds and says nothing about how many records the collection has. Entries come in the order the feed publishes them, which runs newest first without being sorted: read 'published_at' rather than the position to date one. Each entry names the song and the artist as one line, which is read apart at the first separator and kept whole under 'listed_as'. Use get_song on the id for the record itself: year, writers, label, duration and the words when the page carries them. When you show a record to a user, credit Bide & Musique and link the page.

NameRequiredDescriptionDefault
limitNoMaximum entries to return, taken from the head of the feed.

Output Schema

NameRequiredDescription
notesYes
sourceYes
resultsYes
result_countYes
entries_in_feedYesHow many entries the feed carries, read or not. It is a fixed window on the newest records, never a count of the collection.

TDQS

A4.6/5.0
Behavior5/5

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

Goes well past the annotations: fixed feed size with no second page, the count reflects the page not the collection, newest-first ordering that is not sorted so 'published_at' must be read rather than position, the 'listed_as' combined line and how to split it, and a credit/link obligation when presenting records. That is exactly the contextual load the annotations do not carry.

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?

Six sentences, front-loaded with scope before the ordering and format details, and each sentence carries a distinct fact. Some framing ('The collection is built by hand and grows a few records at a time') is atmospheric rather than operational, which costs it the top mark.

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, return fields need no explanation, yet the description still supplies ordering semantics, entry shape and the attribution requirement. Nothing an agent needs in order to call this correctly and present results responsibly is missing.

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 coverage is 100% and already documents limit (default 20, max 50, taken from the head of the feed). The description adds genuinely useful constraint context – the feed has a fixed number of entries and no second page – which explains why the limit behaves as it does, though it never restates the parameter's bounds itself.

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?

Opens with a specific verb and resource ('Read the records Bide & Musique has just catalogued') and immediately scopes it away from what the station is playing. An agent can distinguish this from search_songs or get_random_song 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?

Explicitly routes the agent onward: 'Use get_song on the id for the record itself' for year, writers, label, duration and lyrics, and contrasts the feed's scope with 'what the station is playing'. It never names search_songs as the alternative for the full collection, so the exclusion is implied rather than stated.

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

search_songsSearch songsA
Read-onlyIdempotent

Search the Bide & Musique collection: French songs, mostly forgotten ones, catalogued by hand since 2000 by the association that runs the station. Bide & Musique is a French site, so French terms work best. 'search_type' picks the axis and has to be stated: 'performer' for the artist credited on the record, 'title' for the name of the song, 'writer' for who wrote or composed it, 'lyrics' for the words sung in it, 'label' for the label it came out on, 'year' for the year printed on it. Each asks a different question and they are never merged, so a name that finds nothing as a performer may still be a title. 'year' takes one four-digit year and nothing else: the site drops any other word on that axis instead of filtering on it, and the ranges its own form documents return nothing. To combine a year with words, search the words on their own axis and read each record's year from its page. Use 'lyrics' to find a song from a line someone remembers. It answers with the songs whose words match, without showing what matched; read the words themselves with get_song on the id. Several keywords are combined with AND, each matched inside words, so every extra word narrows the search and never widens it. Quoting a phrase returns nothing, whatever the site's own form says. Results carry the song id, the artist and the page to read, which is where the song's own record lives: year, label, catalogue reference and writers. The count returned counts matching songs across every page, so it is usually larger than the rows of one page; ask for the next page with 'page'. When you show a song to a user, credit Bide & Musique and link the source URL.

NameRequiredDescriptionDefault
pageNoWhich page of results to read. The answer states which page the site served.
limitNoMaximum songs to return from that page.
queryYesWhat to search for, in French, for example 'Pierre Bachelet' or 'vacances'.
search_typeYesWhich axis to search: 'performer' for the artist credited on the record, 'title' for the name of the song, 'writer' for who wrote or composed it, 'lyrics' for the words sung in it, 'label' for the label it came out on, 'year' for the year printed on it. The 'year' axis takes one four-digit year and nothing else: the site drops any other word there instead of filtering on it.

Output Schema

NameRequiredDescription
notesYes
queryYes
sourceYes
resultsYes
page_countYes
page_servedYesThe page the site actually served, read from its pagination bar. Asking for a page past the last one returns the last page, so this can differ from 'page_requested'.
search_typeYes
result_countYesSongs returned, after 'limit'.
rows_on_pageYesSongs this page held, before 'limit'.
total_matchesYesThe number Bide & Musique prints above the results, counting matching songs across every page. Null when the site printed none, which is different from zero.
has_more_pagesYes
page_requestedYes

TDQS

A4.9/5.0
Behavior5/5

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

Beyond annotations declaring a safe read-only idempotent operation, the description discloses important quirks: the year axis accepts only one four-digit year, ranges return nothing, quoted phrases return nothing, keywords are ANDed within words, and count spans all pages rather than one page.

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 description is front-loaded and most sentences carry operational value, but it repeats the search_type enum definitions at length even though the schema already describes them fully. Slightly tighter editing would improve it without losing the important caveats.

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?

For a search tool with an output schema and read-only annotations, the description covers the remaining gaps an agent needs: query semantics, paging, result count meaning, result fields, attribution, and where to read full song details.

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?

Although schema coverage is 100%, the description adds critical semantics not captured by the schema: the axes are never merged, extra words narrow rather than widen, the year axis silently drops other words, and lyrics matches without showing the matched text.

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: searching the Bide & Musique song collection. It also clearly separates this from siblings by explaining that records are read with get_song on the returned id.

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?

It gives explicit when-to-use guidance for each axis, especially lyrics for finding a song from a remembered line, and explains why a failed performer search does not mean the name is absent. It also handles the year-combination limitation and points to get_song for record details.

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. 5 tool updatesv2.1.0
    • Changedget_artist18 fields changed
      • removedOutput schema / properties / birth_date / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / birth_date / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / discography / items / properties / image_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / discography / items / properties / image_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / discography / items / properties / programming / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / discography / items / properties / programming / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / discography / items / properties / thumbnail_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / discography / items / properties / thumbnail_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / first_name / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / first_name / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / nationality / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / nationality / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / photo_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / photo_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / presentation / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / presentation / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / surname / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / surname / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedget_random_song16 fields changed
      • removedOutput schema / properties / added_on / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / added_on / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / catalogue_reference / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / catalogue_reference / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / credited_performer / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / credited_performer / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / image_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / image_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / lyrics / properties / text / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lyrics / properties / text / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / lyrics / properties / transcriber / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lyrics / properties / transcriber / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / presentation / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / presentation / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / thumbnail_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / thumbnail_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedget_song16 fields changed
      • removedOutput schema / properties / added_on / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / added_on / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / catalogue_reference / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / catalogue_reference / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / credited_performer / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / credited_performer / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / image_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / image_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / lyrics / properties / text / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lyrics / properties / text / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / lyrics / properties / transcriber / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / lyrics / properties / transcriber / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / presentation / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / presentation / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / thumbnail_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / thumbnail_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedlist_new_songs4 fields changed
      • removedOutput schema / properties / results / items / properties / artist_name / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / artist_name / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / results / items / properties / published_at / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / published_at / type
        Added value: +[
        +  "string",
        +  "null"
        +]
    • Changedsearch_songs10 fields changed
      • removedOutput schema / properties / has_more_pages / anyOf
        Removed value: -[
        -  {
        -    "type": "boolean"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / has_more_pages / type
        Added value: +[
        +  "boolean",
        +  "null"
        +]
      • removedOutput schema / properties / results / items / properties / artist / properties / alias_of / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / artist / properties / alias_of / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / results / items / properties / image_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / image_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / results / items / properties / programming / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / programming / type
        Added value: +[
        +  "string",
        +  "null"
        +]
      • removedOutput schema / properties / results / items / properties / thumbnail_url / anyOf
        Removed value: -[
        -  {
        -    "type": "string"
        -  },
        -  {
        -    "type": "null"
        -  }
        -]
      • addedOutput schema / properties / results / items / properties / thumbnail_url / type
        Added value: +[
        +  "string",
        +  "null"
        +]
  2. 2 tool updatesv1.0.0
    • Changedget_artist1 field changed
      • changedInput schema / properties / artist_id / description
        Previous value: -"The artist id returned by search_songs or get_song, digits only, for example '290'."New value: +"The artist id returned by search_songs, get_song or get_random_song, digits only, for example '290'."
    • Changedget_random_song1 field changed
      • addedInput schema / properties / include_lyrics
        Added value: +{
        +  "default": true,
        +  "description": "Whether to return the transcription the drawn record's page carries. Browsing chains many calls, and a record with one runs to a few thousand characters.",
        +  "type": "boolean"
        +}
  3. 5 tool updatesv0.3.0
    • First observedget_artist
    • First observedget_random_song
    • First observedget_song
    • First observedlist_new_songs
    • First observedsearch_songs

TDQS

A4.7/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct role: search_songs finds songs by a chosen axis, get_song reads one record by id, get_artist opens a discography, get_random_song browses, and list_new_songs surfaces recent additions. The descriptions explicitly resolve the only potential overlaps ('for a particular song, use get_song' vs random; 'read the words with get_song on the id' after a lyrics search). An agent can pick correctly without guessing.

Naming Consistency5/5

Uniform verb_noun snake_case throughout: search_songs, get_song, get_artist, get_random_song, list_new_songs. Plural nouns for search/list collection operations and singular for single-record reads, which is a coherent, predictable convention.

Tool Count5/5

Five tools is well-scoped for a read-only niche song catalogue: discovery (search, random, new) plus drill-down (song, artist). No redundant or filler tools; each covers a workflow the others cannot.

Completeness4/5

The surface covers the full read lifecycle: multi-axis search with paging, single-record detail, artist discography, random browsing, and recent additions. Minor gaps exist (no way to browse by label or chart ranking as an entry point, no combined field filtering), but the descriptions show agents can work around these via search axes and per-record year reading.

Maintenance

ActivityActive
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers