View a markdown version of this page

Gunakan elicitation dengan gateway Anda AgentCore - Batuan Dasar Amazon AgentCore

Gunakan elicitation dengan gateway Anda AgentCore

Elicitation adalah fitur MCP yang memungkinkan server MCP untuk meminta informasi tambahan dari klien selama panggilan alat. Ketika alat membutuhkan konfirmasi pengguna, otentikasi, atau input tambahan untuk melanjutkan, server mengirimkan permintaan elisitasi kembali ke klien. AgentCore Gateway meneruskan permintaan dari target server MCP ke klien Anda, menggantikan permintaan id dengan pengenal yang dihasilkan gateway.

Prasyarat

Untuk menggunakan elicitation dengan gateway Anda, Anda harus memiliki:

  • Sesi diaktifkan - Elicitation membutuhkan dukungan sesi. Lihat Menggunakan sesi MCP dengan gateway Anda.

  • Streaming respons diaktifkan - Permintaan elicitation dikirim sebagai potongan Server-Sent Acara (SSE) selama koneksi terbuka. Setel streamingConfiguration.enableResponseStreaming ke true dalam gateway AndaprotocolConfiguration.mcp.

  • Jenis target server MCP - Elicitation hanya didukung untuk target server MCP. Elisitasi berasal dari server MCP dan diteruskan melalui gateway ke klien.

  • Klien mendeklarasikan kemampuan elisitasi — Klien harus menyatakan dukungan untuk elisitasi selama permintaan gateway untuk meneruskan initialize permintaan elisitasi.

Mode elisitasi yang didukung

AgentCore Gateway mendukung tiga mode elisitasi yang ditentukan oleh spesifikasi MCP:

Modus Deskripsi

Mode formulir

Server mengirimkan formulir terstruktur dengan bidang untuk diisi klien. Digunakan untuk mengumpulkan konfirmasi pengguna, preferensi, atau data input. Permintaan tetap terbuka sambil menunggu tanggapan.

Mode URL (berbasis permintaan)

Server mengirimkan URL yang harus dikunjungi pengguna untuk menyelesaikan suatu tindakan (biasanya otentikasi). Permintaan tetap terbuka sambil menunggu tindakan selesai.

Mode URL (berbasis pengecualian)

Server melempar URLElicitationRequiredError berisi URL. Permintaan ditutup, pengguna menyelesaikan tindakan di URL, dan klien mencoba ulang panggilan alat asli.

Negosiasi kemampuan

Gateway hanya mendeklarasikan dukungan elisitasi ke target server MCP jika:

  1. Klien menyatakan dukungan elisitasi selama. initialize

  2. Versi protokol MCP mendukung mode elicitation — mode memerlukan versi atau yang lebih baru, form url mode memerlukan versi 2025-03-26 2025-11-25 atau yang lebih baru.

  3. Gateway cocok dengan kemampuan elisitasi spesifik yang dideklarasikan oleh klien (formulir, url, atau keduanya).

Aliran elisitasi mode bentuk

  1. Klien mengirimkan tools/call permintaan dengan Mcp-Session-Id header.

  2. Gateway meneruskan panggilan alat ke target server MCP.

  3. Target membuka aliran SSE dan mengirimkan elicitation/create permintaan sebagai acara pertama.

  4. Gateway meneruskan elicitation/create permintaan ke klien pada aliran SSE, menggantikan permintaan. id

  5. Klien menyajikan formulir kepada pengguna dan mengumpulkan respons.

  6. Klien mengirimkan permintaan baru dengan respons elisitasi (tindakan: accept ataudecline) menggunakan yang sama. Mcp-Session-Id

  7. Gateway meneruskan respons ke target server MCP.

  8. Target mengakui dengan HTTP 202 Diterima.

  9. Target menyelesaikan panggilan alat dan mengirimkan hasil akhir pada aliran SSE asli.

  10. Gateway meneruskan hasil akhir ke klien dan menutup aliran.

Aliran elisitasi mode URL (berbasis pengecualian)

  1. Klien mengirimkan tools/call permintaan dengan Mcp-Session-Id header.

  2. Gateway meneruskan panggilan alat ke target server MCP.

  3. Target melempar URLElicitationRequiredError sebagai JSON-RPC kesalahan, berisi URL dan ID elisitasi.

  4. Gateway meneruskan URLElicitationRequiredError ke klien, menggantikan permintaanid.

  5. Klien mengarahkan pengguna ke URL yang disediakan untuk menyelesaikan tindakan (biasanya otentikasi OAuth).

  6. Setelah pengguna menyelesaikan tindakan, klien mencoba ulang permintaan aslitools/call.

  7. Gateway meneruskan percobaan lagi ke target. Target menyelesaikan panggilan alat sejak elisitasi URL terpenuhi.

  8. Gateway meneruskan hasil alat akhir ke klien.

Panggilan alat paralel dengan elisitasi

Klien dapat memulai beberapa tools/call permintaan dalam sesi yang sama, bahkan saat elisitasi tertunda. Setiap elisitasi dilacak secara independen olehnya. id Saat mengirim respons elisitasi, klien harus menyertakan hal yang sama id yang dikirim oleh gateway dalam permintaan. elicitation/create

Panduan untuk pengembang target server MCP

penting

Target server MCP yang mengirim permintaan elisitasi harus membungkus panggilan elicitation dalam blok try-catch dan menangani kasus di mana klien tidak mendukung elisitasi. Jika klien gateway tidak mendeklarasikan kemampuan elisitasi, gateway tidak mendeklarasikannya ke target. Jika target tetap mengirimkan elisitasi, gateway mengembalikan kesalahan -32601 (Metode tidak ditemukan) ke target.

Server harus mengimplementasikan jalur fallback (seperti menggunakan nilai default atau melewatkan operasi) saat elicitation tidak tersedia.

Penanganan kesalahan

Skenario Kesalahan Deskripsi

Klien mengirimkan respons elisitasi ketika tidak ada elisitasi yang tertunda

JSON-RPC -32600(Permintaan Tidak Valid)

Tidak ada elisitasi yang cocok ditemukan untuk sesi ini.

Klien mengirimkan respons elisitasi dengan yang tidak cocok dengan elisitasi id yang tertunda

JSON-RPC -32600(Permintaan Tidak Valid)

idHarus cocok dengan yang dikirim oleh gateway dalam elicitation/create permintaan.

Koneksi terputus antara gateway dan target server MCP

JSON-RPC kesalahan dengan DependencyFailedException

Klien harus mencoba lagi permintaan panggilan alat asli.

Koneksi terputus antara klien dan gateway

N/A

Elisitasi yang tertunda dibersihkan. Klien harus mencoba lagi panggilan alat.

Server MCP mengirimkan elisitasi tetapi gateway tidak menyatakan dukungan

JSON-RPC -32601(Metode tidak ditemukan)

Kembali ke target server MCP. Lihat Pemecahan Masalah.

Pemecahan masalah

Kesalahan: “Kesalahan memanggil alat 'sample_tool': Metode tidak ditemukan:" elicitation/create

Kesalahan ini terjadi ketika target server MCP mengirimkan permintaan elisitasi tetapi klien gateway tidak mendeklarasikan kemampuan elisitasi selama. initialize Gateway mengembalikan kesalahan -32601 (Metode tidak ditemukan) ke target, dan target dapat mengembalikan ini sebagai kesalahan eksekusi alat ke klien.

Untuk menyelesaikan:

  • Jika Anda adalah pengembang server MCP: Tambahkan penanganan kesalahan di sekitar panggilan elisitasi Anda. Menerapkan jalur fallback saat elicitation tidak didukung:

    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()
  • Jika Anda adalah pengembang klien gateway: Pastikan klien Anda mendeklarasikan kemampuan elisitasi selama: initialize

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

Sampel Kode

Contoh mode formulir

Dalam mode formulir, server mengirimkan skema terstruktur untuk diisi klien. Permintaan tetap terbuka sambil menunggu tanggapan.

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

Contoh mode URL

Dalam mode URL, server mengirimkan URL yang harus dikunjungi pengguna untuk menyelesaikan tindakan (biasanya otentikasi OAuth). Permintaan tetap terbuka sambil menunggu pengguna menyelesaikan tindakan di URL.

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