View a markdown version of this page

Verwenden Sie Elicitation mit Ihrem Gateway AgentCore - Amazon Grundgestein AgentCore

Verwenden Sie Elicitation mit Ihrem Gateway AgentCore

Elicitation ist eine MCP-Funktion, die es einem MCP-Server ermöglicht, während eines Tool-Aufrufs zusätzliche Informationen vom Client anzufordern. Wenn ein Tool eine Benutzerbestätigung, Authentifizierung oder zusätzliche Eingaben benötigt, um fortzufahren, sendet der Server eine Abrufanforderung zurück an den Client. AgentCore Das Gateway leitet Auslöseanfragen von MCP-Serverzielen an Ihre Clients weiter und ersetzt die Anfrage durch eine vom Gateway generierte Kennung. id

Voraussetzungen

Um Elicitation mit Ihrem Gateway verwenden zu können, benötigen Sie:

  • Sitzungen aktiviert — Für Elicitation ist Sitzungsunterstützung erforderlich. Siehe Verwenden von MCP-Sitzungen mit Ihrem Gateway.

  • Antwort-Streaming aktiviert — Elicitation-Anfragen werden während einer offenen Verbindung als Server-Sent Event-Chunks (SSE) gesendet. In Ihren streamingConfiguration.enableResponseStreaming Gateways auf true eingestellt. protocolConfiguration.mcp

  • MCP-Serverzieltyp — Die Erfassung wird nur für MCP-Serverziele unterstützt. Die Abfrage stammt vom MCP-Server und wird über das Gateway an den Client weitergeleitet.

  • Der Client deklariert die Abruffunktion — Der Client muss während der Anfrage angeben, dass das Gateway die Abrufanforderungen weiterleiten kann. initialize

Unterstützte Erhebungsmodi

AgentCore Gateway unterstützt drei in der MCP-Spezifikation definierte Auslösemodi:

Mode Description

Formularmodus

Der Server sendet ein strukturiertes Formular mit Feldern, die der Kunde ausfüllen kann. Wird zum Sammeln von Benutzerbestätigungen, Einstellungen oder Eingabedaten verwendet. Die Anfrage bleibt geöffnet, während auf die Antwort gewartet wird.

URL-Modus (anforderungsbasiert)

Der Server sendet eine URL, die der Benutzer aufrufen muss, um eine Aktion abzuschließen (normalerweise Authentifizierung). Die Anfrage bleibt geöffnet, während auf den Abschluss der Aktion gewartet wird.

URL-Modus (ausnahmenbasiert)

Der Server gibt eine URL aus, die eine URL URLElicitationRequiredError enthält. Die Anfrage wird geschlossen, der Benutzer schließt die Aktion unter der URL ab und der Client versucht erneut, das ursprüngliche Tool aufzurufen.

Aushandlung von Fähigkeiten

Das Gateway deklariert einem MCP-Serverziel nur dann Unterstützung für Abrufe, wenn:

  1. Der Client hat während angegeben, dass die Abfrage unterstützt wird. initialize

  2. Die MCP-Protokollversion unterstützt den Elicitation-Modus — form für den Modus ist eine Version oder höher erforderlich, für die url Modi ist eine Version 2025-03-26 oder höher erforderlich. 2025-11-25

  3. Das Gateway entspricht den vom Client deklarierten spezifischen Abruffunktionen (Form, URL oder beides).

Abfragefluss im Formularmodus

  1. Der Client sendet eine tools/call Anfrage mit dem Mcp-Session-Id Header.

  2. Das Gateway leitet den Tool-Aufruf an das MCP-Serverziel weiter.

  3. Das Ziel öffnet einen SSE-Stream und sendet als erstes elicitation/create Ereignis eine Anfrage.

  4. Das Gateway leitet die elicitation/create Anfrage im SSE-Stream an den Client weiter und ersetzt die Anfrageid.

  5. Der Client präsentiert dem Benutzer das Formular und sammelt die Antwort.

  6. Der Client sendet eine neue Anfrage mit der Auslösungsantwort (Aktion: accept oderdecline) und verwendet dieselbe. Mcp-Session-Id

  7. Das Gateway leitet die Antwort an das MCP-Serverziel weiter.

  8. Das Ziel bestätigt dies mit HTTP 202 Accepted.

  9. Das Ziel schließt den Tool-Aufruf ab und sendet das Endergebnis im ursprünglichen SSE-Stream.

  10. Gateway leitet das Endergebnis an den Client weiter und schließt den Stream.

Auslöseablauf im URL-Modus (ausnahmenbasiert)

  1. Der Client sendet eine tools/call Anfrage mit dem Header. Mcp-Session-Id

  2. Das Gateway leitet den Tool-Aufruf an das MCP-Serverziel weiter.

  3. Das Ziel gibt URLElicitationRequiredError als JSON-RPC Fehler ein aus, das die URL und eine Auslöse-ID enthält.

  4. Das Gateway leitet das URLElicitationRequiredError an den Client weiter und ersetzt die Anfrage. id

  5. Der Client leitet den Benutzer zur angegebenen URL weiter, um die Aktion abzuschließen (normalerweise OAuth-Authentifizierung).

  6. Nachdem der Benutzer die Aktion abgeschlossen hat, wiederholt der Client die ursprüngliche Anfrage. tools/call

  7. Gateway leitet den Wiederholungsversuch an das Ziel weiter. Das Ziel schließt den Tool-Aufruf ab, da die URL-Abfrage abgeschlossen wurde.

  8. Gateway leitet das endgültige Tool-Ergebnis an den Client weiter.

Parallele Werkzeugabrufe mit Elicitationen

Ein Client kann innerhalb derselben Sitzung mehrere tools/call Anfragen initiieren, auch wenn noch eine Anfrage aussteht. Jede Anfrage wird unabhängig anhand ihrer Daten nachverfolgt. id Beim Senden einer Antwortantwort muss der Client dieselbe Antwort, die vom Gateway gesendet wurdeid, in die Anfrage aufnehmen. elicitation/create

Anleitung für Entwickler von MCP-Servern

Wichtig

MCP-Serverziele, die Exicitation-Anfragen senden, sollten Exicitation-Aufrufe in Try-Catch-Blöcke packen und den Fall behandeln, dass der Client die Auslösung nicht unterstützt. Wenn der Client des Gateways keine Auslösefähigkeit deklariert hat, deklariert das Gateway sie nicht gegenüber dem Ziel. Wenn das Ziel trotzdem eine Exicitation sendet, gibt das Gateway einen Fehler -32601 (Methode nicht gefunden) an das Ziel zurück.

Server sollten einen Fallback-Pfad implementieren (z. B. Standardwerte verwenden oder den Vorgang überspringen), wenn die Auslösung nicht verfügbar ist.

Fehlerbehandlung

Szenario Fehler Description

Der Client sendet eine Abfrageantwort, wenn keine Abfrage aussteht

JSON-RPC -32600(Ungültige Anfrage)

Für diese Sitzung wurde kein passendes Ergebnis gefunden.

Der Client sendet eine Antwortantwort mit einerid, die nicht mit einer ausstehenden Abfrage übereinstimmt

JSON-RPC -32600(Ungültige Anfrage)

Die id muss mit der vom Gateway in der elicitation/create Anfrage gesendeten übereinstimmen.

Verbindungsabbrüche zwischen Gateway und MCP-Serverziel

JSON-RPC Fehler bei DependencyFailedException

Der Kunde sollte die ursprüngliche Tool-Call-Anfrage erneut versuchen.

Verbindungsabbrüche zwischen Client und Gateway

N/A

Die ausstehende Abfrage wurde bereinigt. Der Client sollte den Toolaufruf erneut versuchen.

Der MCP-Server sendet eine Anfrage, aber das Gateway hat keine Unterstützung angegeben

JSON-RPC -32601(Methode nicht gefunden)

Zum MCP-Serverziel zurückgekehrt. Siehe Problembehandlung.

Fehlerbehebung

Fehler: „Fehler beim Aufrufen des Tools 'sample_tool': Methode nicht gefunden:" elicitation/create

Dieser Fehler tritt auf, wenn ein MCP-Serverziel eine Abrufanforderung sendet, der Client des Gateways währenddessen jedoch keine Abruffunktion deklariert hat. initialize Das Gateway gibt einen Fehler -32601 (Methode nicht gefunden) an das Ziel zurück, und das Ziel gibt dies möglicherweise als Fehler bei der Ausführung des Tools an den Client zurück.

Um dies zu lösen:

  • Wenn Sie der MCP-Serverentwickler sind: Fügen Sie eine Fehlerbehandlung zu Ihren Elicitation-Aufrufen hinzu. Implementieren Sie einen Fallback-Pfad, wenn die Auslösung nicht unterstützt wird:

    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()
  • Wenn Sie der Gateway-Client-Entwickler sind: Stellen Sie sicher, dass Ihr Client in den folgenden Fällen die Möglichkeit zur Datenabfrage deklariert: initialize

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

Codebeispiele

Beispiel für den Formularmodus

Im Formularmodus sendet der Server ein strukturiertes Schema, das der Client ausfüllen kann. Die Anfrage bleibt geöffnet, während auf die Antwort gewartet wird.

Beispiel
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"}]} )

Beispiel für den URL-Modus

Im URL-Modus sendet der Server eine URL, die der Benutzer aufrufen muss, um eine Aktion abzuschließen (normalerweise OAuth-Authentifizierung). Die Anfrage bleibt geöffnet, während darauf gewartet wird, dass der Benutzer die Aktion an der URL abschließt.

Beispiel
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"}]} )