MCP协议详解-模型上下文协议实战

引言

MCP(Model Context Protocol,模型上下文协议)是 Anthropic 推出的开放协议,旨在标准化 AI 模型与外部工具、数据源的集成方式。本文将深入解析 MCP 协议的原理和实战应用。

什么是 MCP

MCP 定义了一套标准化的接口规范,使得 AI 模型能够:

  • 发现和调用外部工具
  • 访问结构化数据
  • 执行特定领域的操作

核心概念

1
2
3
4
┌─────────────┐     MCP Protocol     ┌─────────────┐
│ AI Model │ ◄──────────────────► │ MCP Tool │
│ (Client) │ │ (Server) │
└─────────────┘ └─────────────┘

MCP 协议架构

1. 协议分层

1
2
3
应用层:Tool Definition、Resource Access
传输层:JSON-RPC 2.0
传输层:Stdio / SSE / HTTP

2. 核心组件

Tool(工具)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public interface MCPTool {
/**
* 工具名称
*/
String getName();

/**
* 工具描述
*/
String getDescription();

/**
* 参数定义(JSON Schema)
*/
String getInputSchema();

/**
* 执行工具
*/
ToolResult execute(Map<String, Object> arguments);
}

Tool 实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@Component
public class WeatherTool implements MCPTool {

@Autowired
private WeatherService weatherService;

@Override
public String getName() {
return "get_weather";
}

@Override
public String getDescription() {
return "获取指定城市的天气信息";
}

@Override
public String getInputSchema() {
return """
{
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
},
"date": {
"type": "string",
"description": "日期,格式:YYYY-MM-DD"
}
},
"required": ["city"]
}
""";
}

@Override
public ToolResult execute(Map<String, Object> arguments) {
String city = (String) arguments.get("city");
String date = (String) arguments.getOrDefault("date", "today");

try {
WeatherInfo weather = weatherService.query(city, date);
return ToolResult.success(weather.toString());
} catch (Exception e) {
return ToolResult.error("查询天气失败: " + e.getMessage());
}
}
}

SpringAI 集成 MCP

1. 依赖配置

1
2
3
4
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-mcp</artifactId>
</dependency>

2. MCP Server 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
public class MCPConfig {

@Bean
public MCPServer mcpServer(List<MCPTool> tools) {
MCPServer server = new MCPServer();

// 注册所有工具
for (MCPTool tool : tools) {
server.registerTool(tool);
}

return server;
}

@Bean
public McpSyncServer mcpSyncServer(MCPServer server) {
// 配置传输方式(Stdio)
StdioServerTransport transport = new StdioServerTransport();

return McpSyncServer.create(server, transport);
}
}

3. 客户端调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@Service
public class MCPClientService {

@Autowired
private ChatModel chatModel;

public String chatWithTools(String userMessage) {
// 定义可用工具
List<ToolDefinition> tools = Arrays.asList(
ToolDefinition.builder()
.name("get_weather")
.description("获取指定城市的天气信息")
.inputSchema("""
{
"type": "object",
"properties": {
"city": {"type": "string"},
"date": {"type": "string"}
},
"required": ["city"]
}
""")
.build(),
ToolDefinition.builder()
.name("search_database")
.description("查询数据库")
.inputSchema("""
{
"type": "object",
"properties": {
"sql": {"type": "string"}
},
"required": ["sql"]
}
""")
.build()
);

Prompt prompt = new Prompt(
userMessage,
ToolCallingChatOptions.builder()
.toolDefinitions(tools)
.build()
);

ChatResponse response = chatModel.call(prompt);

// 处理工具调用
if (response.hasToolCalls()) {
List<ToolCall> toolCalls = response.getToolCalls();
// 执行工具调用并返回结果
return executeToolCalls(toolCalls);
}

return response.getResult().getOutput().getContent();
}
}

实际应用场景

1. 智能运维助手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Component
public class DevOpsAssistant {

@Autowired
private MCPClient mcpClient;

/**
* 分析系统异常
*/
public String analyzeError(String errorLog) {
String prompt = """
分析以下系统错误日志,并提供解决方案:

%s

你可以使用以下工具:
1. search_logs - 搜索相关日志
2. query_metrics - 查询系统指标
3. check_config - 检查配置文件
""".formatted(errorLog);

return mcpClient.chat(prompt);
}
}

2. 数据库查询助手

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Component
public class DatabaseQueryTool implements MCPTool {

@Autowired
private JdbcTemplate jdbcTemplate;

@Override
public String getName() {
return "execute_query";
}

@Override
public String getDescription() {
return "执行 SQL 查询并返回结果";
}

@Override
public ToolResult execute(Map<String, Object> arguments) {
String sql = (String) arguments.get("sql");

// SQL 安全检查
if (!isSafeSQL(sql)) {
return ToolResult.error("不安全的 SQL 语句");
}

try {
List<Map<String, Object>> results = jdbcTemplate.queryForList(sql);
return ToolResult.success(JSON.toJSONString(results));
} catch (Exception e) {
return ToolResult.error("查询失败: " + e.getMessage());
}
}

private boolean isSafeSQL(String sql) {
String lowerSQL = sql.toLowerCase();
// 禁止危险操作
return !lowerSQL.contains("drop")
&& !lowerSQL.contains("delete")
&& !lowerSQL.contains("update")
&& lowerSQL.trim().startsWith("select");
}
}

MCP 与 Function Calling 对比

特性 MCP Function Calling
标准化 是,开放协议 各厂商独立实现
工具发现 支持动态发现 需预定义
传输方式 Stdio/SSE/HTTP HTTP
生态系统 正在发展 已成熟
跨平台 支持 依赖厂商

最佳实践

1. 工具设计原则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 工具设计最佳实践
*/
public class ToolBestPractices {

// 1. 清晰的命名
// ❌ query
// ✅ search_user_orders

// 2. 详细的描述
// 描述应包含:功能、参数说明、返回值、示例

// 3. 参数验证
public ToolResult execute(Map<String, Object> args) {
// 参数校验
if (!args.containsKey("required_param")) {
return ToolResult.error("缺少必需参数: required_param");
}

// 类型检查
if (!(args.get("count") instanceof Integer)) {
return ToolResult.error("count 必须是整数");
}

// 业务逻辑...
}

// 4. 错误处理
// 提供清晰的错误信息,便于模型理解
}

2. 安全性考虑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Component
public class SecureMCPExecutor {

/**
* 工具调用权限控制
*/
public ToolResult executeWithAuth(MCPTool tool,
Map<String, Object> args,
UserContext user) {
// 1. 权限检查
if (!hasPermission(user, tool.getName())) {
return ToolResult.error("无权使用该工具");
}

// 2. 参数过滤
Map<String, Object> sanitizedArgs = sanitizeArgs(args);

// 3. 执行工具
return tool.execute(sanitizedArgs);
}

private Map<String, Object> sanitizeArgs(Map<String, Object> args) {
// 防止注入攻击
// 过滤敏感字符
// ...
return args;
}
}

总结

MCP 协议为 AI 工具集成提供了标准化方案,主要优势:

  1. 标准化接口:统一工具定义和调用方式
  2. 动态发现:支持运行时工具发现
  3. 跨平台:不依赖特定 AI 厂商
  4. 可扩展:易于添加新工具

随着生态的发展,MCP 有望成为 AI 工具集成的标准协议。


本文基于 SpringAI MCP 模块实践,探索 AI 工具标准化集成方案


MCP协议详解-模型上下文协议实战
https://zxyblog.top/2025/01/10/MCP协议详解-模型上下文协议实战/
作者
zxy
发布于
2025年1月10日
许可协议