Перейти к основному содержимому
Продвинутый8 мин1275 слов

MCP form vs URL elicitation: как безопасно запрашивать данные пользователя

Практический выбор между form и URL elicitation в MCP: capability negotiation, чувствительные данные, сторонний OAuth, completion, защита от фишинга, тесты и rollout.

Содержание статьи
  1. 01Коротко: form собирает несекретные поля, URL изолирует чувствительное взаимодействие
  2. 02Capability negotiation определяет доступный UX до первого request
  3. 03Form mode требует минимальной схемы, preview и двойной валидации
  4. 04URL mode отделяет consent to navigate от завершения внешнего flow
  5. 05Third-party authorization нельзя путать с MCP client authorization
  6. 06Тестовая матрица проверяет privacy, association и recovery
  7. 07Rollout начинается с read-only form и одного allowlisted URL flow

Коротко: form собирает несекретные поля, URL изолирует чувствительное взаимодействие

Используйте form mode для небольшого набора несекретных структурированных ответов, которые пользователь может проверить и отправить в MCP client: имя окружения, формат отчёта, диапазон дат или подтверждение параметров. URL mode нужен, когда взаимодействие содержит пароль, API key, access token, платёжные данные или стороннюю авторизацию. Эти значения вводятся вне client и не возвращаются в ElicitResult content.

Elicitation не разрешает модели действовать и не заменяет authorization. Она лишь даёт server контролируемый способ запросить участие пользователя во время исходного request. После ответа server заново проверяет identity, scope, business policy и текущее состояние объекта. Если значение уже известно из authoritative system или вопрос не нужен для выполнения, не вызывайте elicitation: лишний prompt увеличивает friction и phishing surface.

  • Несекретные primitive fields → form mode.
  • Credentials, payment или внешний OAuth → URL mode.
  • Approval для consequential action → отдельный policy/approval gate, а не произвольное поле формы.
  • Client не объявил нужный mode → контролируемый fallback или отказ.
  • Authoritative value уже есть → прочитайте его из system of record.

Capability negotiation определяет доступный UX до первого request

Client объявляет elicitation capability во время initialization и поддерживаемые form и/или URL modes. Пустой elicitation object совместим с form-only поведением; server не должен считать его поддержкой URL. Храните session capability manifest вместе с negotiated protocol version и implementation version и перед elicitation/create проверяйте нужный mode. Название приложения или наличие кнопки в одном client не доказывает совместимость другого deployment.

Server-to-client elicitation должна быть связана с исходным client request, например tools/call или resources/read. Не создавайте отдельный канал unsolicited prompts. Router определяет requirement до запуска side effect: form-supported, URL-supported, no-elicitation fallback или blocked. Если workflow без URL mode не может безопасно получить credential, правильный fallback — setup link вне workflow или чёткий отказ, а не запрос секрета через text field.

Form mode требует минимальной схемы, preview и двойной валидации

Form request содержит понятное сообщение и restricted JSON Schema: плоский object с primitive properties. Ограничение полезно — оно сохраняет elicitation как короткое взаимодействие, а не скрытую платформу форм. Названия, descriptions, defaults, enum labels и required fields должны объяснять последствия ответа. Не вставляйте clickable URL в поля формы и не запрашивайте секреты, даже если schema технически принимает string.

Client позволяет пользователю просмотреть, изменить, accept, decline или cancel ответ и валидирует content по schema. Server повторяет schema и domain validation: range, tenant membership, object existence, current version и разрешённые transitions. Accept означает, что пользователь отправил значения; это не автоматическое одобрение следующего высокорискового действия. Decline завершает request без скрытого default, а cancel нельзя трактовать как отрицательное business decision.

  • Собирайте только поля, необходимые для текущего request.
  • Отделяйте schema validity от business authorization.
  • Не логируйте полный content без retention purpose и data classification.
  • После decline/cancel не повторяйте prompt в бесконечном agent loop.

Third-party authorization нельзя путать с MCP client authorization

MCP authorization защищает доступ client к MCP server. URL elicitation решает другую задачу: server просит пользователя подключить downstream service или выполнить secure out-of-band interaction. Bearer token между client и MCP server в этом flow не меняется. Не возвращайте downstream token через model context, tool result или form content; server хранит credential в управляемом vault и привязывает его к проверенным identity и scope.

Connect URL должен противостоять phishing relay. Server проверяет, что browser user — тот же authoritative subject, для которого создана elicitation, а не доверяет email или имени из query parameter. State/nonce одноразовый, короткоживущий и привязан к provider и redirect target. Callback проверяет issuer, audience, state и разрешённый redirect URI. Повторное открытие, смена пользователя или просроченный record завершаются без credential attachment.

  • MCP token → client-to-server access.
  • Downstream grant → server-to-third-party access для конкретного user/tenant.
  • elicitationId → correlation handle, не доказательство identity или completion.
  • Browser session + verified subject → authoritative binding.

Тестовая матрица проверяет privacy, association и recovery

Contract tests покрывают initialization с form-only, URL-only, обоими modes и без elicitation; omitted mode как form; unsupported mode; accept, decline, cancel; schema rejection; unknown/duplicate completion ID и request association. URL cases проверяют, что client не prefetch-ит адрес, показывает host, требует consent и не возвращает external content в protocol result. Form cases блокируют password, token, API key и payment fixtures независимо от названия поля.

Security tests пытаются изменить elicitationId, tenant, provider, redirect, state и browser subject; повторить callback; использовать expired URL; подставить Punycode host; прочитать secret в logs или traces. Recovery tests теряют accept response, completion notification и originating retry. Assertions требуют idempotent resume: повторный tool request сначала reconciles elicitation state и downstream connection, а не создаёт второй OAuth grant или payment.

  • Hard gate → secret в form, automatic navigation, identity mismatch или credential leakage.
  • Protocol gate → request без association или mode без capability.
  • Recovery gate → lost notification не должна создавать duplicate external effect.
  • UX gate → server, purpose, domain и decline/cancel понятны до consent.

Rollout начинается с read-only form и одного allowlisted URL flow

Сначала запустите form mode для reversible read-only workflow с двумя-тремя несекретными полями. Измеряйте completion, decline/cancel, validation failures, repeated prompts и time-to-resume без записи raw values в общую telemetry. Затем добавьте один URL flow к allowlisted HTTPS origin с pinned redirect policy, verified identity binding, expiry, replay protection, vault storage, audit evidence и kill switch.

Продвигайте canary только после contract, privacy, phishing, recovery и accessibility gates. Rollback блокирует новые elicitation requests, сохраняет reconciliation для in-flight records, отзывает незавершённые state handles и возвращает documented manual setup path. Retest нужен после изменения MCP revision, SDK/client, capability manifest, browser container, identity provider, downstream OAuth configuration или data classification. Verdict всегда относится к конкретной комбинации client-server-flow, а не к универсальной безопасности URL mode.

Практические примеры

Form для параметров read-only export

Tool не хватает формата и периода отчёта. Server запрашивает enum format и date range, client показывает preview, а server повторно проверяет range и tenant. Decline завершает export без side effect; форма не собирает credentials.

URL для подключения CRM

Server создаёт короткоживущий elicitation record и показывает allowlisted HTTPS URL. Browser user проходит third-party OAuth, callback проверяет subject и state, а token попадает напрямую в server vault. Client получает completion signal, но никогда не видит credential.

FAQ

Можно ли запрашивать API key через form elicitation?

Нет. Спецификация запрещает form mode для passwords, API keys, access tokens и платёжных credentials. Используйте URL mode с secure out-of-band flow.

Означает ли accept в URL mode, что OAuth завершён?

Нет. Это только согласие перейти по URL. Завершение подтверждает server-side flow; completion notification может уведомить client, но retry и reconciliation всё равно нужны.

Заменяет ли URL elicitation MCP authorization?

Нет. MCP authorization контролирует client-to-server access. URL elicitation может получить third-party grant для server без изменения bearer token клиента.

Что делать, если client поддерживает только form mode?

Не отправляйте URL request. Предложите безопасный manual setup path вне workflow, другой совместимый client или завершите операцию с явной ошибкой; не собирайте secret в form как fallback.

Связанные материалы

Источники

  1. Elicitation — MCP specification 2025-11-25первичный
  2. Lifecycle — MCP specification 2025-11-25первичный
  3. Authorization — MCP specification 2025-11-25первичный
  4. MCP 2025-11-25 changelogпервичный
  5. SEP-1036 — URL Mode Elicitationпервичный