mr-magic-mcp-server 0.3.9 → 0.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +36 -26
- package/README.md +166 -13
- package/package.json +9 -7
- package/prompts/airtable-song-importer.md +143 -34
- package/src/index.js +89 -3
- package/src/provider-result-schema.js +88 -0
- package/src/providers/lrclib.js +25 -6
- package/src/providers/melon.js +46 -10
- package/src/services/lyrics-service.js +4 -0
- package/src/tests/mcp-tools.test.js +157 -2
- package/src/transport/mcp-tools.js +297 -52
package/.env.example
CHANGED
|
@@ -5,25 +5,26 @@
|
|
|
5
5
|
# ───────────────────────────────────────────────────────────────────────────────
|
|
6
6
|
# There are three ways to supply the Genius token (tried in order):
|
|
7
7
|
#
|
|
8
|
+
# Direct token (env var, see debug section below)) — static bearer token, no auto-refresh
|
|
9
|
+
# Set GENIUS_DIRECT_TOKEN. Works everywhere but the token must be
|
|
10
|
+
# manually updated on expiry (or redeploy with a new value).
|
|
11
|
+
# Use this only when client_credentials are unavailable.
|
|
12
|
+
#
|
|
8
13
|
# Auto-refresh (recommended for all deployments, including Render/ephemeral)
|
|
9
14
|
# Set GENIUS_CLIENT_ID + GENIUS_CLIENT_SECRET. The server calls the Genius
|
|
10
15
|
# OAuth client_credentials endpoint at runtime and refreshes the token in
|
|
11
16
|
# memory automatically. No disk, no scripts, no manual token copying needed.
|
|
12
17
|
#
|
|
13
|
-
# Direct token (env var) — static bearer token, no auto-refresh
|
|
14
|
-
# Set GENIUS_DIRECT_TOKEN. Works everywhere but the token must be
|
|
15
|
-
# manually updated on expiry (or redeploy with a new value).
|
|
16
|
-
# Use this only when client_credentials are unavailable.
|
|
17
|
-
#
|
|
18
18
|
# Cache token (on-disk) — local instance or persistent servers only
|
|
19
19
|
# Run `npm run fetch:genius-token` to write a token to
|
|
20
20
|
# `.cache/genius-token.json`. The server reads it on startup when a
|
|
21
21
|
# persistent, writable filesystem is available. Not suitable for
|
|
22
22
|
# ephemeral hosts.
|
|
23
|
+
#
|
|
23
24
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
25
|
+
|
|
24
26
|
GENIUS_CLIENT_ID=
|
|
25
27
|
GENIUS_CLIENT_SECRET=
|
|
26
|
-
GENIUS_DIRECT_TOKEN=
|
|
27
28
|
|
|
28
29
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
29
30
|
# REQUIRED (feature-specific) — Musixmatch
|
|
@@ -32,7 +33,7 @@ GENIUS_DIRECT_TOKEN=
|
|
|
32
33
|
# ───────────────────────────────────────────────────────────────────────────────
|
|
33
34
|
# Token resolution priority (1 = highest):
|
|
34
35
|
#
|
|
35
|
-
# 1. MUSIXMATCH_DIRECT_TOKEN (env var)
|
|
36
|
+
# 1. MUSIXMATCH_DIRECT_TOKEN (env var, see debug section below)
|
|
36
37
|
# Static bearer token. Works everywhere but must be manually updated on
|
|
37
38
|
# expiry. Use when no other option is available.
|
|
38
39
|
#
|
|
@@ -47,34 +48,22 @@ GENIUS_DIRECT_TOKEN=
|
|
|
47
48
|
# Run `npm run fetch:musixmatch-token` — writes .cache/musixmatch-token.json.
|
|
48
49
|
# The server reads it on startup when a writable filesystem is available.
|
|
49
50
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
50
|
-
MUSIXMATCH_DIRECT_TOKEN=
|
|
51
|
-
|
|
52
|
-
# KV store for Musixmatch token persistence (ephemeral deployments / npx installs)
|
|
53
|
-
# Priority: Upstash Redis (priority 1) → Cloudflare KV (priority 2)
|
|
54
|
-
# If both are set, Upstash Redis is used and Cloudflare KV is ignored.
|
|
55
51
|
#
|
|
56
|
-
# Upstash Redis: reuse the same creds as the export backend (see below) — no extra setup.
|
|
57
|
-
# Cloudflare KV: set the three CF_* vars; create a namespace at dash.cloudflare.com.
|
|
58
|
-
CF_API_TOKEN= # Cloudflare API token with KV:Edit permission (CF KV only)
|
|
59
|
-
CF_ACCOUNT_ID= # Cloudflare account ID (CF KV only)
|
|
60
|
-
CF_KV_NAMESPACE_ID= # KV namespace ID to store the token in (CF KV only)
|
|
61
|
-
# Optional overrides (defaults are sensible for most users)
|
|
62
|
-
MUSIXMATCH_TOKEN_KV_KEY= # KV key name (default: mr-magic:musixmatch-token)
|
|
63
|
-
MUSIXMATCH_TOKEN_KV_TTL_SECONDS= # Token TTL in seconds (default: 2592000 = 30 days)
|
|
64
|
-
|
|
65
52
|
# Headless / Render deployment — push a pre-captured token without opening a browser.
|
|
66
53
|
# run `npm run fetch:musixmatch-token` or sign into Musixmatch manually to get a token, then set it in the env to push it to the KV store without browser automation.
|
|
67
54
|
# Set MUSIXMATCH_DIRECT_TOKEN to the full musixmatchUserToken JSON payload (from fetch:musixmatch-token output),
|
|
55
|
+
#
|
|
68
56
|
# then run `npm run push:musixmatch-token` or prepend it to the start command:
|
|
69
57
|
# npm run push:musixmatch-token && npm run server:mcp:http
|
|
70
58
|
# If unset, push:musixmatch-token exits silently (safe no-op in start commands).
|
|
71
59
|
# MUSIXMATCH_DIRECT_TOKEN also serves as the runtime token override (highest env priority).
|
|
72
|
-
|
|
60
|
+
#
|
|
73
61
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
74
62
|
# REQUIRED (feature-specific) — Airtable
|
|
75
63
|
# Only needed if you use the push_catalog_to_airtable tool.
|
|
76
64
|
# Get from https://airtable.com/create/tokens
|
|
77
65
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
66
|
+
|
|
78
67
|
AIRTABLE_PERSONAL_ACCESS_TOKEN=
|
|
79
68
|
|
|
80
69
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -86,25 +75,36 @@ AIRTABLE_PERSONAL_ACCESS_TOKEN=
|
|
|
86
75
|
# inline — embeds payload directly in the MCP response (no storage needed)
|
|
87
76
|
# redis — stores in Upstash Redis KV store; best for production/ephemeral hosts
|
|
88
77
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
78
|
+
|
|
89
79
|
MR_MAGIC_EXPORT_BACKEND= # local | inline | redis
|
|
90
80
|
|
|
91
|
-
#
|
|
92
|
-
|
|
81
|
+
# KV store for Musixmatch token persistence (ephemeral deployments / npx installs)
|
|
82
|
+
# Priority: Upstash Redis (priority 1) → Cloudflare KV (priority 2)
|
|
83
|
+
# If both are set, Upstash Redis is used and Cloudflare KV is ignored.
|
|
93
84
|
|
|
94
|
-
#
|
|
85
|
+
# Note: Upstash Redis is required when BACKEND=redis — get from https://console.upstash.com/redis/rest
|
|
95
86
|
# These same credentials are also used by the Musixmatch KV token store, so
|
|
96
87
|
# setting them once enables both features.
|
|
97
88
|
UPSTASH_REDIS_REST_URL=
|
|
98
89
|
UPSTASH_REDIS_REST_TOKEN=
|
|
99
90
|
|
|
91
|
+
# Cloudflare KV: set the three CF_* vars; create a namespace at dash.cloudflare.com.
|
|
92
|
+
CF_API_TOKEN= # Cloudflare API token with KV:Edit permission (CF KV only)
|
|
93
|
+
CF_ACCOUNT_ID= # Cloudflare account ID (CF KV only)
|
|
94
|
+
CF_KV_NAMESPACE_ID= # KV namespace ID to store the token in (CF KV only)
|
|
95
|
+
|
|
96
|
+
# Required when BACKEND=local
|
|
97
|
+
MR_MAGIC_EXPORT_DIR=/Users/naji/Downloads/magic-export/ # Absolute path to the directory to write export files into
|
|
98
|
+
|
|
100
99
|
# Base URL the server uses to build download links returned to the MCP client.
|
|
101
|
-
# Examples: https://yourserver.com | http://localhost:3444
|
|
100
|
+
# Examples: https://yourserver.com | http://localhost:3444 | http://localhost:3333
|
|
102
101
|
# See README for details.
|
|
103
102
|
MR_MAGIC_DOWNLOAD_BASE_URL=
|
|
104
103
|
|
|
105
104
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
106
105
|
# Server & Runtime
|
|
107
106
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
107
|
+
|
|
108
108
|
PORT= # Override all server ports (default: 3444 MCP / 3333 HTTP automation)
|
|
109
109
|
LOG_LEVEL= # error | warn | info | debug (default: info)
|
|
110
110
|
MR_MAGIC_QUIET_STDIO=0 # Set to 1 to suppress non-error stdout logs (recommended under stdio MCP clients)
|
|
@@ -113,6 +113,7 @@ MR_MAGIC_HTTP_TIMEOUT_MS=10000 # Global outbound HTTP timeout in ms (default: 1
|
|
|
113
113
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
114
114
|
# Optional — Melon provider
|
|
115
115
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
116
|
+
|
|
116
117
|
MELON_COOKIE= # Pin a browser session cookie for consistent results; anonymous access usually works without it
|
|
117
118
|
|
|
118
119
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -130,10 +131,19 @@ MR_MAGIC_EXPORT_TTL_SECONDS=3600
|
|
|
130
131
|
GENIUS_TOKEN_CACHE=.cache/genius-token.json
|
|
131
132
|
MUSIXMATCH_TOKEN_CACHE=.cache/musixmatch-token.json
|
|
132
133
|
|
|
134
|
+
# Direct tokens — Use these as temp overrides for testing or debugging, but for long-term use the auto-refresh or KV options are recommended to avoid manual token management.
|
|
135
|
+
# Set GENIUS_DIRECT_TOKEN and MUSIXMATCH_DIRECT_TOKEN to the full token payloads (from fetch-genius-token and fetch-musixmatch-token output), then restart the server.
|
|
136
|
+
GENIUS_DIRECT_TOKEN=
|
|
137
|
+
MUSIXMATCH_DIRECT_TOKEN=
|
|
138
|
+
|
|
133
139
|
# Musixmatch: when 1, provider will attempt to re-run the fetch script
|
|
134
140
|
# automatically (headless) if no token is available
|
|
135
141
|
MUSIXMATCH_AUTO_FETCH=0
|
|
136
142
|
|
|
143
|
+
# Optional overrides for Musixmatch KV token storage (only needed if using KV storage and want to customize beyond the defaults)
|
|
144
|
+
MUSIXMATCH_TOKEN_KV_KEY= # KV key name (default: mr-magic:musixmatch-token)
|
|
145
|
+
MUSIXMATCH_TOKEN_KV_TTL_SECONDS= # Token TTL in seconds (default: 2592000 = 30 days)
|
|
146
|
+
|
|
137
147
|
# Playwright Headless mode toggle for fetch scripts that require browser automation (default: false)
|
|
138
148
|
HEADLESS=
|
|
139
149
|
|
package/README.md
CHANGED
|
@@ -609,19 +609,141 @@ Responses:
|
|
|
609
609
|
|
|
610
610
|
Both the stdio and Streamable HTTP & SSE transports expose the same tool registry:
|
|
611
611
|
|
|
612
|
-
| Tool | Purpose
|
|
613
|
-
| -------------------------- |
|
|
614
|
-
| `find_lyrics` | Fetch best lyrics (prefers synced) plus metadata and payload.
|
|
615
|
-
| `find_synced_lyrics` | Like `find_lyrics` but rejects plain-only results.
|
|
616
|
-
| `search_lyrics` |
|
|
617
|
-
| `search_provider` | Query a single named provider.
|
|
618
|
-
| `get_provider_status` | Report readiness and notes for each provider.
|
|
619
|
-
| `format_lyrics` | Format lyrics in memory (optional romanization) for display.
|
|
620
|
-
| `export_lyrics` | Write plain / LRC / SRT / romanized files to the export backend.
|
|
621
|
-
| `select_match` | Pick a prior result
|
|
622
|
-
| `build_catalog_payload` | Return a compact record (title / link / lyrics) for Airtable-style inserts.
|
|
623
|
-
| `push_catalog_to_airtable` | Write catalog records to Airtable server-side — lyrics never pass through LLM arguments. Requires `AIRTABLE_PERSONAL_ACCESS_TOKEN`.
|
|
624
|
-
| `runtime_status` | Snapshot provider readiness plus relevant env vars.
|
|
612
|
+
| Tool | Purpose |
|
|
613
|
+
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
614
|
+
| `find_lyrics` | Fetch best lyrics (prefers synced) plus metadata and payload from direct track metadata, or resolve a prior provider reference / selected match. |
|
|
615
|
+
| `find_synced_lyrics` | Like `find_lyrics` but rejects plain-only results; also accepts direct track metadata, a provider reference, or a selected match. |
|
|
616
|
+
| `search_lyrics` | Return grouped, preview-only candidate matches across all providers, including reusable provider references. |
|
|
617
|
+
| `search_provider` | Query a single named provider and return flat, preview-only matches plus reusable provider references. |
|
|
618
|
+
| `get_provider_status` | Report readiness and notes for each provider. |
|
|
619
|
+
| `format_lyrics` | Format lyrics in memory (optional romanization) for display from direct track metadata, a provider reference, or a selected match. |
|
|
620
|
+
| `export_lyrics` | Write plain / LRC / SRT / romanized files to the export backend from direct track metadata, a provider reference, or a selected match. |
|
|
621
|
+
| `select_match` | Pick a single prior search result from grouped `items`, flat `matches`, or a direct `match`, using provider/index/synced filters. |
|
|
622
|
+
| `build_catalog_payload` | Return a compact record (title / link / lyrics) for Airtable-style inserts from direct track metadata, a provider reference, or a selected match. |
|
|
623
|
+
| `push_catalog_to_airtable` | Write catalog records to Airtable server-side — lyrics never pass through LLM arguments. Requires `AIRTABLE_PERSONAL_ACCESS_TOKEN`. |
|
|
624
|
+
| `runtime_status` | Snapshot provider readiness plus relevant env vars. |
|
|
625
|
+
|
|
626
|
+
### MCP search result behavior
|
|
627
|
+
|
|
628
|
+
`search_lyrics` and `search_provider` now return **preview-only** search results. They are intentionally compact and do **not** include full lyrics or raw provider payloads.
|
|
629
|
+
|
|
630
|
+
Each returned result is designed for follow-up tool calls and includes:
|
|
631
|
+
|
|
632
|
+
- core metadata such as provider, title, artist, album, duration, source URL, confidence, and synced/plain-only flags
|
|
633
|
+
- preview snippets (`plainPreview` / `syncedPreview`) when available
|
|
634
|
+
- a reusable `reference` object that can be passed back into downstream tools for exact result recall
|
|
635
|
+
|
|
636
|
+
The `reference` object is the durable handoff between search and resolution. Instead of copying large provider payloads around, clients can reuse the compact reference to resolve the exact provider result later.
|
|
637
|
+
|
|
638
|
+
### MCP provider-reference workflow
|
|
639
|
+
|
|
640
|
+
After a search step, the following tools can resolve lyrics from **either**:
|
|
641
|
+
|
|
642
|
+
- direct `track` metadata
|
|
643
|
+
- a provider `reference` returned by `search_lyrics` or `search_provider`
|
|
644
|
+
- a selected `match` object from prior search output
|
|
645
|
+
|
|
646
|
+
This applies to:
|
|
647
|
+
|
|
648
|
+
- `find_lyrics`
|
|
649
|
+
- `find_synced_lyrics`
|
|
650
|
+
- `build_catalog_payload`
|
|
651
|
+
- `format_lyrics`
|
|
652
|
+
- `export_lyrics`
|
|
653
|
+
|
|
654
|
+
### `select_match` in the workflow
|
|
655
|
+
|
|
656
|
+
`select_match` is the bridge between preview-only search results and the tools that resolve full lyrics.
|
|
657
|
+
|
|
658
|
+
It accepts any of these input shapes:
|
|
659
|
+
|
|
660
|
+
- `items` — grouped provider results returned by `search_lyrics`
|
|
661
|
+
- `matches` — flat results returned by `search_provider` (or other flattened match arrays)
|
|
662
|
+
- `match` — a single previously returned result passed through directly
|
|
663
|
+
|
|
664
|
+
Use `criteria` to narrow the choice by provider, require synced lyrics, and/or choose a zero-based index. The returned selected match can then be passed directly into `find_lyrics`, `find_synced_lyrics`, `build_catalog_payload`, `format_lyrics`, or `export_lyrics`. If you already know which result you want, you can skip `select_match` and pass that result's `reference` directly.
|
|
665
|
+
|
|
666
|
+
### Example workflow: search → select → build/export
|
|
667
|
+
|
|
668
|
+
1. Call `search_lyrics` to get grouped, preview-only results plus provider `reference` objects.
|
|
669
|
+
2. Call `select_match` with the returned `items` to choose one result.
|
|
670
|
+
3. Pass the returned `match` into `build_catalog_payload`, `find_lyrics`, `format_lyrics`, or `export_lyrics`.
|
|
671
|
+
4. Optionally reuse the nested `match.result.reference` later to resolve the exact same provider result again without repeating the original broad search.
|
|
672
|
+
|
|
673
|
+
Example sequence:
|
|
674
|
+
|
|
675
|
+
```json
|
|
676
|
+
{
|
|
677
|
+
"track": { "artist": "Coldplay", "title": "Yellow" }
|
|
678
|
+
}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
→ `search_lyrics`
|
|
682
|
+
|
|
683
|
+
```json
|
|
684
|
+
{
|
|
685
|
+
"items": [
|
|
686
|
+
{
|
|
687
|
+
"provider": "lrclib",
|
|
688
|
+
"results": [
|
|
689
|
+
{
|
|
690
|
+
"title": "Yellow",
|
|
691
|
+
"artist": "Coldplay",
|
|
692
|
+
"synced": true,
|
|
693
|
+
"reference": {
|
|
694
|
+
"provider": "lrclib",
|
|
695
|
+
"providerId": "...",
|
|
696
|
+
"fingerprint": "..."
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
]
|
|
700
|
+
}
|
|
701
|
+
],
|
|
702
|
+
"criteria": { "requireSynced": true, "index": 0 }
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
→ `select_match`
|
|
707
|
+
|
|
708
|
+
```json
|
|
709
|
+
{
|
|
710
|
+
"match": {
|
|
711
|
+
"provider": "lrclib",
|
|
712
|
+
"result": {
|
|
713
|
+
"title": "Yellow",
|
|
714
|
+
"artist": "Coldplay",
|
|
715
|
+
"reference": {
|
|
716
|
+
"provider": "lrclib",
|
|
717
|
+
"providerId": "...",
|
|
718
|
+
"fingerprint": "..."
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
},
|
|
722
|
+
"options": {
|
|
723
|
+
"omitInlineLyrics": true,
|
|
724
|
+
"lyricsPayloadMode": "payload"
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
→ `build_catalog_payload`
|
|
730
|
+
|
|
731
|
+
Or export the same exact result later with:
|
|
732
|
+
|
|
733
|
+
```json
|
|
734
|
+
{
|
|
735
|
+
"reference": {
|
|
736
|
+
"provider": "lrclib",
|
|
737
|
+
"providerId": "...",
|
|
738
|
+
"fingerprint": "..."
|
|
739
|
+
},
|
|
740
|
+
"options": {
|
|
741
|
+
"formats": ["plain", "lrc", "srt"]
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
→ `export_lyrics`
|
|
625
747
|
|
|
626
748
|
## Airtable Integration
|
|
627
749
|
|
|
@@ -1199,6 +1321,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1199
1321
|
|
|
1200
1322
|
#### `find_lyrics`
|
|
1201
1323
|
|
|
1324
|
+
Accepts either direct `track` metadata, a provider `reference` from prior search output, or a selected `match`.
|
|
1325
|
+
|
|
1202
1326
|
```bash
|
|
1203
1327
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1204
1328
|
-H 'Content-Type: application/json' \
|
|
@@ -1208,6 +1332,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1208
1332
|
|
|
1209
1333
|
#### `find_synced_lyrics`
|
|
1210
1334
|
|
|
1335
|
+
Same lookup inputs as `find_lyrics`, but only returns timestamped results.
|
|
1336
|
+
|
|
1211
1337
|
```bash
|
|
1212
1338
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1213
1339
|
-H 'Content-Type: application/json' \
|
|
@@ -1217,6 +1343,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1217
1343
|
|
|
1218
1344
|
#### `build_catalog_payload` — inline lyrics
|
|
1219
1345
|
|
|
1346
|
+
Accepts direct `track` metadata, a reusable `reference`, or a selected `match` from prior search output.
|
|
1347
|
+
|
|
1220
1348
|
```bash
|
|
1221
1349
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1222
1350
|
-H 'Content-Type: application/json' \
|
|
@@ -1241,6 +1369,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1241
1369
|
|
|
1242
1370
|
#### `search_lyrics`
|
|
1243
1371
|
|
|
1372
|
+
Returns grouped, preview-only results under `items`. Each result includes a reusable `reference`, plus compact metadata and previews when available. Full lyrics and raw provider payloads are intentionally omitted.
|
|
1373
|
+
|
|
1244
1374
|
```bash
|
|
1245
1375
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1246
1376
|
-H 'Content-Type: application/json' \
|
|
@@ -1250,6 +1380,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1250
1380
|
|
|
1251
1381
|
#### `search_provider`
|
|
1252
1382
|
|
|
1383
|
+
Returns a flat `matches` array with the same preview-only result shape used by the grouped `search_lyrics` output.
|
|
1384
|
+
|
|
1253
1385
|
```bash
|
|
1254
1386
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1255
1387
|
-H 'Content-Type: application/json' \
|
|
@@ -1259,6 +1391,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1259
1391
|
|
|
1260
1392
|
#### `format_lyrics`
|
|
1261
1393
|
|
|
1394
|
+
Accepts direct `track` metadata, a reusable `reference`, or a selected `match`.
|
|
1395
|
+
|
|
1262
1396
|
```bash
|
|
1263
1397
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1264
1398
|
-H 'Content-Type: application/json' \
|
|
@@ -1268,6 +1402,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1268
1402
|
|
|
1269
1403
|
#### `export_lyrics`
|
|
1270
1404
|
|
|
1405
|
+
Accepts direct `track` metadata, a reusable `reference`, or a selected `match`.
|
|
1406
|
+
|
|
1271
1407
|
```bash
|
|
1272
1408
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1273
1409
|
-H 'Content-Type: application/json' \
|
|
@@ -1321,6 +1457,8 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1321
1457
|
|
|
1322
1458
|
#### `select_match`
|
|
1323
1459
|
|
|
1460
|
+
Use `items` for grouped `search_lyrics` output, `matches` for flat `search_provider` output, or `match` to pass through a single result directly.
|
|
1461
|
+
|
|
1324
1462
|
```bash
|
|
1325
1463
|
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1326
1464
|
-H 'Content-Type: application/json' \
|
|
@@ -1334,6 +1472,21 @@ curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
|
1334
1472
|
}' | jq
|
|
1335
1473
|
```
|
|
1336
1474
|
|
|
1475
|
+
Example using grouped `items` from `search_lyrics`:
|
|
1476
|
+
|
|
1477
|
+
```bash
|
|
1478
|
+
curl -sS -X POST http://127.0.0.1:3444/mcp \
|
|
1479
|
+
-H 'Content-Type: application/json' \
|
|
1480
|
+
-H 'Accept: application/json, text/event-stream' \
|
|
1481
|
+
-d '{
|
|
1482
|
+
"jsonrpc":"2.0","id":14,"method":"tools/call",
|
|
1483
|
+
"params":{"name":"select_match","arguments":{
|
|
1484
|
+
"items":[{"provider":"lrclib","results":[{"title":"Yellow","artist":"Coldplay","synced":true,"reference":{"provider":"lrclib","providerId":"123","fingerprint":"abc"}}]}],
|
|
1485
|
+
"criteria":{"requireSynced":true,"index":0}
|
|
1486
|
+
}}
|
|
1487
|
+
}' | jq
|
|
1488
|
+
```
|
|
1489
|
+
|
|
1337
1490
|
> **MCP tool response shape:**
|
|
1338
1491
|
>
|
|
1339
1492
|
> - `result.structuredContent` — machine-friendly object (all fields, full values)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mr-magic-mcp-server",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"description": "Lyrics MCP server connecting LRCLIB, Genius, Musixmatch, and Melon",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
".env.example"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
+
"check-for-updates": "npx npm-check-updates",
|
|
25
|
+
"update-deps": "npx npm-check-updates -u && npm install",
|
|
24
26
|
"cleanup": "eslint . --fix && prettier --write .",
|
|
25
27
|
"cli": "node src/bin/cli.js",
|
|
26
28
|
"server:http": "node src/bin/http-server.js",
|
|
@@ -59,17 +61,17 @@
|
|
|
59
61
|
"node": ">=20"
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"@dotenvx/dotenvx": "^1.
|
|
63
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
64
|
-
"axios": "^1.
|
|
64
|
+
"@dotenvx/dotenvx": "^1.59.1",
|
|
65
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
66
|
+
"axios": "^1.14.0",
|
|
65
67
|
"cheerio": "^1.2.0",
|
|
66
68
|
"commander": "^14.0.3"
|
|
67
69
|
},
|
|
68
70
|
"devDependencies": {
|
|
69
|
-
"eslint": "^10.0
|
|
71
|
+
"eslint": "^10.1.0",
|
|
70
72
|
"eslint-config-prettier": "^10.1.8",
|
|
71
|
-
"eslint-plugin-import-x": "^4.
|
|
72
|
-
"playwright": "^1.
|
|
73
|
+
"eslint-plugin-import-x": "^4.16.2",
|
|
74
|
+
"playwright": "^1.59.0",
|
|
73
75
|
"prettier": "^3.8.1"
|
|
74
76
|
},
|
|
75
77
|
"overrides": {
|