Skip to main content
Glama

Score one song for a voice

check_song_fit
Read-onlyIdempotent

Score a specific catalog song against a singer's range and explain why it fits or does not, including a suggested key to transpose to. Call this when someone asks whether they can sing a particular song. Resolve the song with search_songs first to get its slug.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
slugYesThe catalog slug of the song, from search_songs.
rangeLowYesLowest comfortable note, as a note name like "D3" or a raw MIDI number.
rangeHighYesHighest comfortable note, as a note name like "C5" or a raw MIDI number.
voiceTypeNoOptional voice type hint (soprano, mezzo, alto, tenor, baritone, bass). Inferred from the range when omitted.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
urlNoCanonical HumMatch page for the song.
slugYesCatalog slug; the identifier check_song_fit takes.
yearNo
genreNo
titleYes
artistYes
reasonNoPlain-language verdict.
lowNoteNoLowest note of the song as a MIDI number.
highNoteNoHighest note of the song as a MIDI number.
whyItFitsNo
fitDetailsNoLabels behind the scores.
matchScoreYesOverall suitability for this voice, 0-100.
lowNoteNameNoSame as lowNote, as a note name like "G2".
rangeSourceNoProvenance tag for the range, e.g. "estimated_curated_seed".
riskWarningNo
highNoteNameNoSame as highNote, as a note name like "C#5".
suggestedKeyNoTransposition advice, e.g. "Try a lower key".
vocalFitScoreNoHow well the song range sits inside the singer range, 0-100.
likelyVoiceFitNo
tessituraScoreNoHow comfortable the song sits where the voice spends most time, 0-100.
difficultyScoreNoKaraoke difficulty, 0-100. Higher is harder.
rangeConfidenceYesHow the range was established, strongest first. "manual_research" was researched against sheet music or a score and is the most trustworthy tier. "estimated" was derived from published sources rather than measured, so present those scores as guidance rather than fact. "high" and "low" are legacy confidence labels. "unknown" means no range data.
voiceTypeFitScoreNoFit against the voice type lane, 0-100. Can be high while matchScore is low when the range still exceeds the singer.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedOutput schema / properties / rangeConfidence / description
      Previous value: -"How the range was established. \"verified\" was measured from the recording; \"estimated\" was derived from published sources and should be presented as guidance, not fact; \"unknown\" means no range data."New value: +"How the range was established, strongest first. \"manual_research\" was researched against sheet music or a score and is the most trustworthy tier. \"estimated\" was derived from published sources rather than measured, so present those scores as guidance rather than fact. \"high\" and \"low\" are legacy confidence labels. \"unknown\" means no range data."
    • addedOutput schema / properties / rangeConfidence / enum
      Added value: +[
      +  "manual_research",
      +  "estimated",
      +  "high",
      +  "low",
      +  "unknown"
      +]
  2. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "artist": {
      +      "type": "string"
      +    },
      +    "difficultyScore": {
      +      "description": "Karaoke difficulty, 0-100. Higher is harder.",
      +      "type": [
      +        "integer",
      +        "null"
      +      ]
      +    },
      +    "fitDetails": {
      +      "description": "Labels behind the scores.",
      +      "properties": {
      +        "catalogQualityLabel": {
      +          "type": "string"
      +        },
      +        "familiarityTier": {
      +          "type": "string"
      +        },
      +        "likelyVoiceFit": {
      +          "type": "string"
      +        },
      +        "missingRange": {
      +          "type": "boolean"
      +        },
      +        "priorityTier": {
      +          "type": "integer"
      +        },
      +        "rangeFitLabel": {
      +          "description": "e.g. \"Comfortable\", \"Exploratory\".",
      +          "type": "string"
      +        },
      +        "reviewedSongProfile": {
      +          "type": "boolean"
      +        },
      +        "riskLabel": {
      +          "description": "e.g. \"May be too high\".",
      +          "type": "string"
      +        },
      +        "toneReliable": {
      +          "type": "boolean"
      +        },
      +        "trustPhrases": {
      +          "items": {
      +            "type": "string"
      +          },
      +          "type": "array"
      +        },
      +        "voiceTypeFitLabel": {
      +          "type": "string"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    "genre": {
      +      "type": "string"
      +    },
      +    "highNote": {
      +      "description": "Highest note of the song as a MIDI number.",
      +      "type": [
      +        "integer",
      +        "null"
      +      ]
      +    },
      +    "highNoteName": {
      +      "description": "Same as highNote, as a note name like \"C#5\".",
      +      "type": "string"
      +    },
      +    "likelyVoiceFit": {
      +      "type": "string"
      +    },
      +    "lowNote": {
      +      "description": "Lowest note of the song as a MIDI number.",
      +      "type": [
      +        "integer",
      +        "null"
      +      ]
      +    },
      +    "lowNoteName": {
      +      "description": "Same as lowNote, as a note name like \"G2\".",
      +      "type": "string"
      +    },
      +    "matchScore": {
      +      "description": "Overall suitability for this voice, 0-100.",
      +      "type": "integer"
      +    },
      +    "rangeConfidence": {
      +      "description": "How the range was established. \"verified\" was measured from the recording; \"estimated\" was derived from published sources and should be presented as guidance, not fact; \"unknown\" means no range data.",
      +      "type": "string"
      +    },
      +    "rangeSource": {
      +      "description": "Provenance tag for the range, e.g. \"estimated_curated_seed\".",
      +      "type": "string"
      +    },
      +    "reason": {
      +      "description": "Plain-language verdict.",
      +      "type": "string"
      +    },
      +    "riskWarning": {
      +      "type": "string"
      +    },
      +    "slug": {
      +      "description": "Catalog slug; the identifier check_song_fit takes.",
      +      "type": "string"
      +    },
      +    "suggestedKey": {
      +      "description": "Transposition advice, e.g. \"Try a lower key\".",
      +      "type": "string"
      +    },
      +    "tessituraScore": {
      +      "description": "How comfortable the song sits where the voice spends most time, 0-100.",
      +      "type": "integer"
      +    },
      +    "title": {
      +      "type": "string"
      +    },
      +    "url": {
      +      "description": "Canonical HumMatch page for the song.",
      +      "type": "string"
      +    },
      +    "vocalFitScore": {
      +      "description": "How well the song range sits inside the singer range, 0-100.",
      +      "type": "integer"
      +    },
      +    "voiceTypeFitScore": {
      +      "description": "Fit against the voice type lane, 0-100. Can be high while matchScore is low when the range still exceeds the singer.",
      +      "type": "integer"
      +    },
      +    "whyItFits": {
      +      "type": "string"
      +    },
      +    "year": {
      +      "type": [
      +        "integer",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "slug",
      +    "title",
      +    "artist",
      +    "matchScore",
      +    "rangeConfidence"
      +  ],
      +  "type": "object"
      +}
  3. First observed

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint. The description adds behavioral context beyond these by explaining that the tool not only scores but also 'explain why it fits or does not, including a suggested key to transpose to.' This describes the output behavior without contradicting the annotations.

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 three sentences long, front-loaded with the core purpose, and each sentence contributes necessary information: what it does, when to use it, and a prerequisite. No wasted words or redundant restating of the title.

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 the tool's moderate complexity, the presence of rich annotations, a complete input schema with 100% descriptions, and an output schema, the description fully covers the necessary context. It tells the agent exactly when and how to invoke the tool, and the schema/output schema cover the technical details.

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 100%, so the schema already documents each parameter. The description adds valuable semantic context for the slug parameter by noting it comes from search_songs. This extra guidance helps the agent understand the parameter's provenance 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?

The description clearly states the tool's function: 'Score a specific catalog song against a singer's range and explain why it fits or does not.' It distinguishes itself from siblings like recommend_songs and group_song_fit by focusing on a single song evaluation, and directly mentions the search_songs prerequisite.

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?

The description provides explicit usage context: 'Call this when someone asks whether they can sing a particular song.' It also gives a clear instruction to resolve the song via search_songs first. While it doesn't explicitly state when not to use it or name alternatives, the context is unambiguous and actionable.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources