{"id":359142,"date":"2025-08-20T11:24:12","date_gmt":"2025-08-20T11:24:12","guid":{"rendered":"https:\/\/www.europesays.com\/de\/359142\/"},"modified":"2025-08-20T11:24:12","modified_gmt":"2025-08-20T11:24:12","slug":"model-context-protocol-anwendungsbeispiel-in-typescript","status":"publish","type":"post","link":"https:\/\/www.europesays.com\/de\/359142\/","title":{"rendered":"Model Context Protocol: Anwendungsbeispiel in TypeScript"},"content":{"rendered":"<p>    close notice<\/p>\n<p class=\"notice-banner__text a-u-mb-0\">\n      This article is also available in<br \/>\n        <a href=\"https:\/\/www.heise.de\/en\/background\/Model-Context-Protocol-Application-example-in-TypeScript-10553218.html\" class=\"notice-banner__link a-u-inline-link\" target=\"_blank\" rel=\"noopener\">English<\/a>.<\/p>\n<p>      It was translated with technical assistance and editorially reviewed before publication.\n    <\/p>\n<p class=\"notice-banner__link a-u-mb-0\">\n    Don\u2019t show this again.\n<\/p>\n<p>Das KI-Unternehmen Anthropic, das 2021 von ehemaligen OpenAI-Mitarbeitern gegr\u00fcndet wurde, hat das Model Context Protocol (MCP) mit dem Ziel einer Standardisierung der Kommunikation zwischen Large Language Models und externen Datenquellen entwickelt. Beim sogenannten Tool Calling hat das LLM die M\u00f6glichkeit, auf vordefinierte Schnittstellen zuzugreifen. Diese lassen sich parametrisieren und erlauben so gro\u00dfe Flexibilit\u00e4t. Die meisten LLM-Anbieter unterst\u00fctzen dieses Feature. Jede Datenquelle braucht dabei eine Verkn\u00fcpfung \u00fcber eine eigene Funktion, was in der Regel eine Anpassung am Programmcode erforderlich macht.<\/p>\n<p>    <img loading=\"lazy\" decoding=\"async\" alt=\"Sebastian Springer\" height=\"500\" src=\"data:image\/svg+xml,%3Csvg xmlns='http:\/\/www.w3.org\/2000\/svg' width='696px' height='391px' viewBox='0 0 696 391'%3E%3Crect x='0' y='0' width='696' height='391' fill='%23f2f2f2'%3E%3C\/rect%3E%3C\/svg%3E\" style=\"aspect-ratio: 500 \/ 500; object-fit: cover;\" width=\"500\"\/><\/p>\n<p class=\"a-inline-textbox__synopsis\">\n          Sebastian Springer weckt als Dozent f\u00fcr JavaScript, Sprecher auf zahlreichen Konferenzen und Autor die Begeisterung f\u00fcr professionelle Entwicklung mit JavaScript.&#13;<\/p>\n<p>Das Model Context Protocol soll die Verkn\u00fcpfung externer Datenquellen deutlich vereinfachen und es erlauben, externe Schnittstellen, Datenbanken, Unternehmenssysteme oder Dateisysteme ohne zus\u00e4tzliche Anpassung direkt anzubinden. Dieser Artikel widmet sich den technischen Details der Funktionsweise des MCP und zeigt anhand eines konkreten Beispiels mit dem MCP-TypeScript-SDK, wie eine Integration in eine Applikation gelingen kann.<\/p>\n<p>Die zentrale Anlaufstelle f\u00fcr Ressourcen zum Thema MCP sind zum einen <a href=\"https:\/\/modelcontextprotocol.io\/\" rel=\"external noopener\" target=\"_blank\">die offizielle Website des Projekts<\/a> und zum anderen <a href=\"https:\/\/github.com\/modelcontextprotocol\" rel=\"external noopener\" target=\"_blank\">das GitHub-Repo<\/a>. Dort stehen die Dokumentation, die Spezifikation und eine ganze Reihe von Software Development Kits (SDKs) f\u00fcr verschiedene Programmiersprachen wie Python, TypeScript, C# oder Kotlin zur Verf\u00fcgung.<\/p>\n<p>Die Architektur einer MCP-Applikation<\/p>\n<p>Eine Applikation, die das MCP nutzt, besteht aus verschiedenen Komponenten:<\/p>\n<ul class=\"rte__list rte__list--unordered\">\n<li>MCP-Server: Der Server ist die Stelle bei MCP, die ihre Funktionalit\u00e4t \u00fcber das MCP zur Verf\u00fcgung stellt. Das k\u00f6nnen Daten aus einer Datenbank, aber auch Suchergebnisse aus dem Internet sein. Die Schnittstellen des Servers sind exakt definiert und lassen sich von der Clientseite verwenden.<\/li>\n<li>MCP-Client: Die Gegenseite zum Server ist der Client. Er kommuniziert mit dem Server und f\u00fchrt die verf\u00fcgbaren Operationen \u00fcber die Schnittstellen aus. Dabei gibt es sowohl lesende als auch schreibende Operationen.<\/li>\n<li>MCP-Host: Die Applikation, mit der die Benutzer interagieren. Das kann eine Web-Applikation, eine klassische Desktop-Applikation (wie Claude Desktop), eine Entwicklungsumgebung (wie Cursor) oder ein eigener, auf Frameworks wie Langchain basierender Agent sein. In diese Applikation ist der Client eingebettet, sodass der Host nicht direkt \u00fcber MCP mit dem Server, sondern \u00fcber den Umweg des Clients kommuniziert.<\/li>\n<\/ul>\n<p>MCP-Server<\/p>\n<p>Ein MCP-Server kann direkt in eine Applikation integriert, aber auch, und das wird der h\u00e4ufigere Fall sein, ein eigenst\u00e4ndiger Dienst sein. Die MCP-Initiative stellt eine Reihe von SDKs in unterschiedlichen Programmiersprachen bereit, die die Grundlage f\u00fcr die Serverimplementierung bilden. Der Server selbst ist modular aufgebaut und erlaubt verschiedene Transportmechanismen, \u00fcber die er mit den Clients kommuniziert. Das TypeScript-SDK sieht aktuell die Transportmechanismen Streamable HTTP, SSE und stdio vor. Streamable HTTP und SSE basieren auf HTTP, wobei <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-03-26\/changelog\" rel=\"external noopener\" target=\"_blank\">die MCP-Spezifikation vom 26.03.2025<\/a> den SSE-Transport als veraltet (deprecated) markierte und <a href=\"https:\/\/modelcontextprotocol.io\/specification\/2025-06-18\" rel=\"external noopener\" target=\"_blank\">die Version vom 18.06.2025 (latest)<\/a> SSE bereits nicht mehr erw\u00e4hnt.<\/p>\n<p>Ein MCP-Client kann die HTTP-basierten Transportmechanismen verwenden, um sich mit einem entfernten Server zu verbinden. Der stdio-Transport ist f\u00fcr lokale Anwendungen gedacht. Hierbei verbindet sich der Client \u00fcber die Standard-Ein- und -Ausgabe mit dem Server. Dieser Weg arbeitet deutlich schneller, ist jedoch nur f\u00fcr die Verwendung auf einem System geeignet. Das Python-SDK definiert zus\u00e4tzlich zu diesen Transporttypen noch weitere wie den ASGI-Transport (Asynchronous Server Gateway Interface), eine Schnittstelle aus der Python-Welt, die neben der Kommunikation \u00fcber HTTP noch weitere Protokolle wie WebSockets oder benutzerdefinierte Protokolle unterst\u00fctzt.<\/p>\n<p>Die MCP-Spezifikation unterteilt die Features, die ein Server seinen Clients bietet, in drei Kategorien: Resources, Tools und Prompts.<\/p>\n<p>Resources<\/p>\n<p>Mit der Feature-Kategorie Resources stellt ein MCP-Server Daten zur Verf\u00fcgung. Ein typisches Beispiel ist die Anbindung an eine Datenbank. Resources sollten Daten nur lesend zur Verf\u00fcgung stellen, keine komplexen Berechnungen durchf\u00fchren und keine Seiteneffekte wie Datenmanipulationen aufweisen. Sie sind parametrisierbar, um die Abfrage zu beeinflussen und eine h\u00f6here Flexibilit\u00e4t zu erreichen.<\/p>\n<p>Die MCP-Spezifikation sieht vor, dass das Format [protocol]:\/\/[host]\/[path] Resources spezifiziert. Ein Beispiel k\u00f6nnte folgenderma\u00dfen aussehen: postgres:\/\/database\/users. Die Antwort auf eine Resources-Anfrage kann entweder im Textformat wie beispielsweise JSON oder als Bin\u00e4rdaten wie PDFs oder Bilder erfolgen.<\/p>\n<p>Der MCP-Server stellt \u00fcber den Endpunkt resources\/list eine Liste der verf\u00fcgbaren Resources zur Verf\u00fcgung. Jeder Datensatz weist mindestens die URL der jeweiligen Resource und einen menschenlesbaren Namen auf. Hinzu kommen noch eine optionale Beschreibung und ein ebenfalls optionaler MIME-Type, der das Format der R\u00fcckmeldung spezifiziert.<\/p>\n<p>Die Spezifikation sieht nicht nur den lesenden Zugriff auf Ressourcen vor, sondern auch einen Benachrichtigungsmechanismus, \u00fcber den der Server registrierte Clients \u00fcber \u00c4nderungen der verf\u00fcgbaren sowie Daten\u00e4nderungen einer einzelnen Resource benachrichtigen kann.<\/p>\n<p>Tools<\/p>\n<p>Die Features der Kategorie Tools d\u00fcrfen Berechnungen durchf\u00fchren und Seiteneffekte aufweisen. Clients m\u00fcssen ber\u00fccksichtigen, dass eine Toolausf\u00fchrung im Vergleich zu einer Ressourcenabfrage l\u00e4nger dauern kann. Diese Werkzeuge k\u00f6nnen Funktionen sein, die aufgrund einer Eingabe eine bestimmte Ausgabe produzieren, aber auch Schnittstellen zu Datenbanken und anderen Systemen, um dort gespeicherte Informationen zu manipulieren. \u00c4hnlich wie Resources k\u00f6nnen Clients auch die verf\u00fcgbaren Tools eines Servers \u00fcber einen Endpunkt auslesen. Dieser lautet tools\/list.<\/p>\n<p>Die Beschreibung eines MCP-Tools ist etwas umfangreicher als die einer Resource. Sie enth\u00e4lt einen Namen und ein Input-Schema, um die Parameter des Tools zu beschreiben. Hinzu kommen noch dessen optionale Beschreibung und optionale Metadaten \u00fcber die Tool-Annotations. Die Annotations liefern Clients beziehungsweise Hinweise f\u00fcr Entwicklerinnen und Entwicklern \u00fcber das Verhalten eines Tools. Die meisten vordefinierten Annotations der MCP-Spezifikation sind Boolean-Werte. So sagt beispielsweise die readOnlyHint-Annotation aus, dass das Tool sein Umfeld nicht modifiziert. Wie auch bei den Resources kann ein Client sich beim Server registrieren, um \u00fcber \u00c4nderungen benachrichtigt zu werden.<\/p>\n<p>Prompts<\/p>\n<p>Prompts sind Vorlagen, die dem MCP-Host die Arbeit mit dem Large Language Model (LLM) erleichtern. Damit kann eine MCP-Applikation nicht nur die Kommunikation zwischen Client und Server, sondern auch zum LLM hin standardisieren. Bei einer Applikation, die ein Code-Review-Feature anbietet, dient der Prompt beispielsweise dazu, den zu \u00fcberpr\u00fcfenden Code korrekt einzubetten. Laut der MCP-Spezifikation besitzen die Prompt-Templates einen eindeutigen Namen. Zus\u00e4tzlich sieht die Spezifikation noch die optionalen Felder description f\u00fcr eine menschenlesbare Beschreibung und arguments mit einer Liste der unterst\u00fctzten Argumente des Schemas vor.<\/p>\n<p>Die Prompt-Endpunkte eines MCP-Servers kommen \u00e4hnlich wie Tools zum Einsatz. Der Client fragt nach dem eindeutigen Identifier und \u00fcbermittelt die ben\u00f6tigten Werte. Der Server antwortet mit dem Prompt, in den die Werte integriert sind, sodass der Client beziehungsweise die Host-Applikation den Prompt direkt verwenden kann.F\u00fcr eine Liste aller verf\u00fcgbaren Prompts bietet der MCP-Server den Endpunkt prompts\/list an.<\/p>\n<p>Die SDKs, die die MCP-Initiative zur Verf\u00fcgung stellt, implementieren die Spezifikation und dienen als Grundlage f\u00fcr die Implementierung von MCP-Servern und MCP-Clients. Das folgende Beispiel implementiert einen einfachen MCP-Server mit je einer Resource, einem Tool und einem Prompt mit dem TypeScript-SDK.<\/p>\n<p>import {<br \/>\n  McpServer,<br \/>\n  ResourceTemplate,<br \/>\n} from &#8218;@modelcontextprotocol\/sdk\/server\/mcp.js&#8216;;<br \/>\nimport { StdioServerTransport } from &#8218;@modelcontextprotocol\/sdk\/server\/stdio.js&#8216;;<br \/>\nimport { z } from &#8218;zod&#8216;;<\/p>\n<p>const server = new McpServer({<br \/>\n  name: &#8218;mcp-server&#8216;,<br \/>\n  version: &#8218;1.0.0&#8216;,<br \/>\n});<\/p>\n<p>server.tool(<br \/>\n  &#8218;currency-converter&#8216;,<br \/>\n  &#8218;Convert currency between EUR and USD&#8216;,<br \/>\n  {<br \/>\n    amount: z.number(),<br \/>\n    from: z.enum([&#8218;EUR&#8216;, &#8218;USD&#8216;]),<br \/>\n    to: z.enum([&#8218;EUR&#8216;, &#8218;USD&#8216;]),<br \/>\n  },<br \/>\n  async ({ amount, from, to }) =&gt; {<br \/>\n    const exchangeRate =<br \/>\n      from === &#8218;EUR&#8216; &amp;&amp; to === &#8218;USD&#8216;<br \/>\n        ? 1.1<br \/>\n        : from === &#8218;USD&#8216; &amp;&amp; to === &#8218;EUR&#8216;<br \/>\n        ? 0.91<br \/>\n        : 1;<br \/>\n    const convertedAmount = amount * exchangeRate;<br \/>\n    return {<br \/>\n      content: [<br \/>\n        {<br \/>\n          type: &#8218;text&#8216;,<br \/>\n          text: `${amount} ${from} is ${convertedAmount.toFixed(2)} ${to}`,<br \/>\n        },<br \/>\n      ],<br \/>\n    };<br \/>\n  }<br \/>\n);<\/p>\n<p>server.resource(<br \/>\n  &#8218;price-list&#8216;,<br \/>\n  new ResourceTemplate(&#8218;price-list:\/\/products\/{category}&#8216;, {<br \/>\n    list: undefined,<br \/>\n  }),<br \/>\n  async (uri, { category }) =&gt; {<br \/>\n    const priceList = [<br \/>\n      { name: &#8218;Apple&#8216;, category: &#8218;Fruit&#8216;, price: 1.2 },<br \/>\n      { name: &#8218;Banana&#8216;, category: &#8218;Fruit&#8216;, price: 0.8 },<br \/>\n      { name: &#8218;Carrot&#8216;, category: &#8218;Vegetable&#8216;, price: 0.5 },<br \/>\n      { name: &#8218;Bread&#8216;, category: &#8218;Bakery&#8216;, price: 2.5 },<br \/>\n      { name: &#8218;Milk&#8216;, category: &#8218;Dairy&#8216;, price: 1.5 },<br \/>\n    ];<\/p>\n<p>    const filteredList =<br \/>\n      category !== &#8218;all&#8216;<br \/>\n        ? priceList.filter(<br \/>\n            (item) =&gt; item.category.toLowerCase() === category.toLowerCase()<br \/>\n          )<br \/>\n        : priceList;<\/p>\n<p>    return {<br \/>\n      contents: [<br \/>\n        {<br \/>\n          uri: uri.href,<br \/>\n          text: JSON.stringify(filteredList),<br \/>\n          json: filteredList,<br \/>\n        },<br \/>\n      ],<br \/>\n    };<br \/>\n  }<br \/>\n);<\/p>\n<p>server.prompt(<br \/>\n  &#8218;get-product-description-prompt&#8216;,<br \/>\n  {<br \/>\n    productName: z.string().describe(&#8218;The name of the product.&#8216;),<br \/>\n    length: z<br \/>\n      .enum([&#8217;short&#8216;, &#8218;medium&#8216;, &#8218;long&#8216;])<br \/>\n      .optional()<br \/>\n      .describe(&#8218;The desired length of the description.&#8216;),<br \/>\n  },<br \/>\n  async (input) =&gt; {<br \/>\n    const { productName, length } = input;<\/p>\n<p>    let promptInstructions = `Please generate a compelling product description.`;<\/p>\n<p>    let promptCore = `The product is named &#8222;${productName}&#8220;. `;<br \/>\n    promptCore += `Focus on its general benefits and appeal. `;<\/p>\n<p>    let refinements = &#8220;;<\/p>\n<p>    if (length) {<br \/>\n      let lengthGuidance = &#8220;;<br \/>\n      if (length === &#8217;short&#8216;)<br \/>\n        lengthGuidance = &#8218;Keep it concise, around 1-2 sentences. &#8218;;<br \/>\n      if (length === &#8218;medium&#8216;)<br \/>\n        lengthGuidance = &#8218;Aim for a paragraph of about 3-5 sentences. &#8218;;<br \/>\n      if (length === &#8218;long&#8216;)<br \/>\n        lengthGuidance =<br \/>\n          &#8218;Provide a detailed description, potentially multiple paragraphs. &#8218;;<br \/>\n      refinements += lengthGuidance;<br \/>\n    }<\/p>\n<p>    const fullPrompt = `${promptInstructions}\\n\\nProduct Details:\\n${promptCore}\\n\\nStyle and Constraints:\\n${refinements.trim()}`;<\/p>\n<p>    return {<br \/>\n      messages: [<br \/>\n        {<br \/>\n          role: &#8218;user&#8216;,<br \/>\n          content: {<br \/>\n            type: &#8218;text&#8216;,<br \/>\n            text: fullPrompt,<br \/>\n          },<br \/>\n        },<br \/>\n      ],<br \/>\n    };<br \/>\n  }<br \/>\n);<\/p>\n<p>const transport = new StdioServerTransport();<br \/>\nawait server.connect(transport);<\/p>\n<p>Listing 1: MCP-Serverimplementierung<\/p>\n<p>Die Grundlage f\u00fcr das Beispiel bildet das TypeScript-SDK, das mit dem Kommando npm install @modelcontextprotocol\/sdk installiert wird. Das Paket stellt mit der McpServer-Klasse die Grundlage f\u00fcr die Serverimplementierung zur Verf\u00fcgung. Auf der Server-Instanz sind die Methoden tool, resource und prompt implementiert, die die Schnittstelle zur Registrierung der verschiedenen MCP-Features darstellen. Nachdem die Applikation alle Features registriert hat, ruft sie die connect-Methode der Serverinstanz auf und \u00fcbergibt ein Transport-Objekt. Das kann wie im Beispiel eine Instanz der StdioServerTransport-Klasse f\u00fcr den Stdio-Transport sein oder auch eine Instanz der StreamableHTTPServerTransport-Klasse f\u00fcr eine Remote-Schnittstelle \u00fcber Streamable-HTTP. Alternativ dazu unterst\u00fctzt das TypeScript-SDK auch noch die SSEServerTransport-Klasse f\u00fcr Server Sent Events als Transportmethode.<\/p>\n<p>F\u00fcr die Implementierung der einzelnen Features des MCP-Servers gelten einige Regeln, die das SDK mit einer sehr strikten Schemavalidierung absichert. Folgt die Implementierung nicht diesen Regeln, l\u00e4sst sich der Serverprozess nicht starten. Die Validierung stellt auch die Konsistenz der Argumente beim Aufruf sicher und spielt damit eine wichtige Rolle bei der Sicherheit in der Applikation.<\/p>\n<p>Resource im Beispiel<\/p>\n<p>Zur Definition von Resources sieht das SDK die resource-Methode des Serverobjekts vor. Diese Methode akzeptiert die Bezeichnung der Resource, die zugeh\u00f6rige URL und eine Callback-Funktion, die das Ergebnis produziert. Die Callback-Funktion darf asynchron sein, sodass auch der Anbindung einer Datenbank nichts im Wege steht. Eine Besonderheit gibt es bei der Registrierung von Resources allerdings: Ist die URL als Zeichenkette angegeben, darf sie keine dynamischen Parameter enthalten. F\u00fcr diesen Fall akzeptiert die resource-Methode eine ResourceTemplate-Instanz. Hier werden die Parameter im Pfad mit geschweiften Klammern gekennzeichnet. Die Callback-Funktion kann \u00fcber ihr zweites Argument auf die Parameter der URL zugreifen und das Ergebnis entsprechend modifizieren.<\/p>\n<p>Im Beispiel ist die Resource eine statische Preisliste f\u00fcr eine Reihe von Produkten. Sie tr\u00e4gt die Bezeichnung price-list und ist \u00fcber die URL price-list:\/\/products\/{category} erreichbar, wobei category f\u00fcr eine Kategorie steht, nach der die Callback-Funktion die Datens\u00e4tze filtert. Das TypeScript-SDK arbeitet mit Zod als Validierungsbibliothek und nutzt diese beispielsweise f\u00fcr die \u00dcberpr\u00fcfung des R\u00fcckgabewerts der Resource-Callback-Funktion, sodass diese verpflichtend eine gewisse Struktur zur\u00fcckgeben muss. Das contents-Array im R\u00fcckgabewert kann eine Reihe von Objekten aufweisen, die mindestens \u00fcber die Eigenschaften uri und text verf\u00fcgen m\u00fcssen. Zus\u00e4tzlich akzeptiert das SDK noch weitere Eigenschaften wie json, in der die Daten als JSON-Objekt vorliegen d\u00fcrfen.<\/p>\n<p>\n      Dieser Link ist leider nicht mehr g\u00fcltig.\n    <\/p>\n<p>Links zu verschenkten Artikeln werden ung\u00fcltig,<br \/>\n      wenn diese \u00e4lter als 7\u00a0Tage sind oder zu oft aufgerufen wurden.\n    <\/p>\n<p><strong>Sie ben\u00f6tigen ein heise+ Paket, um diesen Artikel zu lesen. Jetzt eine Woche unverbindlich testen \u2013 ohne Verpflichtung!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"close notice This article is also available in English. It was translated with technical assistance and editorially reviewed&hellip;\n","protected":false},"author":2,"featured_media":359143,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[135],"tags":[84847,29,30,196,1256,98995,98996,190,189,194,191,98997,193,192],"class_list":{"0":"post-359142","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-wissenschaft-technik","8":"tag-anthropic","9":"tag-deutschland","10":"tag-germany","11":"tag-it","12":"tag-kuenstliche-intelligenz","13":"tag-large-language-model","14":"tag-model-context-protocol","15":"tag-science","16":"tag-science-technology","17":"tag-technik","18":"tag-technology","19":"tag-typescript","20":"tag-wissenschaft","21":"tag-wissenschaft-technik"},"share_on_mastodon":{"url":"https:\/\/pubeurope.com\/@de\/115060845102760287","error":""},"_links":{"self":[{"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/posts\/359142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/comments?post=359142"}],"version-history":[{"count":0,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/posts\/359142\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/media\/359143"}],"wp:attachment":[{"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/media?parent=359142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/categories?post=359142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.europesays.com\/de\/wp-json\/wp\/v2\/tags?post=359142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}