diff --git a/src/EllieBot/Modules/Music/Music.cs b/src/EllieBot/Modules/Music/Music.cs
index cba818b..e5e9814 100644
--- a/src/EllieBot/Modules/Music/Music.cs
+++ b/src/EllieBot/Modules/Music/Music.cs
@@ -7,13 +7,24 @@ namespace EllieBot.Modules.Music;
 [NoPublicBot]
 public sealed partial class Music : EllieModule<IMusicService>
 {
-    public enum All { All = -1 }
+    public enum All
+    {
+        All = -1
+    }
 
     public enum InputRepeatType
     {
-        N = 0, No = 0, None = 0,
-        T = 1, Track = 1, S = 1, Song = 1,
-        Q = 2, Queue = 2, Playlist = 2, Pl = 2
+        N = 0,
+        No = 0,
+        None = 0,
+        T = 1,
+        Track = 1,
+        S = 1,
+        Song = 1,
+        Q = 2,
+        Queue = 2,
+        Playlist = 2,
+        Pl = 2
     }
 
     public const string MUSIC_ICON_URL = "https://i.imgur.com/nhKS3PT.png";
@@ -22,9 +33,13 @@ public sealed partial class Music : EllieModule<IMusicService>
 
     private static readonly SemaphoreSlim _voiceChannelLock = new(1, 1);
     private readonly ILogCommandService _logService;
+    private readonly ILyricsService _lyricsService;
 
-    public Music(ILogCommandService logService)
-        => _logService = logService;
+    public Music(ILogCommandService logService, ILyricsService lyricsService)
+    {
+        _logService = logService;
+        _lyricsService = lyricsService;
+    }
 
     private async Task<bool> ValidateAsync()
     {
@@ -110,10 +125,10 @@ public sealed partial class Music : EllieModule<IMusicService>
         try
         {
             var embed = CreateEmbed()
-                               .WithOkColor()
-                               .WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
-                               .WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
-                               .WithFooter(trackInfo.Platform.ToString());
+                .WithOkColor()
+                .WithAuthor(GetText(strs.queued_track) + " #" + (index + 1), MUSIC_ICON_URL)
+                .WithDescription($"{trackInfo.PrettyName()}\n{GetText(strs.queue)} ")
+                .WithFooter(trackInfo.Platform.ToString());
 
             if (!string.IsNullOrWhiteSpace(trackInfo.Thumbnail))
                 embed.WithThumbnailUrl(trackInfo.Thumbnail);
@@ -301,39 +316,39 @@ public sealed partial class Music : EllieModule<IMusicService>
 
 
             desc += tracks
-                    .Select((v, index) =>
-                    {
-                        index += LQ_ITEMS_PER_PAGE * curPage;
-                        if (index == currentIndex)
-                            return $"**⇒**`{index + 1}.` {v.PrettyFullName()}";
+                .Select((v, index) =>
+                {
+                    index += LQ_ITEMS_PER_PAGE * curPage;
+                    if (index == currentIndex)
+                        return $"**⇒**`{index + 1}.` {v.PrettyFullName()}";
 
-                        return $"`{index + 1}.` {v.PrettyFullName()}";
-                    })
-                    .Join('\n');
+                    return $"`{index + 1}.` {v.PrettyFullName()}";
+                })
+                .Join('\n');
 
             if (!string.IsNullOrWhiteSpace(add))
                 desc = add + "\n" + desc;
 
             var embed = CreateEmbed()
-                               .WithAuthor(
-                                   GetText(strs.player_queue(curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1)),
-                                   MUSIC_ICON_URL)
-                               .WithDescription(desc)
-                               .WithFooter(
-                                   $"  {mp.PrettyVolume()}  |  🎶 {tracks.Count}  |  ⌛ {mp.PrettyTotalTime()}  ")
-                               .WithOkColor();
+                .WithAuthor(
+                    GetText(strs.player_queue(curPage + 1, (tracks.Count / LQ_ITEMS_PER_PAGE) + 1)),
+                    MUSIC_ICON_URL)
+                .WithDescription(desc)
+                .WithFooter(
+                    $"  {mp.PrettyVolume()}  |  🎶 {tracks.Count}  |  ⌛ {mp.PrettyTotalTime()}  ")
+                .WithOkColor();
 
             return embed;
         }
 
         await Response()
-              .Paginated()
-              .Items(tracks)
-              .PageSize(LQ_ITEMS_PER_PAGE)
-              .CurrentPage(page)
-              .AddFooter(false)
-              .Page(PrintAction)
-              .SendAsync();
+            .Paginated()
+            .Items(tracks)
+            .PageSize(LQ_ITEMS_PER_PAGE)
+            .CurrentPage(page)
+            .AddFooter(false)
+            .Page(PrintAction)
+            .SendAsync();
     }
 
     // search
@@ -353,15 +368,15 @@ public sealed partial class Music : EllieModule<IMusicService>
 
 
         var embeds = videos.Select((x, i) => CreateEmbed()
-                                                    .WithOkColor()
-                                                    .WithThumbnailUrl(x.Thumbnail)
-                                                    .WithDescription($"`{i + 1}.` {Format.Bold(x.Title)}\n\t{x.Url}"))
-                           .ToList();
+                .WithOkColor()
+                .WithThumbnailUrl(x.Thumbnail)
+                .WithDescription($"`{i + 1}.` {Format.Bold(x.Title)}\n\t{x.Url}"))
+            .ToList();
 
         var msg = await Response()
-                        .Text(strs.queue_search_results)
-                        .Embeds(embeds)
-                        .SendAsync();
+            .Text(strs.queue_search_results)
+            .Embeds(embeds)
+            .SendAsync();
 
         try
         {
@@ -425,10 +440,10 @@ public sealed partial class Music : EllieModule<IMusicService>
         }
 
         var embed = CreateEmbed()
-                           .WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
-                           .WithDescription(track.PrettyName())
-                           .WithFooter(track.PrettyInfo())
-                           .WithErrorColor();
+            .WithAuthor(GetText(strs.removed_track) + " #" + index, MUSIC_ICON_URL)
+            .WithDescription(track.PrettyName())
+            .WithFooter(track.PrettyInfo())
+            .WithErrorColor();
 
         await _service.SendToOutputAsync(ctx.Guild.Id, embed);
     }
@@ -593,11 +608,11 @@ public sealed partial class Music : EllieModule<IMusicService>
         }
 
         var embed = CreateEmbed()
-                           .WithTitle(track.Title.TrimTo(65))
-                           .WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
-                           .AddField(GetText(strs.from_position), $"#{from + 1}", true)
-                           .AddField(GetText(strs.to_position), $"#{to + 1}", true)
-                           .WithOkColor();
+            .WithTitle(track.Title.TrimTo(65))
+            .WithAuthor(GetText(strs.track_moved), MUSIC_ICON_URL)
+            .AddField(GetText(strs.from_position), $"#{from + 1}", true)
+            .AddField(GetText(strs.to_position), $"#{to + 1}", true)
+            .WithOkColor();
 
         if (Uri.IsWellFormedUriString(track.Url, UriKind.Absolute))
             embed.WithUrl(track.Url);
@@ -652,12 +667,12 @@ public sealed partial class Music : EllieModule<IMusicService>
             return;
 
         var embed = CreateEmbed()
-                           .WithOkColor()
-                           .WithAuthor(GetText(strs.now_playing), MUSIC_ICON_URL)
-                           .WithDescription(currentTrack.PrettyName())
-                           .WithThumbnailUrl(currentTrack.Thumbnail)
-                           .WithFooter(
-                               $"{mp.PrettyVolume()} | {mp.PrettyTotalTime()} | {currentTrack.Platform} | {currentTrack.Queuer}");
+            .WithOkColor()
+            .WithAuthor(GetText(strs.now_playing), MUSIC_ICON_URL)
+            .WithDescription(currentTrack.PrettyName())
+            .WithThumbnailUrl(currentTrack.Thumbnail)
+            .WithFooter(
+                $"{mp.PrettyVolume()} | {mp.PrettyTotalTime()} | {currentTrack.Platform} | {currentTrack.Queuer}");
 
         await Response().Embed(embed).SendAsync();
     }
@@ -768,4 +783,71 @@ public sealed partial class Music : EllieModule<IMusicService>
             await Response().Confirm(strs.wrongsong_success(removed.Title.TrimTo(30))).SendAsync();
         }
     }
+
+    [Cmd]
+    [RequireContext(ContextType.Guild)]
+    public async Task Lyrics([Leftover] string name = null)
+    {
+        if (string.IsNullOrWhiteSpace(name))
+        {
+            if (_service.TryGetMusicPlayer(ctx.Guild.Id, out var mp)
+                && mp.GetCurrentTrack(out _) is { } currentTrack)
+            {
+                name = currentTrack.Title;
+            }
+            else
+            {
+                return;
+            }
+        }
+
+        var tracks = await _lyricsService.SearchTracksAsync(name);
+
+        if (tracks.Count == 0)
+        {
+            await Response().Error(strs.no_lyrics_found).SendAsync();
+            return;
+        }
+
+        var embed = CreateEmbed()
+            .WithFooter("type 1-5 to select");
+
+        for (var i = 0; i <= 5 && i < tracks.Count; i++)
+        {
+            var item = tracks[i];
+            embed.AddField($"`{(i + 1)}`. {item.Author}", item.Title, false);
+        }
+
+        await Response()
+            .Embed(embed)
+            .SendAsync();
+
+        var input = await GetUserInputAsync(ctx.User.Id, ctx.Channel.Id, str => int.TryParse(str, out _));
+
+        if (input is null)
+            return;
+
+        var index = int.Parse(input) - 1;
+        if (index < 0 || index > 4)
+        {
+            return;
+        }
+
+        var track = tracks[index];
+        var lyrics = await _lyricsService.GetLyricsAsync(track.Id);
+
+        if (string.IsNullOrWhiteSpace(lyrics))
+        {
+            await Response().Error(strs.no_lyrics_found).SendAsync();
+            return;
+        }
+
+        await Response()
+            .Embed(CreateEmbed()
+                .WithOkColor()
+                .WithAuthor(track.Author)
+                .WithTitle(track.Title)
+                .WithDescription(lyrics))
+            .SendAsync();
+    }
 }
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/Services/ILyricsService.cs b/src/EllieBot/Modules/Music/Services/ILyricsService.cs
new file mode 100644
index 0000000..3506e1f
--- /dev/null
+++ b/src/EllieBot/Modules/Music/Services/ILyricsService.cs
@@ -0,0 +1,7 @@
+namespace EllieBot.Modules.Music;
+
+public interface ILyricsService
+{
+    public Task<IReadOnlyList<TracksItem>> SearchTracksAsync(string name);
+    public Task<string> GetLyricsAsync(int trackId);
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/Services/LyricsService.cs b/src/EllieBot/Modules/Music/Services/LyricsService.cs
new file mode 100644
index 0000000..bb67eca
--- /dev/null
+++ b/src/EllieBot/Modules/Music/Services/LyricsService.cs
@@ -0,0 +1,25 @@
+using Musix;
+
+namespace EllieBot.Modules.Music;
+
+public sealed class LyricsService(HttpClient client) : ILyricsService, IEService
+{
+    private readonly MusixMatchAPI _api = new(client);
+
+    private static string NormalizeName(string name)
+        => string.Join("-", name.Split()
+                .Select(x => new string(x.Where(c => char.IsLetterOrDigit(c)).ToArray())))
+            .Trim('-');
+
+    public async Task<IReadOnlyList<TracksItem>> SearchTracksAsync(string name)
+        => await _api.SearchTracksAsync(NormalizeName(name))
+            .Fmap(x => x
+                .Message
+                .Body
+                .TrackList
+                .Map(x => new TracksItem(x.Track.ArtistName, x.Track.TrackName, x.Track.TrackId)));
+
+    public async Task<string> GetLyricsAsync(int trackId)
+        => await _api.GetTrackLyricsAsync(trackId)
+            .Fmap(x => x.Message.Body.Lyrics.LyricsBody);
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/Header.cs b/src/EllieBot/Modules/Music/_common/Musix/Header.cs
new file mode 100644
index 0000000..402e00f
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/Header.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class Header
+{
+    [JsonPropertyName("status_code")]
+    public int StatusCode { get; set; }
+
+    [JsonPropertyName("execute_time")]
+    public double ExecuteTime { get; set; }
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/Lyrics.cs b/src/EllieBot/Modules/Music/_common/Musix/Lyrics.cs
new file mode 100644
index 0000000..bc78ba0
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/Lyrics.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class Lyrics
+{
+    [JsonPropertyName("lyrics_body")]
+    public string LyricsBody { get; set; } = string.Empty;
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/LyricsResponse.cs b/src/EllieBot/Modules/Music/_common/Musix/LyricsResponse.cs
new file mode 100644
index 0000000..e5b32fc
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/LyricsResponse.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class LyricsResponse
+{
+    [JsonPropertyName("lyrics")]
+    public Lyrics Lyrics { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/Message.cs b/src/EllieBot/Modules/Music/_common/Musix/Message.cs
new file mode 100644
index 0000000..85f276f
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/Message.cs
@@ -0,0 +1,12 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class Message<T>
+{
+    [JsonPropertyName("header")]
+    public Header Header { get; set; } = null!;
+
+    [JsonPropertyName("body")]
+    public T Body { get; set; } = default!;
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/MusixMatchAPI.cs b/src/EllieBot/Modules/Music/_common/Musix/MusixMatchAPI.cs
new file mode 100644
index 0000000..cd4279f
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/MusixMatchAPI.cs
@@ -0,0 +1,141 @@
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Text.Json;
+using System.Web;
+using Microsoft.Extensions.Caching.Memory;
+using Musix.Models;
+
+// All credit goes to https://github.com/Strvm/musicxmatch-api for the original implementation
+namespace Musix
+{
+    public sealed class MusixMatchAPI
+    {
+        private readonly HttpClient _httpClient;
+        private readonly string _baseUrl = "https://www.musixmatch.com/ws/1.1/";
+
+        private readonly string _userAgent =
+            "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36";
+
+        private readonly IMemoryCache _cache;
+        private readonly JsonSerializerOptions _jsonOptions;
+
+        public MusixMatchAPI(HttpClient httpClient)
+        {
+            _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(_userAgent);
+            _httpClient.DefaultRequestHeaders.Add("Cookie", "mxm_bab=AB");
+
+            _jsonOptions = new()
+            {
+                PropertyNameCaseInsensitive = true
+            };
+            _cache = new MemoryCache(new MemoryCacheOptions { });
+        }
+
+        private async Task<string> GetLatestAppUrlAsync()
+        {
+            var url = "https://www.musixmatch.com/search";
+            using var request = new HttpRequestMessage(HttpMethod.Get, url);
+            request.Headers.UserAgent.ParseAdd(
+                "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36");
+            request.Headers.Add("Cookie", "mxm_bab=AB");
+
+            var response = await _httpClient.SendAsync(request);
+            response.EnsureSuccessStatusCode();
+            var htmlContent = await response.Content.ReadAsStringAsync();
+
+            var pattern = @"src=""([^""]*/_next/static/chunks/pages/_app-[^""]+\.js)""";
+            var matches = Regex.Matches(htmlContent, pattern);
+
+            return matches.Count > 0
+                ? matches[^1].Groups[1].Value
+                : throw new("_app URL not found in the HTML content.");
+        }
+
+        private async Task<string> GetSecret()
+        {
+            var latestAppUrl = await GetLatestAppUrlAsync();
+            var response = await _httpClient.GetAsync(latestAppUrl);
+            response.EnsureSuccessStatusCode();
+            var javascriptCode = await response.Content.ReadAsStringAsync();
+
+            var pattern = @"from\(\s*""(.*?)""\s*\.split";
+            var match = Regex.Match(javascriptCode, pattern);
+
+            if (match.Success)
+            {
+                var encodedString = match.Groups[1].Value;
+                var reversedString = new string(encodedString.Reverse().ToArray());
+                var decodedBytes = Convert.FromBase64String(reversedString);
+                return Encoding.UTF8.GetString(decodedBytes);
+            }
+
+            throw new Exception("Encoded string not found in the JavaScript code.");
+        }
+
+        // It seems this is required in order to have multiword queries.
+        // Spaces don't work in the original implementation either
+        private string UrlEncode(string value)
+            => HttpUtility.UrlEncode(value)
+                .Replace("+", "-");
+
+        private async Task<string> GenerateSignature(string url)
+        {
+            var currentDate = DateTime.Now;
+            var l = currentDate.Year.ToString();
+            var s = currentDate.Month.ToString("D2");
+            var r = currentDate.Day.ToString("D2");
+
+            var message = (url + l + s + r);
+            var secret = await _cache.GetOrCreateAsync("secret", async _ => await GetSecret());
+            var key = Encoding.UTF8.GetBytes(secret ?? string.Empty);
+            var messageBytes = Encoding.UTF8.GetBytes(message);
+
+            using var hmac = new HMACSHA256(key);
+            var hashBytes = hmac.ComputeHash(messageBytes);
+            var signature = Convert.ToBase64String(hashBytes);
+            return $"&signature={UrlEncode(signature)}&signature_protocol=sha256";
+        }
+
+        public async Task<MusixMatchResponse<TrackSearchResponse>> SearchTracksAsync(string trackQuery, int page = 1)
+        {
+            var endpoint =
+                $"track.search?app_id=community-app-v1.0&format=json&q={UrlEncode(trackQuery)}&f_has_lyrics=true&page_size=100&page={page}";
+            var jsonResponse = await MakeRequestAsync(endpoint);
+            return JsonSerializer.Deserialize<MusixMatchResponse<TrackSearchResponse>>(jsonResponse, _jsonOptions)
+                   ?? throw new JsonException("Failed to deserialize track search response");
+        }
+
+        public async Task<MusixMatchResponse<LyricsResponse>> GetTrackLyricsAsync(int trackId)
+        {
+            var endpoint = $"track.lyrics.get?app_id=community-app-v1.0&format=json&track_id={trackId}";
+            var jsonResponse = await MakeRequestAsync(endpoint);
+            return JsonSerializer.Deserialize<MusixMatchResponse<LyricsResponse>>(jsonResponse, _jsonOptions)
+                   ?? throw new JsonException("Failed to deserialize lyrics response");
+        }
+
+        private async Task<string> MakeRequestAsync(string endpoint)
+        {
+            var fullUrl = _baseUrl + endpoint;
+            var signedUrl = fullUrl + await GenerateSignature(fullUrl);
+
+            Console.WriteLine($"DEBUG - Request URL: {signedUrl}");
+
+            var request = new HttpRequestMessage(HttpMethod.Get, signedUrl);
+            request.Headers.UserAgent.ParseAdd(_userAgent);
+            request.Headers.Add("Cookie", "mxm_bab=AB");
+
+            var response = await _httpClient.SendAsync(request);
+
+            var content = await response.Content.ReadAsStringAsync();
+            if (!response.IsSuccessStatusCode)
+            {
+                Console.WriteLine($"ERROR - Status: {response.StatusCode}, Content: {content}");
+                response.EnsureSuccessStatusCode(); // This will throw with the appropriate status code
+            }
+
+            return content;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/MusixMatchResponse.cs b/src/EllieBot/Modules/Music/_common/Musix/MusixMatchResponse.cs
new file mode 100644
index 0000000..e54bdb0
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/MusixMatchResponse.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Text.Json.Serialization;
+
+namespace Musix.Models
+{
+    public class MusixMatchResponse<T>
+    {
+        [JsonPropertyName("message")]
+        public Message<T> Message { get; set; } = null!;
+    }
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/Track.cs b/src/EllieBot/Modules/Music/_common/Musix/Track.cs
new file mode 100644
index 0000000..33fbc7e
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/Track.cs
@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class Track
+{
+    [JsonPropertyName("track_id")]
+    public int TrackId { get; set; }
+
+    [JsonPropertyName("track_name")]
+    public string TrackName { get; set; } = string.Empty;
+
+    [JsonPropertyName("artist_name")]
+    public string ArtistName { get; set; } = string.Empty;
+
+    [JsonPropertyName("album_name")]
+    public string AlbumName { get; set; } = string.Empty;
+
+    [JsonPropertyName("track_share_url")]
+    public string TrackShareUrl { get; set; } = string.Empty;
+
+    public override string ToString() => $"{TrackName} by {ArtistName} (Album: {AlbumName})";
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/TrackListItem.cs b/src/EllieBot/Modules/Music/_common/Musix/TrackListItem.cs
new file mode 100644
index 0000000..297fd97
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/TrackListItem.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class TrackListItem
+{
+    [JsonPropertyName("track")]
+    public Track Track { get; set; } = null!;
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/Musix/TrackSearchResponse.cs b/src/EllieBot/Modules/Music/_common/Musix/TrackSearchResponse.cs
new file mode 100644
index 0000000..630f9fe
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/Musix/TrackSearchResponse.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace Musix.Models;
+
+public class TrackSearchResponse
+{
+    [JsonPropertyName("track_list")]
+    public List<TrackListItem> TrackList { get; set; } = new();
+}
\ No newline at end of file
diff --git a/src/EllieBot/Modules/Music/_common/TracksItem.cs b/src/EllieBot/Modules/Music/_common/TracksItem.cs
new file mode 100644
index 0000000..3ebb77b
--- /dev/null
+++ b/src/EllieBot/Modules/Music/_common/TracksItem.cs
@@ -0,0 +1,3 @@
+namespace EllieBot.Modules.Music;
+
+public record struct TracksItem(string Author, string Title, int Id);
\ No newline at end of file
diff --git a/src/EllieBot/strings/aliases.yml b/src/EllieBot/strings/aliases.yml
index 38df275..8f2929a 100644
--- a/src/EllieBot/strings/aliases.yml
+++ b/src/EllieBot/strings/aliases.yml
@@ -1586,4 +1586,6 @@ fishspot:
 xprate:
   - xprate
 xpratereset:
-  - xpratereset
\ No newline at end of file
+  - xpratereset
+lyrics:
+   - lyrics
\ No newline at end of file
diff --git a/src/EllieBot/strings/commands/commands.en-US.yml b/src/EllieBot/strings/commands/commands.en-US.yml
index 3f9c668..e71adcf 100644
--- a/src/EllieBot/strings/commands/commands.en-US.yml
+++ b/src/EllieBot/strings/commands/commands.en-US.yml
@@ -4977,4 +4977,12 @@ xpratereset:
   params:
     - { }
     - channel:
-        desc: "The channel to reset the rate for."
\ No newline at end of file
+        desc: "The channel to reset the rate for."
+lyrics:
+   desc: |-
+     Looks up lyrics for a song. Very hit or miss.
+   ex:
+     - 'biri biri'
+   params:
+     - song:
+         desc: "The song to look up lyrics for."
\ No newline at end of file
diff --git a/src/EllieBot/strings/responses/responses.en-US.json b/src/EllieBot/strings/responses/responses.en-US.json
index 886c8eb..cd15917 100644
--- a/src/EllieBot/strings/responses/responses.en-US.json
+++ b/src/EllieBot/strings/responses/responses.en-US.json
@@ -1178,5 +1178,6 @@
   "xp_rate_channel_set": "Channel **{0}** xp rate set to **{1}** xp per every **{2}** min.",
   "xp_rate_server_reset": "Server xp rate has been reset to global defaults.",
   "xp_rate_channel_reset": "Channel {0} xp rate has been reset.",
-  "xp_rate_no_gain": "No xp gain"
+  "xp_rate_no_gain": "No xp gain",
+  "no_lyrics_found": "No lyrics found."
 }