

# Utilice la elicitación con su AgentCore puerta de enlace
<a name="gateway-mcp-elicitation"></a>

La elicitación es una función de MCP que permite a un servidor de MCP solicitar información adicional al cliente durante una llamada de herramienta. Cuando una herramienta necesita la confirmación del usuario, la autenticación o una entrada adicional para continuar, el servidor envía una solicitud de obtención de información al cliente. AgentCore Gateway reenvía las solicitudes de obtención de datos de los servidores MCP a sus clientes y las reemplaza por un identificador generado por la pasarela. `id`

## Requisitos previos
<a name="gateway-mcp-elicitation-prereqs"></a>

Para utilizar la elicitación con su pasarela, debe tener:
+  **Sesiones habilitadas**: la elicitación requiere soporte de sesión. Consulte [Usar sesiones de MCP con su](gateway-sessions.md) puerta de enlace.
+  **Transmisión de respuestas habilitada**: las solicitudes de obtención de información se envían como fragmentos de Server-Sent eventos (SSE) durante una conexión abierta. Se configura `true` en `streamingConfiguration.enableResponseStreaming` la puerta de enlace. `protocolConfiguration.mcp`
+  **Tipo de destino del servidor MCP**: la elicitación solo se admite en los destinos del servidor MCP. La obtención se origina en el servidor MCP y se reenvía al cliente a través de la puerta de enlace.
+  **El cliente declara su capacidad de elicitación**: el cliente debe declarar su apoyo a la elicitación durante la `initialize` solicitud para que la pasarela reenvíe las solicitudes de elicitación.

## Modos de elicitación compatibles
<a name="gateway-mcp-elicitation-modes"></a>

AgentCore Gateway admite tres modos de obtención definidos por la especificación MCP:


| Mode | Description (Descripción) | 
| --- | --- | 
|  **Modo de formulario**  | El servidor envía un formulario estructurado con campos para que el cliente los complete. Se utiliza para recopilar las confirmaciones, las preferencias o los datos de entrada de los usuarios. La solicitud permanece abierta mientras espera la respuesta. | 
|  **Modo URL (basado en solicitudes)**  | El servidor envía una URL que el usuario debe visitar para completar una acción (normalmente la autenticación). La solicitud permanece abierta mientras espera a que se complete la acción. | 
|  **Modo URL (basado en excepciones)**  | El servidor lanza un mensaje `URLElicitationRequiredError` que contiene una URL. La solicitud se cierra, el usuario completa la acción en la URL y el cliente vuelve a intentar la llamada a la herramienta original. | 

## Negociación de capacidades
<a name="gateway-mcp-elicitation-capability"></a>

La puerta de enlace solo declara el soporte de elicitación a un servidor MCP de destino si:

1. El **cliente declaró su apoyo** a la elicitación durante. `initialize`

1. La **versión del protocolo MCP** admite el modo de obtención: el `form` modo requiere una versión `2025-03-26` o posterior, los `url` modos requieren una versión `2025-11-25` o posterior.

1. La puerta de enlace coincide con las capacidades de obtención específicas declaradas por el cliente (formulario, URL o ambos).

## Modo de formulario: flujo de elicitación
<a name="gateway-mcp-elicitation-form-flow"></a>

1. El cliente envía una `tools/call` solicitud con el `Mcp-Session-Id` encabezado.

1. Gateway reenvía la llamada a la herramienta al servidor MCP de destino.

1. El objetivo abre una transmisión SSE y envía una `elicitation/create` solicitud como primer evento.

1. Gateway reenvía la `elicitation/create` solicitud al cliente en la transmisión SSE y reemplaza la solicitud`id`.

1. El cliente presenta el formulario al usuario y recopila la respuesta.

1. El cliente envía una nueva solicitud con la respuesta de provocación (acción: `accept` o`decline`) utilizando la misma`Mcp-Session-Id`.

1. Gateway reenvía la respuesta al servidor MCP de destino.

1. El objetivo reconoce con HTTP 202 Accepted.

1. El objetivo completa la llamada a la herramienta y envía el resultado final a la transmisión SSE original.

1. Gateway reenvía el resultado final al cliente y cierra la transmisión.

## Flujo de elicitación en modo URL (basado en excepciones)
<a name="gateway-mcp-elicitation-url-exception-flow"></a>

1. El cliente envía una `tools/call` solicitud con el encabezado. `Mcp-Session-Id`

1. Gateway reenvía la llamada a la herramienta al servidor MCP de destino.

1. El objetivo muestra un `URLElicitationRequiredError` JSON-RPC error que contiene la URL y un identificador de obtención.

1. Gateway la reenvía `URLElicitationRequiredError` al cliente y reemplaza la solicitud. `id`

1. El cliente redirige al usuario a la URL proporcionada para completar la acción (normalmente, la autenticación OAuth).

1. Una vez que el usuario completa la acción, el cliente vuelve a intentar la solicitud original. `tools/call`

1. Gateway reenvía el reintento al objetivo. El objetivo completa la llamada a la herramienta desde que se obtuvo la URL.

1. Gateway reenvía el resultado final de la herramienta al cliente.

## Llamadas de herramientas paralelas con notificaciones
<a name="gateway-mcp-elicitation-parallel"></a>

Un cliente puede iniciar varias `tools/call` solicitudes en la misma sesión, incluso cuando hay una solicitud pendiente. Cada elicitación es rastreada de forma independiente por su. `id` Al enviar una respuesta de elicitación, el cliente debe incluir en la solicitud la misma `id` que envió la pasarela. `elicitation/create`

## Guía para los desarrolladores de servidores MCP Target
<a name="gateway-mcp-elicitation-server-guidance"></a>

**importante**  
Los destinos del servidor MCP que envían solicitudes de elicitación **deben agrupar** las llamadas de elicitación en bloques try-catch y gestionar el caso en el que el cliente no admita la elicitación. Si el cliente de la puerta de enlace no declaró la capacidad de elicitación, la puerta de enlace no la declara al objetivo. Si el objetivo envía una activación de todos modos, la puerta de enlace devuelve un error `-32601` (método no encontrado) al objetivo.  
Los servidores deben implementar una ruta alternativa (por ejemplo, usar valores predeterminados u omitir la operación) cuando la elicitación no esté disponible.

## Gestión de errores
<a name="gateway-mcp-elicitation-errors"></a>


| Escenario | Error | Description (Descripción) | 
| --- | --- | --- | 
| El cliente envía una respuesta de elicitación cuando no hay ninguna elicitación pendiente | JSON-RPC `-32600`(Solicitud no válida) | No se encontró ninguna elicitación coincidente para esta sesión. | 
| El cliente envía una respuesta de elicitación con una `id` que no coincide con una elicitación pendiente | JSON-RPC `-32600`(Solicitud no válida) | `id`Debe coincidir con el enviado por la pasarela en la `elicitation/create` solicitud. | 
| Se interrumpe la conexión entre la puerta de enlace y el servidor MCP de destino | JSON-RPC error con DependencyFailedException | El cliente debe volver a intentar la solicitud de llamada a la herramienta original. | 
| Se interrumpe la conexión entre el cliente y la puerta de enlace | N/A | Se ha eliminado la solicitud pendiente. El cliente debe volver a intentar la llamada a la herramienta. | 
| El servidor MCP envía la solicitud, pero la puerta de enlace no declaró su compatibilidad | JSON-RPC `-32601`(No se encontró el método) | Regresó al destino del servidor MCP. Consulte [Solución de problemas](#gateway-mcp-elicitation-troubleshooting) | 

## Resolución de problemas
<a name="gateway-mcp-elicitation-troubleshooting"></a>

 **Error: «Error al llamar a la herramienta 'sample\_tool': no se ha encontrado el método:» elicitation/create** 

Este error se produce cuando un servidor MCP objetivo envía una solicitud de elicitación, pero el cliente de la pasarela no declaró la capacidad de elicitación en ese momento. `initialize` La puerta de enlace devuelve un error `-32601` (método no encontrado) al destino, y el objetivo puede devolverlo como un error de ejecución de la herramienta al cliente.

Para resolverlo:
+  **Si es el desarrollador del servidor MCP**: añada la gestión de errores a sus llamadas de captación. Implemente una ruta alternativa cuando no se admita la elicitación:

  ```
  try:
      result = await context.session.create_elicitation(
          message="Confirm this action?",
          requested_schema={"type": "object", "properties": {"confirm": {"type": "boolean"}}}
      )
  except Exception as e:
      # Fallback when client doesn't support elicitation
      logger.warning(f"Elicitation not supported: {e}")
      result = default_action()
  ```
+  **Si usted es el desarrollador del cliente de pasarela**: asegúrese de que su cliente declare la capacidad de elicitación durante: `initialize`

  ```
  {
    "capabilities": {
      "elicitation": {
        "form": {},
        "url": {}
      }
    }
  }
  ```

## Ejemplos de código
<a name="gateway-mcp-elicitation-examples"></a>

### Ejemplo de modo formulario
<a name="gateway-mcp-elicitation-examples-form"></a>

En el modo formulario, el servidor envía un esquema estructurado para que el cliente lo rellene. La solicitud permanece abierta mientras espera la respuesta.

**Example**  

1. 

   ```
   import requests
   import json
   import sseclient
   
   gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"
   headers = {
       "Content-Type": "application/json",
       "Accept": "text/event-stream",
       "Authorization": "Bearer YOUR_ACCESS_TOKEN"
   }
   
   # Step 1: Initialize with elicitation capability
   init_response = requests.post(gateway_url, headers=headers, json={
       "jsonrpc": "2.0",
       "id": "init-request",
       "method": "initialize",
       "params": {
           "protocolVersion": "2025-06-18",
           "capabilities": {"elicitation": {"form": {}, "url": {}}},
           "clientInfo": {"name": "my-agent", "version": "1.0.0"}
       }
   })
   session_id = init_response.headers["Mcp-Session-Id"]
   headers["Mcp-Session-Id"] = session_id
   
   # Step 2: Call tool (streaming response)
   response = requests.post(gateway_url, headers=headers, json={
       "jsonrpc": "2.0",
       "id": "tool-call-1",
       "method": "tools/call",
       "params": {
           "name": "use_aws",
           "arguments": {"command": "aws s3 rm s3://my-bucket/important-file"}
       }
   }, stream=True)
   
   # Step 3: Process SSE events
   client = sseclient.SSEClient(response)
   for event in client.events():
       data = json.loads(event.data)
       if data.get("method") == "elicitation/create":
           elicitation_id = data["id"]
           print(f"Form elicitation received: {data['params']['message']}")
   
           # Step 4: Send elicitation response
           requests.post(gateway_url, headers=headers, json={
               "jsonrpc": "2.0",
               "id": elicitation_id,
               "result": {"action": "accept", "content": {"confirm": True}}
           })
       elif "result" in data:
           print(f"Tool result: {data['result']}")
           break
   ```

1. 

   ```
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   import asyncio
   
   async def elicitation_handler(request):
       """Handle form elicitation requests from the server."""
       print(f"Elicitation: {request.params.message}")
       return {"action": "accept", "content": {"confirm": True}}
   
   async def use_elicitation(url, token):
       headers = {"Authorization": f"Bearer {token}"}
   
       async with streamablehttp_client(url=url, headers=headers) as (
           read_stream, write_stream, _
       ):
           async with ClientSession(
               read_stream, write_stream,
               elicitation_handler=elicitation_handler
           ) as session:
               await session.initialize()
               result = await session.call_tool(
                   name="use_aws",
                   arguments={"command": "aws s3 rm s3://my-bucket/important-file"}
               )
               print(f"Tool result: {result}")
               return result
   
   asyncio.run(use_elicitation(
       url="https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp",
       token="YOUR_ACCESS_TOKEN"
   ))
   ```

1. 

   ```
   from mcp.client.streamable_http import streamablehttp_client
   from mcp.types import ElicitResult
   from strands import Agent
   from strands.tools.mcp import MCPClient
   
   mcp_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"
   access_token = "YOUR_ACCESS_TOKEN"
   
   async def elicitation_callback(context, params):
       """Handle form elicitation requests from the MCP server target."""
       print(f"Elicitation: {params.message}")
       user_response = get_user_input(params)  # Your UI logic
       return ElicitResult(action="accept", content=user_response)
   
   mcp_client = MCPClient(
       lambda: streamablehttp_client(
           mcp_url, headers={"Authorization": f"Bearer {access_token}"}
       ),
       elicitation_callback=elicitation_callback,
   )
   
   with mcp_client:
       agent = Agent(tools=mcp_client.list_tools_sync())
       response = agent("Delete the file s3://my-bucket/important-file using AWS CLI")
       print(response)
   ```

1. 

   ```
   from langchain_mcp_adapters.client import MultiServerMCPClient
   from langchain_mcp_adapters.callbacks import Callbacks, CallbackContext
   from langchain.agents import create_agent
   from mcp.shared.context import RequestContext
   from mcp.types import ElicitRequestParams, ElicitResult
   
   async def on_elicitation(
       mcp_context: RequestContext,
       params: ElicitRequestParams,
       context: CallbackContext,
   ) -> ElicitResult:
       """Handle elicitation requests from MCP servers."""
       print(f"[{context.server_name}] Elicitation: {params.message}")
       # Prompt user for input based on params.requestedSchema
       return ElicitResult(
           action="accept",
           content={"confirm": True},
       )
   
   client = MultiServerMCPClient(
       {
           "gateway": {
               "url": "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp",
               "transport": "http",
               "headers": {"Authorization": "Bearer YOUR_ACCESS_TOKEN"},
           }
       },
       callbacks=Callbacks(on_elicitation=on_elicitation),
   )
   
   tools = await client.get_tools()
   agent = create_agent("claude-sonnet-4-20250514", tools)
   
   result = await agent.ainvoke(
       {"messages": [{"role": "user", "content": "Delete s3://my-bucket/important-file"}]}
   )
   ```

### Ejemplo de modo URL
<a name="gateway-mcp-elicitation-examples-url"></a>

En el modo URL, el servidor envía una URL que el usuario debe visitar para completar una acción (normalmente la autenticación OAuth). La solicitud permanece abierta mientras espera a que el usuario complete la acción en la URL.

**Example**  

1. 

   ```
   import requests
   import json
   import sseclient
   import webbrowser
   
   gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"
   headers = {
       "Content-Type": "application/json",
       "Accept": "text/event-stream",
       "Authorization": "Bearer YOUR_ACCESS_TOKEN",
       "Mcp-Session-Id": "session-abc123def456"
   }
   
   # Call tool that triggers URL elicitation
   response = requests.post(gateway_url, headers=headers, json={
       "jsonrpc": "2.0",
       "id": "tool-call-2",
       "method": "tools/call",
       "params": {
           "name": "access_github_repo",
           "arguments": {"repo": "my-org/my-repo"}
       }
   }, stream=True)
   
   # Process SSE events
   client = sseclient.SSEClient(response)
   for event in client.events():
       data = json.loads(event.data)
       if data.get("method") == "elicitation/create":
           elicitation_id = data["id"]
           url = data["params"]["url"]
           print(f"URL elicitation: {data['params']['message']}")
   
           # Open browser for user to complete authentication
           webbrowser.open(url)
           input("Press Enter after completing authentication...")
   
           # Send elicitation response
           requests.post(gateway_url, headers=headers, json={
               "jsonrpc": "2.0",
               "id": elicitation_id,
               "result": {"action": "accept"}
           })
       elif "result" in data:
           print(f"Tool result: {data['result']}")
           break
   ```

1. 

   ```
   from mcp import ClientSession
   from mcp.client.streamable_http import streamablehttp_client
   import asyncio
   import webbrowser
   
   async def elicitation_handler(request):
       """Handle URL elicitation by opening the browser."""
       if hasattr(request.params, 'url') and request.params.url:
           print(f"Opening URL for authentication: {request.params.url}")
           webbrowser.open(request.params.url)
           input("Press Enter after completing authentication...")
           return {"action": "accept"}
       # Form mode fallback
       return {"action": "accept", "content": {}}
   
   async def use_url_elicitation(url, token):
       headers = {"Authorization": f"Bearer {token}"}
   
       async with streamablehttp_client(url=url, headers=headers) as (
           read_stream, write_stream, _
       ):
           async with ClientSession(
               read_stream, write_stream,
               elicitation_handler=elicitation_handler
           ) as session:
               await session.initialize()
               result = await session.call_tool(
                   name="access_github_repo",
                   arguments={"repo": "my-org/my-repo"}
               )
               print(f"Tool result: {result}")
               return result
   
   asyncio.run(use_url_elicitation(
       url="https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp",
       token="YOUR_ACCESS_TOKEN"
   ))
   ```

1. 

   ```
   from mcp.client.streamable_http import streamablehttp_client
   from mcp.types import ElicitResult
   from strands import Agent
   from strands.tools.mcp import MCPClient
   import webbrowser
   
   mcp_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"
   access_token = "YOUR_ACCESS_TOKEN"
   
   async def elicitation_callback(context, params):
       """Handle URL elicitation by opening the browser."""
       if hasattr(params, 'url') and params.url:
           print(f"Opening URL: {params.url}")
           webbrowser.open(params.url)
           input("Press Enter after completing authentication...")
           return ElicitResult(action="accept")
       return ElicitResult(action="accept", content={})
   
   mcp_client = MCPClient(
       lambda: streamablehttp_client(
           mcp_url, headers={"Authorization": f"Bearer {access_token}"}
       ),
       elicitation_callback=elicitation_callback,
   )
   
   with mcp_client:
       agent = Agent(tools=mcp_client.list_tools_sync())
       response = agent("Access the my-org/my-repo GitHub repository")
       print(response)
   ```

1. 

   ```
   from langchain_mcp_adapters.client import MultiServerMCPClient
   from langchain_mcp_adapters.callbacks import Callbacks, CallbackContext
   from langchain.agents import create_agent
   from mcp.shared.context import RequestContext
   from mcp.types import ElicitRequestParams, ElicitResult
   import webbrowser
   
   async def on_elicitation(
       mcp_context: RequestContext,
       params: ElicitRequestParams,
       context: CallbackContext,
   ) -> ElicitResult:
       """Handle URL elicitation by opening the browser."""
       if params.url:
           print(f"[{context.server_name}] Opening URL: {params.url}")
           webbrowser.open(params.url)
           input("Press Enter after completing authentication...")
           return ElicitResult(action="accept")
       return ElicitResult(action="accept", content={})
   
   client = MultiServerMCPClient(
       {
           "gateway": {
               "url": "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp",
               "transport": "http",
               "headers": {"Authorization": "Bearer YOUR_ACCESS_TOKEN"},
           }
       },
       callbacks=Callbacks(on_elicitation=on_elicitation),
   )
   
   tools = await client.get_tools()
   agent = create_agent("claude-sonnet-4-20250514", tools)
   
   result = await agent.ainvoke(
       {"messages": [{"role": "user", "content": "Access the my-org/my-repo GitHub repository"}]}
   )
   ```