通过Bedrock AgentCore Gateway为无网络搜索的Claude Desktop连接网页搜索,含JWT认证和IAM Identity Center/Cognito集成的完整配置。
Amazon Bedrock 上的 Claude Desktop 提供了强大的 AI 辅助功能,但如果没有集成的网络搜索,回复内容仅限于模型训练知识的截止日期。当你需要最新信息(如最近的文档更新、实时价格或天气信息)时,模型无法自行获取。
Amazon Bedrock AgentCore 是一个用于大规模构建、连接和优化 AI 智能体的平台,支持任意框架或模型。通过 AgentCore Gateway(Amazon Bedrock AgentCore 的一项功能),你可以连接 Claude Desktop 与 Web Search 来弥补知识截止日期的差距。Web Search 是一种完全托管的、兼容 Model Context Protocol(MCP)的网络搜索能力,由覆盖数百亿文档的 Amazon 网络索引提供支持。所有查询流量都保持在 AWS 基础设施内,无需管理外部 API 密钥,且查询不会离开你的边界。
通过 Claude Desktop,你可以使用托管的 MCP 服务器连接到已启用 Web Search 目标的 AgentCore Gateway。在这篇文章中,我们将逐步介绍如何设置此集成,并使用基于 JSON Web Token(JWT)的入站认证来保护通信安全。
许多在 AWS 上运行的企业使用 AWS IAM Identity Center 通过单点登录(SSO)访问其 AWS 账户。在本演练中,我们使用 AWS IAM Identity Center 作为 AgentCore Gateway 的认证源。通过此设置,Amazon Bedrock 上的 Claude Desktop 可以通过可信的企业托管身份流调用 Web Search。这种方法与现有组织身份治理保持一致。无需单独的凭据或第三方身份提供商。
为了将 AWS IAM Identity Center 与 AgentCore Gateway 基于 JWT 的认证连接起来,我们使用 Amazon Cognito 作为联邦层,采用 OAuth 2.0 授权码授予流程。IAM Identity Center 通过安全断言标记语言(SAML)处理用户身份验证。Amazon Cognito 颁发 JWT,AgentCore Gateway 在每次请求时验证它们。整个认证链都保持在 AWS 内部。
以下序列图说明了这种认证流程。
图 1:用户认证和授权序列图
要跟随这篇文章中的步骤,你需要具备以下条件:
Amazon Bedrock AgentCore 上的 Web Search 目前可在美国东部(弗吉尼亚北部)AWS 区域(us-east-1)、欧洲(爱尔兰)区域(eu-west-1)和亚太地区(东京)区域(ap-northeast-1)使用。请确认你的网关创建于这些区域之一。
该配置涉及设置认证链(AWS IAM Identity Center → Amazon Cognito → JWT),然后将 AgentCore Gateway 接入 Claude Desktop。我们将在下一节中逐步介绍每个步骤。
步骤 1:创建 Amazon Cognito 用户池
在你的目标 AWS 账户中,创建一个 Amazon Cognito 用户池,作为 AgentCore Gateway 的 OpenID Connect(OIDC)令牌颁发者。
export AWS_REGION=<your-region>
# Create User Pool
aws cognito-idp create-user-pool \
--pool-name "agentcore-websearch-pool" \
--region $AWS_REGION \
--auto-verified-attributes email \
--schema '[{"Name":"email","Required":true,"Mutable":true,"AttributeDataType":"String"}]' \
--username-attributes email \
--username-configuration "CaseSensitive=false" \
--mfa-configuration "OFF"
# Note the Pool ID
export USER_POOL_ID=$(aws cognito-idp list-user-pools --max-results 10 \
--region $AWS_REGION \
--query "UserPools[?Name=='agentcore-websearch-pool'].Id" --output text)
echo "User Pool ID: $USER_POOL_ID"
# Create a domain (must be globally unique)
aws cognito-idp create-user-pool-domain \
--domain "<your-unique-prefix>" \
--user-pool-id $USER_POOL_ID \
--region $AWS_REGION
保存以下值以供后续步骤使用:
步骤 2:配置 IAM Identity Center SAML 应用程序
在你的 AWS Organizations 管理账户中,创建一个与 Cognito 联合的 SAML 应用程序:
步骤 3:将 SAML IdP 接入 Cognito
回到目标账户,在你的 Cognito 用户池中将 IAM Identity Center 注册为 SAML 身份提供商:
# Add IAM Identity Center as SAML IdP
METADATA=$(cat /path/to/downloaded-metadata.xml)
aws cognito-idp create-identity-provider \
--user-pool-id $USER_POOL_ID \
--provider-name "IAMIdentityCenterIdP" \
--provider-type SAML \
--provider-details "{\"MetadataFile\": $(echo "$METADATA" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read()))')}" \
--attribute-mapping '{"email": "email"}' \
--region $AWS_REGION
步骤 4:为 Amazon Bedrock AgentCore 创建 Cognito 应用客户端
创建一个带有客户端密钥的应用客户端。Claude Desktop 使用此客户端启动 OAuth 流程,通过 IAM Identity Center 对用户进行身份验证,并获取 AgentCore Gateway 的 JWT:
aws cognito-idp create-user-pool-client \
--user-pool-id $USER_POOL_ID \
--client-name "agentcore-websearch-client" \
--generate-secret \
--supported-identity-providers "IAMIdentityCenterIdP" \
--callback-urls '["http://localhost:53280/callback"]' \
--allowed-o-auth-flows code \
--allowed-o-auth-scopes "openid" "email" "profile" \
--allowed-o-auth-flows-user-pool-client \
--region $AWS_REGION
从输出中记下客户端 ID 和客户端密钥。这些是你的应用程序客户端 ID 和密钥。
步骤 5:配置带有 Web Search 工具的 AgentCore Gateway
在这一步中,我们创建一个新的 AgentCore Gateway,入站认证类型为 JSON Web Token(JWT)。对于此配置,我们使用前几步中创建的 Cognito 用户池 ID 和应用程序客户端 ID。
运行以下 Python 脚本以创建具有所需配置的网关,将所有占位符替换为你环境中的实际值:
import boto3
import json
import time
session = boto3.Session(region_name="your-region")
iam_client = session.client("iam")
gateway_client = session.client("bedrock-agentcore-control")
ACCOUNT_ID = "your-target-aws-account-id"
ROLE_NAME = "websearch-gateway-role"
GATEWAY_NAME = "websearch-gateway"
COGNITO_DISCOVERY_URL = "https://cognito-idp.<your-region>.amazonaws.com/<user-pool-id>/.well-known/openid-configuration"
COGNITO_CLIENT_ID = "<cognito-application-client-id>"
# --- Step 1: Create IAM execution role ---
trust_policy = {
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "bedrock-agentcore.amazonaws.com"},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {"aws:SourceAccount": ACCOUNT_ID}
}
}]
}
permissions_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Sid": "GetGateway",
"Effect": "Allow",
"Action": "bedrock-agentcore:GetGateway",
"Resource": f"arn:aws:bedrock-agentcore:us-east-1:{ACCOUNT_ID}:gateway/*"
},
{
"Sid": "GetConfigBundle",
"Effect": "Allow",
"Action": "bedrock-agentcore:GetConfigurationBundleVersion",
"Resource": f"arn:aws:bedrock-agentcore:us-east-1:{ACCOUNT_ID}:configuration-bundle/*"
},
{
"Sid": "InvokeWebSearch",
"Effect": "Allow",
"Action": "bedrock-agentcore:InvokeWebSearch",
"Resource": "arn:aws:bedrock-agentcore:us-east-1:aws:tool/web-search.v1"
}
]
}
try:
iam_client.create_role(
RoleName=ROLE_NAME,
AssumeRolePolicyDocument=json.dumps(trust_policy),
Description="Execution role for web search AgentCore gateway",
)
print(f"✓ Role '{ROLE_NAME}' created.")
except iam_client.exceptions.EntityAlreadyExistsException:
print(f"✓ Role '{ROLE_NAME}' already exists, reusing.")
iam_client.put_role_policy(
RoleName=ROLE_NAME,
PolicyName="websearch-gateway-policy",
PolicyDocument=json.dumps(permissions_policy),
)
print(f"✓ Inline policy attached to '{ROLE_NAME}'.")
# --- Step 2: Create the gateway ---
response = gateway_client.create_gateway(
name=GATEWAY_NAME,
description="AgentCore gateway with managed Web Search connector",
roleArn=f"arn:aws:iam::{ACCOUNT_ID}:role/{ROLE_NAME}",
protocolType="MCP",
protocolConfiguration={
"mcp": {
"supportedVersions": ["2025-03-26"],
}
},
authorizerType="CUSTOM_JWT",
authorizerConfiguration={
"customJWTAuthorizer": {
"discoveryUrl": COGNITO_DISCOVERY_URL,
"allowedClients": [COGNITO_CLIENT_ID],
}
},
)
gateway_id = response["gatewayId"]
gateway_url = response.get("gatewayUrl")
print(f"✓ Gateway created: {gateway_id}")
print(f" URL: {gateway_url}")
# --- Step 3: Wait for gateway to become READY ---
print(" Waiting for gateway to reach READY status...", end="", flush=True)
for i in range(40): # up to ~10 minutes
resp = gateway_client.get_gateway(gatewayIdentifier=gateway_id)
status = resp.get("status")
if status == "READY":
print(f" READY (after {(i+1)*15}s)")
break
elif status == "FAILED":
print(f"\n✗ Gateway entered FAILED status.")
reasons = resp.get("statusReasons", [])
for r in reasons:
print(f" Reason: {r}")
exit(1)
print(".", end="", flush=True)
time.sleep(15)
else:
print(f"\n✗ Gateway did not reach READY within 10 minutes (last status: {status})")
exit(1)
# --- Step 4: Attach the managed Web Search connector target ---
gateway_client.create_gateway_target(
gatewayIdentifier=gateway_id,
name="web-search-tool",
description="Managed Web Search connector",
targetConfiguration={
"mcp": {
"connector": {
"source": {"connectorId": "web-search"},
"con
现在你拥有了一个带 Web Search 工具的 AgentCore Gateway,并配置了基于 JWT 的入站授权。
按照 Claude Desktop 配置文档中的步骤,访问 Claude Desktop with Amazon Bedrock 的配置窗口。打开后,选择 Connectors and Extensions,然后选择 Add server,再选择 Blank。
以下截图展示了配置窗口及这些选项的位置。
图 2: Claude Desktop 连接器配置窗口
输入以下详细信息:
Transport: Streamable HTTP
URL: 输入 Step 5 中创建的 AgentCore Gateway 的网关资源 URL
OAuth: Bring your own client
Client ID: 输入 Step 4 中创建的应用客户端的 Client ID
Client Secret: 输入 Step 4 中创建的应用客户端的 Client Secret
Authorization Server: 输入 ["https://<your-unique-prefix>.auth.<region>.amazoncognito.com/oauth2/authorize"]
Callback host: localhost
Callback port: 53280
完成后,选择 Sign in and Test。这将打开浏览器让你进行身份验证,重定向到 AWS IAM Identity Center SSO 登录页面。输入你的凭据进行身份验证。如果成功,你应该会看到类似"Authorization complete. You can close this tab and return to Claude."的消息。
返回 Claude Desktop,你应该会看到一条成功的 MCP 服务器注册消息,如下图所示。
图 3: Claude Desktop 中成功的 MCP 服务器注册
Claude Desktop 现在会通过 MCP tools/list 调用发现 WebSearchTool。只要模型需要从网络获取最新信息,它就会自动调用该工具。
在你喜欢的界面(例如 Chat 或 Cowork)中,发送一个需要 Claude Desktop 获取最新结果的查询。你应该会看到一个工具执行批准框,表明 Claude 已成功发现 Web Search 工具。批准后,你应该会在回复中看到网络搜索结果。
图 4: Web Search 工具执行批准对话框
对话框显示了 Claude 要运行的查询,并提供三个选项:Deny(拒绝)、Allow for this task(允许本次任务)或 Allow once(允许一次)。批准后,Web Search 结果会被包含在回复中。
如果你在跟随本教程创建了资源,请执行以下步骤进行删除:
# Delete the gateway target
aws bedrock-agentcore-control delete-gateway-target --gateway-identifier <gateway-id> --target-id <target-id> --region $AWS_REGION
# Delete the gateway (only if it was created for this walkthrough)
aws bedrock-agentcore-control delete-gateway --gateway-identifier <gateway-id> --region $AWS_REGION
# Delete the IAM policy (only if it was created for this walkthrough)
aws iam delete-role-policy --role-name websearch-gateway-role --policy-name websearch-gateway-policy
# Delete the IAM role (only if it was created for this walkthrough)
aws iam delete-role --role-name websearch-gateway-role
# Delete the Cognito application client
aws cognito-idp delete-user-pool-client --user-pool-id $USER_POOL_ID --client-id <client-id> --region $AWS_REGION
# Delete the Cognito identity provider
aws cognito-idp delete-identity-provider --user-pool-id $USER_POOL_ID --provider-name IAMIdentityCenterIdP --region $AWS_REGION
# Delete the Cognito pool domain
aws cognito-idp delete-user-pool-domain --user-pool-id $USER_POOL_ID --domain <your-unique-prefix> --region $AWS_REGION
# Delete the cognito pool
aws cognito-idp delete-user-pool --user-pool-id $USER_POOL_ID --region $AWS_REGION
最后,在管理账户的 IAM Identity Center 控制台中,删除你在 Step 2 中创建的 SAML 应用程序。
在本文中,我们完成了将 Web Search 与 AgentCore 集成到 Claude Desktop 的全过程。虽然本教程使用 AWS IAM Identity Center 作为身份提供者,但相同的模式也适用于任何 SAML 或 OIDC 兼容的身份提供者。你可以通过在 Amazon Cognito 中将其配置为联合源来替换为你现有的 IdP。这种方法在不引入第三方依赖的情况下弥合了网络搜索的空白,所有查询都保留在你的 AWS 边界内。
要开始使用,请按照上述步骤在你自己的环境中设置集成。如需高级网关配置,请参阅 AgentCore Gateway Developer Guide。如需了解更多关于 Web Search 的信息,请参阅 Web Search 文档。