AWS AgentCore — 网关 + 外部 MCP
简介
此示例演示了如何使用 AWS AgentCore 网关连接运行在 AWS Fargate 上的外部 Neo4j MCP 服务器。该堆栈提供了一套用于机器对机器(client_credentials)身份验证的最小化 Amazon Cognito OAuth 设置,并使用 Lambda 拦截器将 OAuth 令牌转换为 Neo4j 凭据,以便您能够以 HTTP 模式运行 官方 Neo4j MCP 服务器。
核心功能
-
AgentCore 网关:企业工具治理和集中式 MCP 管理
-
Lambda 请求拦截器:将 OAuth 令牌转换为 Neo4j 基本身份验证(Basic Auth)标头
-
官方 Neo4j MCP:在 HTTP 模式下使用未经修改的官方 Docker 镜像
-
ECS Fargate 部署:无服务器容器编排
-
内置 Cognito OAuth:为外部客户端提供安全的 M2M 身份验证
应用场景
-
使用官方供应商支持的镜像进行企业级部署
-
通过 OAuth 2.0 实现集中式身份管理
-
在边缘(网关)进行安全的凭据注入,而非在容器内
-
具有公共负载均衡器的高可用架构
架构设计
组件
-
AWS AgentCore 网关
-
MCP 服务器的反向代理
-
使用 Cognito OIDC 发现(
CUSTOM_JWT)进行入站 JWT 验证 -
执行 Lambda 拦截器(REQUEST 拦截点)
-
-
网关目标
-
将 Neo4j MCP ALB 注册为 MCP 服务器目标
-
通过
gateway_identifier自动关联到网关
-
-
请求拦截器 Lambda
-
在请求到达后端之前执行
-
从 Secrets Manager 获取 Neo4j 凭据
-
将 OAuth
Authorization标头替换为Basic <user:pass>
-
-
应用程序负载均衡器(公共,HTTPS)
-
使用 ACM 证书终止 TLS
-
通过 Route53 A 记录别名注册的自定义域
-
将流量分发到端口 443 上的 Fargate 任务
-
-
Neo4j MCP 容器(官方)
-
运行
mcp/neo4j:latest镜像 -
配置为 HTTP 模式(
NEO4J_TRANSPORT_MODE=http) -
通过按请求基本身份验证实现无状态认证
-
-
AWS Secrets Manager
-
存储 Neo4j 凭据
-
由拦截器 Lambda 访问以进行标头注入
-
深度分析
身份验证流程(令牌交换)
此模式的核心创新在于 Auth 拦截器,它实现了基于 OAuth 的网关客户端与基于 Basic Auth 的 Neo4j MCP 之间的兼容性。
External Agent (OAuth Token)
↓
[OAuth Validation - Cognito User Pool (created by stack)]
↓
AgentCore Gateway
↓
Request Interceptor Lambda
├─ Retrieve Secret ("neo4j/creds")
├─ Compute Basic Auth Header
└─ Replace "Authorization" Header
↓
[Basic Auth: neo4j:password]
↓
Application Load Balancer (Public)
↓
Official Neo4j MCP (HTTP Mode)
优势
-
安全性:Neo4j 凭据绝不会暴露给客户端
-
合规性:为客户端使用标准 OAuth 模式
-
简洁性:后端使用无状态的标准 HTTP 身份验证
Fargate 服务架构
Neo4j MCP 服务
-
镜像:
mcp/neo4j:latest -
环境变量
-
NEO4J_TRANSPORT_MODE:http -
NEO4J_MCP_HTTP_PORT:8080 -
NEO4J_MCP_HTTP_HOST:0.0.0.0 -
NEO4J_READ_ONLY:true
-
-
机密(来自 Secrets Manager)
-
NEO4J_URI,NEO4J_DATABASE
-
负载均衡器配置
AgentCore 网关需要 HTTPS 端点进行 MCP 目标注册,因此 ALB 配置了 TLS 侦听器和自定义域名
-
侦听器:HTTPS:443(已附加 ACM 证书)
-
自定义域名:
<subdomain>.<domain_name>— 由 CDK 自动创建 Route53 A 记录别名 -
目标组:Fargate 任务的 IP 模式目标
-
运行状况检查:
/mcp端点,代码200-499 -
安全组:允许来自 AgentCore 网关 IP 范围的入站流量(可选加固)
域名和证书配置
该堆栈读取三个 CDK 上下文变量
| 上下文键 | 默认 | 描述 |
|---|---|---|
|
(必需) |
现有 Route53 托管区域的顶点域名(例如 |
|
|
子域名后缀 — 结果为 |
|
(必需) |
覆盖 FQDN 的现有 ACM 证书的 ARN(例如 |
Cognito 托管域前缀自动生成为 neo4j-mcp-<account>-<region>。
证书通过 ARN 导入(from_certificate_arn),且必须位于与堆栈相同的区域中。
如何使用此示例
先决条件
-
具有 Bedrock、ECS 和 AgentCore 访问权限的 AWS 账户
-
已安装 AWS CLI 和 CDK
-
Neo4j 数据库(或使用默认的 Neo4j 演示数据库)
-
已在您的 AWS 账户中配置用于您的域名的 Route53 公共托管区域
-
在部署区域中有一个覆盖
<subdomain>.<domain_name>(或匹配的通配符)的 ACM 证书 — 从 ACM 控制台复制其 ARN -
无需预先存在的 Cognito 设置;此堆栈会创建用户池、应用客户端和托管域
第 1 步:克隆仓库
git clone https://github.com/neo4j-labs/neo4j-agent-integrations.git
cd neo4j-agent-integrations/aws-agentcore/samples/2-gateway-external-mcp
第 3 步:配置您的域名
打开 cdk.json 并在 context 键下填写您的域名详细信息
{
"context": {
"domain_name": "example.com",
"subdomain": "mcp",
"certificate_arn": "arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
第 4 步:部署基础设施
# Bootstrap CDK (first time only)
cdk bootstrap
# Deploy the stack
cdk deploy Neo4jAgentCoreGatewayStack \
-c domain_name=example.com \
-c subdomain=mcp \
-c certificate_arn=arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
已创建的堆栈资源
-
具有公共子网的 VPC
-
ECS 集群和 Fargate 服务(Neo4j MCP)
-
公共应用程序负载均衡器(HTTPS/443,已附加 ACM 证书)
-
Route53 A 记录别名 → ALB(
<subdomain>.<domain_name>) -
Lambda 拦截器函数
-
Secrets Manager 机密(Neo4j 凭据)
-
Amazon Cognito 用户池、托管域、资源服务器作用域和应用客户端
-
IAM 角色(Fargate 任务、Lambda、网关)
-
AgentCore MCP 网关
-
指向 Neo4j MCP 的网关目标(使用自定义域名端点)
堆栈输出
| 输出 | 描述 |
|---|---|
|
Neo4j MCP 服务的自定义域名 |
|
Neo4j MCP 服务的 HTTPS URL |
|
Neo4j 凭据机密的 ARN |
|
请求拦截器 Lambda 的 ARN |
|
AgentCore MCP 网关的 ARN |
|
AgentCore MCP 网关的 URL |
|
网关授权方使用的 Cognito 用户池 ID |
|
用于 OAuth 客户端凭据的 Cognito 应用客户端 ID |
|
在网关授权方中配置的 OIDC 发现 URL |
|
用于客户端凭据流程的 Cognito 令牌端点 |
|
网关调用所需的作用域( |
第 5 步:使用演示笔记本进行测试(可选)
在 Jupyter 或 VS Code 中打开 demo.ipynb。将 STACK_NAME 设置为您的堆栈名称,然后运行单元格以从 Cognito 获取 OAuth 令牌并调用网关(列出工具,调用 Neo4j MCP 工具)。需要 requests 和 AWS 凭据。
第 6 步:获取 OAuth 令牌并测试集成(CLI)
-
验证 DNS:Route53 别名记录应在部署后立即解析到 ALB。
dig mcp.example.com
-
检查 HTTPS:确认 MCP 端点可以通过 TLS 响应。
curl https://mcp.example.com/mcp
-
读取堆栈输出:
STACK_NAME=Neo4jAgentCoreGatewayStack
GATEWAY_URL=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query "Stacks[0].Outputs[?OutputKey=='GatewayUrl'].OutputValue" \
--output text)
COGNITO_USER_POOL_ID=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query "Stacks[0].Outputs[?OutputKey=='CognitoUserPoolId'].OutputValue" \
--output text)
COGNITO_CLIENT_ID=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query "Stacks[0].Outputs[?OutputKey=='CognitoAppClientId'].OutputValue" \
--output text)
COGNITO_TOKEN_ENDPOINT=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query "Stacks[0].Outputs[?OutputKey=='CognitoTokenEndpoint'].OutputValue" \
--output text)
COGNITO_SCOPE=$(aws cloudformation describe-stacks \
--stack-name "$STACK_NAME" \
--query "Stacks[0].Outputs[?OutputKey=='CognitoScope'].OutputValue" \
--output text)
-
检索 Cognito 应用客户端密钥:
COGNITO_CLIENT_SECRET=$(aws cognito-idp describe-user-pool-client \
--user-pool-id "$COGNITO_USER_POOL_ID" \
--client-id "$COGNITO_CLIENT_ID" \
--query "UserPoolClient.ClientSecret" \
--output text)
-
请求 OAuth 令牌(
client_credentials)
OAUTH_TOKEN=$(curl -s -X POST "$COGNITO_TOKEN_ENDPOINT" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "grant_type=client_credentials" \
--data-urlencode "client_id=$COGNITO_CLIENT_ID" \
--data-urlencode "client_secret=$COGNITO_CLIENT_SECRET" \
--data-urlencode "scope=$COGNITO_SCOPE" \
| python3 -c 'import json,sys; print(json.load(sys.stdin)["access_token"])')
-
调用网关:
curl -X POST "$GATEWAY_URL" \
-H "Authorization: Bearer $OAUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":"list-tools-request","method":"tools/list"}'
-
验证流程:
-
网关验证令牌
-
拦截器将令牌交换为 Basic Auth
-
Neo4j MCP 接受请求并返回架构
-