🧪 Tool-Baukasten

Wähle ein echtes Tool aus der Praxis als Vorlage oder baue ein eigenes. Die App erzeugt daraus das JSON Schema, die Antwort auf tools/list, einen tools/call-Aufruf, prüft die Argumente mit Ajv (JSON Schema 2020-12) und zeigt einen minimalen Server in TypeScript und Python – alles im Browser, nichts wird ausgeführt.

1 · Tool beschreiben

Parameter

2 · inputSchema (JSON Schema)

✅ gültig · Draft 2020-12
{
  "type": "object",
  "properties": {
    "ort": {
      "type": "string",
      "minLength": 2,
      "description": "Ortsname, z. B. Berlin"
    },
    "einheit": {
      "type": "string",
      "enum": ["celsius", "fahrenheit"],
      "description": "Temperatur-Einheit"
    },
    "tage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 7,
      "description": "Vorhersage in Tagen (1–7)"
    }
  },
  "required": ["ort"],
  "additionalProperties": false
}

3 · Antwort auf tools/list

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "wetter_abfragen",
        "title": "Wetter abfragen",
        "description": "Liefert das aktuelle Wetter für einen Ort. Reiner Lesezugriff.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "ort": {
              "type": "string",
              "minLength": 2,
              "description": "Ortsname, z. B. Berlin"
            },
            "einheit": {
              "type": "string",
              "enum": ["celsius", "fahrenheit"],
              "description": "Temperatur-Einheit"
            },
            "tage": {
              "type": "integer",
              "minimum": 1,
              "maximum": 7,
              "description": "Vorhersage in Tagen (1–7)"
            }
          },
          "required": ["ort"],
          "additionalProperties": false
        },
        "annotations": {
          "readOnlyHint": true
        }
      }
    ]
  }
}

Annotations wie readOnlyHint sind nur Hinweise – Clients MÜSSEN sie als nicht vertrauenswürdig behandeln, solange der Server nicht vertrauenswürdig ist.

4 · Argumente (wie vom Modell)

Ajv (Draft 2020-12)
✅ Argumente passen zum Schema – der Server führt das Tool aus.

5 · tools/call-Anfrage

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "wetter_abfragen",
    "arguments": {
      "ort": "Berlin",
      "tage": 3
    }
  }
}

6 · Antwort des Servers

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Ergebnis …  (hier stünde die Ausgabe des Tools)"
      }
    ],
    "isError": false
  }
}

Validierungsfehler sind laut Spezifikation Tool-Ausführungsfehler (isError: true), damit sich das Modell selbst korrigieren kann. Ein unbekanntes Tool wäre dagegen ein Protokollfehler -32602.

7 · Minimaler Server (nur Anzeige)

server.ts (SDK 1.x, stdio)ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({ name: "mein-server", version: "1.0.0" });

server.registerTool(
  "wetter_abfragen",
  {
    title: "Wetter abfragen",
    description: "Liefert das aktuelle Wetter für einen Ort. Reiner Lesezugriff.",
    inputSchema: {
      ort: z.string().min(2).describe("Ortsname, z. B. Berlin"),
      einheit: z.enum(["celsius", "fahrenheit"]).optional().describe("Temperatur-Einheit"),
      tage: z.number().int().min(1).max(7).optional().describe("Vorhersage in Tagen (1–7)"),
    },
    annotations: { readOnlyHint: true },
    // Unbekannte Felder: Zod entfernt sie standardmäßig; wer ablehnen will, prüft im Handler.
  },
  async ({ ort, einheit, tage }) => {
    // Hier die eigentliche Arbeit: API aufrufen, Datei lesen, Datenbank abfragen …
    // Zugangsdaten nur aus process.env – nie in Argumente oder Ergebnisse schreiben.
    return { content: [{ type: "text", text: "Ergebnis …" }] };
  },
);

// stdout gehört dem Protokoll – Logs deshalb nur nach stderr (console.error).
await server.connect(new StdioServerTransport());
console.error("mein-server läuft (stdio)");

Beide SDKs erzeugen das JSON Schema selbst – aus Zod (TypeScript) bzw. aus Typ-Hinweisen und Pydantic Field (Python). Die genaue Form (z. B. $schema, additionalProperties, title je Feld) hängt von der SDK-Version ab.