Agent如何传递不同类型的ID给MCP Server

1 概述

在Agent中,ID可以分两大类:一类是大模型推理出的业务ID(例如聊天记录中的ordier_id),另一类是Agent自身决定注入的上下文ID(例如user_id、tenant_id)。上下文ID 往往和系统的认证、权限相关,不能由大模型推理决定,必须由Agent完全把关

Agent作为mcp client,发送的数据包如下:

复制代码
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "cancelOrder",
    "arguments": {  
      // 1. 这里放的是【大模型推理】出的业务ID
      "orderId": "20260811-ABC"
    },
    "_meta": {      
      // 2. 这里放的是【Agent自定决策】的上下文ID(Spring AI 自动放这里)
      "userId": "U-999",
      "tenantId": "TENANT-BJ",
      "traceId": "a1b2c3d4"
    }
  }
}

arguments字段:只包含大模型从用户聊天记录中提取的 orderId。

_meta字段:包含 Agent(例如你写的 Java 代码)决策后强行注入的 userId、tenantId 等。

2 Mcp Client 端(Agent应用)如何把 ID 塞进 _meta

在 Spring AI 中,你通过配置 AsyncMcpToolCallback 的 toolContextToMcpMetaConverter,告诉框架:"请把 Java 上下文里的 ID 自动转为 _meta 字段"。

复制代码
import org.springframework.ai.mcp.AsyncMcpToolCallback;
import org.springframework.ai.tool.ToolContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.security.core.context.SecurityContextHolder;

import java.util.Map;
import java.util.UUID;
import java.util.function.Function;

@Configuration
public class AgentClientConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder
            // 关键配置:定义如何将 ToolContext 转为 MCP 的 _meta
            .mcpToolCallbacks(List.of(AsyncMcpToolCallback.builder()
                .toolContextToMcpMetaConverter((Function<ToolContext, Map<String, Object>>) context -> {
                    // Agent 决策:从安全上下文或本地生成 ID
                    String userId = SecurityContextHolder.getContext().getAuthentication().getName(); // U-999
                    String tenantId = TenantContextHolder.getCurrentTenant(); // TENANT-BJ
                    String traceId = UUID.randomUUID().toString(); // a1b2c3d4
                    
                    // 返回的 Map 将自动成为 JSON 中的 _meta 对象
                    return Map.of(
                        "userId", userId,
                        "tenantId", tenantId,
                        "traceId", traceId
                    );
                })
                .build()))
            .build();
    }
}

业务调用代码(Service 层):

复制代码
@Service
public class OrderAgentService {
    private final ChatClient chatClient;

    public String handleUserRequest(String userInput) {
        // 用户输入:"帮我把订单 20260811-ABC 取消掉"
        // LLM推理出的ID会自动注入arguments字段
        // 上下文类型ID由上面的Converter自动注入_meta字段
        return chatClient.prompt(userInput)
            .call()
            .content();
    }
}

3 Mcp Server端如何拿到 _meta 里的 ID

在 MCP Server 端,Spring AI 会自动将收到的 JSON 解析并注入到 @Tool 方法的参数中。你需要让工具方法接收一个 ToolContext 参数,这个参数里就包含了 _meta 的所有内容。

Server 端工具定义代码:

复制代码
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.ToolContext;
import org.springframework.stereotype.Component;

@Component
public class OrderTools {

    @Tool(description = "根据订单ID取消订单")
    public String cancelOrder(
            // 1. 这里的 orderId 从 JSON 的 arguments 中获取(大模型推理)
            String orderId,
            
            // 2. 这里的 ToolContext 由框架自动注入,包含 _meta 的所有键值对
            ToolContext toolContext) {
        
        // 从 ToolContext 中提取 Agent 决策的 ID
        // 注意:这里拿到的 key 必须和 Client 端 Converter 里写的 key 一致
        String realUserId = (String) toolContext.getContext().get("userId");   // U-999
        String tenantId = (String) toolContext.getContext().get("tenantId");   // TENANT-BJ
        String traceId = (String) toolContext.getContext().get("traceId");     // a1b2c3d4

        // 安全校验:打印日志,确认 userId 绝对不是来自大模型
        System.out.println("安全校验:真实用户ID = " + realUserId);
        System.out.println("大模型提供的订单号 = " + orderId);

        // 执行业务,使用 realUserId 操作数据库,杜绝越权
        return orderService.cancel(realUserId, tenantId, orderId);
    }
}

4 总结:ID的流转路径

环节 动作 数据变化
用户输入 说了一句话 "取消 20260811-ABC"
大模型推理 提取业务参数 输出 arguments: {orderId: "20260811-ABC"}
Client Converter Agent 决策,注入上下文 自动生成 _meta: {userId: "U-999", ...}
网络传输 (JSON) 组装完整请求 params 里同时包含 arguments 和 _meta
Mcp Server 接收 框架解析 JSON 将 arguments 映射给 orderId 参数,将 _meta 映射给 ToolContext 参数
工具方法执行 获取并验证 业务代码从 ToolContext 拿 userId,抛弃大模型可能给出的任何用户标识
相关推荐
伞伞悦读3 分钟前
【第36期】Python 目录与路径详解:pathlib、文件遍历、创建、复制、移动和删除风险
开发语言·python
线上放牧人25 分钟前
Windows删除图标缓存
windows·python·pyqt
qq_5470261791 小时前
Python 变量和简单数据类型
python
智搜广告2 小时前
智搜广告:科技行业AI回答优化公司如何破局
大数据·python·elasticsearch·geo
IpdataCloud3 小时前
AI智能体调用工具怎么核验来源IP?归属地、网络类型与代理风险识别(含Python代码)
数据库·python·tcp/ip
2601_966949653 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
蒸鱼Yuzheng3 小时前
Python 游戏测试开发怎么准备:日志解析、接口校验、并发与可维护性
自动化测试·python·测试开发·面试题·游戏测试
m0_734571763 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
Ivanqhz3 小时前
BM1688 双核架构
python·深度学习·神经网络·cnn·mlir
Java后端的Ai之路4 小时前
Python进阶探索17 - Python中的深拷贝与浅拷贝
人工智能·python·ai·浅拷贝·深拷贝