11|凤雏来了:什么是模型上下文协议MCP?

你好,我是邢云阳。

在前置课程的第二节课,我曾经为你讲解了 Agent 技术。我们抛开思维链不谈,Agent 最牛的是能够通过调用工具实现大模型与外界环境的交互,让大模型不再“闭关锁国”。

Agent在 24 年得到了人们广泛认可,发展得十分迅速,现在已经成了 AI 应用开发的必备技术了。如果我们这些开发者是刘备的话,那 Agent 就是卧龙先生诸葛亮,我得先生,如鱼得水也。

然而就像《西虹市首富》电影里说的那样,“我没想到一所普通的小学,竟能同时培养出你们二位”,有卧龙的地方必有凤雏。因此在去年下半年,Anthropic(Claude 模型的母公司) 推出了模型上下文协议 MCP,该协议旨在统一大型语言模型(LLM)与外部数据源和工具之间的通信协议。

MCP主要是为了解决当前 AI 模型因数据孤岛限制,无法充分发挥潜力的难题,MCP 使得 AI 应用能够安全地访问和操作本地及远程数据,为 AI 应用提供了连接万物的接口。

这个协议在社区发展得非常好,现在已经有很多 AI 应用或框架,比如 Spring AI等接入了MCP,也有很多开发者为其贡献了 MCP Server,在我看来,它与 Agent 技术殊途同归,因此我称之为凤雏。

接下来,我们就深度学习一下 MCP,并体验一下它如何使用。

MCP 架构

首先,我们用一张简化的图回顾一下“卧龙” Agent。

这张图里,我把 AI Agent 看成一个封闭的系统,一个盒子。盒子内部包括大脑 DeepSeek 或其他大模型,以及工具调用程序。当大模型选择了工具之后,需要有一个工具调用程序,去实际的进行工具的调用,例如通过 Rest API 访问墨迹天气获取天气预报等等。

大家可以去 ChatGPT 的 GPTs(需要付费) 创建一个自定义 ChatGPT 应用,或者去扣子、Dify(免费) 等平台创建一个 Agent 来体验一下上图的效果。或者试读一下我的课程《AI 重塑云原生应用开发实战》的第 1314 讲,云体验一下效果。有了这个基础之后,我们再来看 MCP,就相对好理解了。

MCP 采用的是经典的客户端-服务器架构,我首先需要介绍几个概念。

  • MCP 主机(MCP Hosts):发起请求的 LLM 应用程序(例如 Claude Desktop、IDE 或 AI 工具)。

  • MCP 客户端(MCP Clients):在主机程序内部,与 MCP server 保持 1:1 的连接。

  • MCP 服务器(MCP Servers):为 MCP client 提供上下文、工具和 prompt 信息。

  • 本地资源(Local Resources):本地计算机中可供 MCP server 安全访问的资源(例如文件、数据库)。

  • 远程资源(Remote Resources):MCP server 可以连接到的远程资源(例如通过 API)。

之后我还画了一张图,帮你把前面的概念串起来。

咋样?感觉和 AI Agent 的图像不?简直太像了。

唯一不同的点在于 MCP 把工具调用程序做成了一个 C-S 架构,工具的实际调用由 MCP Server 来完成。

MCP Server

MCP Server 相对比较独立,可以独立开发,独立部署,可以远程部署,也可以本地部署。它可以提供三种类型的功能:

  1. 资源(Resources):类似文件的数据,可以被客户端读取,如 API 响应或文件内容。

  2. 工具(Tools):可以被 LLM 调用的函数(需要用户批准)。

  3. 提示(Prompts):预先编写的模板,帮助用户完成特定任务。

这些功能为大模型提供了丰富的上下文信息,从而增强了大模型的实用性和灵活性。现在在 MCP 官方 GitHub 上,有很多用户贡献了对接各种系统和应用的 MCP Server,比如对接本地文件系统的 MCP Server,对接 MySQL 的 MCP Server 等等,我们后续开发如果要使用 MCP,主要的工作量也是在开发 MCP Server 上。

MCP Client && MCP Hosts

了解了 MCP Server 之后,我们再来看一下 MCP Client 以及 MCP Hosts。

MCP Client 负责与 MCP Server 进行通信。而 MCP Hosts 则可以理解为是一个可对话的主机程序。

当用户发送 prompt(例如:我要查询北京的天气) 到 MCP Hosts 时,MCP Hosts 会调用 MCP Client 与 MCP Server 进行通信,获取当前 MCP Server 具备哪些能力,然后连同用户的 prompt 一起发送给大模型,大模型就可以针对用户的提问,决定何时使用这些能力了。这个过程就类似,我们填充 ReAct 模板,发送给大模型。

在 Agent 的学习中,我们知道大模型只管选择工具,并不管调用工具。调用工具要由实际的程序完成,这就像万有引力定律一样,是定理。那么在 MCP 中,当然也不能违背这个定理。

当大模型选择了合适的能力后,MCP Hosts 会调用 MCP Cient 与 MCP Server 进行通信,由 MCP Server 调用工具或者读取资源后,反馈给 MCP Client,然后再由 MCP Hosts 反馈给大模型,由大模型判断是否能解决用户的问题。如果解决了,则会生成自然语言响应,最终由 MCP Hosts 将响应展示给用户。

以上就是 MCP 的原理,你如果掌握了 Agent 的机制,对比着学习 MCP 就非常简单了。

体验 MCP

接下来,我们就来体验一下 MCP。

配置 MCP Hosts

由于 MCP 是 Anthropic 推出的,因此最先支持 MCP 的必然是它的自家产品 Claude Desktop。但由于 Claude Desktop 在使用时需要科学上网,考虑到受众问题,我就不用它做 MCP Hosts 了。我会采用一个开源的编程助手 Cline(Roo Code)作为 MCP Hosts。

Cline 是一个插件化的编程助手,可以在多种 IDE 上安装。这里我就以我最常用的 VSCode 为例,做一下演示。

首先点击左侧侧边栏的扩展商店按钮,之后在输入框输入 “cline”,排名前两名的就是 Roo Code(原名 Roo Cline) 以及 Cline。Cline 是原版的,而 Roo Code 是一个哥们觉得 Cline 做的不好,然后自己基于 Cline 又加了扩展功能,现在几乎每天都在更新版本。这里我就选择安装 Roo Code。安装完成后,就可以在侧边栏看到一个小火箭的图标。

我们点击小火箭,然后点击上方的配置按钮,即可配置让 Roo Code 使用什么大模型,这里我配置的是官方版的 DeepSeek,模型选用的是 deepseek-chat,也就是 DeepSeek-V3。完成配置后点击 Save 保存,然后点击 Done 退出。

之后可以在对话框输入一个 “hello”,测试是否能和大模型连上。

如果能得到回复,就说明配置没问题了。

配置 MCP Server

接下来,我就演示一个通过 PostgreSQL MCP Server 使 DeepSeek 能够基于 PostgreSQL 中的数据来回答问题。MCP Server 支持 NodeJS 和 python 两种语言开发,本次案例使用的是 MCP 官方提供的 PostgreSQL MCP Server,其开发语言是 NodeJS ,因此大家需要根据自己的操作系统安装好NodeJS 。Windows 用户可以点击该链接,下载安装。

环境准备好后,我们就正式开始。首先,用 docker 启动 PostgreSQL 服务。

docker run -d --name postgres \
  -e POSTGRES_PASSWORD=postgres -p 5432:5432 \
  docker.1ms.run/postgres:latest

之后使用如下命令进入到容器内并打开 postgres 客户端。

docker exec -it postgres psql -U postgres

创建数据库和表,并插入数据。

-- 创建数据库
CREATE DATABASE achievement;

-- 连接到新创建的数据库
\c achievement;

-- 创建用户信息 users 表
CREATE TABLE users (
    user_id SERIAL PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL
);

-- 创建绩效得分 score 表
CREATE TABLE score (
    score_id SERIAL PRIMARY KEY,
    score DECIMAL(10, 2) NOT NULL,
    user_id INT REFERENCES users(user_id)
);

-- 插入示例数据
INSERT INTO users (name, email) VALUES
('张三', 'zs@example.com'),
('李四', 'ls@example.com'),
('王五', 'ww@example.com');

INSERT INTO score (score, user_id) VALUES
(87.75, 1),
(97.50, 2),
(93.25, 3);

接下来,在 Roo Cline 中配置 PostgreSQL MCP Server 的连接信息,点击上方的服务器按钮,会进入到 MCP Server 的配置页面。

之后点击 Edit MCP Settings,会打开一个配置文件,我们需要在该文件中填写连接信息。

将配置文件的内容替换为如下内容:

{
  "mcpServers": {
    "postgres": {
      "command": "node",
      "args": [
        "D:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npx-cli.js",
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://postgres:postgres@<你的postgres所在的服务器的IP>:5432/achievement"
      ]
    }
  }
}

该配置文件的含义就是使用 NodeJS 将远程的 postgres MCP Server 下载下来,然后运行。

注意以上的内容是针对 Windows 用户的,如果你是 MAC 用户,可以使用如下内容:

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-postgres",
        "postgresql://postgres:postgres@<你的postgres所在的服务器的IP>:5432/achievement"
      ]
    }
  }
}

完成配置后,会在左侧看到已连接的 MCP Server,并且会列出支持的 Tools 和 Resources。

测试

接下来,我们进行测试。

首先,我们提问“数据库中有哪些表?”

可以看到,大模型请求了 MCP Server,之后使用了 一条 SQL 查询语句查出了数据库中的表。

我们接下来尝试一个难一点的案例,提问“张三,李四,王五的绩效谁高?”在我们的数据库中有 users 和 score 两张表,users 存储了人员姓名和邮箱信息,score 表存储了人员的绩效得分,查询绩效分时需要使用 users 表的主键去查询,因此这是一个两个表联合查询的案例。输出结果如下:

可以看到在最左侧的图中,DeepSeek一开始直接尝试在 score 表中,用 name 字段去查询绩效,结果发现表中没有 name 字段,因此就开始获取 score 表的表结构。之后又查出了 users 表的数据,最后来了一个两个表的联合查询,得到了正确结果。

总结

这节课,我们依托前面对于 Agent 知识的理解,学习了另一种“另辟蹊径”的类 Agent 的实现,也就是 MCP。经过比对简化版的 Agent 和 MCP 的架构图,大家会发现,两者真的非常像。只是在具体实现思路上有所区别。

我们在学习这类框架时,尽管需要去看文档,但没必要上来就深究理论,不要把文档当成阅读理解。而是一定要多多实践,通过实践,我们反而更容易去理解功能,然后再类比之前学过的知识,这样就能做到一通百通。

思考题

你认为 MCP Server 查询数据库的功能,我们用 Agent Tool 能搞定吗?

欢迎你在留言区展示你的思考结果,我们一起探讨。如果你觉得这节课的内容对你有帮助的话,也欢迎你分享给其他朋友,我们下节课再见!

精选留言

  • Lee.

    2025-04-03 10:48:56

    云阳老师你好, 我有一个想法不知道对不对, 感觉有了 mcp 之后微调显得有点鸡肋, 因为私有数据都可以通过 mcp 得到, 唯一的问题是模型支持的上下文长度是否足够长
    作者回复

    你好,首先我们要想明白一个点,那就是 mcp 只是一个协议,是为了大家按统一标准做 AI 开发,大家生产的 tool 可以互相无缝衔接调用,所以抛开这个协议,mcp 能干的事情,用 agent 一样能干。那清楚这一点后,我们就可以去理解为什么有agent技术了,还要做微调。这是因为 agent 做的再好,也始终是需要借助外力的。就好比你问我问题,我如果脑子里有(相当于微调),我就可以直接回复你,省时省力,如果我没有,那我就得去百度(相当于agent)。所以微调肯定比agent效果好,但也比agent难度大很多很多,这也是微调的普及性不如agent的原因。

    2025-04-03 12:48:11

  • flykyle

    2025-04-02 18:32:55

    提供给模型的 tool 如果太多会有问题,使用 mcp 会有这个问题么?比如如何把系统的上百个接口给 ai 使用
    作者回复

    以前用Agent的时候,遇到这种情况,我们会选择多智能体的方案,也就是每个Agent管理一个模块的API(这样就不多了),最后有一个管理Agent负责路由。现在MCP其实也可以这样实现

    2025-04-03 10:42:05

  • Geek_682837

    2025-03-24 09:18:47

    老师,mcp我理解目前只是在个人本地开发环境的应用,最多只是提升开发效率吗?如何应用在生产环境呢?
    作者回复

    比如你开发了一款产品 以前是对外提供OpenAPI 让客户调用 现在可以提供MCP Server 让客户通过自然语言去调用

    2025-03-24 13:02:04

  • 蓝雨

    2025-03-24 10:29:11

    mcp和agent没本质区别,一个mcp server可以作为agent一个tool使用。
    这个sql tool有点逗,居然没有第一时间拿到schema信息,要一个个尝试。那么,当问题复杂的时候,重试次数大增,可以预见,性能下降会很严重
    作者回复

    很正常 其实如果把他当人的话 除非是非常熟悉数据库的运维人员 否则其他人也是一点点的尝试 甚至还要边百度边尝试 我们其实要看到的是他的思维能力 通过不断试错 最后能解决

    2025-03-24 13:00:12

  • Geek_7593a0

    2025-03-24 09:57:47

    老师能否稍微加速,想商用落地,现在的进度是有点落后的
    作者回复

    每周更新三节的

    2025-03-24 11:44:37

  • 西钾钾

    2025-03-24 08:53:36

    思考题:是否可以将 MCP 作为 Agent 的一个 tool,Agent 就可以使用这些能力了。😳
    作者回复

    其实MCP这些工具 我们用Agent也可以实现啊

    2025-03-24 13:02:49

  • 王晓聪

    2025-05-19 18:53:53

    老师,请教个问题。mcp 和 functionCalling 虽然在实现方式上不一样,但是本质上其实都是调用外部工具;另外这两种方式对于开发者来说,在使用上好像也并没有太大差别,都是用注册工具的方式;那么 mcp 的优势是什么,为什么在有了 functionCalling 之后,还会出现 mcp
    作者回复

    MCP在于标准化,以前大家写工具很随意,怎么写都行,只要随后提供一段工具描述写到tools参数中就可以。这样的后果是你写的工具别人没法直接用,需要把你的工具代码拷贝过来,然后把工具描述抄过来,才能用。但用MCP,直接一条命令对接一下Server就搞定

    2025-05-20 14:55:15

  • maybe

    2025-05-14 21:49:21

    试用本地ollama运行的ds1.5b模型,被roo code嫌弃它太弱一直报错。充钱使用了官方的满血ds才行。mcp配置使用的是mysql,成功体验了一把。
    {
    "mcpServers": {
    "mysql": {
    "command": "node",
    "args": [
    "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npx-cli.js",
    "-y",
    "@benborla29/mcp-server-mysql",
    "mysql://root:root@localhost:3306/achievement"
    ]
    }
    }
    }
    作者回复

    嗯嗯 这种对思维力要求高的操作 小模型搞不定

    2025-05-15 14:37:16

  • 2025-04-17 17:30:39

    给使用1Panel 的小伙伴提供个远端MCP 配置案例(1Panle 上可以直接启用mcp server)
    - roo cline 中配置:
    {
    "mcpServers": {
    "postgres": {
    "url": "http://192.168.20.1:8000/postgres"
    }
    }
    }

    - 1Panel 中MCP server 配置:
    {
    "mcpServers": {
    "postgres": {
    "command": "npx",
    "args": [
    "-y",
    "@modelcontextprotocol/server-postgres",
    "postgresql://user:password@1Panel-postgresql-XXXX(数据库名):5432/XXXXX(1panel 本地数据库名)"
    ]
    }
    }
    }
    作者回复

    👍

    2025-04-17 19:27:42

  • ifelse

    2025-04-11 12:53:37

    学习打卡
    tool一样可以实现功能,写好prompt,调用工具
    作者回复

    2025-04-11 15:20:52

  • Xin 

    2025-04-09 17:23:33

    按照例子也执行了一下pgsql的mcp,有个地方不太理解。 我原本的理解是MCP server就是一个代理的组件,会根据你的需求去找所需的模型,但是这个例子中,我配置了pgsql的mcp server,但我实际去连接的不还是deepseek吗,那这里的mcp server起到什么作用呢
    作者回复

    起到的是为deepseek 提供工具的作用,类似function calling和agent。如果对于function calling和agent不了解,可以看一下课程的前置章节哈

    2025-04-09 21:56:09

  • jogholy

    2025-04-08 08:37:23

    roo code目前在vscode中是一个袋鼠图标,roo code Chinese是火箭图标。git的更新来看,袋鼠图标的才是更新频繁的版本。同时袋鼠图标目前才是检索cline排第二的。
    作者回复

    所以就说现在AI应用 框架等变更太快 我开始用的时候还叫Roo Cline 是个火箭图标

    2025-04-08 13:15:49

  • 李维

    2025-03-28 01:46:41

    请教一下老师,mcp协议跟目前主流的agent开发框架之间的区别是什么,比如metagpt\autogpt\langchain。是不是mcp这种协议比较容易接受,可以让各种tool能够串联起来,从而结合llm搭建更好用的agent?还是说metagpt等框架中也使用了类似mcp的这些思想,但是属于各个框架内部都有的,开发者需要了解每个框架的模式才能开发?
    另外后续能否结合实际,也介绍一下这些框架的落地。
    作者回复

    langchain等属于脚手架,就是对agent系统的各个功能做了模块化封装,目的是让你根据自己的实际业务逻辑,快速搭建出一个agent,这样就只关注业务就行了,类似用dify 搭一个agent。但MCP是一个协议,我们写MCP代码,就类似于我的前置课程讲的手撸一个Agent。因此这两者不是一个维度的东西

    2025-03-28 11:40:04

  • Geek_fd9373

    2025-05-15 19:00:36

    MCP Server目前是只能由nodeJs和php实现吗?如果想使用java作为MCP Server的话,是只能基于php去调用java(譬如基于http请求)这种链路嘛?

    另外多问个问题,像spring ai也是继承了mcp,但整个架构看起来,mcp只是一个tools(实际业务工具),spring ai支持自定义method或function作为tools调用,那对于java语言来说,是不是直接把本地的业务方法直接设置为tools,而没必要单独写MCP Server了?谢谢
    作者回复

    现在多语言的MCP SDK都在不断出现,有的是官方写的,有的是第三方写的,可以去github上看看是否支持java 了。MCP Server是为了工具的标准化,统一化,你写的工具别人可以直接调用,如果不是为了这个目的,就没人用这个框架了。因此如果你也是这个目的,那就不论使用什么框架,都得写MCP Server

    2025-05-16 11:06:43

  • CrazyCodes

    2025-04-28 10:13:14

    Agent Tool 的话,是不是需要服务端开发api,然后由agent tool 去调用api,以实现查询数据库
    作者回复

    直接把MCP Server Tool的部分抄过来,让Agent调用就可以

    2025-04-28 19:21:33

  • 唯我天棋

    2025-04-17 11:07:13

    我用mysql实现同样的demo,使用deepseek,跑不了来。
    执行:"query": "DESCRIBE score"
    报错:Error executing query: Unread result found
    作者回复

    这个和模型没啥关系 你需要先调试一下工具是否好用

    2025-04-17 13:34:30

  • huyu6789

    2025-04-10 10:11:15

    在roo code的配置mcp服务的那一步,我这边出现了“编辑全局配置”和“编辑项目配置"两个选项,我点击两个选项都提示我要建立对应的工作目录才可以。无法像你文中那种直接可以有个文件来进行配置,是不是这里还有一些必要的步骤,文中省略掉了?
    作者回复

    刚试了一下 你用的应该是最新的logo是个袋鼠的roo code吧。这个版本中,你需要先打开一个代码工程,然后再点编辑全局或者编辑项目

    2025-04-10 11:00:15

  • 一路前行

    2025-04-03 17:42:47

    老师,我看你用Roo Code在本地环境应用配置,那在生产环境中,mcp host如何实现呢,有没有那种开源的命令行的有没有界面的工具或者包。
    作者回复

    其实就是一个chat模块➕mcp client,我后面有空加一节课,自己实现一个

    2025-04-05 11:53:30

  • 轩爷

    2025-04-02 17:42:51

    我用ollama本机运行的deepseek-r1:1.5b-qwen-distill-q4_K_M模型和deepseek-r1:8b分别做了以上两个问答,完败,完全找不到MCP,理解不了。切换到在线的V3,回答过程一路点击“批准”,答案非常完美。
    另外,Roo Cline已经更名Roo Code,图标是个袋鼠,模型目前似乎不支持阿里百炼的,Cline目前是能够找到Ali的模型的。
    作者回复

    这个就和用Agent是一项的,不能选太差的模型,要用推理能力强的

    2025-04-02 19:50:58

  • 皇家救星

    2025-03-30 08:27:42

    如果以后某个大模型自己出了一套类似mcp协议,被所有大模型广泛支持(类似function call这样) mcp协议会不会没落了。 mcp协议使用有啥限制吗?算是公开协议还是专利协议?发明这个公司的公司有反华倾向,所以我有点担心。
    作者回复

    不是限制的问题,而是是否大家都给他面子,承认他是标准。比如我出一个协议,肯定没人理

    2025-03-30 18:15:12