Skip to content

MCP理论知识

stdio#

进程:执行一个应用程序,就会启动一个进程,操作系统会为其分配内存空间、系统资源。

应用程序执行完毕后,系统分配给进程的资源就会被回收。

课堂演示

进程之间是可以通信的。那这里有一个最基本的要求:进程不能结束。如何让进程不结束?

想想微信、QQ启动后为啥不结束?

因为要监听。

image-20250714233744304

这里也同样,只要进程处于监听状态,就不会结束。

// 监听输入
process.stdin.on('data', () => {})

除此之外,一个进程还可以启动另一个进程,这在操作系统中是非常常见和常用的行为,被称之为 父子进程模型

控制台其实也是一个应用程序,启动后也会有进程。因此下面的代码:

Terminal window
node index.js

控制台就是父进程,node程序就是子进程。

image-20250714233218827

🙋 让终端和 node 程序进行通信,该如何进行通信?

stdio: standard input and output 标准输入输出

每一个进程启动后,都会留出两个对外通信的接口:

上面进程监听输入和对外输出的图,就可以变成这样:

image-20250712130252722

结合前面父子模型的知识:

image-20250712130835444

课堂练习

终端和 node 进程通信

再看下面的例子,增加一个 client.js

const { spawn } = require('child_process')
// 启动 server.js 子进程
const serverProcess = spawn('node', ['server.js']) // node server.js
// 监听服务端的响应
// 数据从哪里来?哪个进程给我的
// 数据会输出到哪儿?我给哪个进程
serverProcess.stdout.on('data', (data) => {
process.stdin.write(data.toString()) // 🙋 往哪里输出?
})
// 发送几条测试消息
const messages = ['生命有意义吗?', '宇宙有尽头吗?', '再见!']
messages.forEach((msg, index) => {
setTimeout(() => {
console.log(`-->${msg}`)
serverProcess.stdin.write(msg)
}, index * 1000) // 每秒发一条
})

如下图:

image-20250715000332368

stdio通信高效、简洁,但仅适用于本地进程间通信

通信格式#

通信涉及到数据传输,数据传输的格式有多种:

JSON-RPC2.0

英语全称为 JSON Remote Procedure Call,远程函数调用。

request

{
"jsonrpc": "2.0",
"method": "sum",
"params": {
"a": 5,
"b": 6
},
"id": 1
}

response

{
"jsonrpc": "2.0",
"result": 11,
"id": 1
}

课堂练习

实现基于 JSON-RPC 的通信

MCP Server#

MCP是一套 标准协议, 它规定了 应用程序 之间 如何通信

如何通信:

基本规范#

1. 初始化 initialize

两个应用程序要开始通信,首先需要初始化

request

{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize", // 固定为 initialize
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {
"roots": {
"listChanged": true
},
"sampling": {},
"elicitation": {}
},
"clientInfo": {
// 告知服务器客户端的信息
"name": "ExampleClient",
"title": "Example Client Display Name",
"version": "1.0.0"
}
}
}

response

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"logging": {},
"prompts": {
"listChanged": true
},
"resources": {
"subscribe": true,
"listChanged": true
},
"tools": {
"listChanged": true
}
},
"serverInfo": {
// 服务端信息
"name": "ExampleServer",
"title": "Example Server Display Name",
"version": "1.0.0"
},
"instructions": "Optional instructions for the client"
}
}

2. 发现工具 tools/list

服务器有哪些工具函数可以供客户端调用

request

{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}

response

{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "get_weather",
"title": "Weather Information Provider",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name or zip code"
}
},
"required": ["location"]
}
}
]
}
}

3. 工具调用 tools/call

request

{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call", // 调用工具
"params": {
"name": "get_weather", // 工具名,对应工具发现中的name
"arguments": {
// 工具参数,需要和工具发现中的结构一致
"location": "New York"
}
}
}

response

{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
// 函数结果需要放到content字段中,如果有多个,使用数组
// 函数结果的类型
// 支持的类型: https://modelcontextprotocol.io/specification/2025-06-18/server/tools#tool-result
"type": "text",
"text": "72°F"
}
]
}
}

工具返回的类型有 多种

课堂练习

实现遵循 MCP 协议的服务器

🤔 服务器是否能够和其它遵循MCP协议的应用程序通信?

调试工具#

服务器目录下,直接运行

Terminal window
npx @modelcontextprotocol/inspector

官方SDK#

非业务代码,一般就会封装出来。

使用@modelcontextprotocol/sdk可以更方便的开发MCP Server

Terminal window
npm install @modelcontextprotocol/sdk

课堂练习

使用官方SDK实现 MCP 服务器

对接AI应用#

什么是AI应用程序?

所有能与大模型交互的应用都可以看作是AI应用程序

常见的AI应用程序:

凡是支持 MCP 协议的 AI 应用,就可以充当客户端,连接 MCP 服务器。

整个流程如下图:

用户和 AI 应用进行交互,AI 应用背后调用的是大模型。

image-20250715111953921

但是有些事情,大模型办不到。

image-20250715112129621

此时可以通过 MCP 服务器扩宽大模型的能力边界。

🤔 工具是谁调用,大模型调用么?

不是大模型调用,大模型只接收 输入输出

所以大模型会回复:我需要调用 XXX 工具。

image-20250715113151070

然后 AI 应用调用工具,将工具调用结果返回给大模型。

image-20250715113402639

两个核心概念:

image-20250712222733393

例如:

  1. 在Claude Desk 中打开一个新的聊天窗口
  2. Claude查看当前启用了哪些MCP Server
  3. Claude(host)为每个MCP Server创建一个Client
  4. 每个Client分别启动各自的MCP Server,并且进行了2次通信,一次是初始化,另外一次是tools/list。
  5. 当时机到达时(要调用工具的时候),每个Client负责调用各自的工具并把结果传递给Host
  6. Host根据结果处理后续逻辑