2024年,AI领域有一个协议特别火,那就是MCP(Model Context Protocol)。它由Anthropic提出,被称为"AI应用的USB-C接口",目标是让AI模型能方便地连接各种外部工具和数据源。

很多人用了MCP,觉得很方便,但对它的底层原理不太了解。这篇文章就来从技术原理的角度,深入剖析MCP协议,包括它的架构设计、通信机制、数据模型、安全机制等。如果你对MCP感兴趣,或者想自己实现MCP服务器,希望这篇文章能帮到你。

MCP是什么

先简单介绍一下MCP是什么。

MCP的全称是Model Context Protocol,是Anthropic在2024年提出的一个开放协议。它的目标是提供一种标准化的方式,让AI模型(比如Claude、GPT)能够连接和使用外部工具、数据源和API。

在MCP之前,AI模型连接外部工具的方式比较混乱。每个AI应用都有自己的工具调用方式,开发者需要为每个平台单独开发插件。比如,为ChatGPT开发插件,为Claude开发插件,为其他AI应用再开发一套。这导致了大量的重复工作,也限制了AI应用的生态发展。

MCP的出现,就是为了解决这个问题。它定义了一套标准的协议,只要按照这个协议开发一个MCP服务器,就能被所有支持MCP的AI客户端使用。就像USB-C接口一样,只要你的设备支持USB-C,就能连接所有支持USB-C的配件。

MCP的核心概念有三个:

  • Host(宿主):AI应用,比如Claude Desktop、Cursor、其他支持MCP的AI客户端
  • Client(客户端):MCP客户端,运行在Host内部,负责和MCP服务器通信
  • Server(服务器):MCP服务器,提供具体的工具、数据源和API,比如文件系统服务器、数据库服务器、GitHub服务器

用户在Host中使用AI时,AI可以通过MCP Client调用MCP Server提供的工具,获取外部数据,执行外部操作。

MCP的架构设计

MCP的架构设计,借鉴了很多现有协议的思想,但也有自己的特点。

第一,客户端-服务器架构。MCP采用经典的客户端-服务器架构,Client主动发起连接,Server被动接受连接。一个Client可以连接多个Server,一个Server也可以被多个Client连接。

第二,传输层无关。MCP不绑定特定的传输协议,它定义了两种标准的传输方式:

  • stdio:通过标准输入输出通信,适合本地运行的MCP服务器。Host启动一个子进程,通过子进程的stdin和stdout通信。这种方式简单、安全,适合本地工具。
  • HTTP/SSE:通过HTTP和Server-Sent Events通信,适合远程MCP服务器。Client发送HTTP请求,Server通过SSE推送消息。这种方式适合远程部署的服务。

除了这两种标准方式,MCP也可以在其他传输层上运行,比如WebSocket、Unix Domain Socket等,只要能传输JSON-RPC消息就行。

第三,JSON-RPC 2.0。MCP的消息格式基于JSON-RPC 2.0协议。所有的请求和响应都是JSON格式,有标准的方法名、参数、ID。JSON-RPC是一个轻量级的远程过程调用协议,简单、通用、易于实现。

第四,能力发现。MCP支持能力发现(Capability Discovery)。Client连接到Server之后,可以查询Server支持哪些能力,比如有哪些工具、哪些资源、哪些提示词模板。这样,Client不需要预先知道Server的功能,就能动态地发现和使用。

第五,双向通信。MCP支持双向通信,不仅Client可以调用Server的方法,Server也可以主动给Client发通知。比如,Server可以通知Client有新的数据可用,或者某个任务完成了。这是通过SSE或者stdio的双向流实现的。

MCP的核心概念

MCP定义了几个核心概念,理解了这些概念,就理解了MCP的大部分原理。

第一个概念是Tools(工具)。工具是MCP服务器提供的可调用的函数。AI模型可以调用这些工具,执行具体的操作。比如,一个文件系统MCP服务器可能提供这些工具:readfile(读取文件)、writefile(写入文件)、listdirectory(列出目录)、searchfiles(搜索文件)。

每个工具有一个名字、一个描述、一个参数的JSON Schema。AI模型根据工具的描述和参数Schema,决定什么时候调用这个工具,以及传什么参数。工具调用之后,返回一个结果,AI模型根据结果继续生成回答。

第二个概念是Resources(资源)。资源是MCP服务器提供的可读取的数据。资源有一个URI(统一资源标识符),Client可以通过URI读取资源的内容。比如,一个数据库MCP服务器可能提供这些资源:database://users(用户表数据)、database://orders(订单表数据)。

资源和工具的区别是:资源是只读的,用来获取数据;工具是可执行的,用来执行操作。比如,读取文件是资源,写入文件是工具。

第三个概念是Prompts(提示词模板)。提示词模板是MCP服务器提供的预定义的提示词。AI模型或者用户可以使用这些提示词模板,快速生成特定的请求。比如,一个代码审查MCP服务器可能提供一个"code_review"提示词模板,用户选择这个模板,输入代码,就能生成代码审查的提示词。

第四个概念是Sampling(采样)。采样是指MCP服务器可以请求AI模型生成文本。比如,一个MCP服务器在处理某个任务时,需要AI模型帮忙生成一段文字,它可以通过Sampling接口,请求Host中的AI模型生成文字。这是MCP的一个独特设计,让服务器也能利用AI的能力。

第五个概念是Roots(根目录)。根目录是MCP服务器可以访问的文件系统路径。比如,一个文件系统MCP服务器,只能访问用户授权的根目录下的文件,不能访问其他目录。这是一种安全机制,限制MCP服务器的访问范围。

MCP的通信流程

了解了核心概念之后,说说MCP的完整通信流程。

第一步,建立连接。Client启动,连接到Server。如果是stdio方式,Client启动一个子进程,通过stdin/stdout通信;如果是HTTP/SSE方式,Client发送一个HTTP请求,建立SSE连接。

第二步,初始化握手。连接建立之后,Client发送一个initialize请求,告诉Server客户端的协议版本和支持的能力。Server返回一个initialize响应,告诉客户端服务器的协议版本、支持的能力、服务器信息。这一步类似于TCP的三次握手,确保双方都支持MCP协议,并且知道对方的能力。

第三步,能力发现。初始化完成之后,Client可以查询Server的能力:

  • 调用tools/list,获取所有可用的工具列表
  • 调用resources/list,获取所有可用的资源列表
  • 调用prompts/list,获取所有可用的提示词模板列表

Server返回这些列表,Client根据这些信息,知道Server能做什么。

第四步,工具调用。当AI模型需要使用外部工具时,Client调用tools/call方法,传入工具名和参数。Server执行工具,返回结果。AI模型根据结果,继续生成回答。

第五步,资源读取。当AI模型需要读取外部数据时,Client调用resources/read方法,传入资源URI。Server返回资源的内容。

第六步,提示词使用。当用户或者AI模型需要使用提示词模板时,Client调用prompts/get方法,传入提示词名和参数。Server返回填充好参数的提示词。

第七步,服务器通知。Server可以主动给Client发通知,比如通知有新的资源可用,或者某个异步任务完成了。Client收到通知后,可以决定是否需要进一步操作。

第八步,连接关闭。当不需要使用Server时,Client关闭连接。如果是stdio方式,终止子进程;如果是HTTP/SSE方式,关闭HTTP连接。

整个流程,都是基于JSON-RPC 2.0的消息格式,每个请求有一个唯一的ID,响应和请求通过ID匹配。

MCP的数据模型

MCP的消息格式基于JSON-RPC 2.0,下面看看具体的数据模型。

一个JSON-RPC请求的格式:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "read_file",
    "arguments": {
      "path": "/path/to/file.txt"
    }
  }
}

一个JSON-RPC响应的格式:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "文件内容..."
      }
    ]
  }
}

一个JSON-RPC通知的格式(没有ID):

{
  "jsonrpc": "2.0",
  "method": "notifications/resources/updated",
  "params": {
    "uri": "file:///path/to/file.txt"
  }
}

MCP定义了很多标准方法,比如:

  • initialize:初始化
  • tools/list:列出工具
  • tools/call:调用工具
  • resources/list:列出资源
  • resources/read:读取资源
  • prompts/list:列出提示词
  • prompts/get:获取提示词
  • sampling/createMessage:请求AI生成文本
  • notifications/initialized:初始化完成通知
  • notifications/progress:进度通知

每个方法都有定义好的参数和返回值格式,确保不同的MCP实现之间能互相兼容。

工具的参数用JSON Schema来描述,比如:

{
  "name": "search_files",
  "description": "搜索文件",
  "inputSchema": {
    "type": "object",
    "properties": {
      "pattern": {
        "type": "string",
        "description": "搜索模式"
      },
      "path": {
        "type": "string",
        "description": "搜索路径"
      }
    },
    "required": ["pattern"]
  }
}

AI模型根据这个JSON Schema,就能知道这个工具需要什么参数,以及每个参数的类型和描述。

MCP的安全机制

MCP连接的是外部工具和数据源,安全非常重要。MCP设计了多层安全机制。

第一,传输安全。对于远程MCP服务器,推荐使用HTTPS,确保通信加密。对于本地stdio服务器,通信在进程内,不需要加密。

第二,权限控制。MCP服务器应该实现自己的权限控制,比如哪些工具可以被调用,哪些资源可以被访问。Host也可以对MCP服务器做权限限制,比如只允许访问特定的目录,只允许调用特定的工具。

第三,用户确认。对于有副作用的操作(比如写入文件、执行命令、发送请求),Host应该在执行前请求用户确认。比如,Claude Desktop在调用写入文件的工具时,会弹出确认框,让用户确认是否允许。

第四,沙箱隔离。MCP服务器应该运行在沙箱环境中,限制它的系统访问权限。比如,文件系统MCP服务器只能访问授权的目录,不能访问整个文件系统。

第五,输入验证。MCP服务器应该对所有输入进行验证,防止注入攻击。比如,工具的参数要校验类型和范围,资源的URI要校验是否在允许的范围内。

第六,审计日志。MCP服务器应该记录所有的工具调用和资源访问,便于审计和排查问题。

安全是MCP推广的关键。如果安全做不好,用户不敢用,生态就发展不起来。MCP在设计的时候,就把安全放在了重要位置。

MCP和其他协议的对比

MCP不是第一个AI工具连接协议,它和其他一些协议/方案有什么区别呢?

和OpenAI Function Calling的对比:

  • Function Calling是OpenAI的私有方案,只能在OpenAI的模型中使用
  • MCP是开放协议,任何AI模型都可以使用
  • Function Calling需要开发者在应用层实现工具调用逻辑,MCP提供了标准化的工具发现和调用机制
  • MCP支持更多的概念(资源、提示词、采样),比Function Calling更丰富

和ChatGPT Plugins的对比:

  • ChatGPT Plugins是OpenAI的插件系统,已经被Function Calling和GPTs取代
  • MCP是开放协议,不绑定特定平台
  • MCP的架构更灵活,支持本地和远程服务器,支持双向通信

和LangChain Tools的对比:

  • LangChain Tools是LangChain框架内的工具抽象,需要在应用代码中集成
  • MCP是独立的协议,工具可以作为独立的服务部署,被多个应用共享
  • MCP的工具可以用任何语言开发,只要实现了MCP协议

总的来说,MCP的优势在于:开放、标准化、跨平台、生态友好。它不是要取代现有的方案,而是提供一个统一的标准,让AI工具的开发和使用更简单。

如何实现一个MCP服务器

如果你想自己实现一个MCP服务器,大致需要这些步骤:

第一,选择传输方式。如果是本地工具,用stdio方式;如果是远程服务,用HTTP/SSE方式。

第二,实现JSON-RPC消息处理。解析收到的JSON-RPC请求,根据method分发到对应的处理函数,返回JSON-RPC响应。

第三,实现标准方法。至少要实现initialize、tools/list、tools/call这几个核心方法。如果需要支持资源和提示词,还要实现resources/list、resources/read、prompts/list、prompts/get。

第四,定义工具。为你的工具定义名字、描述、参数的JSON Schema。工具的描述要清晰准确,这样AI模型才能正确地调用。

第五,实现工具逻辑。每个工具的具体执行逻辑,比如读取文件、查询数据库、调用API等。

第六,测试。用MCP客户端(比如Claude Desktop)连接你的服务器,测试工具是否能被正确发现和调用。

MCP官方提供了多种语言的SDK,比如TypeScript、Python、Java等,用SDK开发MCP服务器会简单很多,不需要自己处理JSON-RPC的细节。

MCP的生态和未来

MCP虽然提出的时间不长,但生态发展很快。

目前,已经有很多MCP服务器可用:

  • 文件系统服务器:读写本地文件
  • 数据库服务器:连接MySQL、PostgreSQL、SQLite等数据库
  • GitHub服务器:管理GitHub仓库、PR、Issue
  • 浏览器服务器:控制浏览器、抓取网页
  • Slack/Discord服务器:发送消息、管理频道
  • 代码服务器:代码搜索、代码审查、测试运行

支持MCP的Host也越来越多:

  • Claude Desktop(Anthropic官方)
  • Cursor(AI编程工具)
  • Continue(开源AI编程助手)
  • Cline(VS Code插件)
  • 各种自研的AI应用

未来,MCP可能会:

  • 成为AI应用的标准连接器,就像HTTP之于Web
  • 支持更多的传输方式和安全机制
  • 有更丰富的工具生态,覆盖更多的场景
  • 和Agent框架深度集成,让AI Agent能更方便地使用工具
  • 形成成熟的工具市场,用户可以像安装APP一样安装MCP工具

当然,MCP也面临一些挑战:

  • 安全问题,如何防止恶意MCP服务器
  • 标准化问题,不同实现之间的兼容性
  • 性能问题,大量工具调用时的延迟和吞吐量
  • 用户体验问题,如何让普通用户也能方便地使用MCP

但总体来说,MCP的方向是对的,它解决了AI应用生态中的一个核心问题:工具连接的标准化。

写在最后

MCP协议是AI领域的一个重要创新,它为AI模型连接外部工具和数据源提供了标准化的方式。

通过客户端-服务器架构、JSON-RPC 2.0消息格式、工具/资源/提示词等核心概念、多种传输方式、完善的安全机制,MCP实现了灵活、安全、可扩展的AI工具连接。

理解MCP的原理,不仅能帮助我们更好地使用现有的MCP工具,也能让我们在需要的时候,自己开发MCP服务器,扩展AI的能力。

AI的未来,不仅是模型本身的能力,更是模型和外部世界连接的能力。MCP作为连接AI和外部世界的桥梁,会在未来的AI生态中扮演越来越重要的角色。

希望这篇文章能帮你深入理解MCP的底层机制。如果你对MCP有什么问题或者想法,欢迎交流。