AI 编码代理正在从"能写代码"走向"能操作基础设施"——但直接把 AWS 凭证塞给代理,等于把整栋楼的钥匙交给一个实习生。AWS 的 Model Context Protocol(MCP)服务器现在正式 GA,它做的事情很明确:用标准接口把 AWS API、文档和运维流程暴露给代理,同时用 IAM 做细粒度权限管控,每一步操作可审计。
MCP 在 AWS 场景里解决了什么
MCP 是 Anthropic 推出的开放协议,定义了 AI 工具与外部系统之间的标准交互方式。对 AWS 来说,这个协议的价值不在"连接"本身——SDK 和 CLI 早就能连——而在连接的安全边界。
过去让代理操作 AWS,常见做法是硬编码一个 Access Key 到环境变量,或者把 ~/.aws/credentials 整个文件喂进去。代理拿到的是全账户权限,调用什么 API、改什么资源,全靠代理"自觉"。审计日志里只能看到一堆 API 调用,无法追溯到是哪个代理、哪次对话触发的。
AWS MCP Server 把这个模型翻转了:
- 代理不再持有原始凭证,它通过 MCP 协议与 Server 交互,Server 背后用 IAM Role 策略决定"能做什么"。
- API 覆盖范围是全量的,GA 版本覆盖了 AWS 已有的 API、文档查询和常见运维工作流(比如 CDK 部署、CloudWatch 告警配置)。
- 每次调用可追溯,Server 在 IAM 审计链路上留下了清晰的调用身份和操作记录。
IAM 治理:不是"能连就行",而是"能连且只做允许的事"
AWS MCP Server 的权限模型完全复用 IAM,没有另搞一套。这意味着你现有的 IAM 策略设计经验可以直接迁移。
核心思路:给 MCP Server 绑定一个 IAM Role,这个 Role 的权限就是代理的权限上限。代理想调用 ec2:RunInstances?先看 Role 里有没有这条 Allow。想读 S3 对象?同理。
实际操作中,推荐用最小权限策略,只开放代理当前任务需要的 API。比如一个只负责查看资源状态的代理,不需要任何写权限:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlyAccess",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"s3:List*",
"s3:GetObject",
"cloudwatch:Describe*",
"cloudwatch:Get*",
"logs:Describe*",
"logs:Get*"
],
"Resource": "*"
}
]
}
如果代理需要执行变更操作——比如创建 Lambda 函数或修改安全组——就逐条加 Allow,而不是给 *:* 权限。审计时,CloudTrail 会记录这个 Role 的每一次调用,你可以在日志里看到"某时间点通过 MCP Server 调用了 lambda:CreateFunction",比追踪一个散落在各处的 Access Key 清晰得多。
实战:把 AWS MCP Server 接入你的编码代理
下面用一个完整示例展示如何配置 AWS MCP Server 并接入 Claude Code(或其他 MCP 客户端)。
前置条件
- 已安装
uv(Python 包管理器,MCP Server 用它运行) - AWS CLI 已配置好,当前身份有足够权限创建 IAM Role
- 已安装 Claude Code CLI 或其他支持 MCP 的客户端
第一步:创建受限 IAM Role
# 创建信任策略,允许当前 AWS 身份扮演该 Role
ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
cat > trust-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT_ID_PLACEHOLDER:root"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
sed -i "s/ACCOUNT_ID_PLACEHOLDER/$ACCOUNT_ID/" trust-policy.json
# 创建 Role
aws iam create-role \
--role-name MCPAgentReadOnly \
--assume-role-policy-document file://trust-policy.json
# 挂载只读策略(上面 JSON 中的策略)
cat > readonly-policy.json << 'EOF'
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOnlyAccess",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"s3:List*",
"s3:GetObject",
"cloudwatch:Describe*",
"cloudwatch:Get*",
"logs:Describe*",
"logs:Get*"
],
"Resource": "*"
}
]
}
EOF
aws iam put-role-policy \
--role-name MCPAgentReadOnly \
--policy-name ReadOnlyForMCP \
--policy-document file://readonly-policy.json
第二步:配置 MCP 客户端
在 Claude Code 的配置文件 ~/.claude/settings.json 中添加 MCP Server:
{
"mcpServers": {
"awslabs": {
"command": "uvx",
"args": [
"awslabs.aws-mcp-server-cli@latest"
],
"env": {
"AWS_REGION": "us-east-1",
"AWS_PROFILE": "mcp-agent"
}
}
}
}
然后在 ~/.aws/config 中配置 mcp-agent profile,让它使用刚创建的 Role:
[profile mcp-agent]
role_arn = arn:aws:iam::YOUR_ACCOUNT_ID:role/MCPAgentReadOnly
source_profile = default
region = us-east-1
把 YOUR_ACCOUNT_ID 替换为你的实际账户 ID。
第三步:启动代理并验证
# 启动 Claude Code,它会自动加载 MCP Server
claude
# 在对话中让代理查询 AWS 资源,比如:
# "列出 us-east-1 区域所有 EC2 实例的状态"
# "查看 my-app-bucket 这个 S3 桶里有哪些文件"
代理会通过 MCP Server 调用 AWS API,权限受 MCPAgentReadOnly Role 限制。如果你让代理尝试创建资源,它会收到 IAM 拒绝错误——这正是你想要的。
几个落地时的取舍点
要不要给代理写权限? 取决于你的自动化成熟度。初期建议只给读权限,让代理做"观察-建议"而非"观察-执行"。等审计流程和回滚机制完善后,再逐步放开特定写操作。
多代理场景怎么隔离? 不同代理绑定不同 IAM Role。前端代理只读 CloudWatch 和 Logs,部署代理有 lambda:CreateFunction 和 s3:PutObject,但不含 iam:*。用 Role 名做审计标识,比用同一个凭证区分代理可靠得多。
MCP Server 本身的运行开销? 它是本地进程,通过 uvx 启动,不额外收费。成本只在 AWS API 调用侧——和手动调用一样计费。唯一新增的是 IAM Role 的管理成本,但这是你本来就该做的事。
和 AWS IAM Identity Center 的关系? 如果你的组织用 Identity Center 统一管人,MCP Server 的 Role 同样可以纳入 Center 的权限集管理,不需要单独维护一套策略体系。
上手检查清单
- 确认当前 AWS CLI 身份能正常
sts:GetCallerIdentity,基础连通没问题 - 创建一个最小权限 IAM Role,先只给读权限,跑通 MCP Server 的连接
- 在 CloudTrail 里验证:代理的查询操作是否以该 Role 身份被记录
- 逐步按任务需要加写权限,每次加一条 Allow,观察一周再扩
- 多代理环境用不同 Role 做权限隔离,不要共用一个"万能 Role"
AWS MCP Server GA 的意义不是"又一个 SDK",而是给 AI 代理和基础设施之间加了一道可审计、可收紧的闸门。闸门开多大,由你用 IAM 决定——这比把钥匙扔给代理要安全得多,也比完全不让代理碰基础设施要实用得多。