Введение в определение инструментов с помощью MCP и Python SDK
В мире больших языковых моделей (LLM) таких как Claude, способность взаимодействовать с внешними системами и данными является ключевой для выполнения сложных и полезных задач. Сам по себе Claude — это мощный мыслитель, но ему нужны "руки" и "глаза", чтобы читать документы, обновлять базы данных или вызывать внешние API. Именно здесь на помощь приходит протокол MCP (Multi-tool Co-op Protocol) и его официальный Python SDK.
MCP позволяет нам определять набор инструментов, которые Claude может использовать. Эти инструменты — это, по сути, функции, которые Claude может вызывать, передавая им параметры и получая результаты. Однако ручное написание сложных JSON schema для каждого инструмента может быть трудоемким и подверженным ошибкам. Python SDK для MCP значительно упрощает этот процесс, позволяя разработчикам определять инструменты с помощью привычных конструкций Python, таких как декораторы и аннотации типов.
В этом уроке мы рассмотрим, как создать простой сервер MCP и определить два основных инструмента для управления документами, хранящимися в памяти: один для чтения содержимого документов и другой для их обновления с помощью операций поиска и замены. Это продемонстрирует элегантность и эффективность подхода SDK.
Настройка сервера MCP
Создание сервера MCP с помощью Python SDK невероятно просто. Вы можете инициализировать полноценный сервер всего одной строкой кода. Для этого используется класс FastMCP из модуля mcp.server.fastmcp.
Вот как это выглядит:
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("DocumentMCP", log_level="ERROR")
В этом примере мы создаем экземпляр сервера FastMCP с именем "DocumentMCP". Параметр log_level="ERROR" настраивает уровень логирования, чтобы выводить только критические ошибки, делая вывод более чистым.
Для нашей реализации документы будут храниться в простом словаре Python, где ключами являются идентификаторы документов, а значениями — их содержимое. Это имитирует простую базу данных или файловую систему для демонстрационных целей:
docs = {
"deposition.md": "This deposition covers the testimony of Angela Smith, P.E.",
"report.pdf": "The report details the state of a 20m condenser tower.",
"financials.docx": "These financials outline the project's budget and expenditure",
"outlook.pdf": "This document presents the projected future performance of the",
"plan.md": "The plan outlines the steps for the project's implementation.",
"spec.txt": "These specifications define the technical requirements for the equipment"
}
Этот словарь docs будет доступен для наших инструментов, позволяя им читать и изменять содержимое документов.
Определение инструментов с помощью декораторов
Python SDK преобразует процесс создания инструментов из многословного и подверженного ошибкам в чистый и читаемый. Вместо того чтобы вручную писать длинные JSON schema, вы используете декораторы Python и аннотации типов. SDK автоматически генерирует необходимую JSON schema, которую Claude использует для понимания доступных инструментов и их параметров.
Создание инструмента для чтения документов
Первый инструмент позволит Claude читать содержимое любого документа по его идентификатору. Это фундаментальная операция, которая часто требуется для обработки информации.
Вот полная реализация:
from pydantic import Field
@mcp.tool(
name="read_doc_contents",
description="Read the contents of a document and return it as a string."
)
def read_document(
doc_id: str = Field(description="Id of the document to read")
):
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
return docs[doc_id]
Давайте разберем этот код:
@mcp.tool(...): Это декоратор, который регистрирует функциюread_documentкак инструмент MCP. Он принимает два ключевых параметра:name: Уникальное имя инструмента, которое Claude будет использовать для его вызова.description: Краткое, но информативное описание того, что делает инструмент. Это описание критически важно, так как Claude использует его для принятия решения о том, какой инструмент использовать и когда.
doc_id: str = Field(description="Id of the document to read"): Здесь мы определяем параметр функции.doc_id: str: Аннотация типа указывает, чтоdoc_idдолжен быть строкой. SDK использует эту информацию для генерации соответствующей JSON schema.Field(description="..."): КлассFieldиз библиотеки Pydantic позволяет нам добавить подробное описание для каждого параметра. Это описание также включается в JSON schema и помогает Claude понять, что ожидается в качестве аргумента.
- Тело функции: Простая логика, которая проверяет, существует ли документ с заданным
doc_idв нашем словареdocs. Если документ найден, его содержимое возвращается. В противном случае генерируется ошибкаValueError.
Декоратор автоматически генерирует JSON schema, которую Claude использует для понимания этого инструмента. Благодаря Pydantic, мы получаем не только описание, но и встроенную валидацию типов для параметров.
Создание инструмента для редактирования документов
Второй инструмент позволяет Claude выполнять простые операции поиска и замены в содержимом документов. Это полезно для внесения небольших корректировок или стандартизации текста.
Вот его реализация:
@mcp.tool(
name="edit_document",
description="Edit a document by replacing a string in the documents content with a new string."
)
def edit_document(
doc_id: str = Field(description="Id of the document that will be edited"),
old_str: str = Field(description="The text to replace. Must match exactly, including whitespace."),
new_str: str = Field(description="The new text to insert in place of the old text.")
):
if doc_id not in docs:
raise ValueError(f"Doc with id {doc_id} not found")
docs[doc_id] = docs[doc_id].replace(old_str, new_str)
return f"Document '{doc_id}' updated successfully."
Этот инструмент принимает три параметра:
doc_id: Идентификатор документа, который будет редактироваться.old_str: Строка, которую нужно найти и заменить. Важно отметить, что она должна совпадать точно, включая пробелы.new_str: Новая строка, которая будет вставлена вместо старой.
Реализация использует встроенный метод .replace() строк Python для простоты. Как и в случае с инструментом для чтения, здесь также присутствует базовая обработка ошибок: если документ с указанным doc_id не найден, генерируется ValueError.
Обработка ошибок в инструментах
Оба наших инструмента включают базовую обработку ошибок, чтобы управлять случаями, когда Claude запрашивает несуществующий документ. Когда предоставляется неверный doc_id, инструменты генерируют исключение ValueError с описательным сообщением. Это сообщение передается обратно Claude, который может понять его и потенциально скорректировать свои действия, например, запросить уточнение у пользователя или попробовать другой doc_id.
Эффективная обработка ошибок в инструментах критически важна для создания надежных систем, управляемых LLM. Она позволяет Claude быть более устойчивым к неверным входным данным и более "умным" в своих попытках выполнить задачу.
Ключевые преимущества подхода SDK
Использование Python SDK для MCP значительно упрощает разработку инструментов для Claude, предлагая ряд существенных преимуществ:
- Автоматическая генерация JSON schema: SDK автоматически создает необходимую JSON schema из аннотаций типов Python и объектов Pydantic Field. Это устраняет необходимость вручную писать и поддерживать сложные JSON-структуры.
- Чистый, читаемый код: Определение инструментов с помощью декораторов и стандартных функций Python делает код интуитивно понятным и легким для понимания, что улучшает поддерживаемость.
- Встроенная валидация параметров: Благодаря интеграции с Pydantic, вы получаете автоматическую валидацию типов и значений параметров, что снижает количество ошибок и повышает надежность.
- Сокращение шаблонного кода: SDK берет на себя множество рутинных задач, связанных с протоколом MCP, позволяя разработчикам сосредоточиться на бизнес-логике своих инструментов.
- Безопасность типов и поддержка IDE: Использование аннотаций типов Python обеспечивает безопасность типов, а также улучшает автодополнение и проверку кода в интегрированных средах разработки (IDE), таких как VS Code или PyCharm.
Python SDK для MCP превращает то, что раньше было сложным процессом написания определений инструментов, в нечто естественное и эффективное для Python-разработчиков. Вы можете сосредоточиться на логике, которую должны выполнять ваши инструменты, в то время как SDK берет на себя все детали протокола.