mcp-adder-simple 1.1.0 → 1.1.2
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 +62 -5
- package/mcp-adder.js +5 -243
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
# MCP
|
|
1
|
+
# MCP Calculator Server
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A modular MCP (Model Context Protocol) server providing mathematical calculations and Sup8 API integration with caching support.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
cd qwen-mcp-adder
|
|
9
|
+
node mcp-adder.js
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Or using npx:
|
|
13
|
+
|
|
7
14
|
```bash
|
|
8
15
|
npx @xiaosheng/mcp-adder
|
|
9
16
|
```
|
|
@@ -15,20 +22,70 @@ Add this server to your MCP client configuration:
|
|
|
15
22
|
```json
|
|
16
23
|
{
|
|
17
24
|
"mcpServers": {
|
|
18
|
-
"
|
|
19
|
-
"command": "
|
|
20
|
-
"args": ["
|
|
25
|
+
"calculator": {
|
|
26
|
+
"command": "node",
|
|
27
|
+
"args": ["/path/to/qwen-mcp-adder/mcp-adder.js"]
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
}
|
|
24
31
|
```
|
|
25
32
|
|
|
33
|
+
## Project Structure
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
qwen-mcp-adder/
|
|
37
|
+
├── mcp-adder.js # 主入口文件 (2.68 KB)
|
|
38
|
+
├── config.js # 配置文件 (258 B)
|
|
39
|
+
├── cache.js # 缓存模块 (1.21 KB)
|
|
40
|
+
├── tools/
|
|
41
|
+
│ ├── index.js # 工具注册 (1.6 KB)
|
|
42
|
+
│ ├── calculator.js # 计算器工具 (921 B)
|
|
43
|
+
│ └── sup8.js # Sup8 API 工具 (2.31 KB)
|
|
44
|
+
├── handlers/
|
|
45
|
+
│ ├── initialize.js # 初始化处理 (429 B)
|
|
46
|
+
│ └── tools.js # 工具调用处理 (954 B)
|
|
47
|
+
└── utils/
|
|
48
|
+
└── http.js # HTTP 请求工具 (3.8 KB)
|
|
49
|
+
```
|
|
50
|
+
|
|
26
51
|
## Tools
|
|
27
52
|
|
|
53
|
+
### Calculator Tools
|
|
54
|
+
|
|
28
55
|
- `add_numbers`: Adds two numbers together
|
|
29
56
|
- `a` (number): The first number
|
|
30
57
|
- `b` (number): The second number
|
|
31
58
|
|
|
59
|
+
- `multiply_numbers`: Multiplies two numbers
|
|
60
|
+
- `a` (number): The first number
|
|
61
|
+
- `b` (number): The second number
|
|
62
|
+
|
|
63
|
+
### Sup8 API Tools (with 10-minute cache)
|
|
64
|
+
|
|
65
|
+
- `sup8_decode`: Decode Sup8 digit
|
|
66
|
+
- `code` (string): The digit code
|
|
67
|
+
- `enterpriseNo` (string): The enterprise number
|
|
68
|
+
|
|
69
|
+
- `sup8_query_code`: Query Sup8 digit information
|
|
70
|
+
- `code` (string): The digit code
|
|
71
|
+
- `enterpriseNo` (string): The enterprise number
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
Edit `config.js` to customize:
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
module.exports = {
|
|
79
|
+
sup8Host: "https://api-fat.yesno.com.cn",
|
|
80
|
+
CACHE_DURATION: 10 * 60 * 1000, // 10 minutes
|
|
81
|
+
serverInfo: {
|
|
82
|
+
name: 'mcp-calculator-server',
|
|
83
|
+
version: '1.0.0'
|
|
84
|
+
},
|
|
85
|
+
protocolVersion: '2024-10-07'
|
|
86
|
+
};
|
|
87
|
+
```
|
|
88
|
+
|
|
32
89
|
## License
|
|
33
90
|
|
|
34
91
|
MIT
|
package/mcp-adder.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Calculator Server
|
|
3
|
-
*
|
|
3
|
+
* 一个模块化的 MCP (Model Context Protocol) 服务器
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const readline = require('readline');
|
|
7
|
-
const https = require('https');
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
const { handleInitialize } = require('./handlers/initialize');
|
|
9
|
+
const { handleToolsList } = require('./tools');
|
|
10
|
+
const { handleToolCall } = require('./handlers/tools');
|
|
11
|
+
|
|
10
12
|
// ========== 配置和初始化 ==========
|
|
11
13
|
|
|
12
14
|
// 创建 readline 接口用于处理 stdin/stdout 通信
|
|
@@ -101,246 +103,6 @@ async function handleRequest(msg) {
|
|
|
101
103
|
console.log(JSON.stringify(response));
|
|
102
104
|
}
|
|
103
105
|
|
|
104
|
-
/**
|
|
105
|
-
* 处理 initialize 请求
|
|
106
|
-
* @returns {Object} 初始化响应
|
|
107
|
-
*/
|
|
108
|
-
function handleInitialize() {
|
|
109
|
-
return {
|
|
110
|
-
protocolVersion: '2024-10-07',
|
|
111
|
-
serverInfo: {
|
|
112
|
-
name: 'mcp-calculator-server',
|
|
113
|
-
version: '1.0.0'
|
|
114
|
-
},
|
|
115
|
-
capabilities: {
|
|
116
|
-
tools: {} // 声明支持 tools 功能
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* 处理工具列表请求
|
|
123
|
-
* @returns {Object} 工具列表响应
|
|
124
|
-
*/
|
|
125
|
-
function handleToolsList() {
|
|
126
|
-
return {
|
|
127
|
-
tools: [
|
|
128
|
-
{
|
|
129
|
-
name: 'add_numbers',
|
|
130
|
-
description: '将两个数字相加',
|
|
131
|
-
inputSchema: {
|
|
132
|
-
type: 'object',
|
|
133
|
-
properties: {
|
|
134
|
-
a: {
|
|
135
|
-
type: 'number',
|
|
136
|
-
description: '第一个数'
|
|
137
|
-
},
|
|
138
|
-
b: {
|
|
139
|
-
type: 'number',
|
|
140
|
-
description: '第二个数'
|
|
141
|
-
}
|
|
142
|
-
},
|
|
143
|
-
required: ['a', 'b']
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
name: 'multiply_numbers',
|
|
148
|
-
description: '将两个数字相乘',
|
|
149
|
-
inputSchema: {
|
|
150
|
-
type: 'object',
|
|
151
|
-
properties: {
|
|
152
|
-
a: {
|
|
153
|
-
type: 'number',
|
|
154
|
-
description: '第一个数'
|
|
155
|
-
},
|
|
156
|
-
b: {
|
|
157
|
-
type: 'number',
|
|
158
|
-
description: '第二个数'
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
required: ['a', 'b']
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
name: 'sup8_decode',
|
|
166
|
-
description: '解码',
|
|
167
|
-
inputSchema: {
|
|
168
|
-
type: 'object',
|
|
169
|
-
properties: {
|
|
170
|
-
code: {
|
|
171
|
-
type: 'string',
|
|
172
|
-
description: '数码'
|
|
173
|
-
},
|
|
174
|
-
enterpriseNo: {
|
|
175
|
-
type: 'string',
|
|
176
|
-
description: '企业号'
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
required: ['code', 'enterpriseNo']
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'sup8_query_code',
|
|
184
|
-
description: '查询数码信息',
|
|
185
|
-
inputSchema: {
|
|
186
|
-
type: 'object',
|
|
187
|
-
properties: {
|
|
188
|
-
code: {
|
|
189
|
-
type: 'string',
|
|
190
|
-
description: '数码'
|
|
191
|
-
},
|
|
192
|
-
enterpriseNo: {
|
|
193
|
-
type: 'string',
|
|
194
|
-
description: '企业号'
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
required: ['code', 'enterpriseNo']
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
]
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* 处理工具调用请求
|
|
206
|
-
* @param {Object} params - 请求参数
|
|
207
|
-
* @param {string} params.name - 工具名称
|
|
208
|
-
* @param {Object} params.arguments - 工具参数
|
|
209
|
-
* @returns {Object} 工具执行结果
|
|
210
|
-
*/
|
|
211
|
-
async function handleToolCall(params) {
|
|
212
|
-
const { name, arguments: args } = params;
|
|
213
|
-
|
|
214
|
-
if (name === 'add_numbers') {
|
|
215
|
-
const { a, b } = args;
|
|
216
|
-
|
|
217
|
-
// 参数类型验证
|
|
218
|
-
if (typeof a !== 'number' || typeof b !== 'number') {
|
|
219
|
-
throw new Error('参数必须是数字');
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// 计算并返回结果
|
|
223
|
-
return {
|
|
224
|
-
content: [
|
|
225
|
-
{
|
|
226
|
-
type: 'text',
|
|
227
|
-
text: `${a} + ${b} = ${a + b}`
|
|
228
|
-
}
|
|
229
|
-
]
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
} else if (name === 'multiply_numbers') {
|
|
233
|
-
const { a, b } = args;
|
|
234
|
-
|
|
235
|
-
// 参数类型验证
|
|
236
|
-
if (typeof a !== 'number' || typeof b !== 'number') {
|
|
237
|
-
throw new Error('参数必须是数字');
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// 计算并返回结果
|
|
241
|
-
return {
|
|
242
|
-
content: [
|
|
243
|
-
{
|
|
244
|
-
type: 'text',
|
|
245
|
-
text: `${a} × ${b} = ${a * b}`
|
|
246
|
-
}
|
|
247
|
-
]
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
else if (name === 'sup8_decode') {
|
|
252
|
-
const { code, enterpriseNo } = args;
|
|
253
|
-
|
|
254
|
-
// 参数类型验证
|
|
255
|
-
if (typeof code !== 'string' || typeof enterpriseNo !== 'string') {
|
|
256
|
-
throw new Error('参数必须是字符串');
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// 构建请求 URL
|
|
260
|
-
const url = `${sup8Host}/digit/v1/decode/decode?digit=${encodeURIComponent(code)}&enterpriseNo=${encodeURIComponent(enterpriseNo)}`;
|
|
261
|
-
|
|
262
|
-
console.error(`[HTTP] 调用外部API: ${url}`);
|
|
263
|
-
|
|
264
|
-
// 调用外部 API 并返回结果
|
|
265
|
-
const result = await new Promise((resolve, reject) => {
|
|
266
|
-
https.get(url, (res) => {
|
|
267
|
-
let data = '';
|
|
268
|
-
res.on('data', (chunk) => {
|
|
269
|
-
data += chunk;
|
|
270
|
-
});
|
|
271
|
-
res.on('end', () => {
|
|
272
|
-
try {
|
|
273
|
-
const jsonData = JSON.parse(data);
|
|
274
|
-
console.error(`[HTTP] API响应:`, JSON.stringify(jsonData, null, 2));
|
|
275
|
-
resolve(jsonData);
|
|
276
|
-
} catch (e) {
|
|
277
|
-
reject(new Error(`JSON解析失败: ${e.message}`));
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
}).on('error', (err) => {
|
|
281
|
-
reject(new Error(`HTTP请求失败: ${err.message}`));
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
// 计算并返回结果
|
|
285
|
-
return {
|
|
286
|
-
content: [
|
|
287
|
-
{
|
|
288
|
-
type: 'text',
|
|
289
|
-
text: JSON.stringify(result, null, 2)
|
|
290
|
-
}
|
|
291
|
-
]
|
|
292
|
-
};
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
else if (name === 'sup8_query_code') {
|
|
296
|
-
const { code, enterpriseNo } = args;
|
|
297
|
-
|
|
298
|
-
// 参数类型验证
|
|
299
|
-
if (typeof code !== 'string' || typeof enterpriseNo !== 'string') {
|
|
300
|
-
throw new Error('参数必须是字符串');
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// 构建请求 URL
|
|
304
|
-
const url = `${sup8Host}/digit/v2/digit/get-digit-info?code=${encodeURIComponent(code)}&enterpriseNo=${encodeURIComponent(enterpriseNo)}`;
|
|
305
|
-
|
|
306
|
-
console.error(`[HTTP] 调用外部API: ${url}`);
|
|
307
|
-
|
|
308
|
-
// 调用外部 API 并返回结果
|
|
309
|
-
const result = await new Promise((resolve, reject) => {
|
|
310
|
-
https.get(url, (res) => {
|
|
311
|
-
let data = '';
|
|
312
|
-
res.on('data', (chunk) => {
|
|
313
|
-
data += chunk;
|
|
314
|
-
});
|
|
315
|
-
res.on('end', () => {
|
|
316
|
-
try {
|
|
317
|
-
const jsonData = JSON.parse(data);
|
|
318
|
-
console.error(`[HTTP] API响应:`, JSON.stringify(jsonData, null, 2));
|
|
319
|
-
resolve(jsonData);
|
|
320
|
-
} catch (e) {
|
|
321
|
-
reject(new Error(`JSON解析失败: ${e.message}`));
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
}).on('error', (err) => {
|
|
325
|
-
reject(new Error(`HTTP请求失败: ${err.message}`));
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
// 计算并返回结果
|
|
329
|
-
return {
|
|
330
|
-
content: [
|
|
331
|
-
{
|
|
332
|
-
type: 'text',
|
|
333
|
-
text: JSON.stringify(result, null, 2)
|
|
334
|
-
}
|
|
335
|
-
]
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
throw new Error(`未知工具: ${name}`);
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
106
|
// ========== 清理和退出 ==========
|
|
345
107
|
|
|
346
108
|
// 当连接关闭时退出进程
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-adder-simple",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"main": "mcp-adder.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"mcp-adder-simple": "./bin/mcp-adder-simple.cmd"
|
|
@@ -27,5 +27,8 @@
|
|
|
27
27
|
"bin/mcp-adder-simple.cmd",
|
|
28
28
|
"package.json",
|
|
29
29
|
"README.md"
|
|
30
|
-
]
|
|
30
|
+
],
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"mysql2": "^3.16.1"
|
|
33
|
+
}
|
|
31
34
|
}
|