WebMCP, MCP Server Cards & Agent Skills: für TanStack Apps

So stellen Sie eine TanStack Start-Anwendung als MCP-Server mit WebMCP für Browser-seitige Agents und einem /well-known/agent-skills/-Manifest bereit.

Huifer
Huifer
12. August 202610 min read
Auch verfügbar auf:English · 中文

Geschrieben von Huifer, Solo-Entwickler und Maintainer von TanStack Ship. In der Woche vom 09.06.2026 habe ich den MCP server-card, WebMCP, das Agent-Skills-Manifest und die OAuth-Endpunkte in TanStack Ship bereitgestellt. Das ist das Tutorial, das ich mir gewünscht hätte — Endpunkte, ihre Bedeutung, 20-Minuten-Setup und die Sicherheitsgrenzen.

Verifizierte Quellen: modelcontextprotocol.io spec · github.com/orgs/tanstackship · datatracker.ietf.org/doc/html/rfc6749

Letzte Aktualisierung: 12.08.2026 · Changelog

TL;DR: MCP ist eine API für KI-Agents, nicht für Menschen. Eine TanStack Start-Anwendung kann vier Endpunkte bereitstellen — server card, WebMCP, Agent-Skills-Manifest, OAuth — und wird in etwa 20 Minuten auffindbar, aufrufbar und authentifizierungsfähig. Dieser Beitrag erläutert jeden Endpunkt mit kopierbarem Code und benennt dann die Sicherheitsgrenzen (Ratenbegrenzung, OAuth-Bereiche, die niemals offenzulegenden Endpunkte), die Sie vor der Bereitstellung durchsetzen müssen.

Was MCP in 90 Sekunden wirklich ist (und was es nicht ist)

Model Context Protocol (MCP) ist ein JSON-RPC-förmiger Standard zur Bereitstellung von Werkzeugen, Ressourcen und Vorlagen für KI-Agents. Das von Anthropic Ende 2024 entwickelte und nun unter der Linux Foundation Agentic AI-Arbeitsgruppe betreute Protokoll ist das, was der Branche am nächsten an einem herstellerübergreifenden Agent-Protokoll liegt. Betrachten Sie es als eine API, die für LLM-Konsum statt für menschlichen Konsum konzipiert wurde:

  • REST/GraphQL — konzipiert für programmatischen Zugriff, menschenlesbare Dokumentation, feste Schemas, feste Pfade.
  • MCP — konzipiert für KI-Agent-Discovery, Werkzeugbeschreibungen, schema-bewusste Generierung, dynamische Fähigkeitsverhandlung.

Gemäß der offiziellen MCP-Spezifikation macht ein MCP-Server drei Primitive und eine Metadatendatei verfügbar:

  1. Werkzeuge — aufrufbare Funktionen, die der Agent aufrufen kann, jeweils mit einem JSON Schema für die Eingaben.
  2. Ressourcen — adressierbare Daten, die der Agent lesen kann, identifiziert durch ein URI-Schema.
  3. Vorlagen — vordefinierte Prompt-Vorlagen, die die Host-UI präsentieren kann.
  4. Server card — eine JSON-Datei unter /.well-known/mcp/server-card.json, die beschreibt, was der Server kann.

Die server card ist das, was MCP von einer einfachen API unterscheidet: Sie ist ein selbstbeschreibendes Fähigkeits-Manifest, das jedes konforme Agent lesen kann, ohne vorherige Kenntnis Ihres Backends zu haben.

Wo WebMCP ansetzt

WebMCP ist das Browser-seitige Gegenstück zu MCP. Dieselben Primitive werden über einen postMessage-Kanal oder ein WebSocket statt über HTTP übertragen, was es einer TanStack Start-Client-Komponente ermöglicht, an einer MCP-Konversation teilzunehmen. Gemäß dem W3C WebMCP Editor's Draft kann ein WebMCP-Server innerhalb der Seite Werkzeuge für ein Sidebar-Agent bewerben und auf Werkzeugaufrufe unter Verwendung des lokalen App-Zustands reagieren.

Zusammen: Eine TanStack Start-Anwendung kann ein serverseitiger MCP-Server (für externe Agents) und ein clientseitiger WebMCP-Server (für Browser-seitige Agents) sein — ohne die Werkzeugdefinitionen zu duplizieren.

Was MCP nicht ist

Es ist kein Ersatz für Ihre REST-API. Ihre Mobile-Clients, Ihre Stripe-Webhook-Handler und Ihre internen Dashboards sprechen kein MCP. Sie behalten ihre HTTP-Endpunkte. MCP ist eine Schicht für KI-Agents, die Ihr Produkt aufrufen möchten. MCP als „die neue API" zu betrachten, ist der häufigste architektonische Fehler; es als eine „agentenorientierte Fassade über der bestehenden API" zu betrachten, ist der richtige Ansatz. In TanStack Ship sind die MCP-Handler dünne Wrapper über dieselben Server Functions, die das Dashboard-UI antreiben — es gibt keinen parallelen Codebaum. Der Stripe-Webhook-Handler, der ein Abonnement aktualisiert, ist eine Methode in einem einzigen Modul; das MCP-Werkzeug create_subscription ruft dieselbe Methode durch eine JSON-RPC-Hülle auf. Die Duplizierungsfalle — „MCP-Versionen" jedes Endpunkts zu bauen — ist der Weg, wie die meisten Teams in einem auseinanderlaufenden Zwei-System-Chaos landen.

Anatomie einer MCP server card

Eine server card ist ein JSON-Dokument unter dem well-known-Pfad /.well-known/mcp/server-card.json. Gemäß dem MCP server-card-Schema müssen Schema-Version, Name, Werkzeuge, Ressourcen und Authentifizierung deklariert werden. Im Folgenden die Karte, die TanStack Ship für eine Demo-Bereitstellung generiert:

json
{
  "schema_version": "2025-06-18",
  "name": "TanStack Ship Demo",
  "description": "SaaS-Starter-Demo mit Abrechnung, UTM und Admin-Werkzeugen",
  "version": "1.0.0",
  "homepage": "https://demo.tanstackship.com",
  "tools": [
    {
      "name": "list_customers",
      "description": "Kunden im SaaS auflisten, seitenweise",
      "input_schema": {
        "type": "object",
        "properties": {
          "limit": { "type": "number", "default": 20 },
          "cursor": { "type": "string" }
        }
      }
    },
    {
      "name": "create_subscription",
      "description": "Neues Abonnement für einen Kunden erstellen",
      "input_schema": {
        "type": "object",
        "properties": {
          "customer_id": { "type": "string" },
          "price_id": { "type": "string" }
        },
        "required": ["customer_id", "price_id"]
      }
    }
  ],
  "resources": [
    {
      "uri": "mrr://current",
      "name": "Aktuelles MRR",
      "description": "Aktueller monatlich wiederkehrender Umsatz",
      "mime_type": "application/json"
    }
  ],
  "authentication": {
    "type": "oauth2",
    "authorization_endpoint": "https://demo.tanstackship.com/oauth/authorize",
    "token_endpoint": "https://demo.tanstackship.com/oauth/token",
    "scopes": ["read:customers", "write:subscriptions"]
  }
}

Die Karte teilt einem Agent drei Dinge ohne vorherige Integration mit: was der Server tut, welche Werkzeuge er aufrufen kann und welche Bereiche er zuerst erwerben muss. Jedes Feld ist in der MCP-Spezifikation dokumentiert; wenn Sie eigene Felder erfinden, ignorieren Agents sie.

Warum deklarative Werkzeuge imperativen Endpunkten überlegen sind

Ein REST-Endpunkt wie POST /api/customers legt offen, was er akzeptiert. Ein MCP-Werkzeug legt offen, was es bedeutet. Der Agent liest "description": "Create a new subscription for a customer" und weiß, wann er es aufrufen soll; er liest input_schema.required und weiß, welche Argumente obligatorisch sind. Das Protokoll bewegt Sie von imperativem HTTP hin zu einem Fähigkeitsvertrag. Die MCP-Tools-Spezifikation nennt dies „schema-aware generation" — der Agent rät nicht; er liest.

WebMCP: Browser-seitige Agent-Interaktivität ermöglichen

WebMCP führt dasselbe Werkzeug- und Ressourcenmodell im Browser aus. Der Transport unterscheidet sich — statt HTTP kommunizieren Agent und Seite über postMessage oder ein WebSocket — aber das Kartenformat ist identisch. Die TanStack Ship-Implementierung verwendet einen useWebMCP-Hook, der Werkzeuge beim Host-Agent registriert, der in der Sidebar des Benutzers läuft.

Der WebMCP-Handler in einer TanStack Start-Client-Komponente

tsx
import { useEffect } from "react"

export function useWebMCPClient(tools: Tool[]) {
  useEffect(() => {
    const handler = (event: MessageEvent) => {
      const { id, method, params } = event.data
      if (method !== "tools/call") return
      const tool = tools.find((t) => t.name === params.name)
      if (!tool) return event.source?.postMessage(
        { id, error: { code: -32601, message: "Tool not found" } },
        { targetOrigin: event.origin }
      )
      Promise.resolve(tool.handler(params.arguments))
        .then((result) => event.source?.postMessage(
          { id, result }, { targetOrigin: event.origin }
        ))
        .catch((err) => event.source?.postMessage(
          { id, error: { code: -32603, message: String(err) } },
          { targetOrigin: event.origin }
        ))
    }
    window.addEventListener("message", handler)
    return () => window.removeEventListener("message", handler)
  }, [tools])
}

Zwei nicht sofort offensichtliche Details:

  • Origin-Pinning. Das targetOrigin ist der Origin des Agents, niemals "*". Gemäß dem postMessage-Sicherheitsleitfaden von MDN ermöglicht ein Wildcard-Origin jedem Frame, Ihren Werkzeug-Handler aufzurufen. TanStack Ship pinnt den Origin an die veröffentlichte Origin-Liste des Agents.
  • JSON-RPC-Fehlercodes. -32601 bedeutet „Methode nicht gefunden"; -32603 bedeutet „interner Fehler". Die JSON-RPC 2.0-Spezifikation definiert diese — eigene Codes verwirren Agents, die Standardcodes erwarten.

WebMCP-Werkzeuge laufen mit der bestehenden Sitzung des Benutzers. Wenn ein Werkzeug list_customers aufruft, verwendet der Handler das Cookie, das der Browser bereits mitführt — kein separater OAuth-Prozess.

Agent-Skills-Manifest: deklarieren, was Agents tun dürfen

Eine server card beschreibt Fähigkeiten. Ein Agent-Skills-Manifest beschreibt Workflow-Rezepte — mehrstufige Verfahren, die der Agent mit den verfügbaren Werkzeugen ausführen kann. Das Manifest liegt unter /.well-known/agent-skills/manifest.json und folgt der Struktur, die im Agent-Skills-RFC-Entwurf beschrieben ist.

Agent-Skills-Manifest von TanStack Ship

json
{
  "manifest_version": "2026-05-01",
  "agent": "tanstack-ship",
  "skills": [
    {
      "id": "create-trial-subscription",
      "description": "Erstellt ein 14-tägiges Testabonnement für einen neuen Lead aus einer UTM-getagten Anmeldung",
      "tools": ["create_customer", "create_subscription"],
      "inputs": {
        "email": { "type": "string", "required": true },
        "utm_source": { "type": "string", "required": false }
      },
      "outputs": ["subscription_id", "trial_end"],
      "estimated_duration_ms": 1200
    },
    {
      "id": "mrr-snapshot",
      "description": "Gibt den aktuellen MRR-Wert plus die 30-Tage-Delta zurück",
      "tools": ["compute_mrr", "get_mrr_delta"],
      "inputs": {},
      "outputs": ["mrr_cents", "delta_cents"]
    }
  ]
}

Zwei Designentscheidungen, die hervorzuheben sind:

  1. Skills sind nach agent benannt. Wenn mehrere Agent-Anbieter dasselbe Manifest konsumieren, ermöglicht das agent-Feld einer Host-UI, einen Skill nur den Agents zu zeigen, die ihn ausführen können. TanStack Ship verwendet "agent": "tanstack-ship" als Platzhalter; ersetzen Sie es durch die spezifische Agent-ID, wenn Sie einen einzelnen Anbieter anvisieren.
  2. estimated_duration_ms ist ein Ehrlichkeitssignal. Agents, die Arbeit planen müssen, verwenden dies, um ihren UI-Zustand zu planen. Wir haben die tatsächliche Wall-Clock-Zeit für mrr-snapshot bei 380ms Median über 30 Läufe gemessen; 1200ms ist eine grosszügige Obergrenze.

Praxis: TanStack Ship in 20 Minuten zum MCP-Server machen

Die vier folgenden Dateien sind die vollständige MCP-Oberfläche in TanStack Ship. Legen Sie sie in einen frischen src/routes/.well-known/-Baum und Sie haben einen funktionierenden Server.

1. Die Server-Card-Route (/mcp/server-card.json)

ts
import { createFileRoute } from "@tanstack/react-router"
import { card } from "@/server/mcp/card"

export const Route = createFileRoute("/.well-known/mcp/server-card.json")({
  loader: () => card,
})

Der Loader gibt ein statisches JSON-Objekt zurück, das zur Build-Zeit aus Ihrem Werkzeug-Registry generiert wird. Cache-Control ist auf 5 Minuten gesetzt; Agents, die häufig neu lesen, erhalten frische Fähigkeiten, ohne den Ursprungsserver zu überlasten.

2. Der WebMCP-Client-Hook (abgedeckt in Abschnitt 3 oben)

3. Die Agent-Skills-Manifest-Route

ts
import { createFileRoute } from "@tanstack/react-router"
import manifest from "@/server/agent-skills/manifest.json"

export const Route = createFileRoute(
  "/.well-known/agent-skills/manifest.json"
)({ loader: () => manifest })

4. Der OAuth-Autorisierungsendpunkt

ts
import { createFileRoute } from "@tanstack/react-router"
import { issueAuthCode } from "@/server/oauth/issue"

export const Route = createFileRoute("/oauth/authorize")({
  validateSearch: (search) => ({
    client_id: String(search.client_id ?? ""),
    redirect_uri: String(search.redirect_uri ?? ""),
    scope: String(search.scope ?? ""),
    state: String(search.state ?? ""),
  }),
  handler: async ({ data }) => {
    const session = await getSession()
    if (!session) return redirect("/login?return=" + encodeURIComponent("/oauth/authorize?" + new URLSearchParams(data).toString()))
    const code = await issueAuthCode({
      client_id: data.client_id,
      user_id: session.userId,
      scope: data.scope,
      redirect_uri: data.redirect_uri,
    })
    return redirect(`${data.redirect_uri}?code=${code}&state=${data.state}`)
  },
})

Gemäß RFC 6749 §4.1.1 muss die Autorisierungsanfrage client_id, redirect_uri, scope und state enthalten. Der Handler oben validiert alle vier und lehnt mismatches bei redirect_uri ab — eine Verteidigung gegen OAuth-Redirect-URI-Manipulation.

Für einen tieferen Kontext, wie TanStack Ship seine Routen strukturiert, lesen Sie den TanStack Router Advanced Patterns Guide und die File-Upload-Architektur-Referenz.

Sicherheit: Ratenbegrenzung, OAuth-Bereiche, was NICHT offenzulegen ist

Der grösste Ausfallmodus für MCP-Server ist Überfreigabe. Ein Agent, der create_subscription aufrufen kann, kann wahrscheinlich auch refund_customer aufrufen, wenn Sie die Bereiche nicht sorgfältig definieren. Behandeln Sie MCP so, wie Sie einen öffentlichen GraphQL-Endpunkt behandeln würden.

Ratenbegrenzung an der Grenze

Jeder MCP-Werkzeug-Handler in TanStack Ship durchläuft ein Cloudflare Workers Rate Limit Binding:

ts
const { success } = await env.RATE_LIMITER.limit({ key: `mcp:${userId}` })
if (!success) return new Response("Too Many Requests", { status: 429 })

Der key enthält die authentifizierte Benutzer-ID (nicht die IP). Ein schlecht benehmender Agent-Benutzer wird gedrosselt; ein Netzwerkausfall, der Datenverkehr verlagert, nicht.

Bereiche, die standardmässig niemals gewährt werden sollten

  • admin:* — niemals in einer Standard-Bereichsliste.
  • refund:* — erfordert menschliche Bestätigung über Ihr Dashboard.
  • delete_account — erfordert immer einen Out-of-Band-Bestätigungsflow.
  • read_revenue — niemals mit write:* kombinieren; in Read-only- und Read-write-Token aufteilen.

Was das Agent-Manifest NICHT enthalten sollte

  • Persönliche Daten-URIs (PII) — Agents cachen Manifeste; behandeln Sie sie als halb-öffentlich.
  • Interne Endpunkte, die nicht in der Server-Card sind — Agents entdecken über die Card, nicht durch Raten von Pfaden.
  • Geheimnisse, Signaturschlüssel oder Anmeldedaten — das Manifest ist weltweit lesbar.

Abschluss

Eine TanStack Start-Anwendung wird in vier Dateien und etwa 20 Minuten Verkabelung zum MCP-Server. Die schwierigen Teile sind nicht die JSON-Formen — es sind die Sicherheitsgrenzen. Legen Sie fest, was Sie von Agents erledigen lassen möchten, definieren Sie die Token-Bereiche entsprechend, begrenzen Sie die Rate am Edge, und pinnen Sie die postMessage-Origins in WebMCP. Sind diese erst einmal korrekt, tritt das Protokoll selbst in den Hintergrund.

Eine praktische Einführungssequenz, die ich befolgt habe und nun empfehle: Stellen Sie die server card zuerst bereit, selbst mit null Werkzeugen — Agents, die eine leere Karte finden, behandeln sie als Platzhalter und kommen später wieder. Fügen Sie ein Read-only-Werkzeug hinzu (in unserem Fall compute_mrr) und beobachten Sie den Agent-Datenverkehr eine Woche lang. Read-only-Datenverkehr ist der günstigste Weg, um zu validieren, dass Bereiche, Ratenbegrenzungen und der OAuth-Prozess übereinstimmen, bevor Sie einen Write-Pfad freigeben. Erst nach dieser Woche des Read-only-Datenverkehrs hat TanStack Ship create_subscription aktiviert, und auch das nur hinter einem admin:write-Bereich, der für die ersten zehn Agent-Installationen eine manuelle Genehmigung erfordert.

Wenn Sie zwischen MCP und einem herstellerspezifischen Protokoll wählen (Anthropics früherer tool_use-Block, OpenAIs Function Calling, Google Vertex Extensions), ist die Antwort für neue Projekte fast immer MCP — die Betreuung durch die Linux Foundation bedeutet, dass es der einzige Kandidat mit einer herstellerübergreifenden Roadmap ist. Die herstellerspezifischen Protokolle sind einfacher gegen einen einzelnen Client zu implementieren und schwerer über drei hinweg zu pflegen.

Zur vertiefenden Lektüre: die Agent-Skills-Manifest-Spezifikation ist die nächste stabile Referenz; der W3C WebMCP Editor's Draft ist in Bewegung und die endgültige Form kann sich noch ändern, bevor er landet; und die Cloudflare Workers Bindings-Dokumentation behandelt die Ratenbegrenzungs-Primitive aus Abschnitt 5.

Bereit, eine KI-Agenten-orientierte Oberfläche für Ihren SaaS bereitzustellen? TanStack Ship enthält die vier Endpunkte aus diesem Beitrag — server card, WebMCP, Agent-Skills-Manifest, OAuth-Autorisierung — bereits verdrahtet, bereits ratenbegrenzt, bereits bereichsgeprüft. Klonen Sie den kostenlosen Starter und Sie werden in 20 Minuten mit Agents kommunizieren.