Index: src/assets/js/mod/admin-audio.js
===================================================================
--- src/assets/js/mod/admin-audio.js	(revision a1178626b3c552f9fffcedb21e83001e34248067)
+++ src/assets/js/mod/admin-audio.js	(revision 5300652c5fdc930a614f60c65e8abb4e56060f4f)
@@ -452,3 +452,92 @@
   });
 })();
+
+  // MusicBrainz-paneel (shaer-mbz). Binnen run(), niet op moduleniveau:
+  // deze modules krijgen bij elke paginawissel opnieuw init(), en een blok dat
+  // maar een keer per sessie draait is precies wat shaer-5s1 opleverde.
+  wireMusicBrainz();
 }
+
+// ── MusicBrainz: ben jij dit? (shaer-mbz, stap 2) ─────────────────
+//
+// De kandidaten komen van de server, want MusicBrainz eist een verzoek per
+// seconde per APPLICATIE en een User-Agent met contact -- allebei niet vanuit
+// een browser af te dwingen.
+//
+// WIJ KIEZEN NIET. Ook niet als er precies een treffer is: een verkeerd
+// geraden MBID zet jouw naam onder andermans werk. De knop staat er, de klik
+// is van de artiest.
+function wireMusicBrainz() {
+  const knop = document.getElementById('mb-zoek-btn');
+  const veld = document.getElementById('mb-q');
+  const uit = document.getElementById('mb-uit');
+  if (!knop || !veld || !uit || knop.__wired) return;
+  knop.__wired = true;
+
+  const el = (tag, cls, tekst) => {
+    const e = document.createElement(tag);
+    if (cls) e.className = cls;
+    if (tekst != null) e.textContent = tekst;   // textContent: nooit HTML uit een vreemd register
+    return e;
+  };
+
+  async function zoek() {
+    const q = (veld.value || '').trim();
+    if (!q) return;
+    uit.hidden = false;
+    uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_busy || 'Zoeken…'));
+    knop.disabled = true;
+    try {
+      const r = await fetch(`api/musicbrainz?q=${encodeURIComponent(q)}`, { credentials: 'same-origin' });
+      const j = await r.json();
+      toon((j && j.kandidaten) || []);
+    } catch {
+      uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_fail || 'MusicBrainz is even niet bereikbaar.'));
+    } finally {
+      knop.disabled = false;
+    }
+  }
+
+  function toon(kandidaten) {
+    if (!kandidaten.length) {
+      uit.replaceChildren(el('p', 'ax-hint', T.aaud_mb_none || 'Niets gevonden.'));
+      return;
+    }
+    const lijst = el('ul', 'mb-lijst');
+    for (const k of kandidaten) {
+      const li = el('li', 'mb-kandidaat');
+      li.appendChild(el('strong', null, k.naam));
+      // De toelichting is het hele punt: er zijn drie bands die Nirvana heten,
+      // en zonder dit veld kiest iemand de verkeerde.
+      const bij = [k.toelichting, k.soort, k.land, k.jaren].filter(Boolean).join(' · ');
+      if (bij) li.appendChild(el('small', 'mb-bij', bij));
+      const open = el('a', 'mb-open', T.aaud_mb_open || 'Bekijk op MusicBrainz');
+      open.href = k.url; open.target = '_blank'; open.rel = 'noopener';
+      li.appendChild(open);
+      li.appendChild(kiesForm(k));
+      lijst.appendChild(li);
+    }
+    uit.replaceChildren(lijst);
+  }
+
+  function kiesForm(k) {
+    const f = document.createElement('form');
+    f.method = 'POST';
+    f.action = 'musicbrainz/link';
+    for (const [naam, waarde] of [['_csrf', csrf()], ['mbid', k.mbid], ['naam', k.naam]]) {
+      const i = document.createElement('input');
+      i.type = 'hidden'; i.name = naam; i.value = waarde || '';
+      f.appendChild(i);
+    }
+    const b = el('button', 'ax-btn', T.aaud_mb_pick || 'Dit ben ik');
+    b.type = 'submit';
+    f.appendChild(b);
+    return f;
+  }
+
+  // Het token staat al in elk formulier op deze pagina; er is er geen apart voor.
+  const csrf = () => (document.querySelector('input[name="_csrf"]') || {}).value || '';
+
+  knop.addEventListener('click', zoek);
+  veld.addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); zoek(); } });
+}
Index: src/routes/admin-audio.js
===================================================================
--- src/routes/admin-audio.js	(revision a1178626b3c552f9fffcedb21e83001e34248067)
+++ src/routes/admin-audio.js	(revision 5300652c5fdc930a614f60c65e8abb4e56060f4f)
@@ -414,4 +414,27 @@
 });
 
+/**
+ * De keuze vastleggen. Alleen een echte MBID komt de kolom in: de naam die we
+ * ernaast bewaren is voor het scherm, de MBID is het enige dat naar buiten gaat.
+ */
+router.post('/musicbrainz/link', requireGod, (req, res) => {
+  const site = res.locals.site;
+  if (!site) return res.status(404).end();
+  const mbid = String(req.body.mbid || '').trim().toLowerCase();
+  const naam = String(req.body.naam || '').trim().slice(0, 200);
+  const terug = (res.locals.siteUrlBase || '') + '/admin/audio';
+  if (!MusicBrainz.isMbid(mbid)) return res.redirect(`${terug}?error=` + encodeURIComponent('Geen geldige MusicBrainz-id.'));
+  db.prepare('UPDATE sites SET mb_artist_id = ?, mb_artist_name = ? WHERE id = ?').run(mbid, naam || null, site.id);
+  res.redirect(`${terug}?success=` + encodeURIComponent('Gekoppeld aan MusicBrainz.'));
+});
+
+/** Terugdraaien. Een verkeerde koppeling zet jouw naam onder andermans werk. */
+router.post('/musicbrainz/unlink', requireGod, (req, res) => {
+  const site = res.locals.site;
+  if (!site) return res.status(404).end();
+  db.prepare('UPDATE sites SET mb_artist_id = NULL, mb_artist_name = NULL WHERE id = ?').run(site.id);
+  res.redirect((res.locals.siteUrlBase || '') + '/admin/audio?success=' + encodeURIComponent('Ontkoppeld.'));
+});
+
 router.get('/api/albums', requireGod, (req, res) => {
   const site = res.locals.site;
Index: src/services/i18n.js
===================================================================
--- src/services/i18n.js	(revision a1178626b3c552f9fffcedb21e83001e34248067)
+++ src/services/i18n.js	(revision 5300652c5fdc930a614f60c65e8abb4e56060f4f)
@@ -360,4 +360,14 @@
     'aaud.fedi_off': 'Niet op de fediverse gedeeld (alleen webspeler, bestand verborgen) — klik om te delen',
     'aaud.embed_player': 'Embedbare speler',
+    'aaud.mb_title': 'Ben jij dit in MusicBrainz?',
+    'aaud.mb_hint': 'MusicBrainz is het open register waar muziekdiensten je aan herkennen. Zoek jezelf op en kies je eigen pagina — dan weten anderen dat jouw muziek van jou is.',
+    'aaud.mb_search': 'Zoeken',
+    'aaud.mb_none': 'Niets gevonden. Sta je er nog niet in? Dan kun je jezelf aanmelden op musicbrainz.org — dat kan alleen daar, niet vanuit Klonkt.',
+    'aaud.mb_pick': 'Dit ben ik',
+    'aaud.mb_linked': 'Gekoppeld aan',
+    'aaud.mb_unlink': 'Ontkoppelen',
+    'aaud.mb_open': 'Bekijk op MusicBrainz',
+    'aaud.mb_busy': 'Zoeken…',
+    'aaud.mb_fail': 'MusicBrainz is even niet bereikbaar.',
     'aaud.embed_hint': 'Plak deze code op je eigen website/blog om je muziek met deze speler in te sluiten:',
     'aaud.preview_player': 'Speler-voorbeeld openen',
@@ -1307,4 +1317,14 @@
     'aaud.fedi_off': 'Not shared on the fediverse (web player only, file hidden) — click to share',
     'aaud.embed_player': 'Embeddable player',
+    'aaud.mb_title': 'Is this you on MusicBrainz?',
+    'aaud.mb_hint': 'MusicBrainz is the open register music services recognise you by. Look yourself up and pick your own page — then others know your music is yours.',
+    'aaud.mb_search': 'Search',
+    'aaud.mb_none': 'Nothing found. Not in there yet? You can add yourself on musicbrainz.org — that can only be done there, not from Klonkt.',
+    'aaud.mb_pick': 'This is me',
+    'aaud.mb_linked': 'Linked to',
+    'aaud.mb_unlink': 'Unlink',
+    'aaud.mb_open': 'View on MusicBrainz',
+    'aaud.mb_busy': 'Searching…',
+    'aaud.mb_fail': 'MusicBrainz is unreachable right now.',
     'aaud.embed_hint': 'Paste this code on your own website/blog to embed your music with this player:',
     'aaud.preview_player': 'Open player preview',
@@ -2253,4 +2273,14 @@
     'aaud.fedi_off': 'Nicht im Fediverse geteilt (nur Web-Player, Datei verborgen) — zum Teilen klicken',
     'aaud.embed_player': 'Einbettbarer Player',
+    'aaud.mb_title': 'Bist das du bei MusicBrainz?',
+    'aaud.mb_hint': 'MusicBrainz ist das offene Register, an dem Musikdienste dich erkennen. Suche dich und wähle deine eigene Seite — dann wissen andere, dass deine Musik von dir ist.',
+    'aaud.mb_search': 'Suchen',
+    'aaud.mb_none': 'Nichts gefunden. Noch nicht dabei? Du kannst dich auf musicbrainz.org eintragen — das geht nur dort, nicht aus Klonkt heraus.',
+    'aaud.mb_pick': 'Das bin ich',
+    'aaud.mb_linked': 'Verknüpft mit',
+    'aaud.mb_unlink': 'Trennen',
+    'aaud.mb_open': 'Bei MusicBrainz ansehen',
+    'aaud.mb_busy': 'Suche läuft…',
+    'aaud.mb_fail': 'MusicBrainz ist gerade nicht erreichbar.',
     'aaud.embed_hint': 'Füge diesen Code auf deiner eigenen Website/deinem Blog ein, um deine Musik mit diesem Player einzubetten:',
     'aaud.preview_player': 'Player-Vorschau öffnen',
Index: src/views/pages/admin-audio.ejs
===================================================================
--- src/views/pages/admin-audio.ejs	(revision a1178626b3c552f9fffcedb21e83001e34248067)
+++ src/views/pages/admin-audio.ejs	(revision 5300652c5fdc930a614f60c65e8abb4e56060f4f)
@@ -12,4 +12,36 @@
   <% if (success) { %><div class="ax-flash ax-flash-ok"><%= success %></div><% } %>
   <% if (error) { %><div class="ax-flash ax-flash-err"><%= error %></div><% } %>
+
+  <%# ── MUSICBRAINZ ─────────────────────────────────────────────
+      Wie ben jij, buiten Klonkt? Een MBID is geen vocabulaire maar een
+      register: eraan koppelen is als je ISBN noemen. Andere muziekdiensten
+      -- Funkwhale voorop -- herkennen je eraan zonder dat wij hun model
+      hoeven over te nemen (shaer-mbz). %>
+  <section class="ax-card" id="mb-card">
+    <div class="ax-card-title"><%= t('aaud.mb_title') %></div>
+    <p class="ax-hint"><%= t('aaud.mb_hint') %></p>
+
+    <% if (site.mb_artist_id) { %>
+      <p class="mb-linked">
+        <%= t('aaud.mb_linked') %>
+        <strong><%= site.mb_artist_name || site.mb_artist_id %></strong>
+        <a href="https://musicbrainz.org/artist/<%= site.mb_artist_id %>"
+           target="_blank" rel="noopener"><%= t('aaud.mb_open') %></a>
+      </p>
+      <%# Ontkoppelen moet kunnen: een verkeerde koppeling zet jouw naam onder
+          andermans werk, en dat hoort met een klik terug te draaien zijn. %>
+      <form method="POST" action="<%= (typeof siteUrlBase !== 'undefined' ? siteUrlBase : '') %>/admin/audio/musicbrainz/unlink">
+        <input type="hidden" name="_csrf" value="<%= csrfToken %>">
+        <button type="submit" class="ax-btn ax-btn-quiet"><%= t('aaud.mb_unlink') %></button>
+      </form>
+    <% } %>
+
+    <div class="mb-zoek">
+      <input type="text" id="mb-q" value="<%= site.author || site.title || '' %>"
+             placeholder="<%= t('aaud.artist') %>" autocomplete="off">
+      <button type="button" class="ax-btn" id="mb-zoek-btn"><%= t('aaud.mb_search') %></button>
+    </div>
+    <div id="mb-uit" class="mb-uit" hidden></div>
+  </section>
 
   <%# ── UPLOAD ──────────────────────────────────────────────── %>
Index: test/musicbrainz.test.js
===================================================================
--- test/musicbrainz.test.js	(revision a1178626b3c552f9fffcedb21e83001e34248067)
+++ test/musicbrainz.test.js	(revision 5300652c5fdc930a614f60c65e8abb4e56060f4f)
@@ -97,2 +97,29 @@
 
 test.after(() => { globalThis.fetch = echt; });
+
+// ── Stap 2: de keuze vastleggen ───────────────────────────────────────────
+
+test('alleen een echte MBID komt de kolom in', async () => {
+  // De route weigert alles wat geen UUID is. Zonder die zeef sluipt er een
+  // hele URL of een handle in het veld dat straks naar buiten gaat.
+  const db = dbMod.default;
+  db.prepare('INSERT INTO users (id, username, email, password_hash, role) VALUES (?,?,?,?,?)')
+    .run('u1', 'u1', 'u1@t', 'x', 'god');
+  db.prepare('INSERT INTO sites (id, slug, title, owner_id) VALUES (?,?,?,?)').run('s1', 'band', 'Band', 'u1');
+  for (const rommel of ['https://musicbrainz.org/artist/8be31978-1884-4773-beae-f73df35b92aa', 'nirvana', '']) {
+    assert.equal(MB.isMbid(rommel), false, `${rommel} hoort geweigerd te worden`);
+  }
+  db.prepare('UPDATE sites SET mb_artist_id = ?, mb_artist_name = ? WHERE id = ?')
+    .run('8be31978-1884-4773-beae-f73df35b92aa', 'Nirvana', 's1');
+  const s = db.prepare("SELECT mb_artist_id, mb_artist_name FROM sites WHERE id = 's1'").get();
+  assert.equal(s.mb_artist_id, '8be31978-1884-4773-beae-f73df35b92aa');
+  assert.equal(s.mb_artist_name, 'Nirvana', 'de naam ernaast, zodat het scherm kan tonen WAT er hangt');
+});
+
+test('ontkoppelen maakt beide velden leeg', () => {
+  const db = dbMod.default;
+  db.prepare('UPDATE sites SET mb_artist_id = NULL, mb_artist_name = NULL WHERE id = ?').run('s1');
+  const s = db.prepare("SELECT mb_artist_id, mb_artist_name FROM sites WHERE id = 's1'").get();
+  assert.equal(s.mb_artist_id, null);
+  assert.equal(s.mb_artist_name, null, 'anders blijft er een naam staan zonder koppeling');
+});
