← Blog

MCP-Server: So machen wir CVR-, DAR- und XBRL-Daten für KI-Agenten zugänglich

Mads Kristiansen

CTO, Liviate

Vor ein paar Jahren war die Integration eines KI-Modells mit den eigenen Systemen eines Unternehmens Handarbeit: Jede Verbindung (zum CRM, zum Dokumentenspeicher, zur internen API) musste von Grund auf gebaut, separat gepflegt und bei jedem Wechsel des KI-Anbieters erneut umgesetzt werden.

Das Model Context Protocol (MCP) ändert diese Rechnung. Wir hatten versprochen, darauf zurückzukommen, nachdem wir uns in den vorherigen Teilen dieser Serie mit Vektordatenbanken sowie Embedding und Reranking beschäftigt haben. Hier ist es also: was MCP ist, warum es für Unternehmen interessant ist und wie wir es selbst genutzt haben, um dänische Unternehmens-, Adress- und Jahresabschlussdaten für KI-Agenten zugänglich zu machen, mit konkreten Beispielen aus fünf verschiedenen Branchen.

Was MCP ist und warum es das gibt

Das Model Context Protocol wurde im November 2024 als offenes, standardisiertes Protokoll eingeführt, das KI-Modelle und KI-Agenten mit externen Datenquellen und Werkzeugen verbindet. Die Idee ist einfach, die Wirkung groß: Statt dass jede KI-Anwendung für jedes System eine eigene Integration baut, bietet MCP einen gemeinsamen „Stecker“, ähnlich wie USB-C ein eigenes Kabel für jedes Gerät überflüssig gemacht hat.

Technisch ist MCP als Client-Server-Architektur aufgebaut. Ein MCP-Server stellt eine Reihe von „Tools“ bereit (Funktionen, die die KI aufrufen kann) und in manchen Fällen auch „Resources“ und „Prompts“. Die Kommunikation läuft über JSON-RPC, entweder lokal über stdio oder als Remote-Verbindung über SSE/HTTP, wenn der Server in der Cloud läuft. Der Client (die KI-Anwendung selbst) erkennt dynamisch, welche Tools ein Server anbietet, und kann sie bei Bedarf aufrufen, ohne dass jemand die Integration vorab fest verdrahtet hat.

Seit dem Start hat das Protokoll schnell breite Unterstützung gefunden. Mehrere große KI-Anbieter haben es übernommen, und im Lauf von 2025-26 ist ein ganzes Ökosystem aus Connectors und Registries entstanden, in dem man fertige MCP-Server für nahezu alles finden und anbinden kann, von Projektmanagement bis zu Finanzdaten.

Der Nutzer fragt, der KI-Client ruft den MCP-Server auf, und die Daten werden aus CVR, DAR und XBRL geholt

Was das in der Praxis für ein Unternehmen bedeutet

Der unmittelbare Gewinn ist, Wissen bei Bedarf verfügbar zu machen. Mitarbeitende müssen nicht wissen, welches System die Antwort hat, sie fragen einfach, während die KI die relevanten Informationen selbst aus CRM, Ticketsystem oder Dokumentenspeicher holt.

Es geht aber über Abfragen hinaus. Weil MCP-Server Aktionen bereitstellen können und nicht nur Daten, kann die KI Routineaufgaben automatisieren: eine Aufgabe anlegen, eine Nachricht senden, ein Feld aktualisieren, ohne dass der Nutzer selbst zwischen zehn verschiedenen Tabs wechseln muss.

Für Unternehmen, die selbst auf Daten oder einer API sitzen, eröffnet MCP zugleich einen neuen Vertriebskanal. Einen eigenen MCP-Server zu bauen heißt, dass die eigenen Daten oder Funktionen für jeden MCP-kompatiblen Client „bekömmlich“ werden, ohne dass man für jeden Kunden eine eigene Integration bauen und pflegen muss. Und weil Zugriffe auf Serverebene begrenzt und gesteuert werden können, gibt es von Anfang an die Möglichkeit, Compliance mitzudenken, relevant für uns, die wir im und rund um den Finanzsektor arbeiten, wo Zugriffssteuerung nichts ist, was man auf die leichte Schulter nimmt.

Der Business Case ist daher leicht zu erkennen: Zeitersparnis, weniger Fehler bei manuellen Abfragen und schnelleres Onboarding, weil neue Mitarbeitende die KI fragen können, statt fünf Systeme auswendig zu lernen.

Unser Fall: Immobiliendaten aus CVR, DAR und XBRL

Wir haben das an einem konkreten, öffentlichen Datensatz umgesetzt: dänische Unternehmens-, Adress- und Jahresabschlussdaten. Diese Daten sind frei zugänglich, in der Praxis aber fragmentiert und programmatisch mühsam zu kombinieren: Das CVR-Register (das dänische zentrale Unternehmensregister), DAR (das dänische Adressregister) und XBRL-Jahresabschlüsse existieren jeweils für sich, in eigenem Format und mit eigenem Zugangsweg.

Wir haben drei MCP-Server gebaut, die jeweils ihre eigene Ecke abdecken. Alle drei sind kostenlos, öffentlich und mit gewöhnlichem OAuth 2.0 abgesichert (Bearer-Token, Dynamic Client Registration, PKCE), sodass sich jeder MCP-Client ohne manuellen Schlüsselaustausch verbinden kann. Kostenloses Kontingent: 500 Aufrufe/Monat, gemeinsam für alle drei Server (nicht 500 pro Server).

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<style>
  :root { --ink:#0f172a; --sub:#475569; --line:#e2e8f0; --bg:#f8fafc; }
  * { box-sizing: border-box; }
  html { overflow: hidden; }
  html, body { margin: 0; padding: 0; background: transparent; }
  body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, Roboto, sans-serif;
    color: var(--ink);
    padding: 14px;
  }
  .card {
    border: 1px solid var(--line);
    border-radius: 12px;
    overflow: hidden;
    background: #fff;
  }
  .tabs {
    display: flex;
    background: var(--bg);
    border-bottom: 1px solid var(--line);
  }
  .tab {
    flex: 1;
    padding: 12px;
    text-align: center;
    font-weight: 600;
    font-size: 14px;
    cursor: pointer;
    color: var(--sub);
    border-bottom: 3px solid transparent;
    background: none;
    border-left: none; border-right: none; border-top: none;
    transition: color .15s, border-color .15s, background .15s;
    font-family: inherit;
  }
  .tab:hover { color: var(--ink); }
  .tab[data-active="true"] { background: #fff; }
  .tab[data-svc="cvr"][data-active="true"]  { color: #0369a1; border-color: #0ea5e9; }
  .tab[data-svc="dar"][data-active="true"]  { color: #0f766e; border-color: #14b8a6; }
  .tab[data-svc="xbrl"][data-active="true"] { color: #4338ca; border-color: #6366f1; }

  .panel { display: none; padding: 16px 18px; }
  .panel[data-active="true"] { display: block; }

  .badge {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 11px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
    padding: 3px 9px; border-radius: 999px; color: #fff; margin-bottom: 8px;
  }
  .panel[data-svc="cvr"] .badge  { background: #0ea5e9; }
  .panel[data-svc="dar"] .badge  { background: #14b8a6; }
  .panel[data-svc="xbrl"] .badge { background: #6366f1; }

  h3 { margin: 0 0 6px; font-size: 17px; }
  /* Fixed height (not min-height -- with a fixed value the tallest description, XBRL's,
     sets the ceiling for all three so switching tabs never reflows the endpoint/row below it). */
  p.desc { margin: 0 0 10px; color: var(--sub); font-size: 14px; line-height: 1.5; height: 42px; overflow: hidden; }

  .endpoint {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px;
    background: var(--bg);
    border: 1px solid var(--line);
    border-radius: 8px;
    padding: 8px 12px;
    color: #1e293b;
    word-break: break-all;
    margin-bottom: 10px;
  }

  .endpoint code { font: inherit; min-width: 0; overflow-wrap: anywhere; }
  .copy {
    flex: none; display: inline-flex; align-items: center; gap: 5px;
    height: 24px; padding: 0 8px; margin: -2px -6px -2px 0;
    font: 600 12px/1 inherit; font-family: inherit; color: var(--sub);
    background: #fff; border: 1px solid var(--line); border-radius: 6px; cursor: pointer;
    transition: color .15s, border-color .15s, background .15s;
  }
  .copy:hover { color: var(--ink); border-color: #cbd5e1; }
  .copy:focus-visible { outline: 2px solid #6366f1; outline-offset: 1px; }
  .copy svg { width: 14px; height: 14px; }
  .copy[data-done="true"] { color: #047857; border-color: #6ee7b7; background: #ecfdf5; }
  .copy .ok { display: none; }
  .copy[data-done="true"] .ok { display: inline; }
  .copy[data-done="true"] .cp { display: none; }

  .row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
  .quota {
    font-size: 12px; color: var(--sub); background: var(--bg);
    border: 1px solid var(--line); border-radius: 999px; padding: 5px 11px;
  }
  a.docs {
    font-size: 13px; font-weight: 600; text-decoration: none;
    padding: 7px 13px; border-radius: 8px; color: #fff;
  }
  .panel[data-svc="cvr"] a.docs  { background: #0ea5e9; }
  .panel[data-svc="dar"] a.docs  { background: #14b8a6; }
  .panel[data-svc="xbrl"] a.docs { background: #6366f1; }
  a.docs:hover { filter: brightness(0.93); }
</style>
</head>
<body>
  <div class="card">
    <div class="tabs" role="tablist">
      <button class="tab" data-svc="cvr" data-active="true">CVR</button>
      <button class="tab" data-svc="dar">DAR</button>
      <button class="tab" data-svc="xbrl">XBRL</button>
    </div>

    <div class="panel" data-svc="cvr" data-active="true">
      <span class="badge">MCP-Server</span>
      <h3>CVR: Unternehmensdaten</h3>
      <p class="desc">Unterstützt Abfragen und Suche nach dänischen Unternehmen, nach Name, Ort, Adresse oder Koordinate, sowie Abfragen zu Beteiligten und Eigentümern.</p>
      <div class="endpoint"><code>https://cvr.mcp.liviate.com/mcp</code><button class="copy" type="button" data-copy="https://cvr.mcp.liviate.com/mcp" aria-label="URL kopieren"><svg class="cp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7"/></svg><span class="lbl">Kopieren</span></button></div>
      <div class="row">
        <span class="quota">Kostenloses Kontingent: 500 Aufrufe/Monat (gemeinsam für alle drei Server)</span>
        <a class="docs" href="https://liviate.com/docs/cvr-dar-xbrl-mcp" rel="noopener" data-open-new>Einrichtung &amp; Auth-Anleitung →</a>
      </div>
    </div>

    <div class="panel" data-svc="dar">
      <span class="badge">MCP-Server</span>
      <h3>DAR: Adressdaten</h3>
      <p class="desc">Bietet Zugriff auf das dänische Adressregister, mit Freitextsuche und straßenbasierter Suche.</p>
      <div class="endpoint"><code>https://dar.mcp.liviate.com/mcp</code><button class="copy" type="button" data-copy="https://dar.mcp.liviate.com/mcp" aria-label="URL kopieren"><svg class="cp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7"/></svg><span class="lbl">Kopieren</span></button></div>
      <div class="row">
        <span class="quota">Kostenloses Kontingent: 500 Aufrufe/Monat (gemeinsam für alle drei Server)</span>
        <a class="docs" href="https://liviate.com/docs/cvr-dar-xbrl-mcp" rel="noopener" data-open-new>Einrichtung &amp; Auth-Anleitung →</a>
      </div>
    </div>

    <div class="panel" data-svc="xbrl">
      <span class="badge">MCP-Server</span>
      <h3>XBRL: Jahresabschlussdaten</h3>
      <p class="desc">Macht Finanzdaten und Kennzahlen über Jahresberichte hinweg verfügbar, für Einzelunternehmen und im Batch, mit teilweisem Element-Matching.</p>
      <div class="endpoint"><code>https://xbrl.mcp.liviate.com/mcp</code><button class="copy" type="button" data-copy="https://xbrl.mcp.liviate.com/mcp" aria-label="URL kopieren"><svg class="cp" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="9" y="9" width="12" height="12" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg><svg class="ok" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12.5l4.5 4.5L19 7"/></svg><span class="lbl">Kopieren</span></button></div>
      <div class="row">
        <span class="quota">Kostenloses Kontingent: 500 Aufrufe/Monat (gemeinsam für alle drei Server)</span>
        <a class="docs" href="https://liviate.com/docs/cvr-dar-xbrl-mcp" rel="noopener" data-open-new>Einrichtung &amp; Auth-Anleitung →</a>
      </div>
    </div>
  </div>

<script>
  var tabs = document.querySelectorAll('.tab');
  var panels = document.querySelectorAll('.panel');
  tabs.forEach(function (tab) {
    tab.addEventListener('click', function () {
      var svc = tab.getAttribute('data-svc');
      tabs.forEach(function (t) { t.removeAttribute('data-active'); });
      panels.forEach(function (p) { p.removeAttribute('data-active'); });
      tab.setAttribute('data-active', 'true');
      document.querySelector('.panel[data-svc="' + svc + '"]').setAttribute('data-active', 'true');
    });
  });

  // A plain <a target="_blank"> inside a sandboxed srcdoc iframe (allow-popups, no
  // allow-top-navigation) opened TWO tabs in Chromium -- the real target AND a spurious
  // duplicate of this card's own document -- confirmed live 2026-09-20. Explicit window.open()
  // on click, instead of relying on the browser's native target="_blank" handling, doesn't
  // trigger it.
  document.querySelectorAll('a[data-open-new]').forEach(function (a) {
    a.addEventListener('click', function (e) {
      e.preventDefault();
      window.open(a.getAttribute('href'), '_blank', 'noopener');
    });
  });
  function fallbackCopy(text) {
    var ta = document.createElement('textarea');
    ta.value = text; ta.setAttribute('readonly', '');
    ta.style.cssText = 'position:fixed;top:0;left:0;opacity:0';
    document.body.appendChild(ta); ta.select();
    var ok = false; try { ok = document.execCommand('copy'); } catch (e) {}
    document.body.removeChild(ta); return ok;
  }
  document.querySelectorAll('.copy').forEach(function (btn) {
    btn.addEventListener('click', function () {
      var text = btn.getAttribute('data-copy');
      var done = function (ok) {
        if (!ok) return;
        btn.setAttribute('data-done', 'true'); btn.querySelector('.lbl').textContent = 'Kopiert';
        setTimeout(function () { btn.removeAttribute('data-done'); btn.querySelector('.lbl').textContent = 'Kopieren'; }, 1800);
      };
      if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(text).then(function () { done(true); }, function () { done(fallbackCopy(text)); });
      } else { done(fallbackCopy(text)); }
    });
  });
</script>
</body>
</html>

Die vollständige Einrichtungs- und Authentifizierungsanleitung (inklusive der Frage, wie Sie die Server in Claude Desktop oder einem anderen MCP-Client hinzufügen) finden Sie auf der Dokumentationsseite zu den drei Servern.

Strukturierte Unternehmensdaten in der Antwort des CVR-Servers

Das Interessante passiert, wenn man sie kombiniert. Unternehmen in einer bestimmten Stadt mit wachsendem Immobilienbesitz zu finden, erfordert, CVR-Daten (wer existiert, und wo) mit XBRL-Daten zu kreuzen (wie sich ihr bilanzierter Immobilienwert, z. B. „LandAndBuildings“, über mehrere Jahre entwickelt hat). Mit den MCP-Servern geschieht das als ein zusammenhängendes Gespräch mit einem KI-Agenten, statt stundenlanger manueller Durchsicht von Jahresabschlüssen.

Zwei Datenquellen in einem Gespräch verknüpft: CVR und XBRL zusammen

Ein paar praktische Details machen für Leistung und Nutzbarkeit einen echten Unterschied: Batch-Endpunkte, die wiederholte Einzelabfragen vermeiden, wenn man Hunderte Unternehmen auf einmal prüfen will; teilweises Element-Matching in XBRL-Daten, sodass man breit nach z. B. „PropertyPlantAndEquipment“ suchen kann, ohne die genaue Kennzahlenbezeichnung zu kennen; und ein ehrliches Eingeständnis der Grenzen, auf die man in der Praxis stößt, z. B. Paginierung und eine Obergrenze für die Zahl der Suchergebnisse. Solche Details sind nicht bloß technische Fußnoten: Sie sind oft der Unterschied zwischen einem Werkzeug, das in der Theorie funktioniert, und einem, das in der Produktion funktioniert.

Ein ganzes Gebiet in einem Durchlauf: DAR, CVR und XBRL im Batch

Wer es nutzen kann: fünf Branchen, fünf Beispiele

Daten zu Unternehmen, Adressen und Jahresabschlüssen sind weit über unser eigenes Feld hinaus interessant. Hier ein Vorschlag, wie fünf verschiedene Berufsgruppen dasselbe Fundament nutzen könnten.

Immobilienmakler

  • Eigentümerwechsel bei Immobilien in einer bestimmten Postleitzahl überwachen
  • Gewerbeimmobilien anhand der bilanzierten Immobilienwerte vergleichbarer Unternehmen bewerten
  • Portfolio-Eigentümer als potenzielle Verkäufer oder Käufer identifizieren
  • Eigene Objektlisten automatisch über DAR mit Adressen anreichern

Kreditprüfung

  • Automatischer Kennzahlen-„Health-Check“ vor der Kreditvergabe, direkt aus XBRL gezogen statt manuellem PDF-Lesen
  • Unternehmen mit sinkendem Eigenkapital oder steigender Verschuldung im Verhältnis zu ihrem Immobilienbesitz markieren
  • Die Kennzahlen eines Antragstellers mit Branchendurchschnitten vergleichen
  • Laufende Überwachung eines gesamten Kundenportfolios, wenn neue Jahresabschlüsse veröffentlicht werden

Due Diligence

  • Schneller Überblick über die Konzernstruktur eines Zielunternehmens per Beteiligtenabfrage
  • Abgleich zwischen öffentlichen Finanzzahlen und dem, was das Zielunternehmen selbst vorgelegt hat
  • Historische Durchsicht der Vermögensentwicklung eines Unternehmens über zehn Jahre in Minuten
  • Screening eines ganzen Branchenclusters auf Red Flags

Vertrieb und Lead-Generierung

  • Leadlisten nach Kriterien wie Eigenkapital, Umsatzwachstum und Geografie
  • Trigger-basierte Ansprache, z. B. wenn ein Unternehmen gerade eine Immobilie gekauft hat
  • Bestehende CRM-Daten mit aktuellen CVR- und Finanzzahlen anreichern
  • Nach Werbeschutz segmentieren, damit man nur diejenigen kontaktiert, die tatsächlich kontaktiert werden dürfen

Journalisten

  • Eigentümernetzwerke über Unternehmen hinweg nachverfolgen
  • Geschichten auf tatsächliche Finanzzahlen stützen
  • Wachstumsbehauptungen eines Unternehmens anhand der tatsächlichen Zahlen überprüfen
  • Schneller Hintergrundcheck zu einem Unternehmen, das in einem Hinweis genannt wird

Ein Beteiligungsnetzwerk in einer Antwort: Aufsichtsratsmandate über Gesellschaften hinweg

Nicht zur Kartierung von Nationalstaaten

MCP verschiebt die Grenze dessen, was ein KI-Agent beitragen kann: vom Beantworten von Fragen auf Basis dessen, was er ohnehin weiß, hin zum eigenständigen Abrufen, Verknüpfen und Handeln auf aktuellen Daten. Für uns hat das konkret bedeutet, dass dänische CVR-, Adress- und Jahresabschlussdaten von drei getrennten, mühsamen Datenquellen zu einem zusammenhängenden Fundament geworden sind, in dem ein KI-Agent selbstständig navigieren kann.

Und seien wir ehrlich: Wenn man drei, vier MCP-Server hat, die im Handumdrehen Unternehmen, Adressen, Jahresabschlüsse und Eigentümernetzwerke über zwanzig Firmen hinweg verknüpfen können, ist es schwer, dieses Palantir-Gefühl zu vermeiden: eine Flowchart-Wand voller roter Fäden und ein paar selbstsichere PowerPoints über „Foundry für den dänischen Mittelstand“. Die gute Nachricht ist, dass das meist dafür genutzt wird, herauszufinden, ob ein Immobilienmakler die richtigen Portfolio-Eigentümer anrufen sollte oder ob ein Wirtschaftsprüfer sich einen Nachmittag PDF-Suche sparen kann, nicht um Nationalstaaten zu kartieren. Sollte aber jemand Lust bekommen, eine Aufklärungsplattform für werbegeschützte Holdinggesellschaften zu bauen, sind die Bausteine jedenfalls bereit. Für Verschwörungstheorien, die unterwegs entstehen, übernehmen wir keine Verantwortung.

Ist das für Sie relevant?

Bauen Sie etwas, bei dem Sie heute öffentliche oder interne Daten manuell über mehrere Quellen hinweg gegenprüfen? Schreiben Sie uns, und lassen Sie uns besprechen, wo Sie starten könnten.

Möchten Sie besprechen, was Ihre KI-Initiativen wirklich blockiert?

Mads Kristiansen führt gerne ein unverbindliches Gespräch.

Termin buchen →