Почему «подключить MCP-сервер» — недостаточное решение
В понедельник утром в корпоративный агент обычно приходит не слово «MCP». Приходит просьба: «Пусть ассистент сам посмотрит статус заказа», «Нужно дать ему доступ к базе знаний», «Пусть создаёт заявку в сервис-деске». У команды появляется сервер, который умеет отвечать на tools/list, а затем выполнять tools/call. Кажется, что решение локальное: настроить адрес, авторизацию и добавить его в список. Но к моменту первого успешного вызова фактически уже принято несколько разных решений — о данных, действиях, личности, журнале и праве остановиться.
Спецификация MCP описывает серверные primitives: prompts, resources и tools. Именно tools выделяются тем, что ими может управлять модель: сервер объявляет имя, описание и JSON Schema входов, а клиент может дать модели возможность обнаружить и вызвать функцию. Это полезный механизм, но он заставляет точнее формулировать границу. Вопрос архитектора не «доверяем ли мы серверу?», а «какой именно вызов этой версии сервера разрешён для какого ресурса и что он может изменить?» (MCP: Tools).
Адрес в защищённой сети, знакомый поставщик или подпись пакета важны, но не отвечают на этот вопрос. Сервер может содержать один безобидный поиск и один инструмент записи. Он может возвращать данные, которые модель затем включит в другой запрос. Его версия может добавить новый tool после того, как первая проверка уже прошла. Поэтому общий allowlist «доверенных MCP-серверов» слишком крупен: он не сообщает, что разрешено сегодня и что изменится завтра.
Это не повод запрещать MCP до лучших времён. Это повод выбрать правильную единицу допуска. В контексте нулевого доверия защищают не только сегмент сети, но и ресурс, учётную запись и действие. NIST описывает этот принцип как отказ от неявного доверия, основанного только на расположении или собственности актива (NIST SP 800-207). Для MCP практическая интерпретация проста: запись в каталоге должна связывать сервер, конкретные tools, класс данных, минимальные полномочия, владельца и проверку результата.
Единица допуска: server, tool, ресурс и действие
Полезно разложить интеграцию на четыре уровня. Они похожи, но не взаимозаменяемы.
- Сервер — исполняемая служба с версией, транспортом, происхождением и владельцем.
- Tool — именованная функция: например,
find_order,get_contract_summaryилиcreate_support_ticket; у неё есть ожидаемые параметры и результат. - Ресурс — то, что tool читает или меняет: запись заказа, документ, заявка, очередь, файл, счётчик или другой сервис.
- Действие — эффект в процессе: показать сведения, создать черновик, отправить уведомление, изменить статус, удалить объект, передать платёж на исполнение.
Если смешать уровни, появляется иллюзия контроля. Например, разрешение серверу на доступ к CRM не говорит, может ли он только искать карточки или ещё менять владельца лида. Разрешение на API-метод не отвечает, какие поля допустимы в запросе и что будет при повторе. Наконец, read-only не всегда безобиден: выборка может содержать чувствительные данные или позволять массовое извлечение.
В паспорте начните с короткой фразы о единице результата: «инструмент возвращает статус одного заказа оператору», «инструмент создаёт черновик заявки без отправки», «инструмент находит только опубликованные документы базы знаний». Она вынуждает назвать границу и помогает не подменить задачу обещанием «дать агенту доступ». Затем перечислите все доступные tools из фактического tools/list, не только тот, который нужен в демо. Спецификация допускает уведомление об изменении списка tools, если сервер объявил соответствующую возможность; поэтому снимок набора tools нужно привязывать к версии и дате проверки (MCP: Tools).
Есть и ещё одна причина вести снимок, а не ориентироваться на рекламное описание. MCP строится на согласовании возможностей при инициализации соединения: клиент и сервер сообщают поддерживаемые функции и используют их в рамках сессии (MCP: Architecture). Стабильное имя сервера не гарантирует стабильный набор возможностей. Внутренний сервер может обновиться вместе с основной системой; у внешнего меняется release, описание или зависимость. Поэтому в паспорте полезны хеш или версия сборки, дата просмотра tools/list, транспорт и источник установки. Это не заменяет supply-chain-контроль, но оставляет минимальное доказательство, что проверяли именно ту реализацию, которую собираются включить.
Для команды это меняет порядок разговора с владельцем системы. Вместо «откройте агенту доступ к HR-системе» появляется узкая заявка: «Разрешите server версии X инструмент find_employee_policy для чтения опубликованного фрагмента без персональных карточек; результат отображается пользователю, журналируется идентификатором запроса, срок допуска — до пересмотра версии». Такая формулировка позволяет владельцу данных сказать содержательное «да», «нет» или «да, но только через обезличенное представление». Широкая заявка этого выбора не даёт.
Особенно полезно заранее отметить составные инструменты. get_customer может выглядеть чтением, но по параметру возвращать историю обращений и вложения; run_report — создавать дорогое вычисление; send_message — обладать обратимым черновиком и необратимой отправкой. Если описание инструмента не позволяет увидеть эти режимы, паспорт должен требовать отдельной схемы параметров и теста, а не компенсировать неопределённость повышенным доверием к серверу. Удобство одного универсального tool не является основанием дать ему универсальное право.
Для каждого tool полезно ответить на пять вопросов. Что он делает? Какие параметры меняют объём, адресата или необратимость? К каким данным он обращается? Что вернётся модели? Кто бизнес-владелец результата? Этот короткий разбор обычно обнаруживает, что один универсальный search требует лимита и фильтра, а «создание заявки» — отдельного подтверждения пользователя. Не нужно выдумывать шкалу риска на 30 пунктов. Достаточно отличить чтение ограниченной области, создание обратимого черновика, изменение процесса и необратимое действие.
Права не равны сетевому доступу
Следующий слой — не просто «авторизован ли агент». В HTTP-профиле MCP сервер выступает защищённым OAuth-ресурсом, а клиент получает и предъявляет токен для конкретного ресурса. Актуальная спецификация требует protected resource metadata для обнаружения сервера авторизации и призывает передавать минимальный scope при недостаточных правах (MCP: Authorization). Это техническая основа, а не готовая корпоративная политика. Её можно превратить в понятный вопрос: какое минимальное право нужно именно этому tool для этого результата?
Минимальность проверяется не общим названием scope, а сочетанием «кто — что — над какими данными — в каком объёме». Для find_order это может быть доступ к одному заранее ограниченному представлению и только к записи, которую вправе видеть инициатор. Для create_support_ticket — разрешение создать черновик с фиксированным набором полей, но не закрывать существующие заявки. Для действия, которое меняет деньги, права, договор или персональные данные, паспорт должен явно назвать маршрут человеческого подтверждения до вызова, а не после него.
Это сохраняет полезную автоматизацию там, где она действительно нужна. Необязательно просить человека подтвердить каждый поиск в публичной базе знаний. Но нельзя переносить это удобство на действие, которое запускает рассылку, меняет статус клиента или снимает ограничение. Спецификация MCP рекомендует приложению показывать, какие tools доступны, отмечать их вызовы и оставлять человеку возможность отказать (MCP: Tools). Архитектору стоит сформулировать это как контракт интерфейса: какой вызов видит пользователь, какие параметры он может проверить и какое действие блокируется без подтверждения.
Сеть остаётся необходимой: сегментация, egress-правила, TLS и контроль адресов уменьшают поверхность атаки. Но она не отменяет проверку ресурса. Агент внутри одной сети с сервером не получает из этого права менять всё, что сервер технически умеет. И сервер не должен считать, что любой токен из знакомой сети предназначен именно ему. Так разграничиваются транспортная достижимость и полномочие.
Параметры тоже входят в полномочие. Поле id может сузить запрос до одного объекта, а отсутствие фильтра — развернуть его на весь раздел. Поле recipient меняет внутреннее уведомление на внешнюю отправку. Поле mode=preview может безопасно подготовить документ, а mode=commit — создать реальное обязательство. Архитектурное правило здесь не в том, чтобы каждый JSON-параметр вынести в IAM. Нужно назвать параметры, которые меняют класс эффекта, и проверить их серверной валидацией. Модель, подсказка в tool description и интерфейс подтверждения не должны быть единственной защитой.
Нужны и границы объёма. Даже законный read-only поиск без лимита может вернуть больше, чем требуется рабочему вопросу. В паспорте укажите максимальное число объектов, пагинацию, допустимые поля, rate limit и причины отказа. Если так сформулировать правило нельзя, сценарий ещё слишком широк. Его лучше разделить: сначала инструмент находит ссылку или идентификатор с минимальными полями, затем второй, более чувствительный инструмент открывает деталь с явным подтверждением. Это чуть длиннее в демонстрации, но понятнее в эксплуатации.
Идентичность: не передавать токен дальше
Самая дорогая ошибка в такой интеграции часто выглядит как удобство: сервер принимает токен от MCP-клиента, а затем пересылает тот же токен вниз в API корпоративной системы. Спецификация MCP прямо требует проверять, что токен выдан для этого MCP-сервера как целевой аудитории, и запрещает принимать или транзитом передавать иной токен. Если серверу нужен доступ к нижестоящему API, он действует там как отдельный OAuth-клиент и использует отдельный токен, выпущенный для целевого API (MCP: Authorization). Механизм resource indicator из RFC 8707 как раз связывает токен с целевым ресурсом.
Смысл здесь не в формальном соответствии спецификации. Если токен, предназначенный для одного ресурса, принимают другие сервисы, появляется риск confused deputy: нижестоящая система получает доказательство, которое не предназначалось для неё, и неправильно интерпретирует, кто и что разрешил. Становится труднее расследовать действие и снять доступ без побочных эффектов. Разделённые полномочия позволяют отозвать доступ конкретного MCP-сервера, не ломая сессию пользователя или весь агентный контур.
В паспорте запишите две идентичности отдельно. Первая — кто инициирует вызов на стороне клиента: пользователь, технический сценарий или сервисный агент. Вторая — от чьего имени MCP-сервер обращается к корпоративной системе. Для второй укажите тип учётной записи, набор прав, место безопасного хранения секрета, срок жизни и владельца. Не записывайте сами секреты или токены. Если transport — local stdio и секрет приходит из окружения, OAuth-профиль может не применяться, но вопрос не исчезает: откуда переменная, у какого процесса есть доступ, как её сменить и может ли она делать больше, чем нужен конкретный tool?
Метаданные защищённого ресурса помогают не угадывать авторизационный контур. В профиле HTTP MCP-сервер сообщает, где искать связанный сервер авторизации, через WWW-Authenticate или well-known URI; этот механизм опирается на RFC 9728. Для архитектора это значит: URL MCP и URL, который выпускает токен, фиксируются как два разных объекта. Их нельзя менять молча вместе с записью в DNS или настройкой прокси. У нового issuer, нового redirect URI, другого scope или другой audience должен быть свой шаг пересмотра паспорта.
Разделение идентичностей ещё и упрощает жизненный цикл. Если сотрудник потерял доступ к роли, достаточно завершить его клиентскую сессию. Если у MCP-сервера найдена ошибка, можно отозвать его сервисную учётную запись и остановить только этот маршрут. Если нижестоящая система сменила API, сервисный доступ обновляют в контролируемом тесте, не выпуская пользователям новые широкие токены. В каждой ситуации журнал должен позволить отличить: отказал пользователь, отказал клиент, сервер не прошёл собственную авторизацию или нижестоящая система запретила сервисную роль.
Паспорт MCP-интеграции
Паспорт — не длинная анкета ради согласования. Это небольшой артефакт, который позволяет воспроизвести решение и проверить его после обновления. Для одного сервера достаточно одной страницы, если она не скрывает существенное.
| Поле | Что зафиксировать | Проверяемый результат |
|---|---|---|
| Сервер и версия | URL или способ запуска, transport, версия, происхождение сборки | Известно, какую реализацию проверяли. |
| Назначение | Один рабочий сценарий и единица результата | Интеграция не превращается в общий «доступ к системе». |
| Tools | Полный список, статус read/write/необратимый, допустимые параметры | Лишний tool не получает доступ по умолчанию. |
| Данные | Класс данных, источник, объём, маскирование и запреты | Нет неявного доступа к чувствительным полям. |
| Права | Scope/роль, граница ресурса, лимит объёма и подтверждение | Полномочие соответствует действию. |
| Идентичности | Клиентская и сервисная учётная запись, без секретов | Токен и права можно отозвать раздельно. |
| Тест | Безопасный вход, ожидаемый результат, отрицательный сценарий | Допуск проверяется, а не предполагается. |
| Наблюдаемость | Кто, какой tool, параметры без секретов, результат, ошибка, корреляция | Расследование связывает вызов с процессом. |
| Пересмотр и отзыв | Дата, условие изменения, владелец и точный путь отключения | Доступ не остаётся бессрочным после обновления. |
Первый тест паспорта должен быть намеренно скучным. Создайте безопасный тестовый маршрут и проверьте разрешённый вызов с обезличенными данными. Потом сделайте отрицательный: вызов с недопустимым параметром, доступ к чужому объекту, попытку выполнить tool после отзыва или действие с недостаточным scope. Успех — не «сервер ответил 200», а ожидаемый бизнес-эффект произошёл только в разрешённой границе, а запрещённый не произошёл и оставил понятную запись в журнале.
Для маршрута записи добавьте проверку повторов. Сбой клиента или тайм-аут не доказывает, что нижестоящая операция не состоялась: модель или оркестратор могут повторить запрос. В паспорте укажите, поддерживает ли tool ключ идемпотентности, как читает итог предыдущего вызова и что возвращает при неопределённом состоянии. Если операция не умеет безопасно повторяться, она должна идти в человеческую очередь, а не запускаться автоматически «ещё раз». Это связывает контроль доступа с надёжностью процесса: право вызвать инструмент не равно праву создавать дубликаты.
Проверяйте результат на трёх уровнях. На уровне протокола сервер вернул корректно структурированный ответ или ошибку. На уровне системы действительно появился только разрешённый объект: один черновик, одна запись аудита, ни одного изменения чужого объекта. На уровне процесса владелец может сказать, что результат пригоден и не скрывает исключение. Так технический тест не превращается в локальную проверку JSON, а бизнес-приёмка не превращается в доверие к красивому ответу модели.
Отдельно проверьте версию. Изменение схемы входа, описания, нового tool, транспорта, авторизационного сервера, нижестоящей роли или класса данных — основание для повторного просмотра паспорта. Это не бюрократия. Даже аккуратное обновление может расширить поверхность: новый инструмент станет виден модели раньше, чем команда заметит его в демонстрации.
Журнал и отзыв: что выдержит понедельник
Когда всё работает, журнал кажется лишней стоимостью. В понедельник он становится ответом на простые вопросы: кто инициировал вызов, какой tool выбрали, с какими безопасно нормализованными параметрами, к какому ресурсу обращались, что вернул сервер и какой нижестоящий эффект произошёл. Не нужно сохранять в логах секреты, полные токены, лишнее содержимое документов или персональные данные. Нужно сохранить корреляцию, которая позволяет найти решение без догадок.
Отзыв стоит проектировать до первого пилота. У него как минимум три независимых уровня: исключить сервер из конфигурации клиента, отключить или сузить его OAuth/сервисное полномочие и остановить сетевой маршрут, если он есть. Владелец паспорта должен знать, какой уровень выключить при подозрительном вызове и как проверить, что новый вызов действительно отклонён. Если отзыв требует ночной заявки неизвестной команде, формально он существует, но эксплуатационно не готов.
У отзыва есть и порядок. Сначала остановите возможность новых вызовов там, где она наиболее надёжно контролируется: клиентский allowlist или policy gateway. Затем отзовите сервисное полномочие, чтобы уже открытая сессия сервера не могла обратиться к корпоративной системе. После этого сохраните корреляционные записи и разберите уже выполненные эффекты: какие данные были возвращены, какие черновики или изменения появились, кому нужно сообщить. Не следует стирать журналы в момент отзыва: тогда исчезает доказательство, по которому можно понять масштаб. При подтверждённом инциденте запускают внутренний процесс реагирования, а не продолжают редактировать паспорт как обычную конфигурацию.
Минимальный мониторинг может быть компактным: счётчик вызовов по tool, процент отказов авторизации, число подтверждённых и отменённых опасных действий, объём возвращённых записей, изменения списка tools и даты ближайшего пересмотра. Эти сигналы не доказывают безопасность сами по себе. Зато они помогают увидеть изменение поведения до того, как оно станет привычной частью процесса. Порог не обязан быть универсальным: у поиска базы знаний и у выдачи платёжного документа разная нормальная частота и разная цена ошибки.
Чего паспорт не заменяет
Паспорт MCP-интеграции полезен, потому что удерживает узкую границу. Его опасно превращать в папку, которая якобы закрывает все риски. Он не заменяет проверку происхождения пакета или контейнера: для внешнего сервера остаются зависимости, уязвимости, лицензии, порядок обновления и репутационная проверка поставщика. Он не заменяет модель угроз: та объясняет, кто способен подменить конфигурацию, заставить модель выбрать опасный tool, украсть секрет или использовать легитимный инструмент не по назначению. Он не заменяет договор и оценку обработки данных: техническая возможность прочитать поле не доказывает право его обрабатывать.
Зато паспорт даёт этим проверкам место для результата. В строке происхождения появляется ссылка на конкретную сборку и её владельца. В строке данных — решение владельца набора или ограничение представления. В строке теста — сценарий, который подтверждает важную гипотезу модели угроз. В строке отзыва — контакт и порядок действий из процесса реагирования. Такой артефакт не отменяет специалистов, а помогает им говорить об одном объекте, а не о расплывчатом «ИИ с доступом».
Не стоит также считать паспорт инструментом оценки самой модели. Модель может неверно понять задачу, быть подвержена prompt injection, выбрать не тот tool или сформировать некорректный параметр. Сужение tool и параметров уменьшает последствия, но не делает ответ умным или корректным. Для критичного процесса остаются тестовая выборка, правила валидации на сервере, возможность отказа, human-in-the-loop и контроль бизнес-результата. Если бизнес-правило нельзя проверить после вызова, его нельзя безопасно делегировать только потому, что tool имеет хорошее описание.
Есть и обратная ошибка — заполнять паспорт настолько подробно, что его никто не способен пересмотреть. Если для read-only поиска понадобились десятки страниц, вернитесь к единице результата. Возможно, сценарий всё ещё включает разные данные или действия и его нужно разделить. Хороший паспорт короток не потому, что в нём нет ограничений, а потому, что граница сформулирована достаточно чётко, чтобы каждое поле можно было проверить. В этом смысле компактность — следствие архитектурной ясности, а не требование сократить документ.
Для пилота полезно зафиксировать и условие успеха. Не «агент смог подключиться», а «оператор получил правильный статус по разрешённой записи, запрещённый идентификатор не вернул сведения, событие видно в журнале, а после отзыва вызов остановился до системы». Это четыре разных наблюдения. Если одно отсутствует, команда не должна закрывать вопрос общим скриншотом успешного ответа. Такой пилот может завершиться решением не подключать сервер — и это тоже ценный результат, принятый до того, как неограниченный доступ стал частью рабочего дня.
Паспорт также помогает подготовить спокойный разговор о расширении. Когда бизнес просит «добавьте ещё одну функцию», не нужно заново спорить о ценности MCP. Откройте существующую запись и спросите: новый tool читает тот же класс данных или другой; у него есть необратимый эффект; меняется ли сервисная роль; какой отрицательный тест добавится; кто станет владельцем решения; можно ли снять доступ независимо от остальных функций? Если ответы совпадают с прежней границей, изменение может быть небольшим. Если нет, это новая интеграционная единица с отдельным риском, а не невидимая строчка в обновлении.
Так же стоит относиться к удобным обобщениям вроде «у нас есть только read access» или «это внутренний сервер». Первое не указывает объём и чувствительность данных, второе не описывает цепочку зависимостей и право сервиса действовать от имени пользователя. Доказуемый доступ всегда выражается конкретнее: ограниченное представление, конкретный параметр, определённое время жизни, один проверяемый эффект и известный владелец. Эта детализация не замедляет зрелую архитектуру; она даёт ей возможность менять части системы без того, чтобы одна интеграция незаметно получила полномочия другой.
Именно так техническое удобство остаётся управляемой частью реального процесса, а не скрытым исключением.
Полезно добавить срок пересмотра и событие пересмотра. Короткий пилот можно проверить через неделю; стабильный read-only маршрут — по внутреннему циклу доступа. Вне расписания пересмотр запускают новая версия, добавленный tool, изменение данных, новый получатель результата, инцидент или смена владельца. Список событий важнее красивой даты: он соединяет изменения в коде с изменениями в разрешении.
Как принять решение без ложной универсальности
Начните с одного сервера и одного полезного сценария. Не собирайте «единый корпоративный MCP» до того, как увидели работу паспорта. Откройте фактический список tools, отметьте те, которых нет в сценарии, и исключите их. Для каждого оставшегося инструмента назовите данные, параметры, нижестоящую учётную запись, ожидаемый результат и запрещённый результат. После этого становится видно, где нужен scope, где лимит, где человеческое подтверждение и где отказ.
Затем проверьте два маршрута: разрешённый и запрещённый. Разрешённый должен дать ровно нужный эффект в тестовом контуре. Запрещённый должен остановиться до эффекта и оставить доказательство причины: недостаточно прав, запрещённый параметр, отмена пользователем, отключённая учётная запись или отозванный server allowlist. Если команда не может описать запрещённый маршрут, она пока не знает собственную границу.
Ниже — короткий шаблон решения, который можно перенести в архитектурный реестр без секретов.
| Вопрос | Минимальная запись в паспорте | Пример проверки |
|---|---|---|
| Зачем нужен tool? | Один процесс и единица результата | Оператор видит статус одного заказа. |
| Что он делает? | read/write/необратимый и опасные параметры | status разрешён, произвольный фильтр запрещён. |
| Какие данные видит? | Класс, поля, лимит и маскирование | Не более одной записи без вложений. |
| От чьего имени? | Клиентская и сервисная идентичности | Входной токен не принимается нижестоящей системой. |
| Как подтвердить? | Требование human-in-the-loop | Отправка ждёт явного согласия. |
| Как проверить? | Разрешённый и запрещённый тест | После отзыва tool получает отказ до эффекта. |
| Как остановить? | Владелец и последовательность отзыва | Выключить allowlist, роль и маршрут. |
Такой паспорт не заставляет начинать каждый новый проект с нуля. Напротив, он создаёт повторяемую форму вопросов. Но готовый шаблон нельзя считать готовым разрешением. Каждая новая система, класс данных, набор tools и нижестоящая роль дают свой ответ. Когда поле в паспорте меняется, должен меняться и тест. Это важнее, чем поддерживать бесконечный список «одобренных» интеграций без даты и границы применения.
Наконец, назначьте владельца. Это не обязательно один технический администратор. У сценария может быть бизнес-владелец результата, у сервера — технический владелец, у данных — владелец ресурса, у доступа — IAM-функция. В паспорте важно не собрать все фамилии, а указать, кто принимает решение о расширении tool, кто подтверждает результат теста и кто имеет право немедленно отозвать допуск.
Тест понедельником: выберите один MCP-сервер, выгрузите его фактический список tools и заполните по одной строке на инструмент. В строке должны быть действие, данные, минимальное право, нижестоящая учётная запись, владелец, разрешённый тест, запрещённый тест и путь отзыва. Если хотя бы одно поле нельзя назвать, сервер ещё не готов к корпоративному агенту — даже если демонстрация уже получилась убедительной.
МCP полезен именно тогда, когда превращает повторяемую интеграцию в видимый контракт. Материал об ИИ-агентах для бизнеса помогает выбрать место агента в процессе; разбор контроля доступов ИИ-ассистента — не смешивать права человека и модели. А для операций, которым нужен повтор после сетевого сбоя, пригодятся принципы API-интеграций: сбоев, повторов и идемпотентности. НТА помогает связать эти границы в архитектуру и эксплуатационный процесс; подход команды описан на странице компании.
Важное уведомление
Материал носит информационный характер и не является индивидуальной консультацией, проектной документацией, инструкцией по внедрению или гарантией результата. Применимость описанных подходов зависит от процессов, систем, данных, требований безопасности и иных условий конкретной организации. Перед внедрением или изменением ИТ‑систем необходимо самостоятельно оценить риски и привлечь профильных специалистов.
«В понедельник утром в корпоративный агент обычно приходит не слово «MCP».»
