Zum Inhalt

Prompts

Maschinelle Übersetzung

Diese Seite wurde automatisch aus der englischen Dokumentation übersetzt, und die englische Seite ist die maßgebliche Fassung. Wenn sich etwas falsch liest, erklärt Übersetzungen, wie du es melden kannst.

Ein Prompt ist eine Nachrichtenvorlage, die die Person am Host auswählt.

Tools sind für das Modell gedacht. Ein Prompt ist das Gegenteil: Die Person wählt einen aus einem Menü in ihrem Client (ein Slash-Command, ein Button), füllt die Argumente aus, und die gerenderten Nachrichten landen in der Unterhaltung, als hätte sie sie selbst getippt.

Du deklarierst einen, indem du @mcp.prompt() auf eine Funktion setzt, die den Text zurückgibt.

Dein erster Prompt

server.py
from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"

Das SDK liest dieselben drei Dinge wie bei einem Tool:

  • Der Name ist der Funktionsname: review_code.
  • Die Beschreibung, die der Client anzeigt, ist der Docstring: Review a piece of code.
  • Die Argumente stammen aus den Parametern. code hat keinen Standardwert, also ist es erforderlich.

Das bekommt ein Client von prompts/list zurück:

{
  "name": "review_code",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "required": true}
  ]
}

Hier gibt es kein JSON Schema. Prompt-Argumente sind eine flache Liste benannter String-Werte: ein Formular, das eine Person ausfüllt, keine Payload, die ein Modell zusammenbaut.

Rendern

Der Client rendert die Vorlage mit prompts/get und übergibt dabei die Argumente. Deine Funktion läuft, und der str, den du zurückgibst, wird zu einer einzigen User-Nachricht:

{
  "description": "Review a piece of code.",
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "Please review this code:\n\ndef add(a, b): return a + b"
      }
    }
  ],
  "resultType": "complete"
}

Das ist der ganze Lebenslauf eines Prompts: unter seinem Namen aufgelistet, bei Bedarf gerendert, in den Chat eingefügt.

Check

required wird durchgesetzt, bevor deine Funktion läuft. Renderst du review_code ohne code, schlägt der Request selbst mit einem JSON-RPC-Fehler (Code -32603) fehl:

mcp.shared.exceptions.MCPError: Internal server error

Es gibt kein Fehlerergebnis im Stil eines Tools, das man einem Modell zurückgeben könnte, denn es ist kein Modell beteiligt: Der Aufruf löst eine Exception aus. Der Grund (Missing required arguments: {'code'}) landet im Log deines Servers.

Ausprobieren

Starte den Server mit dem MCP Inspector:

uv run mcp dev server.py

Öffne den Tab Prompts und wähle review_code. Der Inspector zeichnet ein Formular mit einem erforderlichen Feld code. Fülle es aus, rendere es, und du bekommst genau die User-Nachricht von oben zurück.

Mehr als eine Nachricht

Ein Code-Review ist eine Nachricht. Eine Debugging-Sitzung ist eine Unterhaltung, und ein Prompt kann sie komplett anstoßen.

Gib eine Liste von Nachrichten statt eines str zurück:

server.py
from mcp.server import MCPServer
from mcp.server.mcpserver.prompts.base import AssistantMessage, Message, UserMessage

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"


@mcp.prompt()
def debug_error(error: str) -> list[Message]:
    """Start a debugging conversation."""
    return [
        UserMessage("I'm seeing this error:"),
        UserMessage(error),
        AssistantMessage("I'll help debug that. What have you tried so far?"),
    ]
  • UserMessage und AssistantMessage kommen aus mcp.server.mcpserver.prompts.base. Übergib ihnen einen str, und sie verpacken ihn für dich in TextContent. Die Rolle ist der Klassenname.
  • Message ist ihre gemeinsame Basisklasse. Verwende sie als Rückgabeannotation.

Das Rendern von debug_error erzeugt jetzt drei Nachrichten, in dieser Reihenfolge:

{
  "description": "Start a debugging conversation.",
  "messages": [
    {"role": "user", "content": {"type": "text", "text": "I'm seeing this error:"}},
    {"role": "user", "content": {"type": "text", "text": "TypeError: 'int' object is not iterable"}},
    {
      "role": "assistant",
      "content": {"type": "text", "text": "I'll help debug that. What have you tried so far?"}
    }
  ],
  "resultType": "complete"
}

Beachte die letzte. Einen assistant-Beitrag vorzubelegen ist der Weg, die nächste Antwort des Modells zu lenken, ohne dass die Person die Lenkung selbst tippen muss.

Titel und Argumentbeschreibungen

review_code ist ein Funktionsname, keine Beschriftung. Gib dem Client etwas Besseres für den Button und beschreibe jedes Argument, damit sich das Formular von selbst erklärt:

server.py
from typing import Annotated

from pydantic import Field

from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt(title="Code review")
def review_code(
    code: Annotated[str, Field(description="The code to review.")],
    language: Annotated[str, Field(description="The language the code is written in.")] = "python",
) -> str:
    """Review a piece of code."""
    return f"Please review this {language} code:\n\n{code}"
  • title="Code review" ist der menschenlesbare Name, genau wie das title eines Tools.
  • Annotated[str, Field(description=...)] ist dasselbe Muster, mit dem Tools die Parameter eines Tools beschreibt. Hier landet die Beschreibung am Argument statt in einem Schema.
  • language hat einen Standardwert und ist damit nicht mehr erforderlich.

Der prompts/list-Eintrag enthält jetzt alles, was ein Client braucht, um ein gutes Formular zu zeichnen:

{
  "name": "review_code",
  "title": "Code review",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "description": "The code to review.", "required": true},
    {"name": "language", "description": "The language the code is written in.", "required": false}
  ]
}

Info

Wenn du Tools gelesen hast, kennst du schon alles auf dieser Seite. Derselbe Dekorator, derselbe Docstring als Beschreibung, dasselbe Annotated/Field. Das Einzige, was sich ändert: wer ihn auslöst (die Person) und wohin das Ergebnis geht (in die Unterhaltung).

Zusammenfassung

  • @mcp.prompt() auf einer Funktion macht sie zu einem Prompt. Der Name kommt von der Funktion, die Beschreibung vom Docstring.
  • Prompts sind von der Person gesteuert: Der Client listet sie auf, die Person wählt einen und füllt die Argumente aus.
  • Argumente sind eine flache Liste benannter Strings (kein Schema). Ein Parameter mit Standardwert ist optional.
  • Gibst du einen str zurück, wird daraus eine User-Nachricht. Gib eine Liste von UserMessage / AssistantMessage zurück, um eine mehrteilige Unterhaltung anzustoßen.
  • title= und Field(description=...) sind das, was ein Client in seiner Oberfläche anzeigt.
  • Ein fehlendes erforderliches Argument lässt den ganzen Request fehlschlagen. Es gibt kein Fehlerergebnis pro Prompt.

Serverseitige Autovervollständigung für die Argumente eines Prompts (oder eines Ressourcen-Templates) ist Vervollständigungen.