基于 MCP 协议构建私有研发智能体:将内部 API 与 CI/CD 全面 Agent 化
基于 MCP 协议构建私有研发智能体:将内部 API 与 CI/CD 全面 Agent 化
在日常研发协同中,工程师经常在各种异构平台间疲于奔命:切到 GitLab 提 MR、登录 Jenkins 查看流水线构建失败原因、再开终端敲 kubectl logs 排查 CrashLoopBackOff。虽然大模型拥有强大的代码理解与推理能力,但传统以单一 Function Calling 为核心的二次开发方案存在协议不通用、上下文状态共享脆弱、缺乏统一鉴权与生命周期管理等严重缺陷。
随着 Anthropic 主导开源的 MCP(Model Context Protocol,模型上下文协议) 迅速成为事实标准,研发基础设施的 Agent 化迎来了架构统一的最佳契机。本文将以大厂生产落地的视角,带大家基于 Java / Spring Boot 生态,将 GitLab、Jenkins、K8s 封装为标准化 MCP 架构,并攻克高危发布场景下的 Human-in-the-loop(人机交互确认) 安全难题。
一、问题背景与业务痛点
在尝试让 LLM 接管日常研发与运维流程时,多数团队初期会采用“大模型 + 自建 OpenAPI Plugin”的简易方案,但在复杂企业环境中很快会遭遇以下痛点:
- 协议孤岛与上下文割裂:每个研发系统(GitLab、Jira、Jenkins、ArgoCD)的 API 返回结构迥异。LLM 单纯靠多次调用 Tool,不仅消耗大量 Token,还极易丢失上下文;同时,缺乏如“实时查看日志流”这种针对动态资源(Resource)的标准订阅通道。
- 缺乏统一协议,客户端难以复用:自建的 Function Calling 往往深度绑定特定的 Agent 框架。一旦开发者想在 Claude Desktop、Cursor、VS Code 或内部自研聊天机器人中接入这些运维能力,必须重写大量适配层。
- 高危写操作引发的“灾难性幻觉”:运维操作与代码分析不同,触发流水线、重启 Pod、打 Tag、合并主干均具有不可逆的外部副作用。如果缺乏框架级的安全拦截与二次确认机制,模型的任何一次意图漂移都可能导致生产事故。
MCP 的出现完美解耦了这一架构:它将外部能力抽象为 Resources(静态/动态上下文)、Tools(可执行函数) 以及 Prompts(提示词模版),基于 JSON-RPC 2.0 规范,让私有内部服务能够一处编写、处处挂载。
二、
▲ 权威参考图:Modern Agentic Architecture & RAG Retrieval Flow (已转存博客园图床)
核心设计与解决思路
为了实现高内聚、低耦合且安全可控的 DevOps Agent,我们基于 Spring Boot 构建统一的 Private DevOps MCP Server。
1. 核心架构设计与组件拓扑图
MCP 架构的核心是明确三层职责:Host(宿主) 负责大模型驱动与 UI 渲染,Client(客户端) 负责路由与连接,Server(服务端) 负责业务封装与资源隔离。
flowchart TD
subgraph Agent Host & Client Layer [智能体宿主与交互层]
Host[研发交互终端 IDE / ChatBot / Cursor]
LLM[大语言模型 (DeepSeek / Claude / Qwen)]
MCPClient[MCP Client (路由、协议解析、连接池)]
Host <--> LLM
Host <--> MCPClient
end
subgraph Security Layer [安全与审批层]
HITL[Human-in-the-loop 拦截网关]
Approver[企业微信 / 钉钉审批端]
HITL -.->|高危操作推审| Approver
end
subgraph Private DevOps MCP Server [私有 DevOps MCP 服务端 (Spring Boot 3.x)]
Dispatcher[JSON-RPC 2.0 调度器 (Stdio / SSE)]
subgraph MCP Primitives
Tools[MCP Tools<br/>- trigger_jenkins_build<br/>- restart_k8s_deployment]
Resources[MCP Resources<br/>- k8s://logs/{podName}<br/>- gitlab://diff/{mrId}]
Prompts[MCP Prompts<br/>- triage-ci-failure<br/>- review-k8s-event]
end
Dispatcher --> Tools
Dispatcher --> Resources
Dispatcher --> Prompts
end
subgraph Internal Infra [企业基础设施]
GitLab[(GitLab API)]
Jenkins[(Jenkins Master)]
K8s[(Kubernetes Cluster)]
end
MCPClient <==>|JSON-RPC via SSE/HTTP| Dispatcher
Tools --> HITL
HITL --> Jenkins
HITL --> K8s
Resources --> GitLab
Resources --> K8s
2. 端到端请求执行时序图(含 Human-in-the-loop 审批)
当研发人员发出“排查构建失败并重新发布到预发环境”的意向时,系统通过 MCP 资源拉取日志,分析后若涉及写操作,自动触发中断挂起与人工确认:
▲ 时序图 2:端到端请求处理与调用时序链路
3. 技术方案选型对比
| 评估维度 | 传统自建 OpenAPI + Function Calling | LangChain / Agent Framework 专用 Tool | 基于 MCP 标准协议 (本文方案) |
|---|---|---|---|
| 生态通用性 | 极低,仅私有系统可用 | 中等,强绑定 Python / TS 运行时环境 | 极高,天然支持 Cursor、Claude、各类 IDE 与 CLI |
| 模型上下文管理 | 纯靠字符串拼接,无标准协议约束 | 依赖 Framework 内置 Memory,多系统难共享 | 协议级支持 Resources 与 Prompts,结构化下发 |
| 传输协议支持 | 仅标准 HTTP Restful | 框架进程内部调用,跨语言成本高 | 双模支持:本地 Stdio 管道 / 远程 SSE (Server-Sent Events) |
| 运维控制粒度 | 依赖业务代码写死安全控制 | 难以跨进程解耦中断审核流 | 标准拦截点:在 RPC 协议层原生实现鉴权与 HITL |
三、完整实战代码与配置
环境说明:JDK 21、Spring Boot 3.3.4、Spring AI 1.0.0-M3(包含 MCP 官方规范适配体系)或使用标准 JSON-RPC 2.0 规范接入。此处给出基于真实企业环境的 MCP DevOps Server 核心实现代码。
1. 核心依赖配置与引导配置
<!-- pom.xml 片段 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- 引入标准 JSON-RPC 支持与 Kubernetes Client -->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>6.13.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
# bootstrap.yml
server:
port: 8088
mcp:
server:
name: "corp-devops-agent-server"
version: "1.0.0"
security:
hitl:
webhook-url: "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=your-token"
require-approval-tools:
- "restart_k8s_deployment"
- "trigger_jenkins_build"
gitlab:
api-url: "https://gitlab.internal.corp/api/v4"
token: "${GITLAB_PRIVATE_TOKEN}"
2. MCP 协议基础模型与注解声明
// McpSchema.java - 抽象核心 MCP 交互协议规范
package com.corp.mcp.protocol;
import java.lang.annotation.*;
import java.util.Map;
public class McpSchema {
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface McpTool {
String name();
String description();
boolean requiresApproval() default false;
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface McpResource {
String uriTemplate();
String mimeType() default "text/plain";
String description();
}
public record ToolCallRequest(String name, Map<String, Object> arguments) {}
public record ToolCallResult(String content, boolean isPendingApproval, String taskId) {}
public record ResourceResponse(String uri, String mimeType, String text) {}
}
3. DevOps MCP Server 资源与工具实现
// DevOpsMcpTools.java - 将 Jenkins、K8s 注册为标准 MCP 能力
package com.corp.mcp.server;
import com.corp.mcp.protocol.McpSchema.*;
import com.corp.mcp.security.HitlApprovalService;
import io.fabric8.kubernetes.client.KubernetesClient;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.Map;
@Slf4j
@Component
@RequiredArgsConstructor
public class DevOpsMcpTools {
private final KubernetesClient k8sClient;
private final HitlApprovalService hitlService;
/**
* 声明 MCP Resource:通过 URI 读取实时 Pod 日志
* 客户端可直接读取:k8s://logs/{namespace}/{podName}
*/
@McpResource(
uriTemplate = "k8s://logs/{namespace}/{podName}",
mimeType = "text/plain",
description = "实时获取 Kubernetes 指定集群命名空间内 Pod 的最后 100 行日志"
)
public ResourceResponse getPodLogs(String namespace, String podName) {
log.info("MCP Resource 读取日志: {}/{}", namespace, podName);
String logData = k8sClient.pods()
.inNamespace(namespace)
.withName(podName)
.tailingLines(100)
.getLog();
return new ResourceResponse("k8s://logs/" + namespace + "/" + podName, "text/plain", logData);
}
/**
* 声明 MCP Tool:重启 K8s 服务(定义为敏感写操作,接入审批流程)
*/
@McpTool(
name = "restart_k8s_deployment",
description = "对指定的 Kubernetes Deployment 触发滚动重启",
requiresApproval = true
)
public ToolCallResult restartDeployment(Map<String, Object> params) {
String namespace = (String) params.get("namespace");
String deploymentName = (String) params.get("deploymentName");
String operator = (String) params.getOrDefault("operator", "agent-system");
// 触发 HITL 审批挂起机制
String taskId = hitlService.submitApprovalTask("K8S_ROLLOUT_RESTART",
"请求重启 Deployment: " + namespace + "/" + deploymentName, operator, () -> {
k8sClient.apps().deployments()
.inNamespace(namespace)
.withName(deploymentName)
.rolling()
.restart();
log.info("Approval Passed: Restart executed for {}/{}", namespace, deploymentName);
});
return new ToolCallResult("操作属于高危指令,已进入人机审核队列。任务ID: " + taskId, true, taskId);
}
/**
* 声明 MCP Tool:触发 Jenkins 构建
*/
@McpTool(
name = "trigger_jenkins_build",
description = "触发特定工程的分支流水线构建",
requiresApproval = false
)
public ToolCallResult triggerBuild(Map<String, Object> params) {
String jobName = (String) params.get("jobName");
String branch = (String) params.get("branch");
log.info("执行 Jenkins 构建: job={}, branch={}", jobName, branch);
// 此处省略 Jenkins Rest API 客户端调用
return new ToolCallResult("Build triggered successfully on branch: " + branch, false, null);
}
}
4. Human-in-the-loop (HITL) 审批协调器
// HitlApprovalService.java - 处理安全挂起与异步回调通知
package com.corp.mcp.security;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
@Service
public class HitlApprovalService {
private final Map<String, PendingTask> taskRegistry = new ConcurrentHashMap<>();
public record PendingTask(String taskId, String actionType, String detail, String operator, Runnable callback) {}
public String submitApprovalTask(String actionType, String detail, String operator, Runnable callback) {
String taskId = UUID.randomUUID().toString().substring(0, 8);
taskRegistry.put(taskId, new PendingTask(taskId, actionType, detail, operator, callback));
// 模拟企业微信 Webhook 通知
pushNotificationToApprover(taskId, actionType, detail, operator);
return taskId;
}
public boolean approveAndExecute(String taskId) {
PendingTask task = taskRegistry.remove(taskId);
if (task == null) {
log.warn("审批任务不存在或已失效: {}", taskId);
return false;
}
try {
task.callback().run();
log.info("任务 [{}] 审批通过,已回调成功执行!", taskId);
return true;
} catch (Exception e) {
log.error("执行批准任务失败: {}", e.getMessage(), e);
return false;
}
}
private void pushNotificationToApprover(String taskId, String actionType, String detail, String operator) {
log.warn(">>>> [HITL 预警] 操作需人工确认: TaskID=[{}], Action=[{}], 详情=[{}], 发起人=[{}]",
taskId, actionType, detail, operator);
// 生产对接企业微信 API 发送带「批准」「拒绝」按钮的卡片
}
}
四、避坑指南与总结验证
在生产落地与大模型压测过程中,将运维系统 Agent 化会暴露多个极具隐蔽性的工程挑战,以下是核心避坑经验:
1. 核心踩坑与解决方案
- 避坑 1:日志资源拉取导致“上下文膨胀”与 Token 瞬时打爆
- 问题场景:运维排查让 Agent 读取日志,K8s 默认返回上千行堆栈,直接耗尽上下文窗口甚至引发模型拒绝响应。
- 解法:在 MCP Resource 内部做智能分块(Chunking)与特征修剪(Pruning)。在服务端预过滤掉健康检查(如
/actuator/health200 OK 日志),并仅截取异常抛错点(Exception/Error/Fatal)向上 30 行、向下 50 行的上下文返回,严禁原样抛出原始流。
- 避坑 2:SSE(Server-Sent Events)长连接被内网网关强行超时重置
- 问题场景:远程 MCP 客户端使用 SSE 协议连接内部 MCP Server,Nginx 或 ALB 默认配置了 60 秒无数据自动断开,导致 Agent 长对话中途出现断连。
- 解法:服务端必须实现规范的心跳 ping 机制(每 15 秒推送一次空注释包
:keepalive\n\n);同时配置 Nginx 禁用代理缓冲(proxy_buffering off;)与读写超时时间(proxy_read_timeout 3600s;)。
- 避坑 3:Tool 参数注入漏洞与越权操作(Prompt Injection)
- 问题场景:恶意 PR 或攻击者通过 Issue 标题注入恶意 Prompt,诱导 LLM 构造出如
deploymentName: "order-service; rm -rf /"等异常参数。 - 解法:MCP Server 层坚决不直接通过 Shell/Bash 执行拼接字符串。全面采用强类型的 SDK(如 Fabric8 Kubernetes Client、GitLab4J),参数严格走正则白名单校验(如
^[a-z0-9]([-a-z0-9]*[a-z0-9])?$)。
- 问题场景:恶意 PR 或攻击者通过 Issue 标题注入恶意 Prompt,诱导 LLM 构造出如
2. 成果与验证步骤
- 协议发现验证:启动 MCP 服务,通过客户端发送 JSON-RPC 探活请求:
bash curl -X POST http://localhost:8088/mcp/v1/rpc \ -H "Content-Type: application/json" \ -d '{"jsonrpc": "2.0", "id": 1, "method": "tools/list"}'
检查是否成功输出trigger_jenkins_build、restart_k8s_deployment及其 JSON Schema。 - 端到端发布阻断测试:
在 Chat 终端输入:“帮我重启订单服务”。 - 观察控制台,MCP Server 立即截获该操作,返回状态
Pending Approval,并打印出审批 Task ID; - 模拟运维人员调用审批接口后,K8s 集群才真正触发滚动重启。
总结
通过引入 MCP 协议,我们成功抹平了研发运维体系中由于异构 API 导致的割裂现状。LLM 不再是一个空洞的代码生成器,而是升级为具备私有上下文洞察力、拥有标准化执行抓手、且始终处于安全护栏限制下的高可靠研发副驾(Copilot)。这种标准化的 Agentic DevOps 架构,将是企业研发平台演进的确定性方向。

本文深入剖析基于 MCP(Model Context Protocol)协议构建私有研发智能体的实战方案。通过 Java/Spring Boot 将 GitLab、Jenkins、K8s 封装为标准 MCP Tool 与 Resource,配合 Human-in-the-loop 人机确认机制,实现安全可靠的 CI/CD 自动化与排错闭环。
浙公网安备 33010602011771号