音乐搜索服务

一个基于模糊记忆搜索个人音乐库的服务,支持通过歌词片段、情绪或模糊记忆查找歌曲。

  • by Earththing
  • Python
  • 本地部署
  • 更新于
在 GitHub 查看 Earththing/Music_Search_MCP

使用说明

音乐搜索MCP

使用模糊回忆搜索音乐库的MCP服务器。描述一首你几乎不记得的歌——一段歌词片段、一种情绪、一段模糊的记忆——它会在你的听力历史中找到。

设置

先决条件

  • Python 3.11+
  • Spotify开发者帐户(2026年2月起需要付费)
  • 带有API密钥的Last.fm帐户

1.克隆并安装

git clone https://github.com/Earththing/Music_Search_MCP.git
cd Music_Search_MCP
pip install -e .

2.创建Spotify应用程序

  1. 首选 Spotify开发者仪表板
  2. 创建新应用程序
  3. 将重定向URI设置为 http://127.0.0.1:8888/callback (必须使用IP,而不是 localhost)
  4. 记下您的客户端ID和客户端密码

3.创建Last.fm API帐户

  1. 首选 Last.fm API帐户创建
  2. 请注意您的API密钥(不需要共享密钥)

4.配置凭据

copy .env.example .env

编辑 .env 并填写您的凭据:

SPOTIFY_CLIENT_ID=your_client_id_here
SPOTIFY_CLIENT_SECRET=your_client_secret_here
SPOTIFY_REDIRECT_URI=http://127.0.0.1:8888/callback

LASTFM_API_KEY=your_api_key_here
LASTFM_USERNAME=your_lastfm_username

5.加载音乐库

从Spotify/Last.fm获取歌曲列表并将其保存在本地:

music-search load spotify    # Fetch liked songs from Spotify
music-search load lastfm     # Fetch scrobbles from Last.fm (auto-deduplicates)
music-search load all        # Fetch from both services

music-search status          # See what data you have stored locally

增量加载: 在第一次装载之后 load 命令只获取新歌。Spotify停止播放已知曲目;Last.fm使用最近一次滚动的时间戳。要从头开始重新获取所有内容,请使用 --full:

music-search load lastfm          # Only new scrobbles since last load
music-search load spotify         # Only new liked songs since last load
music-search load all --full      # Re-fetch everything from scratch

首次运行Spotify时,将打开一个浏览器窗口进行登录。令牌在本地缓存以供后续运行。歌曲列表保存到 data/ 因此,所有后续命令都可以脱机工作,而无需再次访问API。

6.用歌词丰富歌曲

# Enrich from your locally stored song lists (no API calls to Spotify/Last.fm!)
music-search lyrics-enrich                           # Use whatever source is loaded (auto-detect)
music-search lyrics-enrich --source spotify          # Spotify liked songs only
music-search lyrics-enrich --source lastfm           # Last.fm scrobbles only
music-search lyrics-enrich --source both             # Both sources combined + deduplicated

# Control how many songs to process
music-search lyrics-enrich --new 500                 # Enrich 500 NEW (uncached) songs only
music-search lyrics-enrich -n 20                     # Process 20 songs total (including cached)
music-search lyrics-enrich --force -n 10             # Re-fetch from LRCLIB, ignoring cache

# Speed up enrichment with concurrent workers
music-search lyrics-enrich --new 500 --workers 8     # 8 parallel LRCLIB lookups

# Auto-rebuild the search index after enrichment
music-search lyrics-enrich --new 500 --index         # Enrich + re-index automatically

# Fill gaps: try alternative sources for songs LRCLIB missed
music-search lyrics-enrich --fill-gaps -n 100 --workers 3
music-search lyrics-enrich --fill-gaps -n 100 --workers 3   # Next run skips already-tried songs
music-search lyrics-enrich --reset-gaps                      # Clear flags to retry all gaps
music-search lyrics-enrich --reset-gaps --fill-gaps -n 100   # Reset + retry in one command

# Search LRCLIB directly (no API key needed)
music-search lyrics-search never gonna give you up rick astley
music-search lyrics-search bohemian rhapsody --show-lyrics

歌词缓存在 data/lyrics_cache.json 因此,后续的跑步会跳过已经收录的歌曲。随时按Ctrl+C可以优雅地停止——所有完成的查找都会立即保存。

7.丰富元数据

从Last.fm和Spotify获取其他元数据:

music-search enrich-metadata lastfm     # Per-user play counts, tags, loved status
music-search enrich-metadata spotify     # Artist genres (paced to avoid rate limits)
music-search enrich-metadata all         # Both services
music-search enrich-metadata lastfm -n 100   # Limit to 100 songs

Last.fm元数据 (27K首歌曲约1小时53分钟,4次请求/秒):每首歌曲的个人播放次数、全球收听次数、社区标签和喜爱状态。

Spotify流派 (2K艺术家约58分钟,1个请求/秒,有节奏停顿):从每个艺术家那里获取流派标签。自Spotify于2026年2月删除批处理端点以来,它使用每秒1次的API调用,每50次调用暂停30秒,以避免触发速率限制禁令。

8.构建搜索索引

缓存歌词后,构建矢量搜索索引:

music-search index                              # Build index from cached lyrics
music-search index --model all-MiniLM-L6-v2     # Specify embedding model (this is the default)

第一次运行下载嵌入模型(约80MB)。后续运行使用缓存的模型。

如果你有一个带CUDA的NVIDIA GPU,嵌入将自动在GPU上运行。否则,它会退回到CPU(对于典型的库大小来说仍然很快)。

9.搜索你的图书馆

用自然语言搜索——以你记忆中的方式描述这首歌:

music-search search that sad song about rain
music-search search upbeat dance track with synthesizers
music-search search "the one where they sing about letting go"
music-search search piano ballad about lost love -n 10        # More results
music-search search melancholy indie song -v                  # Show lyrics preview

搜索对嵌入的歌词+元数据使用余弦相似性,返回按相关性得分排名的匹配项。搜索结果包括可用的Spotify链接。

10.导出到SQLite

将您的完整库导出到SQLite数据库进行即席SQL探索:

music-search export-db                          # Export to data/music_library.db
music-search export-db --path ~/my_music.db     # Custom output path

SQLite数据库包括:

  • A. songs 带有完整元数据和来源的表(in_spotify, in_lastfm)
  • A. lyrics_fts FTS5虚拟表,用于全文歌词搜索

SQL查询示例:

-- Most-represented artists
SELECT artist_name, COUNT(*) as songs FROM songs GROUP BY artist_name ORDER BY songs DESC LIMIT 20;

-- Full-text lyrics search
SELECT track_name, artist_name FROM lyrics_fts WHERE lyrics_fts MATCH 'thunder' LIMIT 10;

-- Spotify vs Last.fm overlap
SELECT SUM(in_spotify AND in_lastfm) as both,
       SUM(in_spotify AND NOT in_lastfm) as spotify_only,
       SUM(in_lastfm AND NOT in_spotify) as lastfm_only
FROM songs;

一个命令刷新

一次性运行整个管道:

music-search refresh                     # load > enrich > index > export (incremental)
music-search refresh --full              # Re-fetch everything from scratch
music-search refresh --fill-gaps         # Also try alternative lyrics sources
music-search refresh --workers 8         # Use 8 concurrent lyrics lookups
music-search refresh --reset-gaps --fill-gaps   # Retry all previously-failed gaps

MCP服务器(克劳德桌面集成)

该项目包括一个MCP服务器,该服务器将语义搜索作为Claude Desktop(或任何兼容MCP的客户端)的工具。这使您可以通过与Claude聊天来搜索您的音乐库。

可用工具

工具 说明
search_music 使用自然语言描述搜索您的库
library_status 检查索引了哪些数据以及是否设置了管道

设置

  1. 确保你已经完成了上述步骤(加载歌曲、丰富歌词、构建索引)。

  2. 安装项目(如果尚未安装):

    pip install -e .
    
  3. 配置克劳德桌面。打开(或创建)配置文件:

    • 窗户: %APPDATA%\Claude\claude_desktop_config.json
    • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

    添加音乐搜索服务器(使用完整路径以避免path问题):

    {
      "mcpServers": {
        "music-search": {
          "command": "C:\\path\\to\\your\\Python311\\Scripts\\music-search-mcp.exe"
        }
      }
    }
    

    通过以下方式找到您的完整路径: where music-search-mcp

  4. 完全重新启动Claude Desktop(从系统托盘退出,然后重新启动)。音乐搜索工具应出现在工具菜单中。

使用示例

一旦连接,问克劳德这样的问题:

  • “在我的音乐库中搜索那首关于雨的悲伤歌曲”
  • “在我的收藏中找到带有合成器的欢快舞曲”
  • “我的音乐搜索库的状态如何?”
  • “你能找到他们唱的关于放手的歌吗?”

关于首次搜索的说明

启动服务器后的第一次搜索需要大约7秒,因为嵌入模型会加载到内存中。后续搜索速度很快(不到1秒)。该模型在服务器进程的生命周期内保持缓存状态。

手动运行(用于测试)

music-search-mcp                          # Start the MCP server on stdio
mcp dev music_search_mcp/mcp_server.py    # Use the MCP CLI inspector (requires mcp[cli])

建筑

music_search_mcp/
  __init__.py         # Package root
  config.py           # Environment/config management
  spotify_client.py   # Spotify API client (auth + data fetching + artist genres)
  lastfm_client.py    # Last.fm API client (scrobble history + track info)
  lyrics_client.py    # LRCLIB lyrics fetcher + syncedlyrics fallback
  lyrics_cache.py     # Local JSON cache for fetched lyrics + metadata
  song_store.py       # Local JSON storage for song lists (avoid re-fetching)
  rate_limiter.py     # Thread-safe rate limiting for all API clients
  vector_store.py     # ChromaDB vector store for semantic search
  sqlite_export.py    # SQLite database export with FTS5 lyrics search
  cli.py              # CLI entry point (all commands)
  mcp_server.py       # MCP server for Claude Desktop integration

data/
  spotify_songs.json    # Liked songs from Spotify (auto-created, gitignored)
  lastfm_scrobbles.json # Unique scrobbles from Last.fm (auto-created, gitignored)
  lyrics_cache.json     # Cached lyrics + metadata (auto-created, gitignored)
  chroma_db/            # Vector database (auto-created, gitignored)
  music_library.db      # SQLite export (auto-created, gitignored)

CLI命令参考

命令 描述
music-search load <source> 从以下位置获取歌曲 spotify, lastfm,或 all 并在本地保存
music-search status 显示本地数据状态(存储、缓存、索引、未丰富计数)
music-search lyrics-enrich 从LRCLIB获取歌词(+后备来源 --fill-gaps)
music-search lyrics-search <query> 直接在LRCLIB中搜索歌词
music-search index 从缓存的歌词构建矢量搜索索引
music-search search <query> 使用自然语言搜索您的音乐库
music-search enrich-metadata <target> 获取播放次数/标签(Last.fm)或流派(Spotify)
music-search export-db 使用FTS5歌词搜索将完整库导出到SQLite
music-search refresh 一个命令管道:加载>丰富>索引>导出
music-search liked-songs 获取并显示Spotify喜欢的歌曲(直接API调用)
music-search scrobbles 获取并显示Last.fm scrobbles(直接API调用)

加载选项

--full                              Re-fetch everything from scratch (default: incremental)

歌词丰富了选择

--source auto|spotify|lastfm|both   Song source (default: auto-detect)
--new N                             Enrich N new uncached songs only
-n N, --limit N                     Process N songs total (including cached)
--workers N                         Concurrent LRCLIB lookups (default: 1)
--force                             Re-fetch even if already cached
--index                             Rebuild search index after enrichment
--fill-gaps                         Try alternative sources (Musixmatch, Genius, NetEase)
                                    for songs LRCLIB missed. Skips already-tried songs.
--reset-gaps                        Clear 'already tried' flags so --fill-gaps retries all

搜索选项

-n N, --limit N                     Max results (default: 5)
--model MODEL                       Embedding model (default: all-MiniLM-L6-v2)
-v, --verbose                       Show lyrics preview in results

丰富元数据选项

target                              lastfm, spotify, or all
-n N, --limit N                     Max songs to enrich (default: all unenriched)

导出数据库选项

--path PATH                         Output path (default: data/music_library.db)

刷新选项

--full                              Re-fetch everything from scratch
--workers N                         Concurrent lyrics lookups (default: 4)
--fill-gaps                         Try alternative lyrics sources for missing songs
--reset-gaps                        Clear 'already tried' flags before filling gaps
--model MODEL                       Embedding model for indexing

Spotify API笔记(2026年2月)

Spotify在2026年2月对其用于开发模式应用程序的Web API进行了重大更改:

  • 已删除批处理终结点: GET /artists?ids=, GET /tracks?ids=等不再可用。必须使用单独的端点,这意味着更多的API调用和谨慎的速率限制。
  • 删除的字段: popularity (曲目和艺术家), followers (艺术家)及其他。
  • 艺术家 genres 字段已弃用: 仍然可以使用,但可能会在未来的更新中删除。
  • 搜索限制减少: 每个查询的最大结果从50个下降到10个。
  • 所需保费: 应用程序所有者必须保持活跃的Spotify Premium。
  • 扩展配额模式 现在需要一个月活跃用户超过25万的注册企业,这使得个人开发人员无法使用。

该项目使用了积极的速率限制缓解措施(每50次艺术家查找呼叫需要1次请求/秒暂停30秒),以避免触发Spotify的滚动窗口速率限制,这可能会导致24小时的禁令。