/* Корневые переменные цвета */
:root {
/* Цвет текста по умолчанию */
/* Система цветов Slate */
--color-slate-50: #faf9f6; /* Светлая слоновая кость */
--color-slate-150: #f0eee6; /* Средняя слоновая кость */
--color-slate-200: #e5e2d9; /* Тёмная слоновая кость */
--color-slate-300: #d1cfc5; /* Светлое облако */
--color-slate-400: #b8b5a6; /* Среднее облако */
--color-slate-500: #9a9788; /* Тёмное облако */
--color-slate-600: #7c7968; /* Светлый сланец */
--color-slate-700: #5e5b4e; /* Средний сланец */
--color-slate-950: #2c2b25; /* Тёмный сланец */
/* Макет контейнера редактора */
/* Стили обозревателя файлов - сохраняем шрифт редактора кода */
#tutorial-container .file-icon,
#tutorial-container .file-name,
/* Вкладки файлов - сохраняем шрифт редактора кода */
/* Пустое состояние при отсутствии открытых файлов */
/* Кнопки навигации */
/* Стили для тура/подсветки */
/* Кнопка триггера тура */
0% {
70% {
100% {
/* Обеспечение корректной работы элементов тура с существующей компоновкой */
/* Мобильные стили */
/* Скрываем название урока на мобильных устройствах */
/* Уменьшаем отступы в навигации урока */
/* Убираем отступы у контейнера кнопок навигации */
/* Уменьшаем высоту кнопок навигации */
/* Уменьшаем отступы контейнера аккордеона */
/* Настройки тура для мобильных устройств */
← Назад Вперёд →
// Данные из advanced_mcp/notifications.js
".gitignore": `# Файлы, сгенерированные Python
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
Виртуальные окружения
.venv
.python-version
`,
"README.md": `# Демонстрация ведения журнала и прогресса MCP
Демонстрация протокола Model Context Protocol с использованием транспорта STDIO.
Установка
Установите зависимости с помощью uv:
\`\`\`bash
uv sync
\`\`\`
Запуск проекта
Запустите клиент MCP:
\`\`\`bash
uv run client.py
\`\`\`
`,
"client.py": `from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from mcp.types import LoggingMessageNotificationParams
server_params = StdioServerParameters(
command="uv",
args=["run", "server.py"],
async def logging_callback(params: LoggingMessageNotificationParams):
print(params.data)
async def print_progress_callback(
progress: float, total: float | None, message: str | None
):
if total is not None:
percentage = (progress / total) * 100
else:
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(
read, write, logging_callback=logging_callback
) as session:
await session.initialize()
await session.call_tool(
name="add",
progress_callback=print_progress_callback,
if __name__ == "__main__":
import asyncio
asyncio.run(run())
`,
"pyproject.toml": `[project]
name = "notifications"
version = "0.1.0"
description = "Демонстрация уведомлений с MCP"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
"aioconsole>=0.8.1",
"mcp[cli]>=1.9.3",
[tool.setuptools]
py-modules = ["client", "server"]
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
`,
"server.py": `from mcp.server.fastmcp import FastMCP, Context
import asyncio
mcp = FastMCP(name="Demo Server")
@mcp.tool()
async def add(a: int, b: int, ctx: Context) -> int:
await ctx.info("Подготовка к сложению...")
await ctx.report_progress(20, 100)
await asyncio.sleep(2)
await ctx.info("Хорошо, складываем...")
await ctx.report_progress(80, 100)
return a + b
if __name__ == "__main__":
mcp.run(transport="stdio")
`,
const tutorialTitle = "Уведомления журнала и прогресса";
file: "server.py",
line: 8,
endLine: 8,
title: "Функция инструмента принимает аргумент Context",
markdown:
"Функции инструментов автоматически получают объект 'Context' в качестве последнего аргумента. Этот объект содержит методы для ведения журнала и отчёта о прогрессе клиенту.",
file: "server.py",
line: 9,
endLine: 15,
title: "Создание журналов и прогресса с помощью контекста",
markdown:
"На протяжении выполнения функции инструмента вызывайте методы `info()`, `warning()`, `debug()` или `error()` для ведения журнала различных типов сообщений для клиента. Также вызывайте метод `report_progress()` для оценки оставшегося объёма работы для вызова инструмента.",
file: "client.py",
line: 11,
endLine: 22,
title: "Определение обратных вызовов на клиенте",
markdown:
"Клиент должен определить обратные вызовы для ведения журнала и прогресса, которые будут автоматически вызываться всякий раз, когда сервер отправляет сообщения журнала или прогресса. Эти обратные вызовы должны пытаться отображать предоставленные данные журнала и прогресса для пользователя.",
file: "client.py",
line: 27,
endLine: 36,
title: "Передача обратных вызовов в соответствующие функции",
markdown:
"Убедитесь, что вы предоставляете обратный вызов ведения журнала объекту `ClientSession`, а обратный вызов прогресса — функции `call_tool()`.",
```