@sxcvicky/xhs-mcp-server 1.0.0

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 ADDED
@@ -0,0 +1,52 @@
1
+ # XHS MCP Server
2
+
3
+ 小红书数据分析平台 MCP 工具,为 LLM 提供 5 个数据查询能力。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npx xhs-mcp-server
9
+ ```
10
+
11
+ 或本地开发:
12
+
13
+ ```bash
14
+ npm install
15
+ npm run build
16
+ ```
17
+
18
+ ## MCP 客户端配置
19
+
20
+ ### Claude Desktop / Cursor
21
+
22
+ ```json
23
+ {
24
+ "mcpServers": {
25
+ "xhs": {
26
+ "command": "npx",
27
+ "args": ["-y", "xhs-mcp-server"],
28
+ "env": {
29
+ "XHS_API_URL": "https://your-backend.example.com",
30
+ "XHS_API_KEY": "your-api-key"
31
+ }
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ ### 环境变量
38
+
39
+ | 变量 | 必填 | 默认值 | 说明 |
40
+ |------|------|--------|------|
41
+ | `XHS_API_URL` | 是 | `http://localhost:8181` | 后端服务地址 |
42
+ | `XHS_API_KEY` | 是 | - | API 鉴权密钥 |
43
+
44
+ ## 5 个工具
45
+
46
+ | 工具 | 用途 |
47
+ |------|------|
48
+ | `xhs_search` | 全局搜索话题/笔记/博主/品牌/SPU |
49
+ | `xhs_rank` | 排行榜(笔记/博主/话题/关键词) |
50
+ | `xhs_entity` | 精确查询实体详情 |
51
+ | `xhs_related` | 下钻查询子资源 |
52
+ | `xhs_drill` | 横向对比/追踪/粉丝画像 |
@@ -0,0 +1,5 @@
1
+ export declare function search(params: Record<string, any>): Promise<any>;
2
+ export declare function rank(params: Record<string, any>): Promise<any>;
3
+ export declare function entity(params: Record<string, any>): Promise<any>;
4
+ export declare function related(params: Record<string, any>): Promise<any>;
5
+ export declare function drill(params: Record<string, any>): Promise<any>;
@@ -0,0 +1,37 @@
1
+ const BASE_URL = process.env.XHS_API_URL || 'http://localhost:8181';
2
+ const API_KEY = process.env.XHS_API_KEY || '';
3
+ if (!API_KEY) {
4
+ console.error('[XHS MCP] XHS_API_KEY not set. Set it in MCP server config env.');
5
+ }
6
+ async function request(path, body) {
7
+ const url = `${BASE_URL}/api/v1/aggregate${path}`;
8
+ const resp = await fetch(url, {
9
+ method: 'POST',
10
+ headers: {
11
+ 'Content-Type': 'application/json',
12
+ 'X-API-Key': API_KEY,
13
+ },
14
+ body: JSON.stringify(body),
15
+ });
16
+ if (!resp.ok) {
17
+ const text = await resp.text();
18
+ throw new Error(`HTTP ${resp.status}: ${text}`);
19
+ }
20
+ return resp.json();
21
+ }
22
+ export async function search(params) {
23
+ return request('/search', params);
24
+ }
25
+ export async function rank(params) {
26
+ return request('/rank', params);
27
+ }
28
+ export async function entity(params) {
29
+ return request('/entity', params);
30
+ }
31
+ export async function related(params) {
32
+ return request('/related', params);
33
+ }
34
+ export async function drill(params) {
35
+ return request('/drill', params);
36
+ }
37
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;AACpE,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;AAE9C,IAAI,CAAC,OAAO,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;AACnF,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,IAAY,EAAE,IAAyB;IAC5D,MAAM,GAAG,GAAG,GAAG,QAAQ,oBAAoB,IAAI,EAAE,CAAC;IAClD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,WAAW,EAAE,OAAO;SACrB;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,QAAQ,IAAI,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAA2B;IACtD,OAAO,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,MAA2B;IACpD,OAAO,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAA2B;IACtD,OAAO,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAA2B;IACvD,OAAO,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,MAA2B;IACrD,OAAO,OAAO,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+ import { createInterface } from 'node:readline';
3
+ import { toolDefinitions, executeTool } from './tools.js';
4
+ const SERVER_NAME = 'xhs-mcp-server';
5
+ const SERVER_VERSION = '1.0.0';
6
+ const rl = createInterface({
7
+ input: process.stdin,
8
+ output: process.stdout,
9
+ terminal: false,
10
+ });
11
+ let initialized = false;
12
+ function send(message) {
13
+ process.stdout.write(JSON.stringify(message) + '\n');
14
+ }
15
+ async function handle(method, params, id) {
16
+ switch (method) {
17
+ case 'initialize':
18
+ initialized = true;
19
+ return {
20
+ protocolVersion: '2024-11-05',
21
+ capabilities: { tools: {} },
22
+ serverInfo: { name: SERVER_NAME, version: SERVER_VERSION },
23
+ };
24
+ case 'notifications/initialized':
25
+ return null;
26
+ case 'tools/list':
27
+ return {
28
+ tools: toolDefinitions.map(({ name, description, inputSchema }) => ({
29
+ name,
30
+ description,
31
+ inputSchema,
32
+ })),
33
+ };
34
+ case 'tools/call': {
35
+ const { name, arguments: args } = params;
36
+ const result = await executeTool(name, args || {});
37
+ return {
38
+ content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
39
+ };
40
+ }
41
+ default:
42
+ throw new Error(`Unknown method: ${method}`);
43
+ }
44
+ }
45
+ rl.on('line', async (line) => {
46
+ let msg;
47
+ try {
48
+ msg = JSON.parse(line);
49
+ }
50
+ catch {
51
+ return;
52
+ }
53
+ if (msg.id == null && msg.method === 'notifications/initialized') {
54
+ initialized = true;
55
+ return;
56
+ }
57
+ if (msg.method && msg.id != null) {
58
+ try {
59
+ const result = await handle(msg.method, msg.params, msg.id);
60
+ if (result !== null) {
61
+ send({ jsonrpc: '2.0', id: msg.id, result });
62
+ }
63
+ }
64
+ catch (err) {
65
+ send({
66
+ jsonrpc: '2.0',
67
+ id: msg.id,
68
+ error: { code: -32000, message: err?.message || String(err) },
69
+ });
70
+ }
71
+ }
72
+ });
73
+ process.stdin.resume();
74
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,246 @@
1
+ export declare const toolDefinitions: ({
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {
5
+ type: "object";
6
+ properties: {
7
+ q: {
8
+ type: string;
9
+ description: string;
10
+ };
11
+ scope: {
12
+ type: string;
13
+ enum: string[];
14
+ default: string;
15
+ description: string;
16
+ };
17
+ category: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ page: {
22
+ type: string;
23
+ default: number;
24
+ description: string;
25
+ };
26
+ pageSize: {
27
+ type: string;
28
+ default: number;
29
+ description: string;
30
+ };
31
+ metric?: undefined;
32
+ timeRange?: undefined;
33
+ limit?: undefined;
34
+ id?: undefined;
35
+ type?: undefined;
36
+ include?: undefined;
37
+ parentId?: undefined;
38
+ parentType?: undefined;
39
+ relation?: undefined;
40
+ filters?: undefined;
41
+ sort?: undefined;
42
+ action?: undefined;
43
+ ids?: undefined;
44
+ traceTo?: undefined;
45
+ metrics?: undefined;
46
+ };
47
+ required: string[];
48
+ };
49
+ } | {
50
+ name: string;
51
+ description: string;
52
+ inputSchema: {
53
+ type: "object";
54
+ properties: {
55
+ scope: {
56
+ type: string;
57
+ enum: string[];
58
+ description: string;
59
+ default?: undefined;
60
+ };
61
+ metric: {
62
+ type: string;
63
+ description: string;
64
+ };
65
+ category: {
66
+ type: string;
67
+ description: string;
68
+ };
69
+ timeRange: {
70
+ type: string;
71
+ enum: string[];
72
+ description: string;
73
+ };
74
+ limit: {
75
+ type: string;
76
+ default: number;
77
+ description: string;
78
+ };
79
+ q?: undefined;
80
+ page?: undefined;
81
+ pageSize?: undefined;
82
+ id?: undefined;
83
+ type?: undefined;
84
+ include?: undefined;
85
+ parentId?: undefined;
86
+ parentType?: undefined;
87
+ relation?: undefined;
88
+ filters?: undefined;
89
+ sort?: undefined;
90
+ action?: undefined;
91
+ ids?: undefined;
92
+ traceTo?: undefined;
93
+ metrics?: undefined;
94
+ };
95
+ required: string[];
96
+ };
97
+ } | {
98
+ name: string;
99
+ description: string;
100
+ inputSchema: {
101
+ type: "object";
102
+ properties: {
103
+ id: {
104
+ type: string;
105
+ description: string;
106
+ };
107
+ type: {
108
+ type: string;
109
+ enum: string[];
110
+ description: string;
111
+ };
112
+ include: {
113
+ type: string;
114
+ items: {
115
+ type: string;
116
+ };
117
+ description: string;
118
+ };
119
+ q?: undefined;
120
+ scope?: undefined;
121
+ category?: undefined;
122
+ page?: undefined;
123
+ pageSize?: undefined;
124
+ metric?: undefined;
125
+ timeRange?: undefined;
126
+ limit?: undefined;
127
+ parentId?: undefined;
128
+ parentType?: undefined;
129
+ relation?: undefined;
130
+ filters?: undefined;
131
+ sort?: undefined;
132
+ action?: undefined;
133
+ ids?: undefined;
134
+ traceTo?: undefined;
135
+ metrics?: undefined;
136
+ };
137
+ required: string[];
138
+ };
139
+ } | {
140
+ name: string;
141
+ description: string;
142
+ inputSchema: {
143
+ type: "object";
144
+ properties: {
145
+ parentId: {
146
+ type: string;
147
+ description: string;
148
+ };
149
+ parentType: {
150
+ type: string;
151
+ enum: string[];
152
+ description: string;
153
+ };
154
+ relation: {
155
+ type: string;
156
+ enum: string[];
157
+ description: string;
158
+ };
159
+ filters: {
160
+ type: string;
161
+ description: string;
162
+ };
163
+ sort: {
164
+ type: string;
165
+ description: string;
166
+ };
167
+ page: {
168
+ type: string;
169
+ default: number;
170
+ description?: undefined;
171
+ };
172
+ pageSize: {
173
+ type: string;
174
+ default: number;
175
+ description?: undefined;
176
+ };
177
+ q?: undefined;
178
+ scope?: undefined;
179
+ category?: undefined;
180
+ metric?: undefined;
181
+ timeRange?: undefined;
182
+ limit?: undefined;
183
+ id?: undefined;
184
+ type?: undefined;
185
+ include?: undefined;
186
+ action?: undefined;
187
+ ids?: undefined;
188
+ traceTo?: undefined;
189
+ metrics?: undefined;
190
+ };
191
+ required: string[];
192
+ };
193
+ } | {
194
+ name: string;
195
+ description: string;
196
+ inputSchema: {
197
+ type: "object";
198
+ properties: {
199
+ action: {
200
+ type: string;
201
+ enum: string[];
202
+ description: string;
203
+ };
204
+ ids: {
205
+ type: string;
206
+ items: {
207
+ type: string;
208
+ };
209
+ description: string;
210
+ };
211
+ type: {
212
+ type: string;
213
+ enum: string[];
214
+ description: string;
215
+ };
216
+ traceTo: {
217
+ type: string;
218
+ description: string;
219
+ };
220
+ metrics: {
221
+ type: string;
222
+ items: {
223
+ type: string;
224
+ };
225
+ description: string;
226
+ };
227
+ q?: undefined;
228
+ scope?: undefined;
229
+ category?: undefined;
230
+ page?: undefined;
231
+ pageSize?: undefined;
232
+ metric?: undefined;
233
+ timeRange?: undefined;
234
+ limit?: undefined;
235
+ id?: undefined;
236
+ include?: undefined;
237
+ parentId?: undefined;
238
+ parentType?: undefined;
239
+ relation?: undefined;
240
+ filters?: undefined;
241
+ sort?: undefined;
242
+ };
243
+ required: string[];
244
+ };
245
+ })[];
246
+ export declare function executeTool(name: string, args: Record<string, any>): Promise<any>;
package/dist/tools.js ADDED
@@ -0,0 +1,139 @@
1
+ import { search, rank, entity, related, drill } from './api-client.js';
2
+ export const toolDefinitions = [
3
+ {
4
+ name: 'xhs_search',
5
+ description: '跨实体搜索小红书数据。不限定实体类型,可搜索话题、笔记、博主、关键词、品牌、SPU。适用于用户提出开放式问题时进行全局检索。',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ q: { type: 'string', description: '搜索关键词' },
10
+ scope: {
11
+ type: 'string',
12
+ enum: ['all', 'topic', 'note', 'author', 'keyword', 'brand', 'spu'],
13
+ default: 'all',
14
+ description: '限定搜索范围',
15
+ },
16
+ category: { type: 'string', description: '类目名称筛选,如"美妆个护"' },
17
+ page: { type: 'number', default: 1, description: '页码' },
18
+ pageSize: { type: 'number', default: 5, description: '每页数量' },
19
+ },
20
+ required: ['q'],
21
+ },
22
+ },
23
+ {
24
+ name: 'xhs_rank',
25
+ description: '查看小红书各类排行榜,支持按赞、阅读、互动等指标排行话题/笔记/博主/关键词/品牌/SPU。适用于"最近什么火""热门排行"等趋势类问题。',
26
+ inputSchema: {
27
+ type: 'object',
28
+ properties: {
29
+ scope: {
30
+ type: 'string',
31
+ enum: ['topic', 'note', 'author', 'keyword', 'brand', 'spu'],
32
+ description: '排行实体类型',
33
+ },
34
+ metric: {
35
+ type: 'string',
36
+ description: '排行指标。note: likeNum/readNum/engageNum; topic: totalViewCount/totalDiscussNum; author: fansCount; keyword/noteNum; spu: engageNum',
37
+ },
38
+ category: { type: 'string', description: '类目名称筛选' },
39
+ timeRange: { type: 'string', enum: ['7d', '30d', '90d'], description: '时间范围' },
40
+ limit: { type: 'number', default: 10, description: '返回数量' },
41
+ },
42
+ required: ['scope', 'metric'],
43
+ },
44
+ },
45
+ {
46
+ name: 'xhs_entity',
47
+ description: '根据ID精确查询某个实体的完整详情。支持笔记、博主、话题、关键词、品牌、SPU、类目。适用于"看看这个笔记的具体数据""这个博主什么情况"等精确查询。',
48
+ inputSchema: {
49
+ type: 'object',
50
+ properties: {
51
+ id: { type: 'string', description: '实体ID(笔记noteId、博主userId、话题topicId等)' },
52
+ type: {
53
+ type: 'string',
54
+ enum: ['note', 'author', 'topic', 'keyword', 'brand', 'spu', 'category'],
55
+ description: '实体类型',
56
+ },
57
+ include: {
58
+ type: 'array',
59
+ items: { type: 'string' },
60
+ description: '额外包含的关联数据,如 ["author", "categories", "spus"]',
61
+ },
62
+ },
63
+ required: ['id', 'type'],
64
+ },
65
+ },
66
+ {
67
+ name: 'xhs_related',
68
+ description: '下钻查询某个实体下的子资源。查话题下的笔记/博主、博主下的笔记、类目下的子类目/品牌/SPU。适用于"这个话题有哪些笔记""这个品牌有哪些SPU"等关联查询。',
69
+ inputSchema: {
70
+ type: 'object',
71
+ properties: {
72
+ parentId: { type: 'string', description: '父级ID' },
73
+ parentType: {
74
+ type: 'string',
75
+ enum: ['topic', 'keyword', 'author', 'brand', 'category'],
76
+ description: '父级类型',
77
+ },
78
+ relation: {
79
+ type: 'string',
80
+ enum: ['notes', 'authors', 'children', 'spus', 'fans'],
81
+ description: '查询的关联关系',
82
+ },
83
+ filters: { type: 'object', description: '额外筛选条件' },
84
+ sort: { type: 'string', description: '排序方式' },
85
+ page: { type: 'number', default: 1 },
86
+ pageSize: { type: 'number', default: 10 },
87
+ },
88
+ required: ['parentId', 'parentType', 'relation'],
89
+ },
90
+ },
91
+ {
92
+ name: 'xhs_drill',
93
+ description: '横向对比/追踪分析。可多对象对比、实体追踪、粉丝画像分析。适用于"对比这几个品牌的营销数据""看看这个博主近期的数据变化""这个赛道的粉丝画像"等分析类问题。',
94
+ inputSchema: {
95
+ type: 'object',
96
+ properties: {
97
+ action: {
98
+ type: 'string',
99
+ enum: ['compare', 'trace', 'fanPortrait'],
100
+ description: '分析动作: compare=对比, trace=追踪, fanPortrait=粉丝画像',
101
+ },
102
+ ids: {
103
+ type: 'array',
104
+ items: { type: 'string' },
105
+ description: '要分析的对象ID列表',
106
+ },
107
+ type: {
108
+ type: 'string',
109
+ enum: ['note', 'author', 'topic', 'brand', 'spu'],
110
+ description: '对象类型',
111
+ },
112
+ traceTo: { type: 'string', description: '追踪目标(trace时使用)' },
113
+ metrics: {
114
+ type: 'array',
115
+ items: { type: 'string' },
116
+ description: '对比指标,如 ["likeNum","readNum","engageNum"]',
117
+ },
118
+ },
119
+ required: ['action', 'ids', 'type'],
120
+ },
121
+ },
122
+ ];
123
+ export async function executeTool(name, args) {
124
+ switch (name) {
125
+ case 'xhs_search':
126
+ return await search(args);
127
+ case 'xhs_rank':
128
+ return await rank(args);
129
+ case 'xhs_entity':
130
+ return await entity(args);
131
+ case 'xhs_related':
132
+ return await related(args);
133
+ case 'xhs_drill':
134
+ return await drill(args);
135
+ default:
136
+ throw new Error(`Unknown tool: ${name}`);
137
+ }
138
+ }
139
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@sxcvicky/xhs-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "XHS Data MCP Server - 小红书数据分析平台 MCP 工具",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "xhs-mcp-server": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsx src/index.ts",
13
+ "typecheck": "tsc --noEmit"
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "devDependencies": {
20
+ "typescript": "^5.7.0",
21
+ "tsx": "^4.19.0",
22
+ "@types/node": "^22.0.0"
23
+ }
24
+ }