内容
# AgentCore MCP 应用
企业构建 AI 驱动的体验需要一种方法,将其后端服务作为交互式、对话式工具暴露出来,而无需重写 API 或绑定到单个 AI 主机。该项目演示了如何使用 **[MCP 应用](https://modelcontextprotocol.io/extensions/apps/overview)** — Model Context Protocol 的扩展,允许 MCP 服务器直接在 ChatGPT、Claude 和 VS Code Copilot 等 AI 主机中提供交互式 HTML 用户界面 — 并在 **Amazon Bedrock AgentCore Runtime** 上部署。
该示例实现了 **独角兽租赁** — 一个具有丰富交互式小部件的对话式租赁服务,直接在内渲染。因为 MCP 应用是主机无关的,所以同一个服务器适用于任何支持的客户端。客户可以:
- **列出独角兽** — 浏览完整的队伍,查看名称、速度、颜色、可用性和每小时费率等详细信息
- **预订独角兽** — 以每小时费率预订独角兽,并接收预订确认
- **查看活动租赁** — 监控当前预订状态和已过去的时间
- **归还独角兽** — 结束租赁并接收自动的基于持续时间的发票
> **免责声明:** 本示例仅用于演示目的,不适用于生产环境,需进一步的安全加固、测试和审查。
---
本示例展示了如何使用 [MCP(Model Context Protocol)](https://modelcontextprotocol.io/) 服务器和 [MCP 应用](https://modelcontextprotocol.io/extensions/apps/overview) 在 [Amazon Bedrock AgentCore Runtime](https://docs.aws.amazon.com/bedrock/latest/userguide/agentcore.html) 上部署,并与 AI 主机(ChatGPT、Claude 等)连接,呈现丰富的交互式小部件 UI。
## 技术栈
- **MCP 服务器**:Node.js 22 / TypeScript
- **业务逻辑**:Python Lambda(DynamoDB 访问)
- **代理 Lambda**:Node.js 22 / TypeScript
- **基础设施**:AWS CDK(TypeScript)
- **运行时**:Amazon Bedrock AgentCore Runtime(NODEJS_22)
## 演示
| 操作 | 截图 |
|-----------|---------|
| 列出独角兽: | <a href="docs/images/list.png"><img src="docs/images/list.png" width="150" alt="独角兽列表" style="margin-right:10px;" /></a> |
| 预订独角兽: | <a href="docs/images/book.png"><img src="docs/images/book.png" width="150" alt="预订独角兽" style="margin-right:10px;" /></a> |
| 显示预订: | <a href="docs/images/show.png"><img src="docs/images/show.png" width="150" alt="显示预订" style="margin-right:10px;" /></a> |
| 归还独角兽: | <a href="docs/images/return.png"><img src="docs/images/return.png" width="150" alt="归还独角兽" /></a> |
您可以通过以下请求与应用交互:
1. 列出所有独角兽
1. 我想预订 Stardust 独角兽
1. 显示我的独角兽预订
1. 我想归还我的独角兽
## 架构

**工作原理:**
| 组件 | 目的 |
|-----------|---------|
| **MCP 服务器**(Node.js/TS) | 薄的 MCP 协议层 — 接收 JSON-RPC,解析身份,调用服务 Lambda,提供小部件 HTML 作为 MCP 资源 |
| **独角兽租赁服务**(Python) | Lambda 函数,实现业务逻辑(列出、预订、查看、归还独角兽)并访问 DynamoDB |
| **AgentCore 运行时** | 托管 MCP 服务器(Node.js 22)的托管运行时 |
| **API 网关** | MCP 主机调用的公共 HTTPS 端点 |
| **API 网关代理 Lambda**(Node.js/TS) | 将 API 网关的 HTTPS 请求转换为 `InvokeAgentRuntime` 调用 |
| **S3 + CloudFront** | 提供小部件引用的独角兽图像 |
| **DynamoDB** | 存储独角兽库存和预订记录 |
### 工作原理
#### 请求流程(工具调用)
1. **MCP 主机** 向 API 网关端点发送 MCP JSON-RPC 请求(例如,`tools/call` with `list_unicorns`)。
1. **API 网关** 接收 HTTPS 请求,应用 WAF 规则(IP 允许列表,速率限制,常见攻击保护),并将请求路由到代理 Lambda。
1. **API 网关代理 Lambda** 将请求转发到 AgentCore 运行时。
1. **AgentCore 运行时(MCP 服务器)** 接收 MCP 请求,从主机上下文解析客户身份,并调用独角兽服务 Lambda。
1. **独角兽服务 Lambda** 执行业务逻辑,对 DynamoDB 进行操作,并返回结果。
1. **AgentCore 运行时(MCP 服务器)** 将响应包装在 MCP 结构化输出中,包含小部件资源引用,并返回给主机。
#### 资源流程(小部件渲染)
1. **MCP 主机** 接收包含小部件资源 URI(例如,`ui://widget/unicorn-list`)的 `tools/call` 响应,位于工具的 `_meta.ui.resourceUri` 字段中。
1. **MCP 主机** 向 API 网关端点发送 MCP `resources/read` 请求,请求该 URI。
1. **API 网关** 通过 WAF 路由请求,并将请求转发到代理 Lambda。
1. **API 网关代理 Lambda** 将请求转发到 AgentCore 运行时。
1. **AgentCore 运行时(MCP 服务器)** 解析资源 URI,加载相应的小部件 HTML(作为 MCP 资源提供),并返回。
1. **MCP 主机** 在沙盒 iframe 中渲染 HTML 小部件,通过 MCP 应用生命周期注入结构化数据。
1. 小部件引用的图像直接从 **CloudFront** (由 S3 支持)获取。
#### 关注点分离
该项目在 **MCP 协议层** 和 **业务逻辑层** 之间实现了清晰的分离:
- **MCP 服务器**(AgentCore 运行时) — 处理 MCP 协议、工具定义、结构化输出、小部件资源(MCP 应用模式)和从主机上下文解析客户身份。所有业务操作都委托给独角兽服务 Lambda。
- **独角兽租赁服务 Lambda** — 纯粹的业务逻辑,接受 JSON 请求并返回 JSON 响应。
## 部署
### 前提条件
- 已启用 Amazon Bedrock AgentCore 的 AWS 账户
- 已配置 AWS CLI(`aws configure`)
- Node.js 22+(适用于 MCP 服务器、代理 Lambda 和 AWS CDK)
- 已全局安装 AWS CDK CLI:`npm install -g aws-cdk`
### 步骤 1:构建所有工件
单个构建脚本同时处理 API 网关代理 Lambda 和 MCP 服务器打包:
```bash
chmod +x build.sh
./build.sh --clean
```
此脚本:
1. 构建 API 网关代理 Lambda(`src/lambda/api-gateway-proxy/dist/index.mjs`)
2. 安装 MCP 服务器依赖项(通过 `--clean` 标志进行干净安装以实现可复制构建)
3. 使用 Vite 捆绑小部件 HTML 文件,并使用 `vite-plugin-singlefile` 内联 MCP 应用 SDK,以便小部件在任何主机上都无需外部 CDN 依赖项
4. 使用 esbuild 将 Node.js 服务器捆绑到单个 `main.js` 文件中
5. 将所有内容打包到 `build/mcp-server-deployment.zip`
`--clean` 标志删除 `node_modules` 和 `package-lock.json`,然后安装,确保可复制构建。如果依赖项未更改,请省略它以便在本地快速迭代。
构建输出是纯 JavaScript — 无本机模块 — 因此无论构建主机架构如何,它都在 ARM64 AgentCore 运行时上运行。
### 步骤 2:安装 CDK 依赖项
```bash
cd infrastructure/cdk
npm install
```
### 步骤 3:引导 CDK(仅首次)
如果这是您在 AWS 账户/区域中首次部署 CDK,则需要引导:
```bash
npx cdk bootstrap
```
### 步骤 4:综合 CloudFormation 模板
验证堆栈是否综合而没有错误:
```bash
npx cdk synth
```
您还可以传递自定义项目名称:
```bash
npx cdk synth -c projectName=unicorn-rentals
```
默认项目名称为 `unicorn-mcp`。
### 步骤 5:部署
```bash
npx cdk deploy
```
CDK 将:
1. 创建 S3 部署存储桶并上传 MCP 服务器 zip 文件
2. 创建 DynamoDB 表并用独角兽数据初始化它们
3. 部署 **独角兽服务 Lambda**,并授予 DynamoDB 权限
4. 为 AgentCore 创建 IAM 角色,授予 S3 读取和 Lambda 调用权限
5. 创建 AgentCore 运行时(MCP 服务器),指向服务 Lambda
6. 部署 API 网关代理 Lambda
7. 部署带有 WAF 的 API 网关
请注意部署后打印的输出 — 您需要 `McpEndpointUrl` 来连接 MCP 主机。
### 步骤 6:连接到 MCP 主机
部署后,将 MCP 端点连接到您首选的主机:
- **ChatGPT** — [ChatGPT 设置指南](docs/chatgpt-setup.md)
- **Claude** — [Claude 设置指南](docs/claude-setup.md)
两个指南都涵盖了配置步骤、演示提示和故障排除。您需要来自 CDK 输出的 `McpEndpointUrl`。
## 安全
该项目实施了多层安全保护,以保护 API 端点和后端服务:
### 1. WAF IP 允许列表(API 网关)
AWS WAF 附加到 API 网关,具有 **默认拒绝** 策略。只有来自允许列表的 IP 范围的请求才被允许通过。已部署的堆栈包括 ChatGPT([OpenAI 外出 IP](https://openai.com/chatgpt-actions.json))和 Claude([Anthropic 外出 IP](https://docs.anthropic.com/en/api/ip-addresses))的外出 IP 范围。要连接其他 MCP 主机或使用 MCP Inspector 等工具直接测试 MCP 服务器,请将它们的外出 IP 范围添加到 WAF IP 集。
### 2. WAF 管理规则(常见攻击保护)
- **AWS 管理规则通用规则集** — 阻止匹配常见攻击模式的请求
- **AWS 管理规则已知不良输入** — 阻止具有已知与利用相关的有效载荷的请求
- **速率限制** — 阻止每 5 分钟超过 1,000 个请求的 IP
### 3. 资源基于策略(AgentCore 运行时)
直接在 AgentCore 运行时附加资源基于访问策略。它明确允许 API 网关代理 Lambda 的执行角色调用运行时,并拒绝所有其他主体。
## 清理
要销毁所有已部署的资源:
```bash
cd infrastructure/cdk
npx cdk destroy
```