mr-magic-mcp-server 0.5.1 → 0.5.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mr-magic-mcp-server",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "Lyrics MCP server connecting LRCLIB, Genius, Musixmatch, and Melon",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -91,7 +91,7 @@ async function buildLyricHeaders(songId) {
91
91
 
92
92
  function extractSongId(value) {
93
93
  if (!value) return null;
94
- const goSongMatch = value.match(/goSongDetail\([^0-9]*?(\d+)\)/);
94
+ const goSongMatch = value.match(/goSongDetail\([^)]*?(\d+)[^)]*\)/);
95
95
  if (goSongMatch) return goSongMatch[1];
96
96
  const searchLogMatch = value.match(/searchLog\('[^']+','[^']+','[^']+','[^']+','(\d+)'\)/);
97
97
  if (searchLogMatch) return searchLogMatch[1];
@@ -100,7 +100,7 @@ function extractSongId(value) {
100
100
  return null;
101
101
  }
102
102
 
103
- function parseSearchPage(html) {
103
+ export function parseSearchPage(html) {
104
104
  const document = parseDocument(html);
105
105
  const seenIds = new Set();
106
106
  return selectAll('#frm_defaultList > div > table > tbody > tr', document)
@@ -129,7 +129,6 @@ function parseSearchPage(html) {
129
129
  if (!title && !artist) return null;
130
130
  return { songId, title, artist, album };
131
131
  })
132
- .get()
133
132
  .filter(Boolean);
134
133
  }
135
134
 
@@ -19,6 +19,7 @@ import {
19
19
  catalogCacheKey,
20
20
  catalogCache
21
21
  } from '../services/lyrics-service.js';
22
+ import { parseSearchPage } from '../providers/melon.js';
22
23
  import { mcpToolDefinitions, handleMcpTool } from '../transport/mcp-tools.js';
23
24
  import { romanizePlainLyrics } from '../utils/lyrics-format.js';
24
25
 
@@ -504,6 +505,37 @@ function testCliEnvPathLoadsCustomEnvFile() {
504
505
  console.log('CLI --env-path loads and persists custom env files: ok');
505
506
  }
506
507
 
508
+ function testMelonSearchParserWithoutCheerioCollection() {
509
+ const html = `
510
+ <div id="frm_defaultList">
511
+ <div>
512
+ <table>
513
+ <tbody>
514
+ <tr>
515
+ <td></td>
516
+ <td></td>
517
+ <td><a class="fc_gray" href="javascript:goSongDetail('38914304')">Summer Nights</a></td>
518
+ <td><div id="artistName"><a href="#artist">St. Lucia</a></div></td>
519
+ <td><a href="#album">When The Night</a></td>
520
+ </tr>
521
+ </tbody>
522
+ </table>
523
+ </div>
524
+ </div>`;
525
+
526
+ const results = parseSearchPage(html);
527
+ assert.equal(results.length, 1, 'Melon parser should return plain arrays, not Cheerio chains');
528
+ assert.deepEqual(results[0], {
529
+ songId: '38914304',
530
+ title: 'Summer Nights',
531
+ artist: 'St. Lucia',
532
+ album: 'When The Night'
533
+ });
534
+
535
+ divider();
536
+ console.log('Melon parser works without Cheerio collection helpers: ok');
537
+ }
538
+
507
539
  async function run() {
508
540
  testAutoPickPrefersSynced();
509
541
  testAutoPickFallbackWhenNoSynced();
@@ -522,6 +554,7 @@ async function run() {
522
554
  await testBuildPayloadFromResultNoCacheKeyWhenNoLyrics();
523
555
  testCliExportCommandHelp();
524
556
  testCliEnvPathLoadsCustomEnvFile();
557
+ testMelonSearchParserWithoutCheerioCollection();
525
558
  const toolNames = mcpToolDefinitions.map((tool) => tool.name);
526
559
  console.log('MCP tooling available:', toolNames.join(', '));
527
560
  console.log('All sanity checks passed');