17 и 18 октября я поднял на своём VPS два небольших MCP-сервера по открытому стандарту Model Context Protocol. Первый даёт моему ИИ-ассистенту Grok Bot читать почту. Второй работает как доска задач: через неё ассистент раздаёт работу трём агентам Grok Build на разных машинах.
Расскажу, как это устроено, как агенты берут и сдают задачи и на какие грабли я наступил по дороге.
Что такое MCP
Model Context Protocol, или MCP, это открытый стандарт подключения ИИ-ассистентов к внешним инструментам и данным. Описание и спецификация лежат на modelcontextprotocol.io.
MCP-сервер это небольшая программа, которая отдаёт ассистенту «инструменты»: функции с описанием, что каждая делает. Ассистент вызывает их по HTTP (streamable HTTP) или через stdio. Для веб-разработчика удалённый MCP-сервер выглядит как маленький бэкенд за nginx, только вместо REST-эндпоинтов у него набор функций.
Почта: три ящика, а IMAP закрыт
Ассистенту нужно было читать три моих ящика: Gmail, Яндекс и почту на Beget. С Gmail всё просто, для него есть готовый коннектор. А вот до IMAP Яндекса и Beget облачная машина ассистента достучаться не могла: исходящие IMAP-порты там закрыты, наружу работает только HTTPS.
Значит, нужен мост: до него ассистент доходит по HTTPS, а он уже сам ходит в почту по IMAP. Таким мостом стал мой VPS.
Почтовый MCP-сервер на Python: только чтение
На VPS с Ubuntu я поднял маленький MCP-сервер на Python: FastMCP из пакета mcp, режим stateless streamable HTTP. В оба ящика он ходит по IMAP только на чтение. Папки открываются через EXAMINE, письма читаются через BODY.PEEK, поэтому они не помечаются прочитанными.
Инструментов пять:
list_accountsиlist_folders: ящики и папки в них;search: поиск писем;get_message: письмо целиком;get_attachment: вложение из письма.
Сам сервер слушает только localhost. Снаружи перед ним стоит nginx с сертификатом Let’s Encrypt на отдельном поддомене и авторизацией по bearer-токену. Сервис работает через systemd под отдельным системным пользователем, с hardening.
Один рабочий момент случился на сертификате. Let’s Encrypt не выдавал его, пока в DNS не добавили CAA-запись для letsencrypt.org.

Доска задач: второй MCP-сервер для агентов Grok Build
На том же VPS работает второй MCP-сервер, task-board. Внутри у него SQLite, снаружи тот же стек: nginx, systemd и отдельный пользователь. Поддомен тот же, только путь свой.
Зачем он понадобился. Мой основной ассистент Grok Bot держит весь контекст: почту, клиентов, планы. А работу на машинах делают агенты Grok Build, и их у меня три: на Linux-десктопе, на VPS и на MacBook. Через доску Grok Bot ставит им задачи, а они забирают их и сдают результат.

Как проходит задача: от create_task до done
Grok Bot создаёт задачу вызовом create_task. Агент смотрит список через list_tasks и забирает задачу через claim_task. Захват атомарный, так что двое одну задачу не возьмут. По ходу работы агент пишет промежуточные отчёты через post_update.
Если агенту что-то непонятно, он вызывает complete_task со статусом needs_input и задаёт вопрос. Ассистент спрашивает меня и передаёт ответ через reply. Когда работа готова, агент закрывает задачу через complete_task со статусом done или failed.

Статусов шесть: open, claimed, needs_input, done, failed и cancelled.

Всего у доски 8 инструментов. Кроме уже названных, есть get_task, чтобы прочитать задачу целиком, и cancel_task для отмены.

Безопасность: два токена и rate limit
Токенов два, у каждого своя роль: bot и builder. С токеном builder нельзя создавать и отменять задачи, это делает только ассистент. На неверный токен сервер отвечает 401, а на nginx стоит rate limit.
Токены не светятся в чатах. Каждый агент забирает свой токен с сервера по SSH и держит его в переменной окружения. В конфиге остаётся только ссылка ${TASKBOARD_TOKEN}.

Как подключить доску к Grok Build
В Grok Build MCP-сервер подключается секцией в ~/.grok/config.toml, подробно об этом в документации xAI про MCP-серверы:
[mcp_servers.taskboard]
url = "https://<ваш-домен>/tasks/mcp"
headers = { "Authorization" = "Bearer ${TASKBOARD_TOKEN}" }
Значение ${TASKBOARD_TOKEN} Grok подставляет из окружения при загрузке конфига, так что сам токен в файле не лежит. Проверить подключение можно так:
grok mcp list grok mcp doctor taskboard
Порядок работы с доской я описываю агенту в файле правил ~/.grok/rules/taskboard.md. Grok подгружает такие файлы в каждую сессию, подробнее в документации про правила проекта.
Тест на трёх машинах и грабли по дороге
Каждой машине я поставил тестовую задачу. Все три агента взяли её и сдали за секунды. Быстрее всех справился десктоп: 11 секунд от claim до done.


Без граблей не обошлось:
- Grok, запущенный под sudo, искал токен в
/root, а не в домашнем каталоге. - На MacBook SSH-ключ был с паролем, и забрать токен с сервера с первого раза не получилось. Помогла команда
ssh-add --apple-use-keychain. - Сессия Grok, открытая до правки конфига, новый сервер не видит. Нужно открыть новую.
- Доска сама не уведомляет агентов. Они проверяют её по команде «проверь доску» или по cron через headless-режим
grok -p.

В итоге у меня один ассистент держит весь контекст и раздаёт работу агентам на разных машинах через собственный защищённый сервер. Как ИИ вообще встроен в мою работу, я рассказывал в посте «Как я использую ИИ в работе».
