@vkse/sse-mcp-skill 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +185 -0
- package/package.json +22 -0
- package/server.js +87 -0
package/README.md
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# sse-mcp-skill
|
|
2
|
+
|
|
3
|
+
一个基于 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 的 **SSE(Server-Sent Events)传输模式** 示例服务器,使用 Node.js + Express 实现。该服务器对外暴露 `query_user_database` 工具,模拟远程数据库查询场景,供 AI 客户端(如 Claude Desktop、Cursor 等)在对话中调用。
|
|
4
|
+
|
|
5
|
+
## 与 Stdio 模式的核心差异
|
|
6
|
+
|
|
7
|
+
| 特性 | Stdio 模式 | SSE 模式(本项目) |
|
|
8
|
+
| -------- | ------------------ | -------------------------------- |
|
|
9
|
+
| 通信方式 | 标准输入/输出 | HTTP + Server-Sent Events |
|
|
10
|
+
| 网络能力 | 仅限本地进程 | 支持远程 / 跨网络连接 |
|
|
11
|
+
| 端口监听 | 无 | 默认监听 `3000` 端口 |
|
|
12
|
+
| 连接建立 | 客户端直接启动进程 | 客户端先 `GET /sse` 建立长连接 |
|
|
13
|
+
| 消息发送 | 通过 stdin/stdout | 客户端 `POST /messages` 发送指令 |
|
|
14
|
+
| 适用场景 | 本地工具、CLI 环境 | 远程服务、多客户端、Web 环境 |
|
|
15
|
+
|
|
16
|
+
## 项目结构
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
sse-mcp-skill/
|
|
20
|
+
├── server.js # 服务器入口,Express 路由 + MCP 工具定义
|
|
21
|
+
├── package.json # 项目依赖与脚本配置
|
|
22
|
+
└── README.md
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 核心依赖
|
|
26
|
+
|
|
27
|
+
| 依赖 | 版本 | 说明 |
|
|
28
|
+
| --------------------------- | ------- | -------------------------------------------------------- |
|
|
29
|
+
| `@modelcontextprotocol/sdk` | ^1.28.0 | MCP 官方 SDK,提供 Server、SSEServerTransport 等核心能力 |
|
|
30
|
+
| `express` | ^5.2.1 | Web 框架,用于创建 HTTP 路由(SSE 握手 + 消息接收) |
|
|
31
|
+
| `cors` | ^2.8.6 | 跨域中间件,允许浏览器内的 AI 客户端跨域请求 |
|
|
32
|
+
|
|
33
|
+
## 工具列表
|
|
34
|
+
|
|
35
|
+
### `query_user_database`
|
|
36
|
+
|
|
37
|
+
根据用户 ID 查询远程数据库中的核心数据(当前为模拟数据)。
|
|
38
|
+
|
|
39
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
40
|
+
| -------- | -------- | ---- | ----------------- |
|
|
41
|
+
| `userId` | `number` | 是 | 需要查询的用户 ID |
|
|
42
|
+
|
|
43
|
+
**返回示例:**
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
查询成功,数据为: {"id":1,"status":"active","plan":"premium"}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## 快速开始
|
|
50
|
+
|
|
51
|
+
### 1. 安装依赖
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
cd sse-mcp-skill
|
|
55
|
+
npm install
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 2. 运行服务
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm start
|
|
62
|
+
# 或
|
|
63
|
+
node server.js
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
启动后,服务监听 `http://localhost:3000`,终端将输出:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
🚀 HTTP/SSE MCP Server 正在运行,请让 AI 客户端连接: http://localhost:3000/sse
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## SSE 通信流程
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
AI 客户端 SSE MCP Server (Express)
|
|
76
|
+
│ │
|
|
77
|
+
│──── GET /sse ────────────────────────>│ ① 建立 SSE 长连接
|
|
78
|
+
│<─── SSE stream (keep-alive) ─────────│
|
|
79
|
+
│ │
|
|
80
|
+
│──── POST /messages ──────────────────>│ ② 发送 JSON-RPC 指令
|
|
81
|
+
│ │ (initialize / tools/list / tools/call)
|
|
82
|
+
│<─── SSE 推送结果 ────────────────────│ ③ 通过长连接推回结果
|
|
83
|
+
│ │
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## 测试方法
|
|
87
|
+
|
|
88
|
+
### 方式一:使用 MCP Inspector 测试
|
|
89
|
+
|
|
90
|
+
[MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector) 是官方提供的可视化调试工具:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx -y @modelcontextprotocol/inspector node server.js
|
|
94
|
+
# 或者
|
|
95
|
+
npx -y @modelcontextprotocol/inspector sse://localhost:3000/sse
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
启动后在浏览器中打开 Inspector 界面,可以:
|
|
99
|
+
|
|
100
|
+
- 查看工具清单(List Tools)
|
|
101
|
+
- 手动调用 `query_user_database` 工具并查看返回结果
|
|
102
|
+
- 调试 JSON-RPC 消息收发
|
|
103
|
+
|
|
104
|
+
### 方式二:使用 curl 手动测试
|
|
105
|
+
|
|
106
|
+
**① 建立 SSE 连接(保持终端窗口打开):**
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
curl -N http://localhost:3000/sse
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**② 在另一个终端发送初始化请求:**
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
curl -X POST http://localhost:3000/messages \
|
|
116
|
+
-H "Content-Type: application/json" \
|
|
117
|
+
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}'
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 方式三:配置到 AI 客户端中测试
|
|
121
|
+
|
|
122
|
+
在支持 MCP 的 AI 客户端(如 Claude Desktop、Cursor、Cline 等)中添加如下配置:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"mcpServers": {
|
|
127
|
+
"remote-database-skill": {
|
|
128
|
+
"url": "http://localhost:3000/sse"
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
配置完成后,在对话中询问"帮我查一下用户 1 的信息"等数据库相关问题,AI 将自动调用 `query_user_database` 工具。
|
|
135
|
+
|
|
136
|
+
## 使用方法
|
|
137
|
+
|
|
138
|
+
### 作为 MCP 技能集成
|
|
139
|
+
|
|
140
|
+
1. 启动本服务(`npm start`)
|
|
141
|
+
2. 将 SSE 端点 `http://localhost:3000/sse` 配置到 AI 客户端
|
|
142
|
+
3. AI 根据对话上下文自动判断是否调用 `query_user_database`
|
|
143
|
+
4. 工具返回结果后,AI 将查询信息整合到回答中
|
|
144
|
+
|
|
145
|
+
### 扩展新工具
|
|
146
|
+
|
|
147
|
+
在 `server.js` 中按以下模式添加新工具:
|
|
148
|
+
|
|
149
|
+
**① 在 `ListToolsRequestSchema` 处理器中注册工具描述:**
|
|
150
|
+
|
|
151
|
+
```javascript
|
|
152
|
+
{
|
|
153
|
+
name: "your_tool_name",
|
|
154
|
+
description: "工具描述(写给 AI 看,决定调用时机)",
|
|
155
|
+
inputSchema: {
|
|
156
|
+
type: "object",
|
|
157
|
+
properties: {
|
|
158
|
+
param1: { type: "string", description: "参数说明" },
|
|
159
|
+
},
|
|
160
|
+
required: ["param1"],
|
|
161
|
+
},
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**② 在 `CallToolRequestSchema` 处理器中实现工具逻辑:**
|
|
166
|
+
|
|
167
|
+
```javascript
|
|
168
|
+
if (request.params.name === "your_tool_name") {
|
|
169
|
+
const { param1 } = request.params.arguments;
|
|
170
|
+
// 执行业务逻辑(如调用远程 API、查询数据库等)...
|
|
171
|
+
return {
|
|
172
|
+
content: [{ type: "text", text: "返回结果" }],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## 注意事项
|
|
178
|
+
|
|
179
|
+
- **CORS 已启用**:`server.js` 中默认配置了 `cors()` 中间件,允许所有来源的跨域请求
|
|
180
|
+
- **单客户端限制**:当前实现仅维护一个全局 `transport` 实例,同一时间只支持一个客户端连接。如需多客户端支持,需使用 Map 按 session 管理 transport
|
|
181
|
+
- **端口冲突**:默认端口为 `3000`,如有冲突可在 `server.js` 底部修改 `PORT` 常量
|
|
182
|
+
|
|
183
|
+
## License
|
|
184
|
+
|
|
185
|
+
ISC
|
package/package.json
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vkse/sse-mcp-skill",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "server.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node server.js",
|
|
8
|
+
"publish:npm": "npm publish --access public",
|
|
9
|
+
"release": "npm version patch && npm publish --access public",
|
|
10
|
+
"release:minor": "npm version minor && npm publish --access public",
|
|
11
|
+
"release:major": "npm version major && npm publish --access public"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "ISC",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
19
|
+
"cors": "^2.8.6",
|
|
20
|
+
"express": "^5.2.1"
|
|
21
|
+
}
|
|
22
|
+
}
|
package/server.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import cors from "cors";
|
|
3
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
4
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
5
|
+
import {
|
|
6
|
+
CallToolRequestSchema,
|
|
7
|
+
ListToolsRequestSchema,
|
|
8
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
|
|
10
|
+
const app = express();
|
|
11
|
+
// 必须配置 CORS,因为 AI 客户端(如浏览器内的环境)可能会跨域请求
|
|
12
|
+
app.use(cors());
|
|
13
|
+
|
|
14
|
+
// 1. 初始化 MCP Server
|
|
15
|
+
const mcpServer = new Server(
|
|
16
|
+
{ name: "remote-database-skill", version: "1.0.0" },
|
|
17
|
+
{ capabilities: { tools: {} } }
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
// 2. 注册工具 (例如:一个模拟的远程数据库查询工具)
|
|
21
|
+
mcpServer.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
22
|
+
return {
|
|
23
|
+
tools: [
|
|
24
|
+
{
|
|
25
|
+
name: "query_user_database",
|
|
26
|
+
description: "根据用户 ID 查询远程数据库中的核心数据",
|
|
27
|
+
inputSchema: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
userId: { type: "number", description: "需要查询的用户 ID" },
|
|
31
|
+
},
|
|
32
|
+
required: ["userId"],
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 3. 处理调用指令
|
|
40
|
+
mcpServer.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
41
|
+
if (request.params.name === "query_user_database") {
|
|
42
|
+
const { userId } = request.params.arguments;
|
|
43
|
+
// 这里可以接入真实的 PostgreSQL 或 CockroachDB 查询逻辑
|
|
44
|
+
const mockData = { id: userId, status: "active", plan: "premium" };
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: "text", text: `查询成功,数据为: ${JSON.stringify(mockData)}` }],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Tool not found: ${request.params.name}`);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// === 核心差异:网络路由与 Transport 绑定 ===
|
|
54
|
+
|
|
55
|
+
let transport; // 维护全局/会话级别的 transport 实例
|
|
56
|
+
|
|
57
|
+
// 接口 1:客户端发起的 SSE 握手连接
|
|
58
|
+
app.get("/sse", async (req, res) => {
|
|
59
|
+
console.log("收到新的客户端连接请求...");
|
|
60
|
+
|
|
61
|
+
// 创建 SSE Transport,并告知客户端未来发消息要用哪个相对路径(/messages)
|
|
62
|
+
transport = new SSEServerTransport("/messages", res);
|
|
63
|
+
|
|
64
|
+
// 将 Transport 绑定到 MCP Server
|
|
65
|
+
await mcpServer.connect(transport);
|
|
66
|
+
|
|
67
|
+
// 此时长连接已建立,客户端会一直保持 pending 状态接收数据
|
|
68
|
+
console.log("SSE 连接已建立!");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// 接口 2:客户端用来发送指令的 POST 接口
|
|
72
|
+
app.post("/messages", async (req, res) => {
|
|
73
|
+
if (!transport) {
|
|
74
|
+
return res.status(400).send("请先访问 /sse 建立连接");
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// 将原生的 HTTP 请求/响应对象交给 SDK 内部去解析 JSON-RPC
|
|
78
|
+
// SDK 拿到指令后,会触发上面定义的 CallToolRequestSchema,
|
|
79
|
+
// 然后通过绑定的 SSE 长连接把结果推回给客户端
|
|
80
|
+
await transport.handlePostMessage(req, res);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// 启动 Express 服务
|
|
84
|
+
const PORT = 3000;
|
|
85
|
+
app.listen(PORT, () => {
|
|
86
|
+
console.log(`🚀 HTTP/SSE MCP Server 正在运行,请让 AI 客户端连接: http://localhost:${PORT}/sse`);
|
|
87
|
+
});
|