Dify as MCP Server
by Yevanchen
Verified
# 网络协议基础知识
计算机网络可能确实有点复杂,我来帮你梳理一下与 MCP 相关的关键网络协议概念。
## HTTP 协议基础
### 什么是 HTTP?
HTTP (超文本传输协议) 是网络上客户端和服务器之间传输数据的基础协议。当你访问网站时,浏览器(客户端)和网站服务器就是通过 HTTP 通信的。
### HTTP 请求方法
1. **GET**: 请求获取资源,如网页或图片
- 例如:访问网页、下载文件
- 参数附在 URL 中 (例如 `?name=value`)
2. **POST**: 向服务器提交数据
- 例如:提交表单、上传文件
- 数据放在请求体中,不在 URL 中
3. **其他方法**: 还有 PUT, DELETE, PATCH 等方法,用于不同操作
### HTTP 请求结构
```
GET /path/to/resource HTTP/1.1
Host: example.com
Accept: text/html
User-Agent: Mozilla/5.0
```
- 第一行: 请求方法 + 路径 + 协议版本
- 后续行: 请求头部(Headers),提供额外信息
- 空行后: 请求体(Body),POST 请求会在这里包含数据
### HTTP 响应结构
```
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1234
<!DOCTYPE html>
<html>...
```
- 第一行: 协议版本 + 状态码 + 状态消息
- 后续行: 响应头部(Headers)
- 空行后: 响应体(Body),包含实际数据
### 状态码
- **2xx**: 成功 (200 = OK)
- **3xx**: 重定向
- **4xx**: 客户端错误 (404 = 未找到)
- **5xx**: 服务器错误
## JSON-RPC
### 什么是 RPC?
RPC (远程过程调用) 允许一个程序调用另一个程序上的函数,就像调用本地函数一样。
### 什么是 JSON-RPC?
JSON-RPC 是一种基于 JSON 的 RPC 协议,主要用于在不同系统间进行函数调用。
### JSON-RPC 请求结构
```json
{
"jsonrpc": "2.0",
"method": "functionName",
"params": {"param1": "value1", "param2": "value2"},
"id": 1
}
```
- **jsonrpc**: 协议版本
- **method**: 要调用的函数名
- **params**: 函数参数
- **id**: 请求标识符,响应会包含相同ID
### JSON-RPC 响应结构
成功响应:
```json
{
"jsonrpc": "2.0",
"result": {"someData": "value"},
"id": 1
}
```
错误响应:
```json
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Invalid Request"
},
"id": 1
}
```
## SSE (Server-Sent Events)
### 什么是 SSE?
SSE 是一种允许服务器向客户端推送实时更新的技术。它建立单向通信通道,服务器可以持续发送数据到客户端。
### SSE 与 WebSocket 区别
- **SSE**: 单向通信(服务器到客户端),基于 HTTP,简单实现
- **WebSocket**: 双向通信,独立协议,更复杂但功能更强大
### SSE 请求
客户端请求:
```
GET /events HTTP/1.1
Host: example.com
Accept: text/event-stream
```
关键点是 `Accept: text/event-stream` 头部,表明这是 SSE 连接请求。
### SSE 响应格式
```
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
data: {"message": "First update"}\n\n
data: {"message": "Second update"}\n\n
```
- 每条消息以 `data:` 开头
- 消息以两个换行符 `\n\n` 结束
- 连接保持打开状态,服务器可以持续发送新消息
### SSE 特点
1. **自动重连**: 连接断开时客户端自动尝试重新连接
2. **事件ID**: 服务器可以发送ID,让客户端在重连时继续接收丢失的消息
3. **事件类型**: 可以指定事件类型,客户端可以针对不同类型处理
## MCP 协议
MCP (Model Context Protocol) 巧妙地结合了上述技术:
1. **HTTP 基础**: 使用标准 HTTP 作为传输层
2. **JSON-RPC**: 用于函数调用和工具定义
3. **SSE**: 用于流式传输和长连接
### MCP 的通信流程
1. **初始化**:
- 客户端通过 HTTP POST 发送 JSON-RPC 请求 `{"method": "initialize"}`
- 服务器返回服务器信息和能力
2. **工具发现**:
- 客户端发送 JSON-RPC 请求 `{"method": "list_tools"}`
- 服务器返回可用工具列表和定义
3. **工具调用**:
- 客户端发送 JSON-RPC 请求 `{"method": "call_tool", "params": {...}}`
- 服务器执行操作并返回结果
4. **SSE 连接** (可选):
- 客户端发送 GET 请求建立 SSE 连接
- 服务器通过 SSE 发送实时更新和事件
## 在 Dify Endpoint 中实现 MCP
Dify Endpoint 本质上是一个 HTTP 处理器,它可以:
1. 接收 HTTP 请求 (GET/POST)
2. 处理请求头部和内容
3. 返回 HTTP 响应
通过这一机制,你可以在单个 endpoint 中实现 MCP 协议的所有功能:
- **GET 处理**: 提供 HTML 页面或建立 SSE 连接
- **POST 处理**: 处理 JSON-RPC 请求
- **响应生成**: 返回合适的头部和内容
## 实际应用示例
想象一下通过 Claude 调用 Dify workflow 的流程:
1. 用户配置 Claude 连接到你的 MCP 服务
2. Claude 通过 JSON-RPC 请求获取可用工具列表
3. 用户向 Claude 提问,涉及需要外部数据的查询
4. Claude 决定需要调用你的工具,发送 JSON-RPC 请求
5. 你的 endpoint 将请求转换为 Dify workflow 调用
6. 结果返回给 Claude,Claude 生成响应给用户
整个过程无缝集成,用户只需与 Claude 交互,而底层的通信细节由 MCP 协议处理。
理解这些网络协议概念对于实现 MCP 服务非常重要,但好消息是 MCP SDK 已经封装了这些复杂细节,让你可以专注于实现业务逻辑。