Промпты
Машинный перевод
Эта страница переведена с английской документации автоматически, и основной версией остаётся английская страница. Если что-то читается неправильно, на странице Переводы объясняется, как об этом сообщить.
Промпт — это шаблон сообщения, который выбирает пользователь.
Инструменты предназначены для модели. Промпт — наоборот: пользователь выбирает его из меню в своём клиенте (слэш-команда, кнопка), заполняет аргументы, и отрендеренные сообщения попадают в диалог так, будто он набрал их сам.
Чтобы объявить промпт, поставьте @mcp.prompt() над функцией, которая возвращает текст.
Первый промпт
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}"
SDK читает те же три вещи, что и у инструмента:
- Имя — это имя функции:
review_code. - Описание, которое показывает клиент, — это строка документации:
Review a piece of code. - Аргументы берутся из параметров. У
codeнет значения по умолчанию, поэтому он обязательный.
Вот что клиент получает в ответ на prompts/list:
{
"name": "review_code",
"description": "Review a piece of code.",
"arguments": [
{"name": "code", "required": true}
]
}
Никакой JSON Schema здесь нет. Аргументы промпта — это плоский список именованных строковых значений: форма, которую заполняет человек, а не полезная нагрузка, которую конструирует модель.
Рендеринг
Клиент рендерит шаблон через prompts/get, передавая аргументы. Функция выполняется, и возвращённая str становится одним сообщением пользователя:
{
"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"
}
Вот и вся жизнь промпта: перечислен по имени, отрендерен по запросу, отправлен в чат.
Check
required проверяется до запуска функции. Попробуйте отрендерить review_code без code —
сам запрос завершится ошибкой JSON-RPC (код -32603):
mcp.shared.exceptions.MCPError: Internal server error
Результата с ошибкой в стиле инструмента, который можно было бы вернуть модели, нет, потому что
модели в этой цепочке нет: вызов выбрасывает исключение. Причина (Missing required arguments: {'code'})
попадает в лог сервера.
Попробуйте сами
Запустите сервер с MCP Inspector:
uv run mcp dev server.py
Откройте вкладку Prompts и выберите review_code. Inspector нарисует форму с одним обязательным полем code. Заполните его, отрендерите — и в ответ придёт ровно то сообщение пользователя, что показано выше.
Больше одного сообщения
Ревью кода — это одно сообщение. Сессия отладки — это диалог, и промпт может задать его целиком.
Верните список сообщений вместо str:
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иAssistantMessageнаходятся вmcp.server.mcpserver.prompts.base. Передайте имstr, и они сами обернут её вTextContent. Роль — это имя класса.Message— их общий базовый класс. Используйте его как аннотацию возвращаемого типа.
Теперь debug_error при рендеринге даёт три сообщения по порядку:
{
"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"
}
Обратите внимание на последнее. Заранее заполненная реплика assistant — это способ направить следующий ответ модели, не заставляя пользователя набирать эти указания самостоятельно.
Заголовки и описания аргументов
review_code — имя функции, а не подпись. Дайте клиенту что-нибудь получше для надписи на кнопке и опишите каждый аргумент, чтобы форма была понятна сама по себе:
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"— человекочитаемое имя, ровно какtitleу инструмента.Annotated[str, Field(description=...)]— тот же приём, которым Инструменты описывают параметры инструмента. Здесь описание попадает в аргумент, а не в схему.- У
languageесть значение по умолчанию, поэтому он перестаёт быть обязательным.
Запись в prompts/list теперь содержит всё, что нужно клиенту, чтобы нарисовать хорошую форму:
{
"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
Если вы читали страницу Инструменты, то уже знаете всё, что здесь написано. Тот же декоратор,
та же строка документации в роли описания, те же Annotated/Field. Меняется только то, кто
запускает промпт (пользователь) и куда идёт результат (в диалог).
Итоги
@mcp.prompt()над функцией делает её промптом. Имя — из функции, описание — из строки документации.- Промпты управляются пользователем: клиент их перечисляет, пользователь выбирает один и заполняет аргументы.
- Аргументы — плоский список именованных строк (без схемы). Параметр со значением по умолчанию необязателен.
- Верните
str— и она станет одним сообщением пользователя. Верните списокUserMessage/AssistantMessage, чтобы задать многоходовой диалог. title=иField(description=...)— это то, что клиент показывает в интерфейсе.- Отсутствующий обязательный аргумент проваливает весь запрос. Отдельного результата с ошибкой у промпта нет.
Автодополнение аргументов промпта (или шаблона ресурса) на стороне сервера — на странице Автодополнение.