MCP的初步学习
本文最后更新于51 天前,其中的信息可能已经过时,如有错误请发送邮件到big_fw@foxmail.com

Part 1:前言

MCP啊,有一段时间了,还算是有开发价值的,作为经常用AI的我不能完全不懂呀(毕竟有人经常拿他来做非常酷的东西)

MCP全称是Model Context Protocol, Anthropic在2024年11月推出的开放协议(不是框架嗷)

说到Anthropic,对,就是那家做出超强模型的公司,接下来的演示我们或许也会用他们家的Claude Desktop写一个MVP

对比SmartAgent模式,MCP有略微不同

SmartAgent模式是调用第三方模型的API(或者你本地部署的模型也可以),编写工具类来让AI调用你的服务层,或直接调用数据链路层的方法

而MCP则是向支持MCP接入的平台提供了AI的手,工具类的用法,以及模型调用的初始化其实都大差不差,但是把项目中的具体能力(查数据、写报告等)封装成标准工具,让第三方平台的 AI 来调用

所以在实际的独立项目开发中我们更倾向于使用SmartAgent模式而非MCP协议

Part 2:基本概念

引用https://github.com/microsoft/mcp-for-beginners

引用范围:00-Introduction, 01-CoreConcepts

当然在第一部分我们提到了SmartAgent,用于本地项目的开发,对比MCP而言不依赖第三方客户端,但是有一个问题就是针对不同模型有不同能力的划分,MCP提出之前,针对每一个工具都需要一套定制的代码作为路由,但每个模型的API格式各不同,在对项目进行更新和修改时往往要投入大量时间对对应的模块进行修改和测试

MCP 的出现统一了这套接口标准,让你只需要写一次 Server,就能被所有支持 MCP 的客户端调用,不用再为每个模型单独适配


基本的架构三角可以分为:

  • MCP Host:运行 AI 模型的宿主程序(比如 Claude Desktop、VSCode)
  • MCP Client:Host 内部负责和 Server 通信的连接器,一个 Client 对应一个 Server
  • MCP Server:你写的,暴露工具和数据的服务

通过MCP协议我们可以有效减少AI的幻觉,让AI去查询真实的数据

同时实现能力的拓展,毕竟我们平常看到的那些ChatBot只能跟我们干巴巴的对话,实际上不能帮我们干活,但MCP协议交给了这些AI能够去实际操作的手(其实跟agent也差不多),让AI能去实现他训练之外的事

而敏感数据也不用塞进prompt里面,直接留在本地的Server里面就可以了,算是在大模型安全这部分更进了一步吧


MCP的三大原语:

原语作用类比
Tools可执行的函数,AI 主动调用你的 @Tool 方法
Resources数据源,只读,提供上下文给 AI 看的参考资料
Prompts预设的提示词模板封装好的工作流指令

而底层的通信流程大概是这样的:

  1. Client 启动,发 tools/list 发现所有可用工具
  2. 用户发起提问
  3. AI 决定调用哪个工具
  4. tools/call 触发工具调用
  5. Server 执行并返回结果

全程通过 JSON-RPC 2.0 通信

传输层上有两种
一般本地通信的话就用stdio: AI启动一个子进程,通过标准输入输出通信

而远程调用的话就用SSE: 通过HTTP+Server-Sent Events

而为了保险起见,MCP定义了一系列规范包括权限控制和OAuth认证,参数校验,请求频率限制等,从而保证接口不会被随意暴露

PART 3 @Tool 与 MCP:一场关于耦合度的进化

OK上一部分我们聊了 MCP 的基本概念,然而很多人其实在接触 MCP 之前都已经接触过一种类似”山寨版”的 MCP 了,对,就是 LangChain4j 里面的 @Tool 注解

以我自己之前写的仓库管理 SmartAgent 项目做例子:

@Tool(description = "查询商品库存")  // AI 看这里,知道自己有这个能力
public Product getProduct(String name) {
    return productMapper.selectByName(name);  // 真正干活的是这里
}

逻辑上基本和 MCP 一模一样:给 AI 一个有描述的函数,AI 来决定什么时候调用,调用后拿到结果再继续对话

那这种框架内的 @Tool 和 MCP 协议到底有什么区别呢?

核心就一个词:耦合度

不管是 LangChain4j 还是 Spring AI,对于工具类的调用都是进程内直接调用的——工具和 AI 住在同一个 JVM 里,AI 直接调用本地方法,根本不存在什么跨进程通信

而 MCP 则是把工具抽成了一个独立运行的 Server 进程,AI 通过标准协议去调用它

直接上表对比:

@ToolMCP
工具位置同一个JVM进程内独立进程,跨进程通信
能否被多端调用❌ 仅限当前项目✅ 任何支持 MCP 的客户端
跨语言
开发复杂度低,加个注解就行较高,需要单独起一个 Server 进程

真正值得上 MCP 的场景是:

  • 你写的工具需要同时被 Claude Desktop、Cursor 等多个客户端复用
  • 工具需要用不同语言实现(比如要用 Python 的科学计算库)
  • 团队协作中,工具逻辑和 AI 逻辑需要分开部署维护

一句话总结来说就是:@Tool 是 MCP 的简化版,MCP 是 @Tool 的标准化升级,选哪个取决于你的工具是否需要被复用

PART 4 MCP项目的搭建

引用https://dev.to/porass/create-your-first-mcp-server-in-spring-boot-1lpp

我们的目标是写一个简单的MCP Server,然后把他接入Claude Desktop,让Claude能真正调用我们写的工具


第一步:先添加依赖

写MCP Server只需要一个核心的依赖

```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>

这个时候starter会自动帮你通过SSE(即Server-Sent Events)把工具暴露出去,不需要配置额外的路由了


第二步:写工具类

@Service
public class XXXService{
    private static final String BASE_URL="https://xxxxxxxx";//注:如果由用到第三方网站的数据则这里需要该网站的网址
    private final RestClient restClient;
    private String api_key=“你的api key”//注:该网站提供与你开发的模块有关的api,类似水质检测或者空气质量检测
    
    public XXXService(){
       restClient=RestClient.builder()
                  .baseUrl(BASE_URL)
                  .defaultHeader("X-Api-Key",api_key)
                  .build();
    }//链式调用结构更清晰
    
    @Tool(description="你对AI描述该服务类需要他怎么操作,比如获取空气质量细节等")
    public String XXXX(String param){
          // 调用 restClient 或者直接查数据库都可以 
          // 返回字符串格式的结果给 AI 
          return result;
       
    }

}

当然这里的@Service会帮我们注册服务类,同理@Tool这个注解也会帮我们创建MCP的工具,MCP clients会扫描并获取该工具


第三步:配置Server基本信息

spring:
  ai:
    mcp:
      server:
        stdio: true

这样就能通过标准方法进行通信传输了


第四步:注册工具

@SpringBootApplication
public class McpApplication {

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

    @Bean
    public ToolCallbackProvider myTools(XXXService service) {
        return MethodToolCallbackProvider.builder()
                .toolObjects(service)
                .build();
    }
}

MethodToolCallbackProvider 会把你的 @Tool 方法转成 MCP 可以识别的回调,这步相当于把工具”登记”到 MCP Server 上


第五步:打包

mvn clean install

打包完后target文件夹会有一个.jar 文件,这个就是我们的MCP Server


第五步:接入Claude Desktop

找到 Claude Desktop 的配置文件:

  • Mac:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows:%APPDATA%\Claude\claude_desktop_config.json

写入我们的Server配置

{
  "mcpServers": {
    "my-mcp-server": {
      "command": "java",
      "args": [
        "-Dspring.ai.mcp.server.stdio=true",
        "-jar",
        "/你的路径/target/xxx.jar"
      ]
    }
  }
}

保存后重启Claude Desktop,我们的工具就出现在Claude 的工具列表里的


(等于说我们直接创建了一个官方和其他人都没有,就我们自个有的工具,拓展性还是不错的)

OK,MCP应该就到这里差不多了,毕竟我们只是浅层地了解基本原理和他的使用方式,不需要过度深究

ps: 或许后面我在读微软发的那几篇文章可能会对该博客进行再次更新也说不定

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇