Учебник: Understanding Roots
Пример проекта: MCP Chat с доступом к файловой системе
MCP Chat — это приложение интерфейса командной строки, обеспечивающее интерактивные возможности чата с ИИ-моделями через API Anthropic. Приложение поддерживает операции с файловой системой с контролируемым доступом к указанным директориям, возможности конвертации видео и расширяемые интеграции инструментов через архитектуру MCP (Model Control Protocol).
Возможности:
- FFmpeg (для функций конвертации видео). У вас должен быть уже установлен FFmpeg, чтобы конвертировать видеофайл. Для установки FFmpeg на MacOS выполните соответствующую команду установки.
Шаг 1: Настройте переменные окружения
- Скопируйте файл `.env.example`, чтобы создать новый файл `.env`.
- Отредактируйте файл `.env` и задайте переменные окружения:
```
CLAUDE_MODEL="claude-sonnet-4-0"
ANTHROPIC_API_KEY=""
```
Шаг 2: Установите зависимости
`uv` — быстрый установщик и резолвер пакетов Python.
- Установите uv, если ещё не установлен.
Запуск проекта: вы должны указать один или несколько корневых каталогов, к которым MCP-сервер будет иметь доступ. Только файлы и директории внутри этих корней доступны серверу.
```
uv run main.py [root2] [root3] ...
uv run main.py /path/to/videos
uv run main.py /home/user/videos /mnt/storage/media ~/Documents
```
Сервер может обращаться только к файлам и директориям внутри указанных корневых путей. Это даёт безопасность, ограничивая доступ файловой системы одобренными местами.
Инструменты сервера:
- list_roots: перечислить все доступные корневые директории
- read_dir: прочитать содержимое директории (должна быть внутри корня)
- convert_video: конвертировать MP4-видео в другие форматы (avi, mov, webm, mkv, gif)
Инструмент конвертации видео использует FFmpeg для конвертации MP4-файлов в различные форматы: стандартные видеоформаты AVI, MOV, WebM, MKV, конвертация в GIF с оптимизированными настройками, пресет среднего качества для баланса размера файла и качества.
Шаг 1: Определение корней
В идеале пользователь диктует, к каким файлам и папкам MCP-серверу можно обращаться.
Эта программа настроена принимать список аргументов командной строки, которые интерпретируются как пути, к которым пользователь хочет разрешить доступ.
Этот список путей передаётся в `MCPClient`.
Шаг 2: Создание объектов корней
Согласно спецификации MCP, все корни должны иметь URI, начинающийся с `file://`.
Эта функция берёт список путей, предоставленный пользователем, и превращает их в объекты `Root`.
Шаг 3: Колбэк корней
Клиент не предоставляет список корней серверу сразу. Вместо этого сервер может запросить у клиента список в некий будущий момент времени. Мы создаём колбэк, который будет выполнен, когда сервер запросит корни. Колбэк должен вернуть список корней внутри объекта `ListRootsResult`.
Этот колбэк передаётся в `ClientSession`.
Шаг 4: Использование корней
Далее — сервер. Сервер использует корни в двух сценариях:
- Когда инструмент пытается обратиться к файлу или папке
- Когда LLM (вроде Claude) нужно разрешить файл или папку в полный путь. Представьте, когда пользователь говорит «read the todos.txt file», — Claude нужно понять, где находится текстовый файл, и он может сделать это, посмотрев на список корней.
Для второго случая можно либо определить инструмент, перечисляющий корни, либо внедрить их напрямую в промпт.
Шаг 5: Доступ к корням
Корни доступны вызовом `ctx.session.list_roots()`.
Это отправляет сообщение обратно клиенту, заставляя его выполнить колбэк листинга корней.
Шаг 6: Авторизация доступа
Помните: MCP SDK не пытается ограничивать то, какие файлы или папки ваши инструменты пытаются читать! Вы должны реализовать эту проверку сами.
Подумайте о реализации функции вроде `is_path_allowed`, которая будет решать, доступен ли путь, сравнивая его со списком корней.
Шаг 7: Применение авторизации
Когда вы собрали функцию авторизации — вроде `is_path_allowed`, — используйте её во всех ваших инструментах, чтобы убедиться, что запрошенный путь доступен.
Код для изучения: `main.py`, `mcp_client.py`, `mcp_server.py`, `core/chat.py`, `core/claude.py`, `core/cli.py`. Ключевые места: создание `Root(uri=file_url, name=...)` из путей пользователя, обработка `_handle_list_roots`, возвращающая `ListRootsResult`, вызов `list_roots()` на сервере и проверка каждого пути перед чтением или конвертацией.