Saltar al contenido principal
Avanzado9 min1609 palabras

MCP form vs URL elicitation: cómo solicitar datos del usuario de forma segura

Una elección práctica entre form y URL elicitation en MCP: capability negotiation, datos sensibles, OAuth de terceros, completion, controles anti-phishing, pruebas y rollout.

Contenido del artículo
  1. 01Respuesta corta: form recopila campos no secretos; URL aísla interacciones sensibles
  2. 02Capability negotiation determina la UX disponible antes del primer request
  3. 03Form mode necesita esquema mínimo, preview y validación en ambos lados
  4. 04URL mode separa el consentimiento para navegar de la finalización del flow externo
  5. 05La autorización de terceros no debe confundirse con la autorización del cliente MCP
  6. 06La matriz de pruebas valida privacidad, asociación y recuperación
  7. 07El rollout empieza con un form read-only y un URL flow allowlisted

Respuesta corta: form recopila campos no secretos; URL aísla interacciones sensibles

Usa form mode para un conjunto pequeño de respuestas estructuradas no secretas que el usuario pueda revisar y enviar en el cliente MCP: nombre del entorno, formato del informe, intervalo de fechas o confirmación de parámetros. URL mode es apropiado cuando la interacción incluye contraseña, API key, access token, datos de pago o autorización de terceros. Esos valores se introducen fuera del cliente y no se devuelven en el content de ElicitResult.

Elicitation no es permiso para que el modelo actúe y no sustituye authorization. Solo ofrece al servidor una forma controlada de solicitar participación del usuario durante un request de origen. Tras la respuesta, el servidor vuelve a comprobar identity, scope, business policy y estado actual del objeto. Si el sistema autoritativo ya conoce el valor o la pregunta no es necesaria para ejecutar la tarea, no uses elicitation: cada prompt adicional aumenta la fricción y la superficie de phishing.

  • Campos primitive no secretos → form mode.
  • Credentials, pago u OAuth externo → URL mode.
  • Aprobación de una acción con consecuencias → gate de policy/approval separado, no un campo arbitrario del formulario.
  • El cliente no anunció el modo requerido → fallback controlado o rechazo.
  • El valor autoritativo ya existe → léelo del system of record.

Capability negotiation determina la UX disponible antes del primer request

El cliente anuncia la capability de elicitation durante initialization y los modos form y/o URL soportados. Un objeto elicitation vacío es compatible con comportamiento form-only; el servidor no debe interpretarlo como soporte de URL. Guarda el manifest de capabilities de la sesión junto con las versiones negociadas del protocolo y de la implementación y comprueba el modo requerido antes de elicitation/create. El nombre de una aplicación o la presencia de un botón en un cliente no demuestra compatibilidad en otro deployment.

La elicitation server-to-client debe estar asociada con un request de cliente de origen, como tools/call o resources/read. No construyas un canal independiente para prompts no solicitados. El router determina el requisito antes de iniciar cualquier side effect: form-supported, URL-supported, fallback sin elicitation o blocked. Si un workflow no puede obtener una credential de forma segura sin URL mode, el fallback correcto es un enlace de setup fuera del workflow o un rechazo claro, no pedir el secreto en un campo de texto.

Form mode necesita esquema mínimo, preview y validación en ambos lados

Un form request contiene un mensaje legible y un JSON Schema restringido: un objeto plano con propiedades primitive. La limitación es útil porque mantiene elicitation como una interacción breve en lugar de convertirla en una plataforma de formularios oculta. Nombres, descripciones, defaults, etiquetas enum y campos required deben explicar la consecuencia de la respuesta. No insertes URLs clicables en campos del formulario ni solicites secretos aunque el schema pueda aceptar técnicamente un string.

El cliente permite al usuario revisar, editar, accept, decline o cancel la respuesta y valida el content contra el schema. El servidor repite la validación de schema y dominio: rango, pertenencia al tenant, existencia del objeto, versión actual y transitions permitidas. Accept significa que el usuario envió valores; no aprueba automáticamente una acción posterior de alto riesgo. Decline termina el request sin un default oculto y cancel no debe interpretarse como una decisión de negocio negativa.

  • Recopila solo los campos necesarios para el request actual.
  • Separa la validez del schema de la autorización de negocio.
  • No registres todo el content sin propósito de retención y data classification.
  • Tras decline o cancel, no repitas el prompt en un agent loop infinito.

URL mode separa el consentimiento para navegar de la finalización del flow externo

Un URL request contiene mode, message, una elicitationId opaca y una URL. El cliente muestra la dirección completa y destaca el dominio, solicita consentimiento explícito, no hace prefetch de metadata y abre el flow en un contexto de navegador seguro donde ni el cliente ni el LLM ven los datos introducidos. El servidor no coloca PII, credentials ni una bearer capability preautenticada en la URL. HTTPS es el baseline de producción; hosts Unicode o Punycode sospechosos requieren una policy de warning o bloqueo.

ElicitResult accept en URL mode solo significa que el usuario aceptó navegar a la dirección. No demuestra que OAuth, pago o configuración de credentials haya terminado. El servidor mantiene un state record separado por elicitationId, ligado al usuario autoritativo, contexto de cliente/sesión, provider previsto, expiry y nonce de un solo uso. Un callback server-side u otro sistema autoritativo confirma completion. Una notification elicitation/complete puede despertar al cliente, pero retry o cancel manual siguen disponibles si la notification se pierde.

La autorización de terceros no debe confundirse con la autorización del cliente MCP

MCP authorization protege el acceso del cliente al servidor MCP. URL elicitation resuelve otro problema: el servidor pide al usuario conectar un servicio downstream o completar una interacción out-of-band segura. El bearer token entre cliente y servidor MCP no cambia durante este flow. Nunca devuelvas un downstream token mediante model context, tool result o form content; el servidor guarda la credential en un vault administrado y la vincula a identity y scope verificados.

La URL de conexión debe resistir phishing relay. El servidor comprueba que el usuario del navegador sea el mismo subject autoritativo para el que se creó la elicitation, en vez de confiar en email o nombre de un query parameter. State y nonce son de un solo uso, corta duración y están ligados al provider y redirect target. El callback valida issuer, audience, state y redirect URI permitida. Reabrir, cambiar de usuario o usar un record expirado termina sin adjuntar una credential.

  • MCP token → acceso cliente-a-servidor.
  • Downstream grant → acceso servidor-a-tercero para un usuario o tenant concreto.
  • elicitationId → identificador de correlación, no prueba de identity ni completion.
  • Browser session + subject verificado → vinculación autoritativa.

La matriz de pruebas valida privacidad, asociación y recuperación

Los contract tests cubren initialization con form-only, URL-only, ambos modos y sin elicitation; modo omitido como form; modo no soportado; accept, decline y cancel; rechazo de schema; completion ID desconocido o duplicado; y asociación con el request. Los casos URL verifican que el cliente no haga prefetch de la dirección, muestre el host, exija consent y no devuelva contenido externo en el protocol result. Los casos form bloquean fixtures de password, token, API key y pago independientemente del nombre del campo.

Los security tests intentan cambiar elicitationId, tenant, provider, redirect, state y browser subject; repetir callback; usar URL expirada; sustituir un host Punycode; o leer un secreto en logs o traces. Los recovery tests pierden accept response, completion notification y originating retry. Las assertions exigen resume idempotente: un tool request repetido primero reconcilia elicitation state y downstream connection en vez de crear un segundo OAuth grant o pago.

  • Hard gate → secreto en form, navegación automática, identity mismatch o credential leakage.
  • Protocol gate → request sin association o modo sin capability.
  • Recovery gate → una notification perdida no debe crear un efecto externo duplicado.
  • UX gate → servidor, propósito, dominio y decline/cancel son claros antes del consent.

El rollout empieza con un form read-only y un URL flow allowlisted

Empieza con form mode para un workflow reversible read-only con dos o tres campos no secretos. Mide completion, decline/cancel, validation failures, prompts repetidos y time-to-resume sin guardar raw values en la telemetry general. Después añade un URL flow a un origen HTTPS allowlisted con redirect policy fijada, identity binding verificado, expiry, replay protection, almacenamiento en vault, audit evidence y kill switch.

Promueve el canary solo después de superar gates de contrato, privacidad, phishing, recovery y accesibilidad. Rollback bloquea nuevas elicitation requests, mantiene reconciliation para records in-flight, revoca state handles incompletos y restaura un manual setup path documentado. Repite las pruebas tras cambios de MCP revision, SDK/cliente, capability manifest, browser container, identity provider, configuración downstream OAuth o data classification. El veredicto siempre corresponde a una combinación concreta cliente-servidor-flow, no a una seguridad universal del URL mode.

Ejemplos prácticos

Form para parámetros de exportación read-only

Al tool le faltan el formato y el periodo del informe. El servidor solicita un formato enum y un intervalo de fechas, el cliente muestra una preview y el servidor vuelve a validar rango y tenant. Decline termina la exportación sin side effect; el formulario no recopila credentials.

URL para conectar un CRM

El servidor crea un elicitation record de corta duración y muestra una URL HTTPS allowlisted. El usuario del navegador completa OAuth de terceros, el callback verifica subject y state y el token va directamente al vault del servidor. El cliente recibe una señal de completion pero nunca ve la credential.

FAQ

¿Puede form elicitation solicitar una API key?

No. La especificación prohíbe form mode para passwords, API keys, access tokens y credenciales de pago. Usa URL mode con un flow out-of-band seguro.

¿Accept en URL mode significa que OAuth ha terminado?

No. Solo significa consentimiento para navegar a la URL. Un flow server-side confirma completion; una completion notification puede informar al cliente, pero retry y reconciliation siguen siendo necesarios.

¿URL elicitation sustituye MCP authorization?

No. MCP authorization controla el acceso cliente-a-servidor. URL elicitation puede obtener un grant de terceros para el servidor sin cambiar el bearer token del cliente.

¿Qué hacer si el cliente solo soporta form mode?

No envíes un URL request. Ofrece un manual setup path seguro fuera del workflow, otro cliente compatible o termina con un error claro; nunca recopiles el secreto en un form como fallback.

Materiales relacionados

Fuentes

  1. Elicitation — MCP specification 2025-11-25primaria
  2. Lifecycle — MCP specification 2025-11-25primaria
  3. Authorization — MCP specification 2025-11-25primaria
  4. MCP 2025-11-25 changelogprimaria
  5. SEP-1036 — URL Mode Elicitationprimaria