@champz-llc/legends-mcp-server 1.7.0 → 1.7.1
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/index.js +63 -17
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import fetch from 'node-fetch';
|
|
|
10
10
|
import sharp from 'sharp';
|
|
11
11
|
|
|
12
12
|
// Helper function to fetch image, resize, and convert to base64
|
|
13
|
-
async function fetchImageAsBase64(imageUrl) {
|
|
13
|
+
async function fetchImageAsBase64(imageUrl, options = {}) {
|
|
14
14
|
try {
|
|
15
15
|
console.error(`[MCP] Fetching image: ${imageUrl}`);
|
|
16
16
|
const response = await fetch(imageUrl);
|
|
@@ -27,24 +27,63 @@ async function fetchImageAsBase64(imageUrl) {
|
|
|
27
27
|
const originalBuffer = Buffer.from(arrayBuffer);
|
|
28
28
|
console.error(`[MCP] Original image size: ${Math.round(originalBuffer.length / 1024)}KB`);
|
|
29
29
|
|
|
30
|
-
//
|
|
31
|
-
const
|
|
32
|
-
|
|
30
|
+
// Default options
|
|
31
|
+
const maxSize = options.maxSize || 300; // Increased from 200 to 300
|
|
32
|
+
const quality = options.quality || 95; // Increased from 80 to 95
|
|
33
|
+
const format = options.format || 'jpeg'; // Can override to 'png'
|
|
34
|
+
|
|
35
|
+
// Resize image
|
|
36
|
+
let processor = sharp(originalBuffer)
|
|
37
|
+
.resize(maxSize, maxSize, {
|
|
33
38
|
fit: 'inside',
|
|
34
39
|
withoutEnlargement: true
|
|
35
|
-
})
|
|
36
|
-
.jpeg({ quality: 80, mozjpeg: true }) // JPEG is much smaller than PNG
|
|
37
|
-
.toBuffer();
|
|
40
|
+
});
|
|
38
41
|
|
|
42
|
+
// Apply format
|
|
43
|
+
if (format === 'png') {
|
|
44
|
+
processor = processor.png({ quality, compressionLevel: 6 });
|
|
45
|
+
} else {
|
|
46
|
+
processor = processor.jpeg({ quality, mozjpeg: true });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const resizedBuffer = await processor.toBuffer();
|
|
39
50
|
const base64 = resizedBuffer.toString('base64');
|
|
40
51
|
console.error(`[MCP] Resized image size: ${Math.round(resizedBuffer.length / 1024)}KB, base64: ${Math.round(base64.length / 1024)}KB`);
|
|
41
|
-
return base64;
|
|
52
|
+
return { base64, format };
|
|
42
53
|
} catch (error) {
|
|
43
54
|
console.error(`[MCP] Error processing image ${imageUrl}:`, error.message);
|
|
44
55
|
return null;
|
|
45
56
|
}
|
|
46
57
|
}
|
|
47
58
|
|
|
59
|
+
// Helper function to fetch token icons (smaller, simpler images)
|
|
60
|
+
async function fetchTokenIcon(iconUrl) {
|
|
61
|
+
try {
|
|
62
|
+
console.error(`[MCP] Fetching token icon: ${iconUrl}`);
|
|
63
|
+
const response = await fetch(iconUrl);
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
console.error(`[MCP] Icon fetch failed: ${response.status}`);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const contentType = response.headers.get('content-type');
|
|
70
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
71
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
72
|
+
|
|
73
|
+
// For small icons, keep original or resize to max 64x64, use PNG for transparency
|
|
74
|
+
const format = contentType?.includes('svg') ? 'png' : 'png';
|
|
75
|
+
const resizedBuffer = await sharp(buffer)
|
|
76
|
+
.resize(64, 64, { fit: 'inside', withoutEnlargement: false })
|
|
77
|
+
.png({ quality: 100 })
|
|
78
|
+
.toBuffer();
|
|
79
|
+
|
|
80
|
+
return resizedBuffer.toString('base64');
|
|
81
|
+
} catch (error) {
|
|
82
|
+
console.error(`[MCP] Error fetching token icon:`, error.message);
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
48
87
|
// MCP Signature Authentication (optional - for player data access)
|
|
49
88
|
const WALLET = process.env.WALLET;
|
|
50
89
|
const SIGNATURE = process.env.SIGNATURE;
|
|
@@ -382,9 +421,12 @@ Last updated: ${new Date(stats.cached_at * 1000).toLocaleString()}`;
|
|
|
382
421
|
};
|
|
383
422
|
}
|
|
384
423
|
|
|
385
|
-
//
|
|
386
|
-
const
|
|
387
|
-
const
|
|
424
|
+
// Fetch and embed token icons as base64
|
|
425
|
+
const champzIconBase64 = await fetchTokenIcon('https://img.champz.world/img/icon_small.png');
|
|
426
|
+
const usdcIconBase64 = await fetchTokenIcon('https://img.champz.world/img/loots/usdc.svg');
|
|
427
|
+
|
|
428
|
+
const champzIcon = champzIconBase64 ? `data:image/png;base64,${champzIconBase64}` : '';
|
|
429
|
+
const usdcIcon = usdcIconBase64 ? `data:image/png;base64,${usdcIconBase64}` : '';
|
|
388
430
|
|
|
389
431
|
let claimsHTML = '';
|
|
390
432
|
|
|
@@ -1146,9 +1188,11 @@ You can still ask about:
|
|
|
1146
1188
|
};
|
|
1147
1189
|
}
|
|
1148
1190
|
|
|
1149
|
-
// Fetch image
|
|
1191
|
+
// Fetch image with higher quality settings
|
|
1150
1192
|
const imageUrl = `https://img.champz.world${legend.image_path}`;
|
|
1151
|
-
const
|
|
1193
|
+
const imageData = await fetchImageAsBase64(imageUrl, { maxSize: 300, quality: 95 });
|
|
1194
|
+
const base64Data = imageData?.base64;
|
|
1195
|
+
const imageFormat = imageData?.format || 'jpeg';
|
|
1152
1196
|
|
|
1153
1197
|
// Build HTML card with embedded image
|
|
1154
1198
|
const rarityColors = {
|
|
@@ -1317,7 +1361,7 @@ You can still ask about:
|
|
|
1317
1361
|
</div>
|
|
1318
1362
|
${base64Data ? `
|
|
1319
1363
|
<div class="image-container">
|
|
1320
|
-
<img src="data:image
|
|
1364
|
+
<img src="data:image/${imageFormat};base64,${base64Data}" alt="${legend.name}" class="legend-image">
|
|
1321
1365
|
</div>` : ''}
|
|
1322
1366
|
<div class="elements">${elementIcons}</div>
|
|
1323
1367
|
<div class="stats">
|
|
@@ -1401,9 +1445,11 @@ You can still ask about:
|
|
|
1401
1445
|
};
|
|
1402
1446
|
}
|
|
1403
1447
|
|
|
1404
|
-
// Fetch and convert image to base64
|
|
1448
|
+
// Fetch and convert image to base64 with higher quality settings
|
|
1405
1449
|
const imageUrl = `https://img.champz.world${throne.image_path}`;
|
|
1406
|
-
const
|
|
1450
|
+
const imageData = await fetchImageAsBase64(imageUrl, { maxSize: 300, quality: 95 });
|
|
1451
|
+
const base64Data = imageData?.base64;
|
|
1452
|
+
const imageFormat = imageData?.format || 'jpeg';
|
|
1407
1453
|
|
|
1408
1454
|
// Build HTML card with embedded image
|
|
1409
1455
|
const rarityColors = {
|
|
@@ -1547,7 +1593,7 @@ You can still ask about:
|
|
|
1547
1593
|
</div>
|
|
1548
1594
|
${base64Data ? `
|
|
1549
1595
|
<div class="image-container">
|
|
1550
|
-
<img src="data:image
|
|
1596
|
+
<img src="data:image/${imageFormat};base64,${base64Data}" alt="${throne.name}" class="throne-image">
|
|
1551
1597
|
</div>` : ''}
|
|
1552
1598
|
<div class="info">
|
|
1553
1599
|
<div class="info-row">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@champz-llc/legends-mcp-server",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.1",
|
|
4
4
|
"description": "MCP server for Legends of Champz - Query game stats, access personal data with signature auth, and claim rewards through Claude Desktop",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|