MCP 服务器部署到 AWS 完整教程
详细讲解将本地 MCP 服务器快速部署到 AWS 的方案,提供了实用的工具链整合指南。
详细讲解将本地 MCP 服务器快速部署到 AWS 的方案,提供了实用的工具链整合指南。
这是一篇包含详细讲解的完整教程。如果你只想快速了解操作流程,请参阅纯代码版本。
“在 AWS 上部署 MCP 服务器,最简单的方法是什么?”
上周,一位朋友问了我这个问题,我意识到:如果你已经有一台本地 MCP 服务器,那么实际上只需要两条 CLI 命令——agentcore configure 和 agentcore launch。从本地开发到生产环境,整个流程只需几分钟。
首先,我们会准备一个小型 MCP 服务器示例,并在本地进行测试以确保它能够正常工作。完成后,我们会将其直接部署到 Bedrock AgentCore Runtime——AWS 为 AI 智能体和 MCP 服务器提供的无服务器托管环境。
只需几分钟,你就能在 AWS 上拥有一台正常运行、可扩展且安全的 MCP 服务器,并可以使用有效的 IAM 凭证直接访问,无需复杂的 OAuth 配置。
开始之前,让我们快速了解一下 AgentCore Runtime,以及为什么它是如此顺理成章的选择。
许多 MCP 服务器需要在请求之间维护会话状态,同时还要确保各个会话之间严格隔离。AWS Lambda 等传统无服务器方案能够提供会话隔离,但它们是无状态的,这意味着你必须自行管理会话,通常需要使用 DynamoDB 或类似服务。ECS 等容器服务可以维持状态,但你必须自行实现会话隔离,或者为每个会话分别运行一个容器——随着时间推移,这可能会变得相当昂贵。
AgentCore Runtime 同时解决了这两个问题:它是无服务器的,你只需为实际处理时间付费;但与 Lambda 不同,它能够在多次调用之间维持会话状态。每个会话都运行在完全隔离的执行环境中。它专门针对 AI 智能体工作负载设计,并会自动处理基础设施。
那么,让我们开始吧!
要学习本教程,你需要:
我们先创建一个简单的掷骰子服务器,用它演示部署流程。这里将使用 FastMCP,它提供了一套基于装饰器的 API,可以快速构建 MCP 服务器。
# Setup your project directory ...
mkdir my-project
# ... and a subdirectory for the server
mkdir my-project/mcp-server
# Then navigate to the subdirectory an initialize with uv
cd my-project/mcp-server
uv init --bare
uv add mcp
uv init --bare 命令会创建一个最小化的项目结构,并且不会显示交互式提示。这样,我们就能获得一个简洁的 pyproject.toml,用于依赖管理。
我们要构建的是一个简单的掷骰子 MCP 服务器,以此演示整个部署工作流。
在 mcp-server 目录中创建一个名为 server.py 的新文件:
# mcp-server/server.py
import random
from mcp.server.fastmcp import FastMCP
mcp = FastMCP(host="0.0.0.0", stateless_http=True)
@mcp.tool()
def roll_d20(number_of_dice: int = 1) -> dict:
"""Rolls one or more 20-sided dice (d20)"""
if number_of_dice < 1:
return {
"error": f"number_of_dice must be at least 1, got: {number_of_dice}"
}
rolls = [random.randint(1, 20) for _ in range(number_of_dice)]
total = sum(rolls)
return {
"number_of_dice": number_of_dice,
"rolls": rolls,
"total": total
}
def main():
mcp.run(transport="streamable-http")
if __name__ == "__main__":
main()
这里发生了什么:
FastMCP 初始化:host="0.0.0.0" 会绑定到所有网络接口,这对于容器化部署是必需的。stateless_http=True 标志非常关键——它告诉 FastMCP 使用基于 HTTP 的传输方式,而不是维持持久连接。
工具注册:@mcp.tool() 装饰器会自动将你的函数注册为 MCP 工具。函数的文档字符串会成为工具描述,类型提示则用于定义输入 schema。MCP 客户端能够发现这个工具,并通过结构化参数调用它。
传输方式:mcp.run(transport="streamable-http") 会使用可流式传输的 HTTP transport 启动服务器。这是基于 HTTP 部署所采用的标准 MCP transport,并且与 AgentCore Runtime 兼容。
部署之前,我们先验证服务器能否正常工作。在本地进行测试有助于尽早发现问题,并能在处理复杂的部署问题之前,确保服务器逻辑正确。
uv run server.py
INFO: Started server process [55952]
INFO: Waiting for application startup.
StreamableHTTP session manager started
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)
FastMCP 在底层使用 Uvicorn,因此你会看到 Uvicorn 的日志。服务器现在正在监听 8000 端口,并已准备好接受 MCP 请求。
打开另一个终端,使用 MCP 协议测试服务器。MCP 使用基于 HTTP 的 JSON-RPC 2.0,因此即使没有 MCP 客户端,我们也可以直接使用 curl 发送 JSON-RPC 请求来测试它。
tools/list 是一个标准 MCP 方法,用于返回所有可用工具。heredoc 语法(<< 'EOF')允许我们直接内联 JSON payload,而不需要创建单独的文件:
curl -X POST http://127.0.0.1:8000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- << 'EOF'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
EOF
你应该能在响应中看到 roll_d20 工具及其描述和输入 schema。
现在让我们调用这个工具。tools/call 方法会使用给定参数调用指定工具:
curl -X POST http://127.0.0.1:8000/mcp \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d @- << 'EOF'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "roll_d20",
"arguments": {
"number_of_dice": 2
}
}
}
EOF
响应中将包含该工具的返回值——在本例中,就是每次掷骰子的结果及其总和。
完成后,使用 CTRL+C 停止本地服务器。这次本地测试能够确认服务器正常工作,之后我们便可以将其打包并部署。
Bedrock AgentCore Starter Toolkit 会处理部署配置。它会生成 Dockerfile、IAM 角色,以及部署服务器所需的全部基础设施代码。请在项目根目录中安装它:
# Navigate to the project root
cd ..
# Initialize a new Python project
uv init --bare
uv add bedrock-agentcore-starter-toolkit
我们在项目根目录中创建一个新项目,是因为该工具包需要将部署配置与 MCP 服务器分开管理。这种分离方式可以让 MCP 服务器代码保持简洁,同时也能更轻松地管理多个部署。
配置你的 AI 智能体:
uv run agentcore configure \
--entrypoint mcp-server/server.py \
--requirements-file mcp-server/pyproject.toml \
--disable-memory --disable-otel \
--non-interactive \
--deployment-type container \
--protocol MCP \
--name my_mcp_server
下面逐一了解每个参数:
--entrypoint 指向服务器的主文件。AgentCore 会在容器内部运行这个文件。
--requirements-file 告诉工具包从哪里查找依赖项。
--disable-memory --disable-otel 用于禁用可选功能。Memory 可以跨会话持久保存状态,而 MCP 服务器不需要此功能。OTEL 用于启用可观测性。为了让示例保持简单,我们将两者都禁用。
--non-interactive 会跳过交互式 CLI 提示并使用默认值。
--deployment-type container 会使用 CodeBuild 将服务器打包为容器镜像,无需本地安装 Docker。
--protocol MCP 告诉 AgentCore 这是一个 MCP 服务器。
--name 用于设置 MCP 服务器名称。
注意:在某些情况下,你可能会看到有关容器引擎或平台不匹配的警告。这些警告可以安全忽略——使用 --deployment-type container 时,AgentCore 会使用 CodeBuild 在云端进行构建。CodeBuild 可以在 ARM64 上运行,而这正是 AgentCore Runtime 使用的架构。因此,即使你的本地计算机使用 x86_64,云端构建仍然能够正常工作。
该配置会创建:
.bedrock_agentcore.yaml——存储所有部署设置的主配置文件。直接编辑此文件时务必格外小心。
.bedrock_agentcore/my_mcp_server/Dockerfile——用于打包服务器的容器定义。工具包会根据你的入口文件和依赖项生成它。
mcp-server/.dockerignore——构建排除规则,用于缩小容器镜像体积。
现在,将服务器部署到 AWS:
uv run agentcore launch --agent my_mcp_server
这一条命令会编排整个部署过程。
其底层会执行以下操作:
1:创建 ECR 仓库——Amazon Elastic Container Registry(ECR)用于存储容器镜像。该工具包会自动创建一个新仓库。
2:设置 IAM 角色——该工具包会创建两个 IAM 角色:
执行角色——授予运行时从 ECR 拉取镜像、执行容器以及将日志写入 CloudWatch 的权限。
CodeBuild 角色——允许 CodeBuild 构建容器并将其推送到 ECR。
3:构建容器——CodeBuild 会在云端构建容器。因此,你不需要在本地安装 Docker——CodeBuild 会负责整个构建过程。
使用生成的 Dockerfile
从 pyproject.toml 安装依赖项
打包服务器代码
创建 ARM64 镜像(AgentCore Runtime 的架构)
将镜像推送到你的 ECR 仓库
4:部署运行时——AgentCore Runtime 使用你的容器镜像创建一个新的运行时实例。
现在,该运行时已准备好接收 MCP 请求。
构建过程大约需要 25~30 秒。完成后,你将看到:
╭────────────────────────────── Deployment Success ───────────────────────────────╮
│ Agent Details: │
│ Agent Name: my_mcp_server │
│ Agent ARN: arn:aws:bedrock-agentcore:REGION:ACCOUNT_ID:runtime/RUNTIME_ID │
│ ... │
╰─────────────────────────────────────────────────────────────────────────────────╯
请记下以下信息——连接服务器时会用到:
Agent ARN——已部署服务器的完整 ARN。它可以在所有 AWS 账户和区域中唯一标识你的运行时。
然后从 ARN 中提取以下信息:
AWS 区域——紧跟在 arn:aws:bedrock-agentcore: 之后,例如 us-west-2。
AWS 账户 ID——一个 12 位数字,紧邻区域。客户端进行基于 IAM 的身份验证时,需要区域和账户 ID。
运行时 ID——ARN 的最后一部分,紧跟在 runtime/ 之后,例如 my_mcp_server-abcde12345。
ARN 格式为:arn:aws:bedrock-agentcore:{region}:{account-id}:runtime/{runtime-id}
使用 AWS CLI 测试已部署的服务器。invoke-agent-runtime 命令会向已部署的服务器发送请求,类似于之前使用 curl 进行的本地测试。
我们将使用进程替换(<(...))直接内联 JSON 载荷,无需创建单独的文件:
# Set your server ARN
export SERVER_ARN="arn:aws:bedrock-agentcore:REGION:ACCOUNT:runtime/RUNTIME_ID"
# List available tools
aws bedrock-agentcore invoke-agent-runtime \
--agent-runtime-arn $SERVER_ARN \
--content-type "application/json" \
--accept "application/json, text/event-stream" \
--payload fileb://<(cat <<'EOF'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
EOF
) list-tools.txt
# Call the tool
aws bedrock-agentcore invoke-agent-runtime \
--agent-runtime-arn $SERVER_ARN \
--content-type "application/json" \
--accept "application/json, text/event-stream" \
--payload fileb://<(cat <<'EOF'
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "roll_d20",
"arguments": {
"number_of_dice": 2
}
}
}
EOF
) call-tool.txt
你将看到:AWS CLI 会打开一个分页器,显示 HTTP 响应元数据,包括状态码、响应头以及 MCP 会话 ID。按 q 退出。实际的 JSON-RPC 响应会写入输出文件——查看 list-tools.txt 获取工具列表,查看 call-tool.txt 获取掷骰子的结果。
请注意,这些请求与本地测试中的请求完全相同——无论是在本地运行还是在 AgentCore Runtime 上运行,MCP 请求都是一样的。唯一的区别是端点和身份验证方式。
现在,我们可以使用官方的 IAM MCP 客户端将 AI 智能体连接到已部署的服务器。该客户端会自动处理 MCP 请求的创建和 IAM 身份验证。这展示了实际应用中的智能体会如何连接到你的服务器。
我们将使用 Strands Agents SDK 作为示例框架,但这种模式适用于任何支持 MCP 的智能体框架。你可以查看我的另一篇文章,其中演示了如何配合 LangChain、LlamaIndex 和 Microsoft 的 Agent Framework 使用 IAM MCP 客户端。
仍然在项目根目录中,添加以下软件包:
uv add mcp-proxy-for-aws strands-agents
mcp-proxy-for-aws 是 AWS 针对标准 MCP 客户端提供的官方封装。标准客户端需要 OAuth,而这个客户端会使用 AWS 凭证通过 SigV4 对请求进行签名,因此能够兼容 AWS 上的 IAM 身份验证。strands-agents 软件包提供了本示例中要使用的智能体框架。
创建 test_agent.py,并添加运行时 ID、AWS 账户 ID 和区域:
# Using Strands Agents SDK for this example
from strands import Agent
from strands.tools.mcp import MCPClient
from mcp_proxy_for_aws.client import aws_iam_streamablehttp_client
# Set your MCP server details from Step 4
RUNTIME_ID = "[YOUR RUNTIME ID]"
ACCOUNT_ID = "[YOUR ACCOUNT ID]"
REGION = "[YOUR AWS REGION]"
def main():
# Build the MCP server URL
url = f"https://bedrock-agentcore.{REGION}.amazonaws.com/runtimes/{RUNTIME_ID}/invocations?qualifier=DEFAULT&accountId={ACCOUNT_ID}"
print(f"\nInitializing MCP client with IAM-based auth for:\n{url}")
mcp_client_factory = lambda: aws_iam_streamablehttp_client(
aws_service="bedrock-agentcore",
aws_region=REGION,
endpoint=url,
terminate_on_close=False
)
with MCPClient(mcp_client_factory) as mcp_client:
mcp_tools = mcp_client.list_tools_sync()
agent = Agent(tools=mcp_tools)
query_1 = "What tools do you have available?"
print(f"\nQ: {query_1}")
agent(query_1)
query_2 = "Roll three dice"
print(f"\nQ: {query_2}")
agent(query_2)
if __name__ == "__main__":
main()
下面来了解其中的关键部分:
端点 URL 构造:该 URL 遵循 AgentCore 的调用端点格式。qualifier=DEFAULT 参数指定要使用的端点版本(AgentCore 支持多个版本,以便进行渐进式发布)。
客户端工厂模式:Strands Agents SDK 的 MCPClient 需要一个工厂函数(即返回客户端的 lambda)。这样,框架就可以管理连接的生命周期——在需要时创建新连接,并在之后正确清理连接。
aws_iam_streamablehttp_client 函数会创建一个 MCP 客户端,并使用你的 AWS 凭证以及服务器所在的区域和 AWS 服务,自动对所有请求进行签名。
工具发现:mcp_client.list_tools_sync() 会从服务器获取所有可用工具。随后,智能体会接收这些工具,并根据用户查询调用它们。当智能体看到“Roll three dice”时,它会识别出该请求与 roll_d20 工具匹配,并使用 number_of_dice=3 调用该工具。
会话管理:terminate_on_close=False 参数指示客户端在关闭时不要显式终止 MCP 会话。AgentCore Runtime 会自动管理会话生命周期,因此无需执行此操作。
uv run test_agent.py
注意:你可能会看到弃用警告:DeprecationWarning: Use 'streamable_http_client' instead.。官方 MCP 客户端库最近重命名了其 HTTP 客户端,IAM 客户端也正在更新,以与之保持一致。可以安全地忽略此警告。等你读到本文时,这个问题可能已经修复。
智能体将使用你的 AWS 凭证建立连接,并使用已部署 MCP 服务器中的工具。
这展示了完整的流程:服务器已经部署,可以通过 IAM 访问,并且已与 AI 智能体框架集成。
同样的模式也适用于 LangChain 或 LlamaIndex 等其他框架——只需替换智能体框架,同时继续使用 IAM MCP 客户端即可。
实验结束后,请销毁部署,以避免产生持续费用:
uv run agentcore destroy --agent my_mcp_server
此命令会移除部署过程中创建的所有资源:
AgentCore 运行时——正在运行的 MCP 服务器实例
ECR 仓库和镜像——存储在 ECR 中的容器镜像
CodeBuild 项目——构建配置(每次构建本身是临时的,但项目定义会持续存在)
IAM 角色——执行角色和 CodeBuild 角色
S3 构建产物——存储在 CodeBuild 所创建 S3 存储桶中的构建产物
该工具包在清理资源时十分谨慎——它不会删除在工具包之外创建的资源。删除前系统会要求你确认,因为此操作不可逆。
本教程介绍了完整的部署工作流:
本地开发——使用 FastMCP 在本地构建和测试 MCP 服务器。本地测试有助于在部署前发现问题。
本地开发——使用 FastMCP 在本地构建和测试 MCP 服务器。本地测试有助于在部署前发现问题。
配置——AgentCore Starter Toolkit 会根据配置生成所有基础设施代码(Dockerfile、IAM 角色等)。这种抽象让你可以专注于服务器逻辑,而不是部署细节。
配置——AgentCore Starter Toolkit 会根据配置生成所有基础设施代码(Dockerfile、IAM 角色等)。这种抽象让你可以专注于服务器逻辑,而不是部署细节。
云端部署——AgentCore Runtime 使用 CodeBuild 构建容器,因此你无需在本地安装 Docker。运行时会自动管理状态、会话隔离和基础设施——你只需提供容器镜像。
云端部署——AgentCore Runtime 使用 CodeBuild 构建容器,因此你无需在本地安装 Docker。运行时会自动管理状态、会话隔离和基础设施——你只需提供容器镜像。
测试——AWS CLI 的 invoke-agent-runtime 命令允许你使用与本地测试相同的 MCP 协议来测试已部署的服务器。IAM 身份验证会通过你的 AWS 凭证自动完成。
测试——AWS CLI 的 invoke-agent-runtime 命令允许你使用与本地测试相同的 MCP 协议来测试已部署的服务器。IAM 身份验证会通过你的 AWS 凭证自动完成。
集成——IAM MCP 客户端让任何智能体框架都能使用 AWS 凭证连接到由 AgentCore 托管的 MCP 服务器,无需搭建 OAuth 基础设施。
集成——IAM MCP 客户端让任何智能体框架都能使用 AWS 凭证连接到由 AgentCore 托管的 MCP 服务器,无需搭建 OAuth 基础设施。
与其他框架集成——查看《无需 OAuth:适用于 AWS IAM 的 MCP 客户端》,了解如何连接 LangChain、LlamaIndex 或其他智能体框架
通过 AgentCore Gateway 部署——使用 Bedrock AgentCore Gateway 将现有 API 转换为 MCP 服务器
探索更复杂的 MCP 服务器——为你的服务器添加多个工具、资源和提示词
核心要点:Bedrock AgentCore Runtime 提供具有状态化会话的无服务器执行环境。即使服务器会在请求之间保持状态,你也只需为实际处理时间付费。这种基于会话的模型非常适合智能体工作负载,包括 MCP。
如果你从中学到了新知识,希望你能为这篇文章点赞。如果想快速了解整个过程而不需要太多讲解,请查看仅包含代码的版本。
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。