@champz-llc/legends-mcp-server 1.4.0 → 1.5.0

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.
Files changed (2) hide show
  1. package/index.js +365 -77
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -831,13 +831,17 @@ You can still ask about:
831
831
  };
832
832
  }
833
833
 
834
- // Build card-like output with gaming vibes
835
- const rarityEmojis = {
836
- unique: '💎',
837
- legendary: '🌟',
838
- epic: '🟣',
839
- rare: '🔵',
840
- common: ''
834
+ // Fetch image
835
+ const imageUrl = `https://img.champz.world${legend.image_path}`;
836
+ const base64Data = await fetchImageAsBase64(imageUrl);
837
+
838
+ // Build HTML card with embedded image
839
+ const rarityColors = {
840
+ unique: '#FFD700',
841
+ legendary: '#FF6B35',
842
+ epic: '#9D4EDD',
843
+ rare: '#4EA8DE',
844
+ common: '#CCCCCC'
841
845
  };
842
846
  const elementEmojis = {
843
847
  fire: '🔥',
@@ -848,46 +852,193 @@ You can still ask about:
848
852
  dark: '🌑'
849
853
  };
850
854
 
851
- let output = `╔════════════════════════╗\n`;
852
- output += `║ ${rarityEmojis[legend.rarity]} ${legend.rarity.toUpperCase()} LEGEND #${legend.legend_id} ║\n`;
853
- output += `╚════════════════════════╝\n\n`;
854
-
855
- output += `🍄 **${legend.name}**\n\n`;
856
-
857
- // Elements with emojis
858
- const elementIcons = legend.elements.map(e => `${elementEmojis[e] || '⭐'} ${e.charAt(0).toUpperCase() + e.slice(1)}`).join(' ');
859
- output += `${elementIcons}\n\n`;
860
-
861
- output += `⚡ **Total Power:** ${legend.total_power}\n`;
862
- output += `⚔️ **ATK:** ${legend.attack}\n`;
863
- output += `🛡️ **DEF:** ${legend.defense}\n`;
864
- output += `💨 **SPD:** ${legend.speed}\n\n`;
865
-
866
- output += `📅 Rolled: ${new Date(legend.rolled_at).toLocaleDateString()}\n`;
867
- output += legend.is_saved ? `⭐ **Saved Trainer** - This legend is in your collection!\n` : `💡 Not saved yet - save this legend to keep it forever!\n`;
868
-
869
- // Fetch image
870
- const imageUrl = `https://img.champz.world${legend.image_path}`;
871
-
872
- // Fetch and convert image to base64
873
- const base64Data = await fetchImageAsBase64(imageUrl);
874
-
875
- const content = [
876
- {
877
- type: 'text',
878
- text: output,
879
- },
880
- ];
881
-
882
- if (base64Data) {
883
- content.push({
884
- type: 'image',
885
- data: base64Data,
886
- mimeType: 'image/jpeg',
887
- });
888
- }
855
+ const elementIcons = legend.elements.map(e => `${elementEmojis[e] || '⭐'} ${e.charAt(0).toUpperCase() + e.slice(1)}`).join(' ');
856
+ const rarityColor = rarityColors[legend.rarity] || '#9D4EDD';
857
+ const rarityBadge = legend.rarity.toUpperCase();
858
+
859
+ const html = `<!DOCTYPE html>
860
+ <html>
861
+ <head>
862
+ <meta charset="UTF-8">
863
+ <style>
864
+ * { margin: 0; padding: 0; box-sizing: border-box; }
865
+ body {
866
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
867
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
868
+ display: flex;
869
+ justify-content: center;
870
+ align-items: center;
871
+ min-height: 100vh;
872
+ padding: 20px;
873
+ }
874
+ .card {
875
+ background: linear-gradient(145deg, #2a2a3e 0%, #1f1f2e 100%);
876
+ border-radius: 16px;
877
+ padding: 24px;
878
+ max-width: 400px;
879
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
880
+ border: 2px solid ${rarityColor};
881
+ position: relative;
882
+ overflow: hidden;
883
+ }
884
+ .card::before {
885
+ content: '';
886
+ position: absolute;
887
+ top: 0;
888
+ left: 0;
889
+ right: 0;
890
+ height: 4px;
891
+ background: linear-gradient(90deg, ${rarityColor}, transparent);
892
+ }
893
+ .header {
894
+ text-align: center;
895
+ margin-bottom: 16px;
896
+ border-bottom: 2px solid rgba(255,255,255,0.1);
897
+ padding-bottom: 12px;
898
+ }
899
+ .rarity-badge {
900
+ background: ${rarityColor};
901
+ color: #000;
902
+ padding: 4px 12px;
903
+ border-radius: 12px;
904
+ font-weight: bold;
905
+ font-size: 11px;
906
+ display: inline-block;
907
+ margin-bottom: 8px;
908
+ text-transform: uppercase;
909
+ letter-spacing: 1px;
910
+ }
911
+ .legend-id {
912
+ color: #fff;
913
+ font-size: 20px;
914
+ font-weight: bold;
915
+ margin-bottom: 4px;
916
+ }
917
+ .legend-name {
918
+ color: ${rarityColor};
919
+ font-size: 18px;
920
+ font-weight: bold;
921
+ }
922
+ .image-container {
923
+ text-align: center;
924
+ margin: 16px 0;
925
+ background: rgba(0,0,0,0.3);
926
+ border-radius: 12px;
927
+ padding: 12px;
928
+ border: 1px solid rgba(255,255,255,0.1);
929
+ }
930
+ .legend-image {
931
+ max-width: 200px;
932
+ border-radius: 8px;
933
+ display: block;
934
+ margin: 0 auto;
935
+ }
936
+ .elements {
937
+ text-align: center;
938
+ font-size: 14px;
939
+ color: #fff;
940
+ margin: 12px 0;
941
+ padding: 8px;
942
+ background: rgba(255,255,255,0.05);
943
+ border-radius: 8px;
944
+ }
945
+ .stats {
946
+ display: grid;
947
+ grid-template-columns: 1fr 1fr;
948
+ gap: 12px;
949
+ margin: 16px 0;
950
+ }
951
+ .stat {
952
+ background: rgba(255,255,255,0.05);
953
+ padding: 12px;
954
+ border-radius: 8px;
955
+ border-left: 3px solid ${rarityColor};
956
+ }
957
+ .stat-label {
958
+ color: #aaa;
959
+ font-size: 12px;
960
+ margin-bottom: 4px;
961
+ }
962
+ .stat-value {
963
+ color: #fff;
964
+ font-size: 18px;
965
+ font-weight: bold;
966
+ }
967
+ .power {
968
+ grid-column: 1 / -1;
969
+ text-align: center;
970
+ background: linear-gradient(135deg, rgba(157, 78, 221, 0.2), rgba(77, 144, 254, 0.2));
971
+ border: 2px solid ${rarityColor};
972
+ }
973
+ .power .stat-value {
974
+ font-size: 24px;
975
+ color: ${rarityColor};
976
+ }
977
+ .footer {
978
+ margin-top: 16px;
979
+ padding-top: 12px;
980
+ border-top: 1px solid rgba(255,255,255,0.1);
981
+ text-align: center;
982
+ color: #888;
983
+ font-size: 12px;
984
+ }
985
+ .saved-badge {
986
+ display: inline-block;
987
+ background: linear-gradient(135deg, #FFD700, #FFA500);
988
+ color: #000;
989
+ padding: 6px 12px;
990
+ border-radius: 8px;
991
+ font-weight: bold;
992
+ margin-top: 8px;
993
+ }
994
+ </style>
995
+ </head>
996
+ <body>
997
+ <div class="card">
998
+ <div class="header">
999
+ <div class="rarity-badge">${rarityBadge}</div>
1000
+ <div class="legend-id">Legend #${legend.legend_id}</div>
1001
+ <div class="legend-name">🍄 ${legend.name}</div>
1002
+ </div>
1003
+ ${base64Data ? `
1004
+ <div class="image-container">
1005
+ <img src="data:image/jpeg;base64,${base64Data}" alt="${legend.name}" class="legend-image">
1006
+ </div>` : ''}
1007
+ <div class="elements">${elementIcons}</div>
1008
+ <div class="stats">
1009
+ <div class="stat power">
1010
+ <div class="stat-label">⚡ TOTAL POWER</div>
1011
+ <div class="stat-value">${legend.total_power}</div>
1012
+ </div>
1013
+ <div class="stat">
1014
+ <div class="stat-label">⚔️ ATTACK</div>
1015
+ <div class="stat-value">${legend.attack}</div>
1016
+ </div>
1017
+ <div class="stat">
1018
+ <div class="stat-label">🛡️ DEFENSE</div>
1019
+ <div class="stat-value">${legend.defense}</div>
1020
+ </div>
1021
+ <div class="stat">
1022
+ <div class="stat-label">💨 SPEED</div>
1023
+ <div class="stat-value">${legend.speed}</div>
1024
+ </div>
1025
+ </div>
1026
+ <div class="footer">
1027
+ 📅 Rolled: ${new Date(legend.rolled_at).toLocaleDateString()}
1028
+ ${legend.is_saved ? '<div class="saved-badge">⭐ SAVED TRAINER</div>' : ''}
1029
+ </div>
1030
+ </div>
1031
+ </body>
1032
+ </html>`;
889
1033
 
890
- return { content };
1034
+ return {
1035
+ content: [
1036
+ {
1037
+ type: 'text',
1038
+ text: html,
1039
+ },
1040
+ ],
1041
+ };
891
1042
  } catch (error) {
892
1043
  return {
893
1044
  content: [
@@ -935,43 +1086,180 @@ You can still ask about:
935
1086
  };
936
1087
  }
937
1088
 
938
- // Build card-like output with gaming vibes
939
- const rarityEmojis = {
940
- legendary: '👑',
941
- epic: '💜',
942
- rare: '💙',
943
- common: '🤍'
944
- };
945
-
946
- let output = `╔════════════════════════╗\n`;
947
- output += `║ ${rarityEmojis[throne.rarity] || '🏆'} ${throne.rarity.toUpperCase()} THRONE #${throne.throne_id} ║\n`;
948
- output += `╚════════════════════════╝\n\n`;
949
-
950
- output += `👑 **${throne.name}**\n\n`;
951
- output += `🎮 **Earned in Cycle:** ${throne.cycle_id}\n`;
952
- output += `📅 **Date Earned:** ${new Date(throne.earned_at).toLocaleDateString()}\n\n`;
953
- output += `🏆 You're a champion! This throne proves you held the Guardian position and won the cycle!\n`;
954
-
955
1089
  // Fetch and convert image to base64
956
1090
  const imageUrl = `https://img.champz.world${throne.image_path}`;
957
1091
  const base64Data = await fetchImageAsBase64(imageUrl);
958
1092
 
959
- const content = [
960
- {
961
- type: 'text',
962
- text: output,
963
- },
964
- ];
1093
+ // Build HTML card with embedded image
1094
+ const rarityColors = {
1095
+ legendary: '#FFD700',
1096
+ epic: '#9D4EDD',
1097
+ rare: '#4EA8DE',
1098
+ common: '#CCCCCC'
1099
+ };
965
1100
 
966
- if (base64Data) {
967
- content.push({
968
- type: 'image',
969
- data: base64Data,
970
- mimeType: 'image/jpeg',
971
- });
972
- }
1101
+ const rarityColor = rarityColors[throne.rarity] || '#FFD700';
1102
+ const rarityBadge = throne.rarity.toUpperCase();
1103
+
1104
+ const html = `<!DOCTYPE html>
1105
+ <html>
1106
+ <head>
1107
+ <meta charset="UTF-8">
1108
+ <style>
1109
+ * { margin: 0; padding: 0; box-sizing: border-box; }
1110
+ body {
1111
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
1112
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
1113
+ display: flex;
1114
+ justify-content: center;
1115
+ align-items: center;
1116
+ min-height: 100vh;
1117
+ padding: 20px;
1118
+ }
1119
+ .card {
1120
+ background: linear-gradient(145deg, #2a2a3e 0%, #1f1f2e 100%);
1121
+ border-radius: 16px;
1122
+ padding: 24px;
1123
+ max-width: 400px;
1124
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
1125
+ border: 2px solid ${rarityColor};
1126
+ position: relative;
1127
+ overflow: hidden;
1128
+ }
1129
+ .card::before {
1130
+ content: '';
1131
+ position: absolute;
1132
+ top: 0;
1133
+ left: 0;
1134
+ right: 0;
1135
+ height: 4px;
1136
+ background: linear-gradient(90deg, ${rarityColor}, transparent);
1137
+ }
1138
+ .header {
1139
+ text-align: center;
1140
+ margin-bottom: 16px;
1141
+ border-bottom: 2px solid rgba(255,255,255,0.1);
1142
+ padding-bottom: 12px;
1143
+ }
1144
+ .rarity-badge {
1145
+ background: ${rarityColor};
1146
+ color: #000;
1147
+ padding: 4px 12px;
1148
+ border-radius: 12px;
1149
+ font-weight: bold;
1150
+ font-size: 11px;
1151
+ display: inline-block;
1152
+ margin-bottom: 8px;
1153
+ text-transform: uppercase;
1154
+ letter-spacing: 1px;
1155
+ }
1156
+ .throne-id {
1157
+ color: #fff;
1158
+ font-size: 20px;
1159
+ font-weight: bold;
1160
+ margin-bottom: 4px;
1161
+ }
1162
+ .throne-name {
1163
+ color: ${rarityColor};
1164
+ font-size: 18px;
1165
+ font-weight: bold;
1166
+ }
1167
+ .image-container {
1168
+ text-align: center;
1169
+ margin: 16px 0;
1170
+ background: rgba(0,0,0,0.3);
1171
+ border-radius: 12px;
1172
+ padding: 12px;
1173
+ border: 1px solid rgba(255,255,255,0.1);
1174
+ }
1175
+ .throne-image {
1176
+ max-width: 200px;
1177
+ border-radius: 8px;
1178
+ display: block;
1179
+ margin: 0 auto;
1180
+ }
1181
+ .info {
1182
+ background: rgba(255,255,255,0.05);
1183
+ padding: 16px;
1184
+ border-radius: 8px;
1185
+ border-left: 3px solid ${rarityColor};
1186
+ margin: 16px 0;
1187
+ }
1188
+ .info-row {
1189
+ display: flex;
1190
+ justify-content: space-between;
1191
+ color: #fff;
1192
+ padding: 8px 0;
1193
+ border-bottom: 1px solid rgba(255,255,255,0.05);
1194
+ }
1195
+ .info-row:last-child {
1196
+ border-bottom: none;
1197
+ }
1198
+ .info-label {
1199
+ color: #aaa;
1200
+ font-size: 14px;
1201
+ }
1202
+ .info-value {
1203
+ font-weight: bold;
1204
+ font-size: 14px;
1205
+ }
1206
+ .trophy-message {
1207
+ text-align: center;
1208
+ background: linear-gradient(135deg, rgba(255, 215, 0, 0.2), rgba(255, 165, 0, 0.2));
1209
+ border: 2px solid ${rarityColor};
1210
+ padding: 16px;
1211
+ border-radius: 8px;
1212
+ margin-top: 16px;
1213
+ }
1214
+ .trophy-message .emoji {
1215
+ font-size: 32px;
1216
+ display: block;
1217
+ margin-bottom: 8px;
1218
+ }
1219
+ .trophy-message .text {
1220
+ color: #fff;
1221
+ font-weight: bold;
1222
+ font-size: 14px;
1223
+ }
1224
+ </style>
1225
+ </head>
1226
+ <body>
1227
+ <div class="card">
1228
+ <div class="header">
1229
+ <div class="rarity-badge">${rarityBadge} THRONE</div>
1230
+ <div class="throne-id">Throne #${throne.throne_id}</div>
1231
+ <div class="throne-name">👑 ${throne.name}</div>
1232
+ </div>
1233
+ ${base64Data ? `
1234
+ <div class="image-container">
1235
+ <img src="data:image/jpeg;base64,${base64Data}" alt="${throne.name}" class="throne-image">
1236
+ </div>` : ''}
1237
+ <div class="info">
1238
+ <div class="info-row">
1239
+ <span class="info-label">🎮 Cycle</span>
1240
+ <span class="info-value">#${throne.cycle_id}</span>
1241
+ </div>
1242
+ <div class="info-row">
1243
+ <span class="info-label">📅 Date Earned</span>
1244
+ <span class="info-value">${new Date(throne.earned_at).toLocaleDateString()}</span>
1245
+ </div>
1246
+ </div>
1247
+ <div class="trophy-message">
1248
+ <span class="emoji">🏆</span>
1249
+ <span class="text">CHAMPION! You held the Guardian position and won Cycle ${throne.cycle_id}!</span>
1250
+ </div>
1251
+ </div>
1252
+ </body>
1253
+ </html>`;
973
1254
 
974
- return { content };
1255
+ return {
1256
+ content: [
1257
+ {
1258
+ type: 'text',
1259
+ text: html,
1260
+ },
1261
+ ],
1262
+ };
975
1263
  } catch (error) {
976
1264
  return {
977
1265
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@champz-llc/legends-mcp-server",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
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",