Sampling de MCP obsoleto: sampling frente a elicitation y qué usar ahora

El sampling de MCP quedó obsoleto el 2026-07-28 (SEP-2577), pero elicitation no. Este artículo compara ambos, explica el nuevo flujo de Multi Round-Trip Requests y muestra qué usar en lugar de sampling, con una lista de migración fechada para servidores.

Sampling de MCP obsoleto: sampling frente a elicitation y qué usar ahora
Cristian Da Conceicao
Fundador de Picasso IA

Si tu servidor MCP llama a sampling/createMessage, la especificación ahora te indica que dejes de construir sobre ello. El 2026-07-28 el Model Context Protocol dejó obsoleto Sampling (SEP-2577), junto con Roots y Logging. Elicitation, la función que mucha gente incluye en el mismo grupo, no quedó obsoleta. En su lugar, se rehizo sobre un nuevo mecanismo de entrega. Este artículo separa lo que desaparece de lo que se mantiene, con las fechas, los nombres de campos y las rutas de reemplazo que necesitas antes de tu próxima versión.

💡 Resumen rápido: Sampling está obsoleto, y la especificación indica que te integres directamente con las APIs de los proveedores de LLM. Elicitation sigue activo y ahora viaja a través de Multi Round-Trip Requests. Nada puede eliminarse antes de una revisión publicada en o después del 2027-07-28.

Un desarrollador frente a una pizarra blanca y luminosa llena de recuadros y flechas dibujados a mano, planificando un cambio en el protocolo MCP

Qué cambió el 2026-07-28

La revisión del 2026-07-28 reescribe la forma en que clientes y servidores se comunican, y la obsolescencia del sampling es una entrada más de una larga lista de cambios. Tres cambios son relevantes aquí:

  • Núcleo sin estado. El handshake initialize y la cabecera Mcp-Session-Id desaparecen. Cada solicitud lleva su versión del protocolo y las capacidades del cliente en _meta.
  • Multi Round-Trip Requests (MRTR). Un servidor ya no puede enviar sampling/createMessage ni elicitation/create por una conexión abierta. Devuelve un resultado provisional, y el cliente repite la llamada original con la respuesta adjunta.
  • Un registro de obsolescencia. Una nueva política de ciclo de vida define los estados Active, Deprecated y Removed, con un plazo mínimo de doce meses antes de que algo pueda eliminarse.

El primer cambio explica el segundo. Sin una sesión persistente no hay canal por el que enviar una solicitud, así que las solicitudes del servidor al cliente tuvieron que rediseñarse. El sampling se rediseñó y quedó obsoleto en la misma versión. Elicitation solo se rediseñó.

Qué está obsoleto, de un vistazo

FunciónEstadoReemplazoRetirada más temprana
SamplingObsoletoLlamar directamente a las APIs de los proveedores de LLMPrimera revisión en o después del 2027-07-28
RootsObsoletoParámetros de herramientas, URI de recursos o configuración del servidorPrimera revisión en o después del 2027-07-28
LoggingObsoletostderr para stdio, OpenTelemetry para observabilidadPrimera revisión en o después del 2027-07-28
Valores includeContext "thisServer" y "allServers"ObsoletosOmitir el campo o usar "none"No más tarde que Sampling
Dynamic Client RegistrationObsoletoClient ID Metadata DocumentsPrimera revisión en o después del 2027-07-28
ElicitationActivoSe mantiene, ahora entregado a través de MRTRSin programar

Qué significa "obsoleto" aquí

"Obsoleto" no es "eliminado". Durante el plazo, el comportamiento a nivel de protocolo no cambia, la negociación de capacidades sigue funcionando y las implementaciones existentes siguen funcionando. Las nuevas implementaciones no deberían adoptar la función, y las existentes deberían migrar. La retirada es una decisión de los Core Maintainers tomada durante la preparación de la versión, así que puede llegar después de la fecha más temprana. El SEP también pide que las implementaciones emitan una advertencia cada vez que se negocie una capacidad obsoleta, por eso los SDK han empezado a mostrar avisos de obsolescencia. Trata esas advertencias como tu lista de tareas pendientes.

⚠️ Trampa: La página de obsolescencia del SDK de Python indica que las llamadas antiguas de estilo sesión, como ctx.session.create_message(), siguen funcionando en sesiones negociadas el 2025-11-25 o antes. En una conexión del 2026-07-28 emiten una advertencia y después lanzan un error, porque ya no queda un canal de retorno por el que enviar.

Por qué se dejó obsoleto el sampling

SEP-2577 da tres razones. Se acumulan.

Un candado de latón desgastado en el pestillo oxidado de una vieja puerta de roble con gotas de lluvia sobre el metal

Demasiado pesado para la mayoría de los clientes

El sampling permite que un servidor pida al modelo del cliente que genere contenido. Hacerlo bien exige aprobación con una persona en el proceso, lógica de selección de modelo, gestión de seguridad y, desde SEP-1577, un bucle de herramientas. Es mucho que construir para una función que un servidor quizá nunca llame. El SEP señala que pocos clientes soportan sampling, a pesar de que está en la especificación desde la revisión de noviembre de 2024.

Una superficie de ataque amplia

El SEP califica el sampling como la más sensible en seguridad de las tres funciones obsoletas. Un servidor que consiga que el modelo del cliente ejecute sus prompts abre la puerta a la inyección de prompts y a la exfiltración de datos, así que todos los clientes tienen que acertar con las pantallas de revisión y los límites de frecuencia.

Las APIs directas dan más control

Un servidor que necesita un modelo puede llamar a un proveedor por su cuenta. Elige el modelo, fija los parámetros y transmite la salida. El argumento original del sampling era que los servidores no necesitaban credenciales propias. La contrapartida ahora es clara: tú tienes las credenciales, pagas la factura y decides qué pasa con los datos. Presupuesta reintentos, límites de frecuencia y un modelo de respaldo, porque ahora eso forma parte de tu operación y ya no de la del cliente.

Elicitation no quedó obsoleto

Una mujer en una mesa de cocina iluminada por el sol a punto de pulsar un botón de confirmación en una tableta que muestra un formulario sencillo

Revisa la prueba en la propia especificación. El registro de funciones obsoletas incluye Roots, Sampling, Logging, Dynamic Client Registration, los valores includeContext y HTTP+SSE. Elicitation no aparece en él. La página de elicitation no contiene ninguna advertencia de obsolescencia, y el changelog sitúa elicitation dentro de MRTR. Algunos artículos agrupan todas las funciones de servidor a cliente, así que consulta el registro antes de repetir esa afirmación.

Elicitation sí perdió dos detalles: la notificación de finalización fuera de banda y el campo elicitationId en el modo URL. Un servidor que debe asociar un reintento con una solicitud anterior ahora codifica su propio identificador dentro de requestState.

Modo formulario

El modo formulario recoge datos estructurados en banda, así que el cliente ve la respuesta. El requestedSchema es un objeto plano con propiedades primitivas únicamente:

  • cadenas, con formatos email, uri, date o date-time
  • números y enteros
  • booleanos
  • enumeraciones de selección única y de selección múltiple

Los objetos anidados y los arrays de objetos no están soportados a propósito. El usuario responde con una de tres acciones: accept con contenido, decline o cancel. Un servidor debe gestionar las tres, incluido ofrecer alternativas cuando alguien rechaza.

⚠️ Los servidores no deben pedir contraseñas, tokens de API, tokens de acceso ni datos de pago en el modo formulario.

Modo URL

El modo URL envía al usuario a una página fuera de banda, y los datos nunca pasan por el cliente. Es la vía para traspasos sensibles y OAuth de terceros. El cliente debe mostrar la URL completa, resaltar el dominio, pedir consentimiento y no precargar nunca la página. Una respuesta accept solo significa que el usuario aceptó abrirla. No significa que la interacción haya terminado.

Mi lectura de por qué sobrevivió: el sampling permite que un servidor se salte un trabajo que podría hacer él mismo llamando a un proveedor. Elicitation es la única vía hasta la persona. Las confirmaciones previas a borrar, publicar o pagar no tienen una API de proveedor a la que recurrir, así que eliminar la función dejaría a los servidores sin saber qué hacer.

Sampling frente a elicitation, lado a lado

Una vista aérea de un sendero en el bosque que se divide en dos en una bifurcación con señales de madera en blanco

PreguntaSamplingElicitation
¿Quién responde?El modelo del cliente, con una persona que puede rechazarloLa persona usuaria
Métodosampling/createMessageelicitation/create
Estado el 2026-07-28ObsoletoActivo
Forma del resultadoUn mensaje del modelo, posiblemente con bloques tool_useaccept, decline o cancel, más contenido
Entregado a través deinputRequests en un InputRequiredResultinputRequests en un InputRequiredResult
Ideal paraGeneración de texto en el servidorDecisiones, datos que faltan, traspasos sensibles
ReemplazoAPI del proveedor, o dejar que el modelo del host razoneNo hace falta

A menudo se dice que ambos son sustitutos, y no lo son. El sampling delega la generación de texto. Elicitation obtiene una respuesta de una persona. Sustituir una llamada de sampling del tipo "resume esta página" por un formulario sería una mala solución, porque el usuario nunca quiso escribir ese resumen. Ir en sentido contrario es igual de erróneo: usar la suposición de un modelo donde hace falta una decisión humana.

Toma como caso práctico un servidor de imágenes. Antes de gastar una generación, necesita un estilo y una luz verde. Ambas son decisiones humanas, así que usa elicitation. También quiere un prompt más rico que el que escribió el usuario. Reescribir es generación de texto, que antes era una llamada de sampling. Ahora el servidor llama a un proveedor por su cuenta, o la descripción de la herramienta indica al modelo del host que envíe un prompt más completo desde el principio.

En esta revisión ambos siguen usando el mismo mecanismo, porque cada uno aparece como una entrada dentro de inputRequests. La diferencia está en quién lee la entrada y en lo que la especificación dice sobre su vigencia.

Cómo funciona el nuevo ida y vuelta

Dos manos pasando un sobre crema sellado con lacre rojo sobre un mostrador de nogal

El flujo tiene cuatro pasos. El cliente llama a tools/call. El servidor devuelve un InputRequiredResult con resultType: "input_required". El cliente reúne la respuesta y repite la llamada original con inputResponses adjunto. Después, el servidor produce el resultado real. Como el reintento lleva todo lo que el servidor necesita, cualquier instancia detrás de un balanceador de carga puede gestionarlo.

Aquí está la respuesta provisional del servidor para una herramienta de imágenes que necesita una relación de aspecto:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "resultType": "input_required",
    "inputRequests": {
      "aspect": {
        "method": "elicitation/create",
        "params": {
          "mode": "form",
          "message": "Which aspect ratio should the image use?",
          "requestedSchema": {
            "type": "object",
            "properties": {
              "ratio": { "type": "string", "enum": ["16:9", "1:1", "9:16"] }
            },
            "required": ["ratio"]
          }
        }
      }
    },
    "requestState": "<signed blob>"
  }
}

Y el reintento del cliente, con la respuesta y el estado devuelto:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "generate_image",
    "arguments": { "prompt": "A foggy harbor at dawn" },
    "inputResponses": {
      "aspect": { "action": "accept", "content": { "ratio": "16:9" } }
    },
    "requestState": "<signed blob>"
  }
}

Los campos obligatorios de _meta (versión del protocolo, información del cliente, capacidades del cliente) se omiten aquí por brevedad. Fíjate en que el id de JSON-RPC cambia entre la solicitud original y el reintento, porque son solicitudes independientes.

Reglas para los clientes

  • Devuelve requestState exactamente tal cual. Nunca lo inspecciones, analices ni modifiques.
  • Si el resultado no tiene requestState, no envíes uno en el reintento.
  • Usa un nuevo id de JSON-RPC para el reintento.
  • Si no hay inputRequests, el cliente puede reintentar de inmediato.
  • Los campos afectan solo al reintento de esa solicitud, nunca a llamadas paralelas.

Reglas para los servidores

Trata requestState como una entrada controlada por un atacante, porque pasa por el cliente. Cuando influya en la autorización, en el acceso a recursos o en la lógica de negocio, protege su integridad con un HMAC o AEAD y rechaza cualquier cosa que no pase la verificación. Incluye el usuario autenticado, una caducidad corta y un identificador de la solicitud original dentro de la carga protegida. Estos datos limitan la reproducción, pero no hacen que un estado sea de un solo uso, así que aplica canjes de un solo uso en el servidor.

Hay dos restricciones más. Cada InputRequiredResult necesita al menos uno de inputRequests o requestState, y un servidor no debe enviar un tipo de solicitud que el cliente nunca declaró soportar. MRTR solo funciona con prompts/get, resources/read y tools/call.

Qué usar en lugar de sampling

Una mano conectando un cable ethernet azul directamente a un puerto de router en un armario de red ordenado

La respuesta de la especificación cabe en una línea: integrarse directamente con las APIs de los proveedores de LLM. En la práctica, el reemplazo correcto depende de por qué llamabas a sampling.

Lo que quería el servidorQué usar ahora
Reescribir, resumir o clasificar textoUna llamada a la API de un proveedor, o devolver los datos en bruto al modelo del host
Pedir al usuario que elija o confirmeElicitation en modo formulario
Entregar un secreto o ejecutar OAuthElicitation en modo URL
Leer rutas del espacio de trabajo (Roots)Argumentos de herramientas o URI de recursos
Enviar líneas de log al clientestderr o OpenTelemetry

Llamar directamente a la API de un proveedor

Cuando necesites generación de texto real, llama al proveedor desde el servidor. Compara los candidatos antes de incluir uno en tu código. En PicassoIA puedes probar Claude Sonnet 5, GPT 5.6 Terra y Gemini 3.5 Flash uno al lado del otro y ver cuál maneja mejor tus prompts a la velocidad que necesitas. Después guarda la credencial como un secreto normal del servidor, define un tiempo de espera y registra el uso de tokens.

Dejar que el modelo del host razone

Muchas llamadas de sampling nunca fueron necesarias. El resultado de una herramienta ya llega al modelo que llamó a la herramienta. Devuelve la página en bruto, una descripción clara y una estructura sensata, y el modelo del host hace el resumen sin una ida y vuelta extra y sin credenciales adicionales. Un servidor de documentación que antes usaba sampling para resumir un changelog largo puede devolver el changelog por secciones y dejar que el modelo que hace la llamada decida qué importa. Esta es mi propia recomendación, no texto de la especificación, pero elimina la mayoría de las llamadas.

Pedir a la persona las decisiones

Cuando lo que falta es una decisión, cambia a elicitation. En el SDK de Python, un artículo muestra el patrón con una elección afirmativa:

CONFIRM = ["cancel", "confirm"]
result = await ctx.elicit("Delete 42 drafts?", response_type=CONFIRM)

El mismo artículo advierte de que pasar response_type=None envía un esquema vacío, así que una aceptación automática es idéntica a una aprobación humana en el protocolo. Ofrece al usuario un valor real para elegir. Revisa la firma actual de tu SDK antes de copiarla.

💡 Regla práctica: si una persona tendría que decidir, usa elicitation. Si un modelo tendría que escribir, llama a un proveedor o deja que lo haga el modelo del host.

Lista de migración para servidores

Un técnico con un portapapeles con una lista de verificación en un pasillo de sala de servidores

  1. Encuentra cada llamada. Busca sampling/createMessage, create_message y cualquier comprobación de la capacidad de sampling.
  2. Clasifica cada llamada por su propósito. La generación de texto va a una API de proveedor o al modelo del host. Las decisiones van a elicitation. El contexto va a los argumentos de herramientas o a las URI de recursos.
  3. Elimina los valores includeContext. Quita "thisServer" y "allServers". Omite el campo o usa "none".
  4. Sustituye Roots y Logging. Pasa las rutas como parámetros de herramientas. Registra en stderr en stdio y usa OpenTelemetry en el resto.
  5. Devuelve InputRequiredResult. Sustituye las solicitudes iniciadas por el servidor por resultados provisionales y un requestState que firmes.
  6. Prueba con una conexión del 2026-07-28. Vigila las advertencias de obsolescencia del SDK y las llamadas antiguas de sesión que lanzan error.
  7. Mantén una ruta de compatibilidad. Los clientes con 2025-11-25 o anterior siguen usando el comportamiento antiguo durante el plazo.

Calendario que conviene seguir

FechaQué ocurre
2024-11Sampling entra en la especificación
2025-11-25Valores includeContext en obsolescencia blanda, se introduce elicitation en modo URL
2026-07-28Sampling, Roots y Logging quedan obsoletos, se introduce MRTR
2027-07-28Primera revisión en la que Sampling puede eliminarse

Tres errores que conviene evitar

  1. Tratar lo obsoleto como eliminado. Las sesiones antiguas siguen funcionando, pero las conexiones del 2026-07-28 rechazan las llamadas antiguas de estilo sesión. Sabe qué versiones sirves.
  2. Usar un formulario para un texto que debería escribir un modelo. Elicitation pide datos a una persona. No es una forma más barata de redactar textos.
  3. Saltarse la integridad del requestState. El estado sin firmar invita a manipular la lógica de tu servidor.

Reglas de revisión que se mantienen

Dos ingenieros revisando páginas impresas con un marcador fluorescente en una larga mesa de arce

La supervisión humana es la parte del sampling que se mantiene. Los clientes de elicitation deben mostrar qué servidor está preguntando, ofrecer opciones claras para rechazar y cancelar, y dejar que las personas revisen las respuestas del formulario antes de enviarlas. En el modo URL deben mostrar el dominio de destino y obtener consentimiento antes de abrir nada. Los servidores deben vincular cada elicitation a la identidad del usuario y verificar quién abre una URL, lo que bloquea el patrón de phishing en el que un atacante envía su propio enlace a una víctima.

Crea tus propias imágenes con Picasso IA

El escritorio de una creadora visto desde arriba con fotografías impresas de un lago de montaña y una tableta

El trabajo con protocolos es más fácil cuando puedes ver lo que estás construyendo. Si escribes un servidor MCP que genera imágenes, el patrón de elicitation descrito arriba encaja bien: pide una relación de aspecto o un estilo antes de gastar una generación.

En PicassoIA puedes probar los modelos detrás de ese tipo de herramienta: PicassoIA Image para texto a imagen, PicassoIA Image Editor Pro para ediciones, y GPT Image 2 si quieres otro resultado. PicassoIA también ofrece una API para desarrolladores al estilo de Replicate en https://api.picassoia.com/v1 y conexiones MCP, así que los mismos generadores pueden funcionar detrás de tus propias herramientas. Consulta los límites actuales en su página de API antes de planificar en torno a ellos.

Abre Picasso IA, escribe un prompt y genera tu primera imagen. Después repítelo con una relación de aspecto distinta y compara los dos resultados. Ese pequeño ciclo es el mismo patrón de solicitud, respuesta y reintento que describe este artículo, con píxeles al final.

Compartir este artículo

Elige tu idioma