Галоўная / Артыкулы

Два спосабы, якімі ламаюцца MCP-серверы, і ахоўны ўзровень супраць іх

MCP-серверы падводзяць праз занадта шырокія токены і інструменты, сляпыя да задачы. Абмежаваныя токены, праверка аўдыторыі, ачышчаныя памылкі і ліміты інструментаў складаюць ахоўны ўзровень.

Выдавец: REACTAPP.TOP8 хв чытання1896 слоў

Крыніцы: MCP Servers Fail in Two Ways, and Both Are Preventable. Here’s the Guardrail Layer.

Большая частка сервераў MCP не выключаецца з-за збою. Яны выключаюцца таму, што надаюць большую доверлівасць, ніж таго трэба для выканання задачы, і гэта відбываецца ў двух аспектах: у правілах дазволаў, якія яны выдаюць, і ў інтэрфейсе, які яны адкрываюць. Болей розумны мадэль гэта не паспрацюе. Але шар захісту, які знаходзіцца між агентам і інструментам, гэта зробіць, і ніжэйшыя часткі пакажуць, што такі шар мае, разам з кодам.

Чыстка, якой ніхто не прасіў

Пользоватэль прасіў агента скопіюваць базу дадзеных для працы ў рэальных умовах у срэду падготовкі. Выкананняя просьбы, агент вірашыў, што чыстка будзе корыстна, і спачатку выдаліў дзеякі стары тэстовы дадзеныя. Ніхто гэтага не прасіў. Калі сервер MCP перадае власныя аўтэнтыфікацыйныя даны карыстальніка, а гэты пользоватэль мае правы адміністратара, выдаленне дадзеных адбываецца, і база дадзеных для працы знікае.

AWS прыводзіць самэ гэты сцэнарый у сваіх рэкамендаціях па кераванню MCP, адказваючы на пытанне, чаму не можна прыхіліцца да спецыяльных токенаў.

Сервер — граніца доверы

Людзі зазвычай апісваюць сервер MCP так сама, як і будзь-які засобы інтэграцыі: як што-то, што спаўнае звязак між агентам і сістэмай, пры чым выкладаюцца калькі інструментаў і задача выканана. Насправдзе ж гэта тое месца, дзе рашэнне модэлю пра дзеянне стае справжнім парадуксам, выкарыстоўваючы рэальную інфраструктуру і рэальныя кранты. Усі крокі до гэтага моменту — толькі логічныя выводы. Сервер — гэта тое месца, дзе логічныя выводы маюць наследкі.

Таму сервер ёсць граніцай доверы, незалежна ад таго, чы рэшана яго такім чынам чы ні. Аднойчы паглядзіце на серверы, якія выкорыстоўваюцца у працэсе, праз гэты прызмат, і ўсія іхія памылкі падзеліцца на два групы.

Клас памылак адзін: занадта большыя правыя

Справа з базайнамі дадзеных — гэта загальны случай. У керавання AWS наводзіцца рэшэння: кожны вызов на выходзе павінен несаць токен, які спецыяльна стварыўся для гэтага вызову і мае адпаведны дыяпазон, а не кранты, якія былі вікорыстаны для запуску агента. Таксама працоўнае падтверджэння токена павінна быць пераканана, чым утрымваецца можлівасць перыгравання токена, створанага для аднаго сервера MCP, на іншым.

Мало команд робіць гэта з самага пачатку, адколькі для гэтага трэба больш налаштавання, чым проста перадача токена вызываючага. Аднак самэ гэта і ёсць розніцэю між вызамам інструмента, які неяксцяшна працюе, але безпечна парадуеся, і тым, які насправды прабывае выконвацца ў працоўнай сітцы.

Тып неяксцяшэння два: паслаблены інтэрфейс

Другая група проблем ўскладненая. Не выклікаецца ніякіх драматычных інцыдэтаў. Надзеянасць пра працэздатнасць паступова зменшваецца, а ўсталяванне прычыны гэтага ўскладнена. Кераванне развіццем Azure MCP ад Microsoft выявляе асновную прычыну: серверы праектуюцца як REST API-і, пры чым кожная операцыя выклікаецца як окрэмы інструмент, хоць праектаванне павінна быць адпрацоўванае так, каб адпавядаць таму, чаго хоча праграма. Ілюстрацыя чытра ілуструе гэты момент. Уместо чатырох інструментаў пад назвамі create_ticket, add_comment, assign_ticket і notify_user, адны інструмент file_support_request внутршнім чынам выконвае ўсе чатыры крокі.

У кераванні паказаны ўсьмі ўжо два сімптамы такога прычынкі. Апісанні могу обяцваць тое, чаго інструмент не можа даць, таму агент павераецца тэкстам, які код ніколі не выпалняе. А паведамленні пра адказы могу быць бесполезнымі (“Адказка”) або занадта адкрываючымі інфармацыю: трэсы стэка, внутрэннія шляхі да файлоў, або падтверджэнне таго, што адпаведны корыстнік існуе ў вашай базе дадзеных, што сама па сабе дазволяе атакі на перыяктуванне.

Асіметрыя ў напрамку падозры

Паглядзіце, сколькі інжынерных зусілляў вкладаецца у фінальны адказ агента: верыфікацыя структураванага выходу, захоўнікі, павторныя спробы і крокі верыфікацыі. Выход модэлю спрацоўвання спрацоўваецца як падозрэлы, і гэта цэлкам праведна.

Цяпер розглянем слой вызоў інструментаў пад гэтым адпаведзеннем. Токен вызываючага праходзіць прымусова. Спіс інструментаў расшыраецца, пры чым ніхто не пераканальваецца, чы можа мадэль яшчэ працаваць з імі. Апісанне інструмента прыймаецца такім, які ён напісаны, і жадны тэст не паказвае, калі агент правільна вікорыстоўвае інструмент. Велічазныя зусілля вкладаюцца ў сумневанне ў тое, што кажэ мадэль, а майжэ жадных — у сумневанне ў тое, што яна робіць.

Гэтыя несбалансаваныя сумневы ёсць справжнім дзефектам у обох групах. Ні болей розумная логіка дазволаў, ні лепшыя назвы інструментаў самыя по сабе не зможуць гэта вылечыць. Патрэбны слой, які пераканальваецца кожным вызоў інструмента, а не толькі кожным адпаведзеннем мадэлі, прычым розглядаючы можнацьце даваць яй доверлівасць.

Стварэнне слоя

У даным случае елементам ёсць вызоў інструмента. Не дазволяйце необработанай запытцы дасягнуць бэкенду. Спачатку яе трэба абгорнуць.

from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import Optional

@dataclass
class ScopedToken:
 audience: str # which MCP server this token is valid for
 permissions: list[str] # e.g. ["read", "create"] - never assume "all"
 issued_at: datetime
 expires_at: datetime
 source_user: str # who originally triggered this, for audit

Кожна польна ў гэтым кэшэўным об’екце існуе для таго, каб наступны слой могаў адначасова ацэніць, насколькі можна даверыць вызову. Цяпер пераходзімо да элементаў керування.

Зафіксаваць дыяпазон токена пры запуске інструмента

Не вяртайцеся да крантэнацый, якія былі вікорыстаны для вызову, для паслядуючых дзеянь. Выдайце токен з вужэйшым дыяпазонам, які будзе стосавацца толькі таго, што плануе зрабіць інструмент.

def issue_scoped_token(user_token: ScopedToken, tool_name: str,
 required_permissions: list[str]) -> ScopedToken:
 # Never grant more than the tool declares it needs
 granted = [p for p in required_permissions if p in user_token.permissions]
 if set(required_permissions) - set(granted):
 raise PermissionError(
 f"{tool_name} requires {required_permissions}, "
 f"caller only has {user_token.permissions}"
 )
 return ScopedToken(
 audience=tool_name,
 permissions=granted,
 issued_at=datetime.utcnow(),
 expires_at=datetime.utcnow() + timedelta(minutes=5),
 source_user=user_token.source_user,
 )

Эта частка забезпечвае безпечную невыконанасць сцэнарыю базы дадзеных. Запрос, прызначаны толькі для чытання і стварэння, проста не можа выканаць апаведзенне, незалежна ад таго, калі гэта рашыў модэль.

Пераканаўцеся ў аудыэнцыі праз кожны вызов

Токен, створаны для аднаго інструмента, павінен быць адхілён усімі іншымі інструментамі.

def enforce_audience(token: ScopedToken, expected_tool: str) -> None:
 if token.audience != expected_tool:
 raise PermissionError(
 f"Token issued for '{token.audience}' cannot be used on '{expected_tool}'"
 )

Формавайце інструмент па заданнай задачы

Гэта выкарыстоўвае шаблон file_support_request з аднараджэнняў Azure:

def file_support_request(customer_email: str, issue_type: str, description: str) -> dict:
 ticket = create_ticket(issue_type, description)
 add_comment(ticket.id, f"Filed by {customer_email}")
 assign_ticket(ticket.id, team=route_by_type(issue_type))
 notify_user(customer_email, ticket.id)
 return {
 "ticket_id": ticket.id,
 "status": "open",
 "assigned_team": ticket.team,
 }

Адзін вызов несе адзін чысты намерунак, таму агенту ніколі не трэба самаму правільна выконваць чатыры операцыі.

Адчыстаць бягі прычын адзінакоў перад тым, як іх пакажаць агенту

Запісаць усі дакладныя даны на серверэ і даць агенту толькі тое, што яму патрэбна для вяснавання сітуацыі.

def safe_error(internal_message: str, request_id: str) -> dict:
 # internal_message goes to your logs, never to the model
 log.error(internal_message, extra={"request_id": request_id})
 return {
 "content": [{
 "type": "text",
 "text": f"Unable to complete the request. Request ID: {request_id}. "
 f"Try again or contact support."
 }],
 "isError": True,
 }

Абсалютныя меры для колькасці інструментаў на серверэ

Дазвольце вам знайсці гэты ліміт раней, чым гэта зрабіць працэс вырабоцтва. У кераванні Microsoft наводзіцца конкрэтная цыфра: не больш 10–15 інструментаў на аднам серверэ, распадзеленых па домэнах, і не трэба продаваляць колькасць інструментаў на аднам серверэ.

MAX_TOOLS_PER_SERVER = 15

def register_tool(server, tool):
 if len(server.tools) >= MAX_TOOLS_PER_SERVER:
 raise ValueError(
 f"{server.name} already has {len(server.tools)} tools. "
 f"Split into a domain-specific server instead of adding more."
 )
 server.tools.append(tool)

Тры якіясці для асэнтнага сервера

Ні адна з іх не вымагае перзбудовы.

Адзіравайце дыяхунок токена, а не толькі яго наявнасць. Абярожыце дзесяць апошніх вызоў інструменту і парабялейце правыя, якія мелі кожны токен, з тымі, якія былі патрэбны інструменту. Калі яны зазвычай разніцяюцца, значыць, распространяюцься токены, шырэйшыя, чым трэба, і гэта, верагацейна, ўсё, што зараз адбываецца.

Вырахавайце колькісць токенаў для вашага сабе інструменту. Рэкамендаціі AWS ацэнююць, што на апісанні адзінам толькі трэба 5,000–10,000 токенаў за кожны вызов, калі сервер мае больш чым 20 інструментаў. Парабялейце інструменты, якія у вас ёсць. Сервер, які значна перасіліў гэты ліміт, без фільтраў чы раздзелення, страждае ад перадмернага кантэксту, які ніякія змены модэля не зможаць выправіць.

Спробуйце тэст на рэвэле агента, які, верагацельна, яшчэ не адбываўся. Абразьце тры найбольш популярныя інструменты і паказваце, выкарыстоўваючы рэальнага агента, а не тэст на едыніцу, чы рэальна ён выбірае правільны варыянт з звычайнага запіту на натуральнай мове. Кераванне Microsoft апісвае гэты слой як той, які практычна всі працягваюць працягваць ігнараваць. Прыямленне тэстаў на едыніцу і протакола без адбыцьця гэтага тэста не дае можнасці з’ясаваць, чы інструменты функцыонуюць.

Як гэта адносіцца да іншага

Нічыя з гэтых мер не заменяе існуючую работу па абаве ненадзеямнасці, а працюе паўзу з яю. Токены з адзначаным дыяпазонам дзеяння следуюць таму ж прынцыпу, што і перакананне вхідных дадзеных на будзь-яй межы надзеямнасці. Ліміт колькасці інструментоў і дызайн, спрывязаны з заданням, адпавядаюць прынцыпам версіявання API і дызайну інтэрфейса, толькі ў тым сенсе, што даныя чытае модэль, а не чалавек-распрацоўшчык. Кожны сервер MCP — ўсё тое ж месца, дзе сістэма вырашае, насколькі можна даверыць вызывачу, таму ён таксама трэбуе той жа атрыбут увагі, як і іншыя.

Команды адмацоўваюць MCP, таму што ён дае агентам большыя можлівасці: адна стандартная дорага да рэальных сістэм у змену сотням індывідуальных інтэграцый. Проблема ў тым, што модэль выкананае пакліканне з паслабна адзначаным дыяпазонам дзеяння выкананае такім жа адданым чынам, як і тое, што мае чыста адзначаны дыяпазон, таму што ён не розумее розніцы. Толькі шар захавання розумее ёю.

Неспрацоўкі прав і проблемы інтэрфейсу выглядаюць некалякуюцымі: адныя стосуюцца доступу, а іншыя — дызайну. І тэ, і іншыя вынікаюць з аднаго неразумнага прыязду, што вызов інструмента заслуговае на довер'е, якога ніхто на самай працы не надаў. Большасць сістэм AI спрамоўваюць свою падозру на выходную частку. Частка вызоў інструмента таксама заслуговае на такую увагу.

Гэта заставляе задаць аднае пытанне кожнаму вікорыстоўванаму серверу MCP: што наразе заважае агенту дзеяць на падставе вызову, які несе занадто вялікае довер'е, і чы хтоць будзе паведамлены, як толькі гэта довер'е выйдзе за межы?

Швяжыя адказы

Што такое скоупінг токена MCP? Гэта значыць надаць кожнаму вызову інструмента свой сае, спецыяльны токен для гэтай мэты, а не перадаваць первісныя кранцыялі вызываючага. Рэкамендаціі AWS па управлінні рэкамендуюць гэта, каб халюцынацыі чы неняхучыя дзеянні не маглі успэсна выконвацца проста таму, што базовыя кранцыялі на тое дазволялі.

Сколькіх інструментаў павінен выкладзаць сервер MCP? У кераванні Azure як правіло прызначаецца 10–15 інструментаў, пасля чаго сервера следуе раздзеляць па доменах. Праз гэта агенты значна рэдзей выбіраюць правы інструмент, а кераванні AWS паказвае, што для довгага спіску інструментаў косцт вырашаецца 5 000–10 000 токенав на кожны вызов толькі для апісаў, калі іх більш 20.

Якія ёсць разлікі між дызайнам інструментаў, орыўнтаваным на задачы, і дызайном сістэмных API? Дызайн сістэмных API прыменяе кожную операцыю бэкенду як окрэмы інструмент, на кшталт REST API. Дызайн, орыўнтаваны на задачы, прыменяе тое, што пашукае корыстнік, як адзін інструмент, які внутршняя адбывае всі неабходныя крокі. Прыкладам ад Microsoft ёсць адзін інструмент file_support_request замест чатырох операцый для обработкі заявок.

Чаму трэба санітазаваць паведамленні пра адзіях MCP? Следы выканання, внутрэнія шляхі або пазнакі пра наявнасць адзінаго рэкорда даюць зловерам дакледзі, якія яны не павінны атрымляць, што ўжо сама по сабе ёсць слабасцю. Безпечнейшы падход — запісваць усі дакледзі ў журналы сервера і вяртаць агенту толькі тое, што яму патрэбна для вяселення, а таксама ідэнтыфікатор карэляцыі.

Чы розпазнаюць ўніт-тэсты такія проблемы? Не розпазнаюць. Уніт-тэсты перакрываюць толькі логіку інструмента, а тэсты протакола — сарабітнасць з MCP, але жадны з іх не падтверджуе, што агент можа знайсці, выбраць і правільна выкарыстаць інструмент у рэальных умовах. Для гэтага патрэбны трэція роўень тэставання, які керуецца рэальным агентам, але большасць команд гэта працягвае ігнораваць.

Супаўязаныя матэрыялы

  • Перыяканне каліквіткі за токены MCP: два опісы інструментаў сталі прычынай ўзросту — Паўторны запуск дзевяці сервераў MCP працэсам 13 дзён паказаў, што калькіліквіткі інструментаў выраслі з 36 320 да 38 738 токенав, прычым практычна усё гэта сталася завяршэннем аднаго з сервераў, які перапісаў яе існуючыя апісанні. —