公司动态

MCP 是什么:Agent 如何通过标准协议连接工具和外部服务

📅 2026/8/14 16:58:49
MCP 是什么:Agent 如何通过标准协议连接工具和外部服务
前言前面我们已经学习了 Tool Calling。Tool Calling 的基本思路是模型决定要调用什么工具后端负责校验参数、执行真实业务然后把结果返回给模型。但是当 Agent 项目逐渐变多时会出现一个新问题每个 Agent 都要重复接数据库工具吗 每个 Agent 都要重复对接 Git、文件系统、接口文档吗 不同模型、不同框架之间工具定义能不能复用这时MCP 就出现了。MCP 全称是 Model Context Protocol可以理解为一种让 AI 应用连接外部能力的标准协议。它希望解决的问题不是“让模型变聪明”而是让 Agent 能以更统一的方式发现、调用和使用外部工具、资源与提示词模板。对于 Java 后端开发者来说MCP 可以先理解成Agent 侧的标准化工具接入协议它和我们平时做 REST API、RPC、消息队列一样核心价值是降低系统之间的耦合。一、没有 MCP 时工具接入会遇到什么问题假设我们开发了三个 Agent项目知识库助手 代码审查助手 运维排障助手它们都可能需要访问一些公共能力查询 Git 提交记录 搜索项目文件 读取接口文档 查询发布记录 查询服务日志如果每个 Agent 都自己封装一套工具会变成下面这样知识库助手 - 自己实现 Git 查询工具 代码审查助手 - 再实现一套 Git 查询工具 运维助手 - 再实现一套日志查询工具久而久之就会出现工具定义不统一参数格式不统一权限校验逻辑分散错误处理方式不一致工具升级时需要改多个项目很难让新的 Agent 快速复用已有能力。MCP 的思路是把这些能力标准化。多个 Agent Client | | MCP 协议 | 多个 MCP Server | Git、数据库、文件、内部接口、日志系统这样Agent 不需要关心每个外部系统具体怎么实现而是通过统一的工具描述和调用方式使用能力。二、MCP 的核心角色理解 MCP 时可以先记住三个角色。1. MCP HostHost 是承载 AI 交互的应用。例如桌面 AI 客户端IDE 插件Agent 平台企业内部智能助手Java 编写的聊天应用。它负责管理用户交互、模型调用以及 MCP Client。2. MCP ClientClient 负责连接具体的 MCP Server。它通常会做这些事情建立连接获取工具列表调用工具获取资源接收结果处理异常和超时。一个 Host 可以有多个 MCP Client因为它可能要连接多个 MCP Server。3. MCP ServerServer 是能力提供方。它可以对外暴露Tools可执行工具Resources可读取资源Prompts可复用提示词模板。例如一个项目管理 MCP Server 可以提供get_project_info list_project_documents search_issue get_release_history一个日志 MCP Server 可以提供search_error_logs get_service_health get_trace_detail三、MCP 中的 Tools、Resources、Prompts1. Tools可执行能力Tool 是模型可以请求调用的动作。例如查询订单状态 搜索项目文件 获取服务健康状态 创建测试任务 查询发布记录工具通常带有工具名称工具描述参数定义参数类型返回结果权限要求。一个工具可以抽象成下面这个结构{name:get_order_status,description:根据订单号查询订单当前状态只能查询当前用户有权限访问的订单。,inputSchema:{type:object,properties:{orderNo:{type:string,description:订单编号}},required:[orderNo]}}模型会根据工具描述判断是否需要调用它。但请注意工具描述是给模型理解能力边界用的不是权限控制。真正的权限校验必须由 MCP Server 或业务后端完成。2. Resources可读取资料Resource 更像“外部可读取内容”。例如项目 README 接口规范 数据库设计文档 部署手册 系统配置说明资源可以理解为给 Agent 提供上下文的内容来源。例如resource://project/readme resource://project/api-doc resource://ops/deploy-guide与 Tool 的区别在于Tool 偏向执行动作Resource 偏向读取内容Tool 可能产生副作用Resource 一般用于提供信息。例如“查询实时订单状态”应该是 Tool“读取订单状态枚举说明”更适合作为 Resource。3. Prompts可复用提示词模板Prompts 用于提供标准化的提示词模板。例如代码审查模板 线上故障排查模板 接口设计模板 SQL 优化分析模板一个“代码审查” Prompt 可能需要参数language diff focus调用时可以传入{language:Java,focus:安全性和事务边界,diff:...}对于团队来说这种方式可以把高质量 Prompt 沉淀下来而不是让每个用户都从零写一遍。四、MCP 和 Tool Calling 有什么关系很多同学第一次看到 MCP 时会觉得它和 Tool Calling 很像。确实它们有关联但不是同一个概念。对比项Tool CallingMCP本质模型调用工具的机制工具、资源、提示词的标准协议关注点模型如何选择并发起调用Agent 如何统一连接外部能力工具定义常由应用自行维护可由 MCP Server 对外暴露复用范围单个应用内也可使用更适合跨 Agent、跨客户端复用权限控制由业务后端实现仍然由 MCP Server 和业务系统实现可以这样理解Tool Calling 解决“模型怎么发起工具调用” MCP 解决“外部工具怎么以标准方式提供给 Agent”它们完全可以配合使用。用户提问 - Agent 判断需要工具 - 通过 MCP Client 发现并调用 MCP Tool - MCP Server 校验权限并执行 - 返回结果给 Agent - Agent 组织最终回答五、一个项目查询 MCP Server 的设计示例假设我们要做一个“项目研发助手”它需要查询项目文档、发布记录和接口信息。可以先定义三个工具search_project_document get_release_history get_api_detail1. 工具定义DatapublicclassMcpToolDefinition{privateStringname;privateStringdescription;privateMapString,ObjectinputSchema;}构造一个查询发布记录工具publicMcpToolDefinitionbuildReleaseHistoryTool(){McpToolDefinitiontoolnewMcpToolDefinition();tool.setName(get_release_history);tool.setDescription( 查询指定项目最近的发布记录。 只能查询当前用户有权限访问的项目。 返回发布时间、版本号、发布环境和发布状态。 );MapString,ObjectpropertiesMap.of(projectId,Map.of(type,string,description,项目ID),limit,Map.of(type,integer,description,返回数量范围1到20));tool.setInputSchema(Map.of(type,object,properties,properties,required,List.of(projectId)));returntool;}这段代码只是表达工具描述的思路。实际接入 MCP SDK 时会按照 SDK 提供的方式注册工具。六、工具执行的正确边界假设模型请求调用{name:get_release_history,arguments:{projectId:project-a,limit:10}}后端不能直接拿参数执行查询而应该完成以下步骤1. 校验工具是否允许调用 2. 校验参数格式 3. 校验当前用户是否登录 4. 校验用户是否有项目权限 5. 执行受控业务查询 6. 过滤敏感字段 7. 记录审计日志 8. 返回结构化结果1. 参数对象DatapublicclassReleaseHistoryQuery{NotBlank(message项目ID不能为空)privateStringprojectId;Min(value1,messagelimit不能小于1)Max(value20,messagelimit不能大于20)privateIntegerlimit10;}2. 工具执行 ServiceServiceRequiredArgsConstructorpublicclassReleaseHistoryToolService{privatefinalProjectPermissionServiceprojectPermissionService;privatefinalReleaseRecordMapperreleaseRecordMapper;privatefinalAgentAuditLogServiceagentAuditLogService;publicToolExecuteResultexecute(LonguserId,ReleaseHistoryQueryquery){projectPermissionService.checkReadPermission(userId,query.getProjectId());ListReleaseRecordrecordsreleaseRecordMapper.selectRecent(query.getProjectId(),query.getLimit());ListReleaseRecordVOresultrecords.stream().map(this::convertToSafeView).toList();agentAuditLogService.record(userId,get_release_history,query.getProjectId(),SUCCESS);returnToolExecuteResult.success(result);}privateReleaseRecordVOconvertToSafeView(ReleaseRecordrecord){ReleaseRecordVOvonewReleaseRecordVO();vo.setVersion(record.getVersion());vo.setEnvironment(record.getEnvironment());vo.setStatus(record.getStatus());vo.setReleaseTime(record.getReleaseTime());returnvo;}}文字说明工具调用之前必须做项目权限校验不要把数据库实体原样返回给模型应该通过 VO 过滤内部字段每次工具执行都应记录审计日志工具失败时应该返回可控错误信息而不是数据库异常堆栈。七、为什么不要让 MCP Server 直接暴露数据库能力有些人会想既然 Agent 要查数据那我干脆提供一个 execute_sql 工具。例如{name:execute_sql,arguments:{sql:SELECT * FROM user}}这在生产环境中风险非常高。模型可能因为理解偏差、提示词注入或参数构造错误生成危险 SQLDELETEFROMuser;或者越权查询SELECT*FROMemployee_salary;更合理的方式是提供业务语义明确的工具get_order_status list_user_orders get_project_release_history search_error_logs get_api_detail这样可以让后端控制查询范围可返回字段分页上限权限逻辑敏感字段脱敏操作审计。核心原则是模型负责表达意图后端负责执行受控业务能力。八、MCP Server 中的安全设计1. 工具白名单不要让客户端随意调用任意内部能力。privatestaticfinalSetStringALLOWED_TOOLSSet.of(search_project_document,get_release_history,get_api_detail);当收到工具调用时publicvoidcheckToolAllowed(StringtoolName){if(!ALLOWED_TOOLS.contains(toolName)){thrownewBusinessException(不允许调用该工具);}}2. 参数校验模型生成的参数并不可靠。例如它可能传{limit:999999}所以必须做类型校验必填校验长度校验枚举校验数值范围校验业务规则校验。3. 高风险操作必须确认以下操作不能因为模型调用了工具就立即执行删除数据修改权限发布生产环境发起支付发送批量通知调整库存执行退款。推荐的流程Agent 生成操作计划 - 后端返回待确认信息 - 用户确认 - 后端执行 - 返回执行结果例如即将发布项目 project-a 到测试环境版本为 v1.2.0。 本次操作会重启 2 个服务实例是否确认4. 审计日志建议至少记录用户ID 会话ID 工具名称 请求参数摘要 执行结果 耗时 时间 失败原因但日志中不要记录完整 Token、密码、密钥和敏感业务字段。九、MCP 与 RAG 如何配合MCP 不等于 RAG。RAG 主要解决“从文档中检索知识”MCP 主要解决“以标准协议连接工具与资源”。但它们可以结合。例如用户问测试环境最近一次发布是什么时候发布后错误率有没有升高Agent 可以拆成两个步骤步骤1通过 MCP Tool 查询最近发布记录。 步骤2通过 MCP Tool 查询发布前后的错误日志或监控指标。 步骤3结合结果生成分析结论。如果用户问项目的灰度发布流程是什么这更适合使用 RAG从发布规范文档中检索答案。简单记忆稳定说明文档 - RAG 实时系统数据 - MCP Tool 用户历史偏好 - Memory 固定高风险流程 - Workflow十、实际开发建议1. 先从只读工具开始第一次做 MCP Server建议先提供只读能力查询项目文档 查询接口说明 查询发布记录 查询日志摘要 查询服务健康状态只读工具的风险更低也更容易调试。2. 工具粒度不要太粗不推荐manage_project operate_system execute_database_command推荐get_project_info get_release_history search_project_document get_service_health search_error_logs工具名称越清晰模型选择工具越稳定后端也越容易控制权限。3. 工具返回要简洁、结构化不要把几百 KB 原始日志直接返回给模型。推荐返回{serviceName:order-service,timeRange:2026-07-18 10:00:00 ~ 2026-07-18 10:10:00,errorCount:12,topErrors:[{type:DatabaseTimeoutException,count:8}]}模型需要的是能用于推理和回答的信息不是无限量原始数据。十一、总结这一篇我们认识了 MCP 的基本作用和开发边界。重点可以记住MCP 是 Agent 连接外部工具、资源和提示词模板的标准协议。MCP 包含 Host、Client、Server 三类角色。Tool 用于执行受控能力Resource 用于读取资料Prompt 用于复用提示词模板。MCP 与 Tool Calling 可以配合但两者不是同一个概念。MCP Server 不应该直接暴露任意 SQL、Shell 或内部高危操作。权限校验、参数校验、脱敏、审计日志必须由后端负责。高风险操作需要显式确认不能只靠模型判断。初学阶段建议先实现只读、业务语义明确的工具。下一篇我们继续学习多智能体协作一个 Agent 不够用时如何把规划、执行、审核等职责拆开。