

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 搭配 AgentCore 閘道使用引出
<a name="gateway-mcp-elicitation"></a>

Elicitation 是一種 MCP 功能，可讓 MCP 伺服器在工具呼叫期間向用戶端請求其他資訊。當工具需要使用者確認、身分驗證或其他輸入才能繼續時，伺服器會將請求傳回給用戶端。AgentCore Gateway 會將請求從 MCP 伺服器目標轉送到您的用戶端，`id`以閘道產生的識別符取代請求。

## 先決條件
<a name="gateway-mcp-elicitation-prereqs"></a>

若要搭配閘道使用引動，您必須具有：
+  **工作階段已啟用 (2025-11-25 版及更早版本）** — 請求需要工作階段支援。請參閱[搭配閘道使用 MCP 工作階段](gateway-sessions.md)。對於版本 `2026-07-28`和更新版本，您不需要將 `sessionConfiguration` 新增至閘道，因為這些版本是無狀態的。
+  **啟用回應串流 (2025-11-25 版及更早版本）** — 在開放連線期間，請求會以伺服器傳送事件 (SSE) 區塊的形式傳送。在閘道的 `true`中`streamingConfiguration.enableResponseStreaming`將 設定為 `protocolConfiguration.mcp`。對於版本 `2026-07-28`和更新版本，您不需要啟用回應串流。這些版本透過多往返請求 (MRTR) 模式而非回應串流上的伺服器起始請求來傳遞引出。如需詳細資訊，請參閱模型內容通訊協定文件中的[多重往返請求](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr)。
+  **MCP 伺服器目標類型** — 僅 MCP 伺服器目標支援請求。引出源自 MCP 伺服器，並透過閘道轉送至用戶端。
+  **用戶端宣告引出功能** — 用戶端必須宣告對引出的支援，閘道才能轉送引出請求。對於版本 `2025-11-25`和更早版本，用戶端會在`initialize`請求中宣告此支援。對於版本 `2026-07-28`和更新版本，用戶端會宣告 `_meta` 欄位 () 中每個請求的功能`io.modelcontextprotocol/clientCapabilities`。

## 支援的引出模式
<a name="gateway-mcp-elicitation-modes"></a>

AgentCore Gateway 支援 MCP 規格定義的三種引出模式：


| Mode | 說明 | 
| --- | --- | 
|  **表單模式**  | 伺服器會傳送結構化表單，其中包含要由用戶端填寫的欄位。用於收集使用者確認、偏好設定或輸入資料。請求在等待回應時保持開啟狀態。 | 
|  **URL 模式 （以請求為基礎）**  | 伺服器會傳送使用者必須造訪的 URL，以完成動作 （通常是身分驗證）。請求在等待動作完成時保持開啟狀態。 | 
|  **URL 模式 （例外類型）**  | 伺服器擲回`URLElicitationRequiredError`包含 URL 的 。請求關閉，使用者在 URL 完成動作，用戶端會重試原始工具呼叫。 | 

## 功能交涉
<a name="gateway-mcp-elicitation-capability"></a>

如果符合下列條件，閘道只會宣告對 MCP 伺服器目標的引出支援：

1. **用戶端**宣告引出支援。對於版本 `2025-11-25`和更早版本，用戶端會在 期間宣告這一點`initialize`。對於版本 `2026-07-28`和更新版本，用戶端會針對 中的每個請求宣告。 `_meta`

1. **MCP 通訊協定版本**支援引出模式。 `form` 模式需要版本 `2025-03-26`或更新版本。 `url` 模式需要版本 `2025-11-25` 或更新版本。

1. 閘道符合用戶端宣告的特定引出功能 （形式、url 或兩者）。

## 表單模式引出流程
<a name="gateway-mcp-elicitation-form-flow"></a>

**注意**  
此處所述的流程適用於版本 `2025-11-25`和更早版本，其中伺服器在開啟的 SSE 串流上`elicitation/create`以伺服器起始的請求傳送。對於 版本 `2026-07-28`和更新版本，引動改為使用多往返請求 (MRTR) 模式。伺服器會傳回臨時結果，而用戶端會使用收集的輸入重試原始請求。如需詳細資訊，請參閱模型內容通訊協定文件中的[多重往返請求](https://modelcontextprotocol.io/specification/2026-07-28/basic/patterns/mrtr)。

1. 用戶端使用 `Mcp-Session-Id`標頭傳送`tools/call`請求。

1. Gateway 會將工具呼叫轉送至 MCP 伺服器目標。

1. 目標會開啟 SSE 串流，並以第一個事件傳送`elicitation/create`請求。

1. Gateway 會將`elicitation/create`請求轉送至 SSE 串流上的用戶端，取代請求 `id`。

1. 用戶端會將表單呈現給使用者，並收集回應。

1. 用戶端會使用相同的 傳送具有引出回應 （動作： `accept`或 `decline`) 的新請求`Mcp-Session-Id`。

1. Gateway 會將回應轉送至 MCP 伺服器目標。

1. 目標確認 HTTP 202 已接受。

1. 目標完成工具呼叫，並在原始 SSE 串流上傳送最終結果。

1. Gateway 會將最終結果轉送至用戶端並關閉串流。

## URL 模式 （例外型） 引出流程
<a name="gateway-mcp-elicitation-url-exception-flow"></a>

1. 用戶端使用 `Mcp-Session-Id`標頭傳送`tools/call`請求。

1. Gateway 會將工具呼叫轉送至 MCP 伺服器目標。

1. 目標擲回 `URLElicitationRequiredError`做為 JSON-RPC 錯誤，其中包含 URL 和引出 ID。

1. Gateway 會將 轉送`URLElicitationRequiredError`到用戶端，取代請求 `id`。

1. 用戶端會將使用者重新導向至提供的 URL 以完成動作 （通常是 OAuth 身分驗證）。

1. 使用者完成動作後，用戶端會重試原始`tools/call`請求。

1. Gateway 會將重試轉送到目標。目標會在完成 URL 引出後完成工具呼叫。

1. Gateway 會將最終工具結果轉送至用戶端。

## 具有引出的平行工具呼叫
<a name="gateway-mcp-elicitation-parallel"></a>

即使正在等待引出，用戶端也可以在同一個工作階段中啟動多個`tools/call`請求。每個引動都會由其 獨立追蹤`id`。傳送引出回應時，用戶端必須包含閘道在`elicitation/create`請求中`id`傳送的相同 。

## MCP 伺服器目標開發人員指南
<a name="gateway-mcp-elicitation-server-guidance"></a>

**重要**  
傳送引出請求的 MCP 伺服器目標**應將**引出呼叫包裝在 try-catch 區塊中，並處理用戶端不支援引出的情況。如果閘道的用戶端未宣告引出功能，閘道不會將其宣告至目標。如果目標仍然傳送引出，閘道會將 `-32601`（找不到方法） 錯誤傳回目標。  
當引出不可用時，伺服器應實作備用路徑 （例如使用預設值或略過操作）。

## 保護請求狀態 (2026-07-28 版及更新版本）
<a name="gateway-mcp-elicitation-request-state-security"></a>

在 版本 `2026-07-28` 和更新版本上，引出使用多往返請求 (MRTR) 模式，在用戶端和 MCP 伺服器目標`requestState`之間具有不透明。保護該值是共同的責任：閘道在不儲存的情況下授權和轉送它，而您的 MCP 伺服器目標必須驗證它，並防止一個使用者重播另一個使用者的請求狀態。如需 MCP 伺服器必須遵循的完整共同責任模型和保護指引，請參閱 MCP 伺服器目標考量中的[保護引出和取樣的請求狀態](gateway-target-MCPservers.md#gateway-target-MCPservers-request-state)。

## 錯誤處理
<a name="gateway-mcp-elicitation-errors"></a>


| 案例 | 錯誤 | 說明 | 
| --- | --- | --- | 
| 用戶端在未等待引出時傳送引出回應 | JSON-RPC `-32600`（無效的請求） | 找不到此工作階段的相符引出。 | 
| 用戶端使用不符合待定引出`id`的 傳送引出回應 | JSON-RPC `-32600`（無效的請求） | `id` 必須與`elicitation/create`請求中閘道傳送的 相符。 | 
| 閘道與 MCP 伺服器目標之間的連線中斷 | 具有 DependencyFailedException 的 JSON-RPC 錯誤 | 用戶端應重試原始工具呼叫請求。 | 
| 用戶端和閘道之間的連線中斷 | N/A | 待定引出已清除。用戶端應重試工具呼叫。 | 
| MCP 伺服器傳送引出，但閘道未宣告支援 | JSON-RPC `-32601`（找不到方法） | 已傳回 MCP 伺服器目標。請參閱[故障診斷](#gateway-mcp-elicitation-troubleshooting)。 | 
| 閘道撰寫的引出需要用戶端未宣告的功能 （版本 `2026-07-28`和更新版本） | JSON-RPC `-32021`（缺少必要的用戶端功能）、HTTP `400`  | 在 版本 `2026-07-28` 和更新版本上，閘道會傳回此程式碼，而不是 `-32601`。當用戶端在其請求 中未宣告所需的功能時，就會發生這種情況`_meta`。 | 

## 疑難排解
<a name="gateway-mcp-elicitation-troubleshooting"></a>

 **錯誤：「錯誤呼叫工具 'sample\_tool'：找不到方法：引出/建立」** 

當 MCP 伺服器目標傳送引出請求，但閘道的用戶端未宣告引出功能時，就會發生此錯誤。對於版本 `2025-11-25`和更早版本，用戶端會在 期間宣告此功能`initialize`。對於版本 `2026-07-28`和更新版本，用戶端會針對 `_meta` 欄位中的每個請求宣告。閘道會將 `-32601`（找不到方法） 錯誤傳回目標。目標可能會將此作為工具執行錯誤傳回給用戶端。

若要解決問題：
+  **如果您是 MCP 伺服器開發人員**：請新增引出呼叫的錯誤處理。不支援引出時實作備用路徑：

  ```
  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()
  ```
+  **如果您是閘道用戶端開發人員**：對於 `2025-11-25`和更早版本，請確保您的用戶端在 期間宣告引出功能`initialize`：

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

 **錯誤：「缺少必要的用戶端功能」(`-32021`)** 

在版本 `2026-07-28`和更新版本上，當閘道撰寫的引出需要未宣告的功能時，閘道會傳回`-32021`錯誤 (HTTP `400`)。由於這些版本是無狀態且沒有`initialize`交握，因此用戶端會在每個請求中宣告 功能。若要解決此錯誤，請在可能觸發引出的每個請求上，在請求的 `_meta` 欄位 (`io.modelcontextprotocol/clientCapabilities`) 中包含引出功能。

## 程式碼範例
<a name="gateway-mcp-elicitation-examples"></a>

### 表單模式範例
<a name="gateway-mcp-elicitation-examples-form"></a>

在表單模式中，伺服器會傳送結構式結構描述供用戶端填寫。請求在等待回應時保持開啟狀態。

**Example**  
在這些版本上，用戶端會在 期間宣告引出功能`initialize`，而引出會在開啟的 SSE 串流上做為`elicitation/create`請求抵達。將 `MCP-Protocol-Version`標頭設定為閘道支援的版本。  

```
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
headers["MCP-Protocol-Version"] = "2025-06-18"

# 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
```
在版本 上`2026-07-28`，引出會使用多往返請求模式，而不是 SSE 串流上的伺服器起始請求。用戶端在每個請求上宣告 `_meta`中的引出功能。如果工具需要輸入，則回應是包含 `inputRequests`和不透明 `input_required`的結果`requestState`。用戶端會收集輸入，並使用新的 `id`、 `inputResponses`和未修改的 重試原始請求`requestState`。工作階段和`initialize`交握不會使用。閘道的 `supportedVersions` 必須包含 `2026-07-28`。  

```
import requests

gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"

META = {
    "io.modelcontextprotocol/protocolVersion": "2026-07-28",
    "io.modelcontextprotocol/clientInfo": {"name": "my-agent", "version": "1.0.0"},
    "io.modelcontextprotocol/clientCapabilities": {"elicitation": {"form": {}, "url": {}}}
}
headers = {
    "Content-Type": "application/json",
    "Accept": "application/json, text/event-stream",
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "MCP-Protocol-Version": "2026-07-28",
    "Mcp-Method": "tools/call",
    "Mcp-Name": "use_aws"
}
arguments = {"command": "aws s3 rm s3://my-bucket/important-file"}

# Step 1: Call the tool, declaring the elicitation capability in _meta
response = requests.post(gateway_url, headers=headers, json={
    "jsonrpc": "2.0",
    "id": "tool-call-1",
    "method": "tools/call",
    "params": {"name": "use_aws", "arguments": arguments, "_meta": META}
}).json()

result = response["result"]
if result.get("resultType") == "input_required":
    # Step 2: Fulfill each input request (form elicitation)
    input_responses = {}
    for key, input_request in result.get("inputRequests", {}).items():
        print(f"Form elicitation received: {input_request['params']['message']}")
        input_responses[key] = {"action": "accept", "content": {"confirm": True}}

    # Step 3: Retry the tool call with a new id, the input responses,
    # and the requestState echoed back unmodified
    retry_params = {"name": "use_aws", "arguments": arguments, "_meta": META,
                    "inputResponses": input_responses}
    if "requestState" in result:
        retry_params["requestState"] = result["requestState"]
    response = requests.post(gateway_url, headers=headers, json={
        "jsonrpc": "2.0",
        "id": "tool-call-2",
        "method": "tools/call",
        "params": retry_params
    }).json()
    result = response["result"]

print(f"Tool result: {result}")
```

```
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"
))
```

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

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

### URL 模式範例
<a name="gateway-mcp-elicitation-examples-url"></a>

在 URL 模式中，伺服器會傳送使用者必須造訪的 URL，以完成動作 （通常是 OAuth 身分驗證）。請求在等待使用者在 URL 完成動作時保持開啟狀態。

**Example**  
在這些版本上，URL 引出會在 MCP 工作階段內的開放 SSE 串流上以`elicitation/create`請求的形式到達。將 `MCP-Protocol-Version`標頭設定為閘道支援的版本。  

```
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-Protocol-Version": "2025-11-25",
    "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
```
在版本 上`2026-07-28`，URL 引出會透過多來回請求模式而不是在 SSE 串流上得出`input_required`結果。使用者會在 URL 完成動作，然後用戶端會使用新的 `id`、 `inputResponses`和未修改的 重試原始請求`requestState`。不會使用工作階段。閘道的 `supportedVersions` 必須包含 `2026-07-28`。  

```
import requests
import webbrowser

gateway_url = "https://mygateway-abcdefghij.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp"

META = {
    "io.modelcontextprotocol/protocolVersion": "2026-07-28",
    "io.modelcontextprotocol/clientInfo": {"name": "my-agent", "version": "1.0.0"},
    "io.modelcontextprotocol/clientCapabilities": {"elicitation": {"form": {}, "url": {}}}
}
headers = {
    "Content-Type": "application/json",
    "Accept": "application/json, text/event-stream",
    "Authorization": "Bearer YOUR_ACCESS_TOKEN",
    "MCP-Protocol-Version": "2026-07-28",
    "Mcp-Method": "tools/call",
    "Mcp-Name": "access_github_repo"
}
arguments = {"repo": "my-org/my-repo"}

# Step 1: Call the tool, declaring the elicitation capability in _meta
response = requests.post(gateway_url, headers=headers, json={
    "jsonrpc": "2.0",
    "id": "tool-call-1",
    "method": "tools/call",
    "params": {"name": "access_github_repo", "arguments": arguments, "_meta": META}
}).json()

result = response["result"]
if result.get("resultType") == "input_required":
    # Step 2: Open the browser for the user to complete each URL elicitation
    input_responses = {}
    for key, input_request in result.get("inputRequests", {}).items():
        params = input_request["params"]
        print(f"URL elicitation: {params['message']}")
        webbrowser.open(params["url"])
        input("Press Enter after completing authentication...")
        input_responses[key] = {"action": "accept"}

    # Step 3: Retry the tool call with a new id, the input responses,
    # and the requestState echoed back unmodified
    retry_params = {"name": "access_github_repo", "arguments": arguments, "_meta": META,
                    "inputResponses": input_responses}
    if "requestState" in result:
        retry_params["requestState"] = result["requestState"]
    response = requests.post(gateway_url, headers=headers, json={
        "jsonrpc": "2.0",
        "id": "tool-call-2",
        "method": "tools/call",
        "params": retry_params
    }).json()
    result = response["result"]

print(f"Tool result: {result}")
```

```
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"
))
```

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

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