mr-magic-mcp-server 0.1.28 → 0.1.30
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.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "Lyrics MCP server connecting LRCLIB, Genius, Musixmatch, and Melon",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
61
|
-
"axios": "^1.
|
|
61
|
+
"axios": "^1.13.6",
|
|
62
62
|
"cheerio": "^1.0.0-rc.12",
|
|
63
63
|
"commander": "^14.0.3",
|
|
64
64
|
"dotenv": "^17.3.1",
|
|
@@ -85,7 +85,11 @@ export function startHttpServer(options = {}) {
|
|
|
85
85
|
if (req.method === 'GET' && req.url.startsWith('/downloads/')) {
|
|
86
86
|
const segments = req.url.split('/');
|
|
87
87
|
const [, , downloadId, ...rest] = segments;
|
|
88
|
-
|
|
88
|
+
// Strip trailing filename segment (e.g. "artist-song.srt") when present so the
|
|
89
|
+
// Redis key lookup uses only the extension portion of the path.
|
|
90
|
+
const hasFilename = rest.length > 1 && rest[rest.length - 1].includes('.');
|
|
91
|
+
const extensionParts = hasFilename ? rest.slice(0, -1) : rest;
|
|
92
|
+
const extension = extensionParts.join('/') || '';
|
|
89
93
|
if (!downloadId || !extension) {
|
|
90
94
|
logger.warn('Invalid download path', {
|
|
91
95
|
context: 'http-download',
|
|
@@ -30,7 +30,8 @@ export default class RedisStorage {
|
|
|
30
30
|
|
|
31
31
|
const expiresAt = new Date(Date.now() + this.ttl * 1000).toISOString();
|
|
32
32
|
const base = this.downloadBaseUrl?.replace(/[\/]+$/, '') || '';
|
|
33
|
-
const
|
|
33
|
+
const bareExt = extension.includes('.') ? extension.split('.').pop() : extension;
|
|
34
|
+
const url = `${base}/downloads/${id}/${extension}/${baseName}.${bareExt}`;
|
|
34
35
|
return new ExportStorageResult({ url, expiresAt, skipped: false });
|
|
35
36
|
}
|
|
36
37
|
}
|
|
@@ -74,7 +74,16 @@ function romanizeWord(word) {
|
|
|
74
74
|
return word;
|
|
75
75
|
}
|
|
76
76
|
const romanized = grouped
|
|
77
|
-
.map((characters) =>
|
|
77
|
+
.map((characters) =>
|
|
78
|
+
characters
|
|
79
|
+
.map((char, idx) => {
|
|
80
|
+
// ㅇ is silent as the initial consonant (position 0 in every syllable group)
|
|
81
|
+
// and pronounced 'ng' only when it appears as a final consonant.
|
|
82
|
+
if (char === 'ㅇ' && idx === 0) return '';
|
|
83
|
+
return ROMAN_MAP[char] ?? char;
|
|
84
|
+
})
|
|
85
|
+
.join('')
|
|
86
|
+
)
|
|
78
87
|
.join('');
|
|
79
88
|
if (!romanized) return word;
|
|
80
89
|
return romanized[0]?.toUpperCase() + romanized.slice(1);
|