Resources — die zweite Säule

Resources sind lesbare Datenquellen, die der Server bereitstellt und die der Nutzer (nicht das Modell!) in den Kontext einhängt. Tools verändern die Welt — Resources liefern Wissen.

Kurzfassung: Jede Resource hat eine URI(eindeutiger Identifier), einen MIME-Type und Inhalt. Der Client kann resources/list abfragen, eine Auswahl an den Nutzer anbieten, und beim Auswählen resources/read aufrufen — der Server liefert den aktuellen Inhalt.

Resource-Browser

Klick eine URI an und sieh, was der Server zurückgibt.

projekt-x.md
Markdown-Notiz aus dem lokalen Filesystem-Server.
# Projekt X

- Ziel: Onboarding für neue Mitarbeitende
- Stakeholder: Anna, Bert
- Deadline: 2026-06-15

## Offene Fragen
- Wo kommt die Mailing-Liste her?

Resources vs. Tools — wer entscheidet?

🛠️ Tools
Das Modell wählt aus, ob und welches Tool aufgerufen wird. Side Effects möglich. Trigger: „tu was“.
📁 Resources
Der Nutzer (über die Client-UI) entscheidet, welche Ressourcen mit in den Kontext gehen. Reine Lesezugriffe, keine Side Effects. Trigger: „hier ist Wissen“.

Das URI-Schema

Resources werden über URIs identifiziert — kein vorgegebenes Schema, der Server darf eigene definieren. Beispiele:

  • file:///abs/path/datei.md — Filesystem-Server für lokale Dateien.
  • postgres://db/schema/tabelle — DB-Server, eine Tabelle.
  • git://repo/branch/path — Git-Server, Datei auf einem Branch.
  • custom://obsidian/note/abc-123 — Eigener Server für ein eigenes System.

Resource Templates — Wildcards für Parameter

Manche Server haben Resources, die parametrisiert sind — etwa eine Tabelle, in der eine Zeile per ID gelesen werden soll. Dafür gibt es resources/templates/list:

{
  "uriTemplate": "postgres://main/public/users/{id}",
  "name": "User by ID",
  "description": "Eine User-Zeile anhand der UUID",
  "mimeType": "application/json"
}

Der Client kann dem Nutzer dann ein Eingabefeld zeigen — beim Lesen wird {id} durch den eingegebenen Wert ersetzt.

Warum eigentlich?Warum trennen Resources und Tools überhaupt?
Weil sie verschiedene Aufmerksamkeits-Loops haben. Tools landen im LLM-Decision-Loop („soll ich create_issue rufen?"). Resources landen im User-Decision-Loop („soll ich diese Datei dranhängen?"). Würde man Resources als Tools modellieren (z.B. read_file), dann müsste das LLM bei jeder Anfrage selbst überlegen, welche Datei relevant ist — das skaliert nicht mit großen Repositories. Mit Resources kann der Nutzer kuratieren, das LLM bekommt die kuratierte Auswahl.
Häufiger DenkfehlerResource-Read als Tool — naheliegend, aber falsch
Klassischer Fehler beim Bau eines Clients: man baut resources/read als Tool und lässt das Modell entscheiden. Resultat: Token-Verbrauch explodiert, weil das Modell auf Verdacht Dateien anzieht, und die UI-Kontrolle des Nutzers verschwindet. Resources gehören in die Client-UI als sichtbarer Anhang — nicht in den Tool-Loop.
Tiefer reinSubscriptions — Live-Resources
MCP unterstützt resources/subscribe: der Client sagt dem Server, dass er bei Änderungen einer Resource benachrichtigt werden will. Der Server schickt dann notifications/resources/updated — der Client kann den Inhalt neu laden. Use-Case: ein Log-File, das live mitwachsen soll, oder ein DB-Snapshot, der bei Änderungen refresht. Funktioniert allerdings nur bei Transports mit Server→Client- Push (SSE, Streamable HTTP).