diff --git a/gems/lib/asciidoctor/foodogsquared-extensions.rb b/gems/lib/asciidoctor/foodogsquared-extensions.rb
index f689658..788339c 100644
--- a/gems/lib/asciidoctor/foodogsquared-extensions.rb
+++ b/gems/lib/asciidoctor/foodogsquared-extensions.rb
@@ -17,6 +17,7 @@ require_relative 'git-blob-include-processor/extension'
 require_relative 'wikipedia-inline-macro/extension'
 require_relative 'package-indices-link-macro/extension'
 require_relative 'fdroid-link-inline-macro/extension'
+require_relative 'musicbrainz-link-inline-macro/extension'
 
 Asciidoctor::Extensions.register do
   inline_macro ManInlineMacro
@@ -40,4 +41,6 @@ Asciidoctor::Extensions.register do
   inline_macro PypiLinkInlineMacro
   inline_macro CratesIOLinkInlineMacro
   inline_macro FDroidLinkInlineMacro
+
+  inline_macro MusicBrainzLinkInlineMacro
 end
diff --git a/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc
new file mode 100644
index 0000000..266d83d
--- /dev/null
+++ b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/README.adoc
@@ -0,0 +1,45 @@
+= Musicbrainz link inline macro
+:toc:
+
+
+An inline macro for easily linking objects from link:https://musicbrainz.org/doc/MusicBrainz_Database[Musicbrainz database].
+
+
+== Synopsis
+
+[source, asciidoc]
+----
+musicbrainz:$ID[$CAPTION, $TYPE]
+----
+
+- `$ID` is the database identifier for that object (e.g., `9adcff14-7dba-4ccf-a6a6-298bcde3dd46`).
+
+- `$CAPTION` is the link text.
+By default, it will be the name of the database object (if valid).
+Take note it will use the MusicBrainz API to query the title/name of the object.
+In other words, it costs an additional network request.
+
+- `$TYPE` is the database object type.
+It defaults to 'Release' object type.
+
+
+== Attributes
+
+The macro can also accept some attributes.
+
+- `caption` is the link text to be used.
+This can be used instead of the first positional attribute.
+
+- `type` is the database object type to be queried.
+This can be used instead of the second positional attribute.
+
+
+== Example usage
+
+- `musicbrainz:9adcff14-7dba-4ccf-a6a6-298bcde3dd46[]` should have a link to the link:https://musicbrainz.org/release/9adcff14-7dba-4ccf-a6a6-298bcde3dd46[Musicbrainz page for The Bindings of Isaac Rebirth] with 'The Bindings of Isaac: Rebirth' as the link caption.
+
+- `musicbrainz:9adcff14-7dba-4ccf-a6a6-298bcde3dd46[Ridiculon's Rebirth soundtrack]` same as above but with the link text replaced with 'Ridiculon's Rebirth Soundtrack'.
+
+- `musicbrainz:b7c7f603-4c42-45a4-b364-3ddba82da412[type=release-group]` links to the link:https://musicbrainz.org/release-group/b7c7f603-4c42-45a4-b364-3ddba82da412[Musicbrainz page for The Bindings of Isaac Rebirth release group] with 'The Bindings of Isaac: Rebirth' as the link text.
+
+- `musicbrainz:f07c6afe-ee84-4cd5-9b11-5c541d1dff3b[type=artist]` links to link:https://musicbrainz.org/artist/f07c6afe-ee84-4cd5-9b11-5c541d1dff3b[Musicbrainz page for Ridiculon] with their name as the caption.
diff --git a/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb
new file mode 100644
index 0000000..5b1ad06
--- /dev/null
+++ b/gems/lib/asciidoctor/musicbrainz-link-inline-macro/extension.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'json'
+require 'open-uri'
+require 'open-uri/cached'
+require 'uri'
+
+class MusicBrainzLinkInlineMacro < Asciidoctor::Extensions::InlineMacroProcessor
+  use_dsl
+
+  named :musicbrainz
+  name_positional_attributes 'caption', 'type'
+  default_attributes 'type' => 'release'
+
+  def process(parent, target, attrs)
+    doc = parent.document
+    root_endpoint = 'https://musicbrainz.org/ws/2'
+
+    begin
+      headers = {
+        'Accept' => 'application/json',
+        'User-Agent' => ::Asciidoctor::FoodogsquaredCustomExtensions::USER_AGENT
+      }
+
+      uri = %(#{root_endpoint}/#{attrs['type']}/#{target})
+
+      if attrs['caption'].nil?
+        metadata = OpenURI.open_uri(uri, headers) { |f| JSON.parse(f.read) }
+        attrs['caption'] ||= case attrs['type']
+                             when 'artist', 'area', 'events', 'genre', 'instrument', 'label', 'place', 'series'
+                               metadata['name']
+                             when 'recording', 'release-group', 'release', 'cdstub', 'work'
+                               metadata['title']
+                             when 'url'
+                               metadata['resource']
+                             end
+      end
+
+      target = %(https://musicbrainz.org/#{attrs['type']}/#{target})
+      doc.register :links, target
+      create_anchor parent, attrs['caption'], type: :link, target: target
+    rescue 
+      warning = %(error while getting Musicbrainz database object '#{target}: #{e}')
+      warn_or_raise doc, warning
+      reader.push_include warning, target, target, 1, attrs
+    end
+  end
+end