View a markdown version of this page

Utilice la elicitación con su AgentCore puerta de enlace - Amazon Bedrock AgentCore

Utilice la elicitación con su AgentCore puerta de enlace

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

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 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

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

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

  2. 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.

  3. 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

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

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

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

  4. Gateway reenvía la elicitation/create solicitud al cliente en la transmisión SSE y reemplaza la solicitudid.

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

  6. El cliente envía una nueva solicitud con la respuesta de provocación (acción: accept odecline) utilizando la mismaMcp-Session-Id.

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

  8. El objetivo reconoce con HTTP 202 Accepted.

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

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

Flujo de elicitación en modo URL (basado en excepciones)

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

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

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

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

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

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

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

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

Llamadas de herramientas paralelas con notificaciones

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

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

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)

idDebe 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

Resolución de problemas

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

Ejemplo de modo formulario

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.

ejemplo
Python requests package
  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
MCP Client
  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" ))
Strands MCP Client
  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)
LangGraph MCP Client
  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

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.

ejemplo
Python requests package
  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
MCP Client
  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" ))
Strands MCP Client
  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)
LangGraph MCP Client
  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"}]} )