# FreqBlog Music Metadata (remote · mcp.freqblog.com)

Audio features + harmonic set-building for tracks by name/ISRC. Spotify audio-features replacement.

- Trust score: 66/100 (medium)
- Change this week: +5
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `mcp.freqblog.com`: 66/100 (this document), [markdown](https://verifymcp.io/servers/com-freqblog-music-metadata/mcp.md), [page](https://verifymcp.io/servers/com-freqblog-music-metadata/mcp)

## Channel facts

- Endpoint: `https://mcp.freqblog.com/mcp`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.1.0`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Endpoint Security**: 63/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation not fully verified: no authorisation is required to call this server, and 12 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe.
  - HTTPS is enforced; there's no plaintext access path.
  - The HSTS (Strict-Transport-Security) header is present.
  - DNSSEC check failed: this domain isn't protected by DNSSEC.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 57/100
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 4267 tokens (~355/item across 12 items; 12 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add --transport http com-freqblog-music-metadata https://mcp.freqblog.com/mcp
```

### Codex

```toml
[mcp_servers.com-freqblog-music-metadata]
url = "https://mcp.freqblog.com/mcp"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "com-freqblog-music-metadata": {
      "type": "remote",
      "url": "https://mcp.freqblog.com/mcp",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add com-freqblog-music-metadata --url https://mcp.freqblog.com/mcp --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  com-freqblog-music-metadata:
    url: "https://mcp.freqblog.com/mcp"
```

### Other

```json
{
  "mcpServers": {
    "com-freqblog-music-metadata": {
      "type": "http",
      "url": "https://mcp.freqblog.com/mcp"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 66, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-01 (score 65, +2)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 63, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-29 (score 63, +1)

- [security] Tool “search_catalog” rewrote its description, which is the text the model reads

### 2026-07-28 (score 62, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-07-27 (score 61, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 60)

First indexed and scored.

## MCP tools (12)

### `get_audio_features` (~516 tokens)

Get Audio Features

Get audio features for ONE track — BPM, musical key (name + Camelot + Open Key),
    energy, danceability, valence, acousticness, instrumentalness, liveness, speechiness,
    loudness, mood, mood_vector, genre, time signature, duration and more.

    This is the drop-in replacement for Spotify's deprecated /audio-features endpoint.
    Provide EXACTLY ONE identifier:
      - `track` (optionally with `artist`) — e.g. track="Blinding Lights", artist="The Weeknd".
      - `isrc` — e.g. "USUM71900001".
      - `mbid` — a MusicBrainz recording UUID.
      - `spotify_id` — a Spotify track ID, URI, or URL (resolves only the <1% of the
        catalog already mapped to a Spotify ID; prefer `track`/`isrc` for full coverage).

    Returns a JSON object of features. Some feature fields may be null for tracks resolved
    via the fallback catalogs (only audio-derived values are present for fully analysed
    tracks). If a track name is not yet in the catalog, the API holds the request during the
    on-demand ingest and usually returns the fully analysed track inline in this same call;
    only if the ingest runs long does it fall back to a queued response you can re-poll
    shortly (~15s). If the track turns out not to be on any streaming source we can analyse,
    you get a definitive not-found instead — that verdict is terminal for ~7 days, so don't
    retry it. If you only have a fuzzy or partial name, call search_catalog first to
    find the exact track.

Input parameters:

- `artist`: Artist name. Only used with `track`; required when the title is <=2 characters.
- `isrc`: ISRC, e.g. 'USUM71900001'.
- `mbid`: MusicBrainz recording ID (UUID). The precise key when there is no ISRC, e.g. pre-1986 recordings.
- `spotify_id`: Spotify track ID, 'spotify:track:...' URI, or open.spotify.com URL. Resolves ONLY tracks already mapped to a Spotify ID (<1% of the catalog) — prefer track (+artist) or isrc.
- `track`: Track title. Use with `artist` when known. Required field is ONE of track/isrc/mbid/spotify_id.

### `get_audio_features_batch` (~347 tokens)

Get Audio Features (Batch)

Get audio features for MANY tracks in one call (up to 50 processed) — ideal for
    analysing a whole playlist at once. Identify each item by name (`track`/`artist`), by
    `isrc` (matched exactly first — best for CJK / K-pop / niche tracks whose fuzzy
    name-match misses), or both (ISRC first, name as the fallback).

    One bad entry never fails the batch. Items beyond the 50-per-call cap come back with
    `found: false` and `backfill_status: "over_limit"`; an item missing BOTH `track` and
    `isrc` comes back `"invalid_no_query"`. Neither is processed or charged — the response's
    `skipped` field counts them, so split a long list into calls of <=50 and resubmit any
    skipped rows.

    Returns counts (`found` / `not_found` / `skipped`) plus a per-track `results` array, where
    each entry's `result` is the same feature object as get_audio_features (or null when not
    found), and `isrc` is echoed back. An item is billed only when it returns features or
    queues an on-demand ingest; an ISRC/name with no match anywhere is free. For a single
    track, use get_audio_features.

Input parameters:

- `tracks` (array, required): List of {track?, artist?, isrc?} objects. Up to 50 are processed per call; any extra (up to 200 accepted) come back skipped. Each item should carry `track` or `isrc`.

### `search_catalog` (~289 tokens)

Search Music Catalog

Full-text search the catalog by any mix of track / artist / album tokens. Use this to
    resolve a fuzzy, partial, or misspelled name into concrete tracks BEFORE calling
    get_audio_features.

    Returns lightweight stubs (itunes_track_id, track_name, artist_name, album, etc.) ranked
    by relevance — NOT audio features. Take the best match's track_name + artist_name and
    pass them to get_audio_features, or reuse its itunes_track_id as a `track_id` seed for
    discovery tools.

    ⚠ Each hit carries a `seedable` boolean. Only a hit with `seedable: true` can be used as
    a seed for get_recommendations / suggest_next_track / build_setlist / score_transition —
    those work off the similarity index, which holds only tracks we have analysed, and about
    a quarter of the catalogue is not analysed yet. **Prefer the highest-ranked hit with
    `seedable: true`.** Seeding with a `seedable: false` id returns a 404; if that track is
    the one you want, call get_audio_features on it first to queue analysis, then retry.

Input parameters:

- `limit` (integer): Max results (default 10).
- `q` (string, required): Search query — any mix of artist / track / album tokens.

### `find_tracks_by_bpm` (~125 tokens)

Find Tracks by BPM

Find catalog tracks near a target tempo. Returns tracks whose BPM is within
    +/-`tolerance` of `bpm`, ordered by closeness then popularity — useful for DJ set
    planning, workout playlists, or tempo-matching. Each returned track carries full audio
    features. To also constrain by musical key, combine with find_tracks_by_key.

Input parameters:

- `bpm` (number, required): Target tempo in BPM.
- `limit` (integer): Max tracks (default 10).
- `tolerance` (number): Plus/minus BPM window (default 2).

### `find_tracks_by_key` (~140 tokens)

Find Tracks by Musical Key

Find catalog tracks in a given musical key — for harmonic mixing and key-locked
    playlists. `key` accepts Camelot ("8A"), Open Key ("1m"), or a key name ("A-Minor",
    "F#-Major"). Returns tracks ordered by popularity, each with full audio features. To
    discover which keys mix well with a given key first, use find_compatible_keys.

Input parameters:

- `key` (string, required): Camelot ('8A'), Open Key ('1m'), or key name ('A-Minor', 'F#-Major').
- `limit` (integer): Max tracks (default 10).

### `find_compatible_keys` (~160 tokens)

Find Harmonically Compatible Keys

Given a Camelot key (e.g. "8A", "12B"), return the harmonically compatible keys for DJ
    mixing — the same key, the relative major/minor, and the adjacent +/-1 keys on the
    Camelot wheel. With `extended=true` also returns the +7/-7 energy-boost / energy-drop
    keys. Pure music theory — no catalog lookup and no quota cost. Pair with find_tracks_by_key
    to then pull actual tracks in each compatible key.

Input parameters:

- `camelot` (string, required): Camelot key, e.g. '8A' or '12B'.
- `extended` (boolean): Also return the +7/-7 energy-boost / energy-drop keys.

### `score_transition` (~267 tokens)

Score Transition

Score how well one catalog track mixes into another (0-100) — the pairwise DJ transition
    score no raw key/BPM API gives you. Combines Camelot-wheel key compatibility, octave-aware
    BPM proximity (half/double-time counts as a match), and energy smoothness.

    Returns the overall `score`, per-component scores (`harmonic`/`tempo`/`energy`), a `detail`
    block (key_relation, both Camelot keys, both BPMs, bpm_delta, bpm_octave_matched, both
    energies, energy_delta), and a one-line human `reason` (e.g. "8A->9A adjacent (+1), 126->128
    BPM (+2), energy +0.04 — clean uplifting mix"). Both ids are catalog itunes_track_ids — get
    them from search_catalog or the itunes_track_id field of a get_audio_features result. Costs
    1 quota unit.

Input parameters:

- `from_track_id` (string, required): The track you're mixing FROM — a catalog itunes_track_id, e.g. 'apple_ad1829eeccb70f9a'.
- `to_track_id` (string, required): The candidate track you're mixing INTO — a catalog itunes_track_id.

### `suggest_next_track` (~424 tokens)

Suggest Next Track

Given a seed track, return the top-N catalog tracks to play NEXT, ranked by transition
    score. Each suggestion carries the same `score`, per-component scores and human `reason` as
    score_transition (e.g. "11B->11B same key, 118->117 BPM (-0.29), energy +0.12"), plus its
    `genre` and `genre_relation` to the seed. GENRE-AWARE by default (cross_genre=auto): off-genre
    picks that only coincidentally share the seed's key/BPM sink to the bottom — use
    cross_genre=strict for same-genre-family only, or allow for the old harmonic-only ranking. It
    is the seed's sonic neighbours re-ranked for a clean mix.

    Returns `seed`, `count`, and a `suggestions` array of {track, score, components, reason}.
    seed_track_id is a catalog itunes_track_id from search_catalog or a get_audio_features
    result. Pair with build_setlist to order a whole crate. Costs 3 quota units.

Input parameters:

- `bpm_drift` (number): Max BPM difference pre-filter before scoring (default 12).
- `cross_genre` (string): Genre handling: 'auto' (default) keeps picks in a mixable genre lane so an off-genre track that only shares key/BPM sinks to the bottom; 'strict' = same genre-family only; 'allow' = genre-blind (harm…
- `exclude_same_artist` (boolean): Drop tracks by the seed's artist (default false).
- `max_key_distance` (integer): Max Camelot-wheel hops pre-filter before scoring (default 2).
- `min_score` (integer): Drop candidates below this overall transition score (default 0).
- `n` (integer): How many next-track suggestions to return (default 10).
- `seed_track_id` (string, required): The track currently playing — a catalog itunes_track_id.

### `build_setlist` (~248 tokens)

Build Setlist

Order a crate of 2-100 catalog tracks into a beat-matched DJ set that follows an energy
    arc, keeping each consecutive transition harmonically and tempo-smooth. `arc` is one of
    peak_time (default — builds to a peak then eases), warmup, cooldown, or flat.

    Returns the `arc`, `count`, an overall `flow_score` (0-100), the `tracks` in play order, the
    per-step `transitions` ({from_index, to_index, score, reason}), and `omitted` (ids not found
    in the catalog). Feed tracks[].itunes_track_id into a Rekordbox/Serato export to drop the set
    straight into your DJ software. track_ids are catalog itunes_track_ids. Costs 5 quota units.

Input parameters:

- `arc` (string): Energy arc: 'peak_time' (default), 'warmup', 'cooldown', or 'flat'.
- `start_track_id`: Optional fixed opener — must be one of track_ids.
- `track_ids` (array, required): The crate to order — 2 to 100 catalog itunes_track_ids.

### `get_recommendations` (~670 tokens)

Get Recommendations

Recommended tracks for one or more seed tracks — the drop-in for Spotify's removed
    GET /v1/recommendations. Blends up to 5 catalog seed tracks into a single point in
    audio-feature space and returns the nearest catalogue tracks, RE-RANKED by genre affinity
    (so a feature-close cross-genre track doesn't outrank same-genre picks).

    Returns `seeds` (each {id, found}), `count`, and `tracks` (each {track, score,
    genre_relation}; each track carries its `genre`). `genre_relation` is "same", "compatible"
    (different but mixable family), "cross" (unrelated), or "unknown" (either side has no mapped
    genre), measured against the PRIMARY seed — the first of your seed_tracks we could actually
    use, so reordering seed_tracks changes it and a skipped seed never becomes the reference.
    With a SINGLE seed the field is the ranking's own verdict, so it explains the order (same as
    suggest_next_track). With SEVERAL seeds the ranking considers ALL of them while the label stays
    relative to your primary seed, so a "cross" label on a multi-seed call does NOT mean the track
    was pushed down — it may share a family with another of your seeds. `score` is the raw
    audio-feature cosine similarity in [0,1]; genre affinity influences the ORDER, not the score,
    so the list is NOT strictly score-descending.
    Use cross_genre=strict to return same-genre-family tracks ONLY (off-genre dropped
    server-side), or allow to disable the genre ranking. seed_tracks are catalog itunes_track_ids
    from search_catalog or the itunes_track_id field of a get_audio_features result.

    NO id? Pass `track` (+ optional `artist`) instead and we resolve the name to the best catalog
    match and seed on it — the resolved track is echoed back as `seed_query`; seed_tracks wins if
    both are given. Costs 2 quota units.

Input parameters:

- `artist`: Artist name narrowing the track seed (case-insensitive).
- `cross_genre` (string): Genre handling (mirrors suggest_next_track): 'auto' (default) re-ranks by genre affinity so a feature-close cross-genre track can't outrank same-genre picks; 'strict' = same genre-family only (off-ge…
- `exclude_seed_artists` (boolean): Drop tracks by any of the seed artists (default false).
- `limit` (integer): Number of recommendations to return (default 20).
- `seed_tracks`: 1-5 catalog itunes_track_ids to base recommendations on, e.g. ['apple_ad1829eeccb70f9a'] (blended into a feature-space centroid). Omit and use track(+artist) to seed by name instead.
- `track`: Seed by track NAME instead of an id — resolved to the best catalog match (echoed back as seed_query). Pair with artist to disambiguate. Ignored when seed_tracks is given.

### `get_related_artists` (~193 tokens)

Get Related Artists

Artists related to a seed artist — the drop-in for Spotify's removed
    GET /v1/artists/{id}/related-artists. No artist graph exists, so we derive one: build the
    seed artist's track-vector centroid, take its nearest catalogue tracks, aggregate by artist
    (each scored on its top-3 track similarities so a prolific artist can't dominate) plus a
    same-genre lift and a cross-genre penalty.

    Returns `artist`, `count`, and `related` (each {artist_name, score, match_count,
    sample_track_id}). Pass a sample_track_id straight to get_audio_features or
    suggest_next_track. Costs 2 quota units.

Input parameters:

- `artist` (string, required): Seed artist name (as it appears in the catalog; case-insensitive).
- `limit` (integer): Number of related artists to return (default 20).

### `tag_track` (~542 tokens)

Tag Track

Get a compact, HONESTLY-LABELLED tag list for a track — energy / danceability / valence /
    acousticness / instrumentalness, plus a mood tag and a broad genre tag. It is a tag-shaped
    projection of the same open-data analysis get_audio_features returns (no audio upload, no extra
    compute), so it costs the same 1 quota unit, charged only on a served result.

    The differentiator vs opaque taggers (e.g. Cyanite) is that EVERY tag carries its own
    `confidence` and `provenance`:
      - confidence: measured (our Essentia analysis) | derived (MIREX mood from valence+energy) |
        model-estimated (AcousticBrainz mood SVM probability — research-grade, raw prob in `value`) |
        catalog-genre (broad catalogue tag, not fine-grained).
      - provenance: essentia | valence+energy | acousticbrainz | catalog.
    `value` is the [0,1] score for numeric tags and null for label-only tags (mood category, genre).

    Provide EXACTLY ONE identifier: `track` (optionally with `artist`), `isrc`, `mbid`,
    `spotify_id`, or `track_id` (catalog itunes_track_id). The broad, reliable coverage is the
    MEASURED tags from our Essentia analysis over the analysed catalogue (plus on-demand by name);
    MBID/ISRC additionally reach 7.5M+ AcousticBrainz recordings WHEN you supply that identifier.

    Returns { track, count, tags:[{tag, category, value, confidence, provenance}], disclaimer }.
    For the full numeric feature set use get_audio_features; for nearest tracks use a discovery tool.

Input parameters:

- `artist`: Artist name. Only used with `track`; improves accuracy.
- `isrc`: ISRC, e.g. 'USUM71900001'.
- `mbid`: MusicBrainz recording ID (UUID). Tags come from AcousticBrainz for that exact recording.
- `spotify_id`: Spotify track ID, 'spotify:track:...' URI, or open.spotify.com URL. Resolves ONLY tracks already mapped to a Spotify ID (<1% of the catalog) — prefer track (+artist) or isrc.
- `track`: Track title. Use with `artist` when known. Required field is ONE of track/isrc/mbid/spotify_id/track_id.
- `track_id`: Catalog itunes_track_id from a search_catalog or get_audio_features result.

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/com-freqblog-music-metadata/mcp#diagnostics

## Score history

- 2026-08-03: 66
- 2026-08-02: 65
- 2026-08-01: 65
- 2026-07-30: 63
- 2026-07-29: 63
- 2026-07-28: 62
- 2026-07-27: 61
- 2026-07-26: 60

## Links

- Remote endpoint: https://mcp.freqblog.com/mcp
- Changelog RSS feed: https://verifymcp.io/servers/com-freqblog-music-metadata/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/com-freqblog-music-metadata/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/com-freqblog-music-metadata/mcp
