MCP模型上下文协议:AI的万能接口与MCP Server实战

前言

在上一篇《AI Agent的工具箱》中,我们讲了 Function Calling——让 AI 调用单个工具的方式。但你有没有想过一个问题:

如果我有 100 个工具,分布在不同的系统里,每个都要在代码里手动注册,那岂不是要疯?

更现实的问题是:工具的提供者和使用者往往是不同的人。数据库团队提供查询能力,运维团队提供部署能力,财务团队提供报销能力——每个团队都想把自己的能力暴露给 AI,但没人想把自己嵌入别人的代码里。

这就是 MCP(Model Context Protocol,模型上下文协议) 要解决的问题。

简单说:MCP 是 AI 世界的 USB 接口。它定义了一套标准协议,让任何系统都能以统一的方式向 AI 暴露能力,不需要改 AI 的代码,也不需要改彼此的代码。


一、MCP 是什么

MCP 由 Anthropic 于 2024 年底提出,2025 年成为开放标准,目前最新规范版本是 2025-11-25

它的核心思想用一句话概括:

把”AI 能用什么工具”这件事,从硬编码变成热插拔。

在没有 MCP 的世界里,如果你想让 AI 查天气,你得:

  1. 写一个 getWeather() 函数
  2. 把它注册到 AI 框架里
  3. 在 prompt 里告诉 AI 有这个工具可用

如果你想让 AI 同时查天气、查股票、操作数据库、发邮件……每个都要手动注册。而且这些能力分散在不同的服务里,你得把它们全部集成到一个项目里。

有了 MCP 之后:

  1. 每个能力方独立实现一个 MCP Server
  2. AI 应用作为 MCP Client 自动发现和连接这些 Server
  3. 标准协议保证它们能互相理解

就像你不需要自己写打印机驱动——操作系统通过 USB 协议自动识别设备。


二、架构:Host、Client、Server

MCP 采用 Host-Client-Server 三层架构:

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────┐
│ Application Host │
│ ┌──────────┐ ┌──────────┐ ┌─────┐ │
│ │ Client 1 │ │ Client 2 │ │ .. │ │
│ └────┬─────┘ └────┬─────┘ └──┬──┘ │
└───────┼─────────────┼──────────┼────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌──▼───┐
│ Server1 │ │ Server2 │ │ ... │
│ 文件/Git│ │ 数据库 │ │ │
└─────────┘ └─────────┘ └──────┘

三个角色:

Host(宿主)

就是你的 AI 应用本体——Claude Desktop、Cursor、你写的 Spring Boot 服务等。它负责:

  • 创建和管理多个 Client
  • 控制连接权限和安全策略
  • 协调 AI 推理和上下文聚合

Client(客户端)

每个 Client 和一个 Server 保持 1:1 的有状态连接。它负责:

  • 协议协商(告诉 Server “我支持哪些能力”)
  • 双向消息路由
  • 管理订阅和通知

Server(服务端)

提供具体能力的程序。可以是本地进程,也可以是远程服务。它负责:

  • 通过标准接口暴露工具、资源、提示词
  • 独立运行,职责单一

一个 Host 可以同时连接多个 Server:查天气的 Server、查数据库的 Server、操作文件的 Server……它们彼此隔离,互不干扰。


三、三大核心能力

MCP Server 可以暴露三种类型的能力:

1. Tools(工具)

类似 Function Calling 的函数,可以被 AI 主动调用。适合执行操作类任务:

1
2
3
4
5
6
7
8
9
10
11
{
"name": "get_weather",
"description": "查询指定城市的天气",
"inputSchema": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "城市名称" }
},
"required": ["city"]
}
}

和 Function Calling 的区别: Function Calling 是在 AI 框架内部定义的,而 MCP Tool 是在外部 Server 里定义的,通过标准协议暴露出来。

2. Resources(资源)

类似 REST API 的 GET 请求,向 AI 提供上下文数据。比如读取文件内容、查询数据库记录、获取配置信息:

1
2
3
4
5
{
"uri": "file:///project/README.md",
"name": "项目说明",
"mimeType": "text/markdown"
}

Resource 是被动的——Client 决定什么时候加载,加载什么。适合给 AI 提供背景知识。

3. Prompts(提示词模板)

预定义的交互模板,帮助用户快速发起特定任务:

1
2
3
4
5
6
7
8
{
"name": "code_review",
"description": "代码审查模板",
"arguments": [
{ "name": "language", "description": "编程语言" },
{ "name": "code", "description": "待审查代码" }
]
}

一句话区分三者:

  • Tool = AI 做的事(主动调用)
  • Resource = AI 知道的事(被动加载)
  • Prompt = AI 怎么做(模板引导)

四、传输方式

MCP 支持两种传输协议:

stdio(标准输入输出)

Server 作为子进程运行,Client 通过 stdin/stdout 和它通信。适合本地工具:

1
2
Client ──stdin──> Server (子进程)
Client <─stdout── Server

Streamable HTTP

Server 作为 HTTP 服务运行,Client 通过 HTTP 请求通信。支持 SSE(Server-Sent Events)实现服务端推送。适合远程服务:

1
2
Client ──HTTP POST──> Server (远程)
Client <──SSE stream── Server

注意: 早期版本支持 SSE 传输,已在 2025-11-25 规范中标记为 deprecated,推荐使用 Streamable HTTP。


五、MCP vs Function Calling

很多人会问:既然有了 Function Calling,为什么还需要 MCP?

维度 Function Calling MCP
定义位置 写在 AI 应用代码里 独立的外部 Server
发现机制 手动注册 自动发现、动态协商
跨进程 ❌ 只能在同一进程 ✅ 支持跨进程、跨机器
复用性 和框架绑定 任何 MCP Client 都能用
安全边界 无隔离 Server 之间互相隔离
能力类型 只有工具 工具 + 资源 + 提示词

简单说:Function Calling 是单机版,MCP 是分布式版。 Function Calling 适合快速原型,MCP 适合生产级的工具生态。


六、实战:用 Python 实现一个 MCP Server

Python SDK 提供了 FastMCP 框架,实现一个 MCP Server 只需要几行代码。

6.1 环境准备

1
2
3
4
5
6
# 创建项目
uv init mcp-weather-server
cd mcp-weather-server

# 安装 MCP SDK
uv add "mcp[cli]"

6.2 实现 Server

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
# weather_server.py
from mcp.server.fastmcp import FastMCP

# 创建 MCP Server
mcp = FastMCP("WeatherServer")

# 模拟天气数据
WEATHER_DB = {
"北京": {"temp": 28, "condition": "晴", "humidity": 35},
"上海": {"temp": 31, "condition": "多云", "humidity": 72},
"深圳": {"temp": 33, "condition": "雷阵雨", "humidity": 85},
}


@mcp.tool()
def get_weather(city: str) -> str:
"""查询指定城市的天气预报"""
if city not in WEATHER_DB:
return f"暂无 {city} 的天气数据"
w = WEATHER_DB[city]
return f"{city}{w['condition']}{w['temp']}°C,湿度 {w['humidity']}%"


@mcp.tool()
def list_cities() -> list[str]:
"""返回所有可查询的城市列表"""
return list(WEATHER_DB.keys())


@mcp.resource("weather://{city}")
def weather_resource(city: str) -> str:
"""以资源形式暴露天气数据"""
if city not in WEATHER_DB:
return f"No data for {city}"
w = WEATHER_DB[city]
return f"{city}: {w['condition']}, {w['temp']}°C"


@mcp.prompt()
def weather_report(city: str) -> str:
"""生成天气播报的提示词模板"""
return f"请用简洁的播报风格,为用户播报 {city} 的天气情况,包含着装建议。"


if __name__ == "__main__":
mcp.run(transport="streamable-http")

6.3 运行和测试

1
2
3
4
5
# 启动 Server
uv run weather_server.py

# 用 MCP Inspector 测试(可视化调试工具)
npx -y @modelcontextprotocol/inspector

打开 Inspector UI,连接 http://localhost:8000/mcp,你可以看到:

  • Tools 列表里有 get_weatherlist_cities
  • Resources 列表里有 weather://{city} 模板
  • Prompts 列表里有 weather_report

直接在 Inspector 里调用工具,看返回结果,非常方便。


七、实战:用 Java(Spring AI)实现一个 MCP Server

Java 生态里,Spring AI 提供了完整的 MCP Server 集成。

7.1 项目依赖

创建一个 Spring Boot 项目(需要 Java 17+),添加依赖:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- pom.xml -->
<dependencies>
<!-- STDIO 模式(本地子进程) -->
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>

<!-- 或者 WebMVC 模式(HTTP 服务) -->
<!--
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
-->
</dependencies>

传输模式选择:

  • spring-ai-starter-mcp-server → stdio 模式,适合本地 CLI 工具
  • spring-ai-starter-mcp-server-webmvc → HTTP 模式,适合 Web 服务

7.2 实现 Server

Spring AI 的 MCP 注解体系非常直观:

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
import org.springframework.ai.mcp.annotation.McpTool;
import org.springframework.ai.mcp.annotation.McpToolParam;
import org.springframework.ai.mcp.annotation.McpResource;
import org.springframework.ai.mcp.annotation.McpPrompt;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.List;

@Component
public class WeatherTools {

private static final Map<String, WeatherData> WEATHER_DB = Map.of(
"北京", new WeatherData(28, "晴", 35),
"上海", new WeatherData(31, "多云", 72),
"深圳", new WeatherData(33, "雷阵雨", 85)
);

@McpTool(name = "get_weather", description = "查询指定城市的天气预报")
public String getWeather(
@McpToolParam(description = "城市名称", required = true) String city) {
var data = WEATHER_DB.get(city);
if (data == null) {
return "暂无 " + city + " 的天气数据";
}
return String.format("%s:%s,%d°C,湿度 %d%%",
city, data.condition(), data.temp(), data.humidity());
}

@McpTool(name = "list_cities", description = "返回所有可查询的城市列表")
public List<String> listCities() {
return List.copyOf(WEATHER_DB.keySet());
}

@McpResource(uri = "weather://{city}", name = "天气数据")
public String weatherResource(String city) {
var data = WEATHER_DB.get(city);
if (data == null) return "No data for " + city;
return String.format("%s: %s, %d°C", city, data.condition(), data.temp());
}

@McpPrompt(name = "weather_report", description = "天气播报提示词模板")
public String weatherReport(String city) {
return "请用简洁的播报风格,为用户播报 " + city + " 的天气情况,包含着装建议。";
}

record WeatherData(int temp, String condition, int humidity) {}
}

7.3 启动类

1
2
3
4
5
6
7
8
9
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class McpServerApplication {
public static void main(String[] args) {
SpringApplication.run(McpServerApplication.class, args);
}
}

7.4 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
# application.yml
spring:
ai:
mcp:
server:
name: WeatherServer
version: 1.0.0

# STDIO 模式(默认)
# spring.ai.mcp.server.stdio=true

# HTTP 模式
# spring.ai.mcp.server.protocol=STREAMABLE

7.5 注解说明

注解 作用 对应 MCP 能力
@McpTool 标记方法为 MCP 工具 Tools
@McpToolParam 描述工具参数 Tools 的 inputSchema
@McpResource 暴露资源(URI 模板) Resources
@McpPrompt 定义提示词模板 Prompts

Spring AI 的自动配置会扫描带这些注解的 Bean,自动生成 JSON Schema,注册到 MCP Server。你不需要手动写 schema、不需要手动注册回调,加注解就是全部工作


八、MCP Server 的进阶玩法

8.1 动态工具注册

除了注解,你也可以用编程方式注册工具:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Bean
public List<McpServerFeatures.SyncToolSpecification> customTools() {
var tool = new McpToolSpecification(
"send_email",
"发送邮件",
emailSchema, // JSON Schema
(exchange, params) -> {
// 执行发送邮件逻辑
return new CallToolResult("邮件已发送", false);
}
);
return List.of(tool);
}

8.2 生命周期管理

Python 的 FastMCP 支持 lifespan,适合管理数据库连接等资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from contextlib import asynccontextmanager
from mcp.server.fastmcp import FastMCP

@asynccontextmanager
async def app_lifespan(server: FastMCP):
# 启动时初始化
db = await Database.connect()
try:
yield AppContext(db=db)
finally:
# 关闭时清理
await db.disconnect()

mcp = FastMCP("MyApp", lifespan=app_lifespan)

8.3 安全上下文

Spring AI 的 MCP Server 支持通过 McpTransportContext 获取认证信息:

1
2
3
4
5
6
7
@McpTool
public String accessProtected(McpSyncRequestContext requestContext) {
McpTransportContext ctx = requestContext.transportContext();
String token = (String) ctx.get("authorization");
// 验证 token 后执行操作
return "操作成功";
}

九、MCP 的生态和工具

MCP Inspector

官方提供的可视化调试工具,支持连接任意 MCP Server,浏览工具、资源、提示词,直接调用测试:

1
npx -y @modelcontextprotocol/inspector

已有的 MCP Server 生态

截至目前,社区已经贡献了大量开箱即用的 MCP Server:

  • 文件系统 — 读写本地文件
  • GitHub — 操作仓库、Issue、PR
  • PostgreSQL / MySQL — 数据库查询
  • Slack / Discord — 消息发送
  • Google Drive — 文件管理
  • Puppeteer — 浏览器自动化

你可以在 MCP Server Registry 找到完整列表。


十、总结

MCP 解决的核心问题是:让 AI 的能力从”写死在代码里”变成”热插拔的标准接口”。

回顾一下关键点:

  1. 架构:Host-Client-Server,一个 Host 可以连多个 Server
  2. 三大能力:Tools(做事)、Resources(获取信息)、Prompts(模板引导)
  3. 传输方式:stdio(本地)、Streamable HTTP(远程)
  4. Python 实现FastMCP + 装饰器,几行代码搞定
  5. Java 实现:Spring AI @McpTool / @McpResource / @McpPrompt 注解驱动

如果你正在做 AI Agent 开发,MCP 几乎是必经之路。它不只是一个协议,更是 AI 能力分发的基础设施。

下一篇预告: Multi-Agent 多智能体协作——当一个 Agent 不够用时,怎么让一群 Agent 协同工作?


参考资料: