MCP 协议架构解析:从设计原理到 Bedrock 集成的安全工具调用方案

背景

AI Agent 的能力边界取决于它能调用的工具。当前主流的工具接入方式是 function calling——模型输出结构化的函数调用请求,应用层解析后执行。

这个方案在工具数量少的时候够用。但随着 Agent 需要接入的工具增多(存储、数据库、消息队列、内部 API...),每个工具都需要:

  • 定义 JSON Schema
  • 实现调用适配层
  • 处理鉴权和权限
  • 做错误处理和重试
  • 维护版本兼容性

MCP(Model Context Protocol)的设计目标是将工具接入标准化,降低上述成本。

协议架构

角色模型

Host Application (IDE / Agent Framework)
    ↓
MCP Client
    ↓ (JSON-RPC over stdio | HTTP+SSE)
MCP Server
    ↓
External Service (S3, DynamoDB, Custom API...)
  • Host:宿主应用,持有 MCP Client 实例
  • Client:维护与 Server 的连接,发现并调用工具
  • Server:暴露工具(Tools)、数据(Resources)、模板(Prompts)

通信协议

基于 JSON-RPC 2.0:

// Client → Server: 调用工具
{
    "jsonrpc": "2.0",
    "method": "tools/call",
    "params": {
        "name": "read_file",
        "arguments": {"bucket": "my-bucket", "key": "data.json"}
    },
    "id": 1
}

// Server → Client: 返回结果
{
    "jsonrpc": "2.0",
    "result": {
        "content": [{"type": "text", "text": "{\"key\": \"value\"}"}]
    },
    "id": 1
}

Transport 层

  • stdio:Client 和 Server 是同一台机器上的两个进程,通过标准输入输出通信。适合本地开发。
  • HTTP + SSE:Client 通过 HTTP POST 发送请求,Server 通过 SSE(Server-Sent Events)推送结果。适合远程部署。

生产环境推荐 HTTP + SSE + TLS。

工具发现机制

Client 连接 Server 后,先调用 tools/list 获取工具列表:

{
    "tools": [
        {
            "name": "read_file",
            "description": "读取 S3 存储桶中的文本文件",
            "inputSchema": {
                "type": "object",
                "properties": {
                    "bucket": {"type": "string", "description": "存储桶名称"},
                    "key": {"type": "string", "description": "文件路径"}
                },
                "required": ["bucket", "key"]
            }
        }
    ]
}

模型看到这些工具定义后,就知道可以调什么、怎么调。

与 Amazon Bedrock 的集成

Bedrock Agent + MCP

Bedrock Agent 支持 MCP Client。配置 MCP Server 后,Agent 自动发现工具并在推理过程中调用。

实现示例:S3 MCP Server

from mcp.server import Server
import boto3, json

app = Server("s3-mcp-server")
s3 = boto3.client('s3', region_name='cn-northwest-1')

ALLOWED_BUCKETS = ["my-agent-data"]

@app.tool()
async def list_files(bucket: str, prefix: str = "") -> str:
    """列出存储桶中指定前缀下的文件"""
    if bucket not in ALLOWED_BUCKETS:
        return json.dumps({"error": "无权访问该存储桶"})
    
    response = s3.list_objects_v2(
        Bucket=bucket, Prefix=prefix, MaxKeys=50
    )
    files = [
        {"key": obj['Key'], "size": obj['Size']}
        for obj in response.get('Contents', [])
    ]
    return json.dumps(files, ensure_ascii=False)

@app.tool()
async def read_file(bucket: str, key: str) -> str:
    """读取存储桶中的文本文件内容"""
    if bucket not in ALLOWED_BUCKETS:
        return "错误:无权访问"
    if ".." in key:
        return "错误:非法路径"
    
    response = s3.get_object(Bucket=bucket, Key=key)
    content = response['Body'].read().decode('utf-8')
    # 截断,防止占满 context window
    return content[:10000]

安全架构

MCP + Bedrock 的安全是多层交叉的:

┌─── 应用层 ───────────────────────────┐
│  MCP Server 代码:白名单 + 参数校验   │
└──────────────┬───────────────────────┘
               ↓
┌─── IAM 层 ──────────────────────────┐
│  Server IAM Role:最小权限            │
│  Agent IAM Role:最小权限            │
│  两者取交集                          │
└──────────────┬───────────────────────┘
               ↓
┌─── 网络层 ──────────────────────────┐
│  VPC Private Subnet                  │
│  VPC Endpoint + Endpoint Policy      │
└──────────────┬───────────────────────┘
               ↓
┌─── 审计层 ──────────────────────────┐
│  MCP Server 调用日志                 │
│  CloudTrail API 日志                 │
│  CloudWatch 告警                     │
└─────────────────────────────────────┘

关键点:MCP Server 的 IAM Role 就是 Agent 通过该 Server 能做的事的上限。即使 Agent 被 prompt injection 诱导尝试删除文件,Server 的 IAM Role 没有 s3:DeleteObject 权限,操作直接被拒绝。

IAM 策略示例

Server Role(只读):

{
    "Statement": [{
        "Effect": "Allow",
        "Action": ["s3:GetObject", "s3:ListBucket"],
        "Resource": [
            "arn:aws-cn:s3:::my-agent-data",
            "arn:aws-cn:s3:::my-agent-data/*"
        ]
    }]
}

Agent Role(只能调 Bedrock + 受限的 MCP 通信):

{
    "Statement": [
        {
            "Effect": "Allow",
            "Action": ["bedrock:InvokeModel"],
            "Resource": "arn:aws-cn:bedrock:*::foundation-model/anthropic.claude-*"
        }
    ]
}

设计考量

MCP vs 直接 function calling

维度 MCP 直接 function calling
工具接入成本 装一个 Server 手写 schema + 调用代码
工具复用 多 Agent 共享 Server 每个 Agent 单独实现
权限控制 Server 层面集中管理 散落在各处
调试 Server 有独立日志 混在 Agent 日志里
适合场景 工具多、需要复用 工具少、一次性

Transport 选择

Transport 适合场景 安全性
stdio 本地开发、同机部署 进程隔离
HTTP + SSE 生产环境、远程部署 TLS + 认证

生产环境务必用 TLS,并在 HTTP 层加认证(API Key 或 mTLS)。

总结

MCP 的价值在于标准化。工具接入从「每个手动适配」变成「装一个 Server」。

配合 Amazon Bedrock,安全模型是清晰的:

  • MCP Server 代码做业务层限制
  • IAM Role 做权限层限制
  • VPC + Endpoint 做网络层限制
  • CloudTrail 做审计层记录

四层各司其职,Agent 只能在安全边界内调用工具。


Amazon Bedrock:https://aws.amazon.com/cn/bedrock/
Amazon Bedrock AgentCore:https://aws.amazon.com/cn/bedrock/agentcore/
IAM:https://docs.aws.amazon.com/iam/
VPC Endpoints:https://docs.aws.amazon.com/vpc/latest/privatelink/
CloudTrail:https://aws.amazon.com/cn/cloudtrail/

posted @ 2026-03-13 20:00  亚马逊云开发者  阅读(1)  评论(0)    收藏  举报