mapbox-create-map-mcp 1.3.1 → 1.4.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 +71 -1
- package/package.json +3 -3
- package/src/icon.js +162 -0
- package/src/server.js +178 -0
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ npx mapbox-create-map-mcp
|
|
|
47
47
|
|
|
48
48
|
输入参数:
|
|
49
49
|
- `name` (string, 必需): 弹框样式名称
|
|
50
|
-
- `htmlContent` (string, 必需): 弹框的HTML
|
|
50
|
+
- `htmlContent` (string, 必需): 弹框的HTML内容,**支持`{fieldName}`占位符动态绑定数据**
|
|
51
51
|
- `theme` (string, 可选): 预设主题 `light` | `dark` | `minimal` | `custom`
|
|
52
52
|
- `closeButton` (boolean, 可选): 是否显示关闭按钮
|
|
53
53
|
- `closeOnClick` (boolean, 可选): 点击地图时是否关闭
|
|
@@ -58,6 +58,35 @@ npx mapbox-create-map-mcp
|
|
|
58
58
|
- `altitude` (number, 可选): 海拔高度(米)
|
|
59
59
|
- `className` (string, 可选): 自定义CSS类名
|
|
60
60
|
|
|
61
|
+
**占位符用法:**
|
|
62
|
+
|
|
63
|
+
`htmlContent` 支持使用 `{fieldName}` 占位符动态绑定 GeoJSON 要素的 `properties` 属性。当点击地图上的要素时,占位符会被替换为实际值。
|
|
64
|
+
|
|
65
|
+
```html
|
|
66
|
+
<!-- htmlContent 示例 -->
|
|
67
|
+
<div>
|
|
68
|
+
<h3>{name}</h3>
|
|
69
|
+
<p>地址: {address}</p>
|
|
70
|
+
<p>类型: {type}</p>
|
|
71
|
+
<p>数值: {value}</p>
|
|
72
|
+
</div>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
当点击的要素 `properties` 为:
|
|
76
|
+
```json
|
|
77
|
+
{"name": "北京站", "address": "北京市东城区", "type": "火车站", "value": 12345}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
弹框显示:
|
|
81
|
+
```html
|
|
82
|
+
<div>
|
|
83
|
+
<h3>北京站</h3>
|
|
84
|
+
<p>地址: 北京市东城区</p>
|
|
85
|
+
<p>类型: 火车站</p>
|
|
86
|
+
<p>数值: 12345</p>
|
|
87
|
+
</div>
|
|
88
|
+
```
|
|
89
|
+
|
|
61
90
|
返回结果示例:
|
|
62
91
|
```json
|
|
63
92
|
{
|
|
@@ -77,6 +106,47 @@ npx mapbox-create-map-mcp
|
|
|
77
106
|
}
|
|
78
107
|
```
|
|
79
108
|
|
|
109
|
+
#### CreateIcon - 搜索图标
|
|
110
|
+
|
|
111
|
+
从 iconfont 搜索图标并返回 `data:image/svg+xml;base64` 格式的图标数据,可直接用于 `<img>` 标签的 `src` 属性。
|
|
112
|
+
|
|
113
|
+
输入参数:
|
|
114
|
+
- `keyword` (string, 必需): 搜索关键词,例如 "车辆"、"建筑"、"定位"
|
|
115
|
+
- `id` (number, 可选): 图标ID,传入后会优先查找该ID的图标,方便复用之前的图标
|
|
116
|
+
- `index` (number, 可选): 选择搜索结果中的第几个图标,从0开始,范围0-49,默认0
|
|
117
|
+
- `color` (string, 可选): 图标颜色,十六进制格式如 "#FF0000"。**不传则保持原始颜色**
|
|
118
|
+
- `size` (number, 可选): 图标大小,单位像素,默认48
|
|
119
|
+
|
|
120
|
+
返回结果示例:
|
|
121
|
+
```json
|
|
122
|
+
{
|
|
123
|
+
"success": true,
|
|
124
|
+
"data": "data:image/svg+xml;base64,PHN2ZyBjbGFzcz0i...",
|
|
125
|
+
"name": "建筑",
|
|
126
|
+
"id": 3841001
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
使用示例:
|
|
131
|
+
```javascript
|
|
132
|
+
// 基本搜索
|
|
133
|
+
{ keyword: "建筑" }
|
|
134
|
+
|
|
135
|
+
// 选择第3个结果
|
|
136
|
+
{ keyword: "建筑", index: 2 }
|
|
137
|
+
|
|
138
|
+
// 使用之前的ID精确查找
|
|
139
|
+
{ keyword: "建筑", id: 3841001 }
|
|
140
|
+
|
|
141
|
+
// 指定颜色和大小
|
|
142
|
+
{ keyword: "建筑", color: "#FF5500", size: 64 }
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
返回的 `data` 可直接用于:
|
|
146
|
+
```html
|
|
147
|
+
<img src="data:image/svg+xml;base64,PHN2Zy..." />
|
|
148
|
+
```
|
|
149
|
+
|
|
80
150
|
## JavaScript 库使用
|
|
81
151
|
|
|
82
152
|
### 基本使用
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mapbox-create-map-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "A Mapbox-based MCP tool for creating geographic data visualizations",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"mapbox-create-map-mcp": "
|
|
9
|
+
"mapbox-create-map-mcp": "bin/cli.js"
|
|
10
10
|
},
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"repository": {
|
|
59
59
|
"type": "git",
|
|
60
|
-
"url": "https://github.com/gis-team/mapbox-create-map.git"
|
|
60
|
+
"url": "git+https://github.com/gis-team/mapbox-create-map.git"
|
|
61
61
|
},
|
|
62
62
|
"bugs": {
|
|
63
63
|
"url": "https://github.com/gis-team/mapbox-create-map/issues"
|
package/src/icon.js
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CreateIcon - 图标搜索工具
|
|
3
|
+
* 从iconfont搜索图标并返回data:image/svg+xml格式
|
|
4
|
+
*/
|
|
5
|
+
class CreateIcon {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.metadata = {
|
|
8
|
+
keyword: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
required: true,
|
|
11
|
+
description: '搜索关键词,例如: "车辆", "地图", "定位" 等'
|
|
12
|
+
},
|
|
13
|
+
id: {
|
|
14
|
+
type: 'number',
|
|
15
|
+
required: false,
|
|
16
|
+
description: '图标ID,传入后会优先查找该ID的图标'
|
|
17
|
+
},
|
|
18
|
+
index: {
|
|
19
|
+
type: 'number',
|
|
20
|
+
required: false,
|
|
21
|
+
default: 0,
|
|
22
|
+
description: '选择搜索结果中的第几个图标,从0开始,范围0-49'
|
|
23
|
+
},
|
|
24
|
+
color: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
required: false,
|
|
27
|
+
description: '图标颜色,十六进制格式,例如: "#FF0000"。不传则保持原始颜色'
|
|
28
|
+
},
|
|
29
|
+
size: {
|
|
30
|
+
type: 'number',
|
|
31
|
+
required: false,
|
|
32
|
+
default: 48,
|
|
33
|
+
description: '图标大小,单位为像素'
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* 搜索图标
|
|
40
|
+
* @param {Object} config - 搜索配置
|
|
41
|
+
* @param {string} config.keyword - 搜索关键词
|
|
42
|
+
* @param {number} [config.id] - 图标ID,优先查找
|
|
43
|
+
* @param {number} [config.index] - 选择第几个(0-49)
|
|
44
|
+
* @param {string} [config.color] - 图标颜色,不传保持原色
|
|
45
|
+
* @param {number} [config.size] - 图标大小
|
|
46
|
+
* @returns {Promise<Object>} 返回图标数据
|
|
47
|
+
*/
|
|
48
|
+
async search(config) {
|
|
49
|
+
if (!config.keyword || typeof config.keyword !== 'string') {
|
|
50
|
+
throw new Error('keyword 是必填字段,且必须是字符串');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const https = require('https');
|
|
54
|
+
const querystring = require('querystring');
|
|
55
|
+
|
|
56
|
+
// 确定 index,限制在0-49范围
|
|
57
|
+
let index = config.index !== undefined ? Math.max(0, Math.min(49, Math.floor(config.index))) : 0;
|
|
58
|
+
// pageSize 取 index + 1,确保能获取到指定位置的图标
|
|
59
|
+
const pageSize = index + 1;
|
|
60
|
+
|
|
61
|
+
const postData = querystring.stringify({
|
|
62
|
+
q: config.keyword,
|
|
63
|
+
sortType: 'updated_at',
|
|
64
|
+
page: 1,
|
|
65
|
+
pageSize: pageSize,
|
|
66
|
+
fromCollection: -1,
|
|
67
|
+
complex: 1,
|
|
68
|
+
t: Date.now(),
|
|
69
|
+
ctoken: 'null'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const options = {
|
|
73
|
+
hostname: 'www.iconfont.cn',
|
|
74
|
+
port: 443,
|
|
75
|
+
path: '/api/icon/search.json',
|
|
76
|
+
method: 'POST',
|
|
77
|
+
headers: {
|
|
78
|
+
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
79
|
+
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
80
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
81
|
+
'Referer': 'https://www.iconfont.cn/search/index',
|
|
82
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
83
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const req = https.request(options, (res) => {
|
|
89
|
+
let data = '';
|
|
90
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
91
|
+
res.on('end', () => {
|
|
92
|
+
try {
|
|
93
|
+
const result = JSON.parse(data);
|
|
94
|
+
if (result.code === 200 && result.data && result.data.icons && result.data.icons.length > 0) {
|
|
95
|
+
const icons = result.data.icons;
|
|
96
|
+
let icon = null;
|
|
97
|
+
|
|
98
|
+
// 优先按 id 查找
|
|
99
|
+
if (config.id !== undefined) {
|
|
100
|
+
icon = icons.find(i => i.id === config.id);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 没找到则按 index 选择,越界默认第一个
|
|
104
|
+
if (!icon) {
|
|
105
|
+
const safeIndex = index < icons.length ? index : 0;
|
|
106
|
+
icon = icons[safeIndex];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let svgContent = icon.show_svg;
|
|
110
|
+
|
|
111
|
+
if (!svgContent) {
|
|
112
|
+
resolve({ success: false, data: null, message: '图标没有SVG内容' });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 应用大小
|
|
117
|
+
const size = config.size || 48;
|
|
118
|
+
|
|
119
|
+
// 只有传入 color 时才替换颜色,否则保持原始样式
|
|
120
|
+
if (config.color) {
|
|
121
|
+
svgContent = svgContent.replace(/fill="[^"]*"/g, `fill="${config.color}"`);
|
|
122
|
+
svgContent = svgContent.replace(/style="[^"]*"/, `style="width: ${size}px; height: ${size}px; vertical-align: middle; fill: ${config.color}; overflow: hidden;"`);
|
|
123
|
+
} else {
|
|
124
|
+
// 不修改颜色,只设置宽高
|
|
125
|
+
svgContent = svgContent.replace(/style="[^"]*"/, `style="width: ${size}px; height: ${size}px; vertical-align: middle; overflow: hidden;"`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 转换为data URI (base64编码)
|
|
129
|
+
const base64 = Buffer.from(svgContent).toString('base64');
|
|
130
|
+
const dataUri = `data:image/svg+xml;base64,${base64}`;
|
|
131
|
+
|
|
132
|
+
resolve({
|
|
133
|
+
success: true,
|
|
134
|
+
data: dataUri,
|
|
135
|
+
name: icon.name,
|
|
136
|
+
id: icon.id
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
resolve({ success: false, data: null, message: '未找到匹配的图标' });
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
reject(new Error(`解析响应失败: ${e.message}`));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
req.on('error', (e) => {
|
|
148
|
+
reject(new Error(`请求失败: ${e.message}`));
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
req.setTimeout(10000, () => {
|
|
152
|
+
req.destroy();
|
|
153
|
+
reject(new Error('请求超时'));
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
req.write(postData);
|
|
157
|
+
req.end();
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
module.exports = { CreateIcon };
|
package/src/server.js
CHANGED
|
@@ -187,10 +187,162 @@ class CreatePopup {
|
|
|
187
187
|
}
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
/**
|
|
191
|
+
* CreateIcon - 图标搜索工具
|
|
192
|
+
* 从iconfont搜索图标并返回data:image/svg+xml格式
|
|
193
|
+
*/
|
|
194
|
+
class CreateIcon {
|
|
195
|
+
constructor() {
|
|
196
|
+
this.metadata = {
|
|
197
|
+
keyword: {
|
|
198
|
+
type: 'string',
|
|
199
|
+
required: true,
|
|
200
|
+
description: '搜索关键词,例如: "车辆", "地图", "定位" 等'
|
|
201
|
+
},
|
|
202
|
+
id: {
|
|
203
|
+
type: 'number',
|
|
204
|
+
required: false,
|
|
205
|
+
description: '图标ID,传入后会优先查找该ID的图标'
|
|
206
|
+
},
|
|
207
|
+
index: {
|
|
208
|
+
type: 'number',
|
|
209
|
+
required: false,
|
|
210
|
+
default: 0,
|
|
211
|
+
description: '选择搜索结果中的第几个图标,从0开始,范围0-49'
|
|
212
|
+
},
|
|
213
|
+
color: {
|
|
214
|
+
type: 'string',
|
|
215
|
+
required: false,
|
|
216
|
+
description: '图标颜色,十六进制格式,例如: "#FF0000"。不传则保持原始颜色'
|
|
217
|
+
},
|
|
218
|
+
size: {
|
|
219
|
+
type: 'number',
|
|
220
|
+
required: false,
|
|
221
|
+
default: 48,
|
|
222
|
+
description: '图标大小,单位为像素'
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async search(config) {
|
|
228
|
+
if (!config.keyword || typeof config.keyword !== 'string') {
|
|
229
|
+
throw new Error('keyword 是必填字段,且必须是字符串');
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
const https = require('https');
|
|
233
|
+
const querystring = require('querystring');
|
|
234
|
+
|
|
235
|
+
// 确定 index,限制在0-49范围
|
|
236
|
+
let index = config.index !== undefined ? Math.max(0, Math.min(49, Math.floor(config.index))) : 0;
|
|
237
|
+
// pageSize 取 index + 1,确保能获取到指定位置的图标
|
|
238
|
+
const pageSize = index + 1;
|
|
239
|
+
|
|
240
|
+
const postData = querystring.stringify({
|
|
241
|
+
q: config.keyword,
|
|
242
|
+
sortType: 'updated_at',
|
|
243
|
+
page: 1,
|
|
244
|
+
pageSize: pageSize,
|
|
245
|
+
fromCollection: -1,
|
|
246
|
+
complex: 1,
|
|
247
|
+
t: Date.now(),
|
|
248
|
+
ctoken: 'null'
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
const options = {
|
|
252
|
+
hostname: 'www.iconfont.cn',
|
|
253
|
+
port: 443,
|
|
254
|
+
path: '/api/icon/search.json',
|
|
255
|
+
method: 'POST',
|
|
256
|
+
headers: {
|
|
257
|
+
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
|
|
258
|
+
'Accept': 'application/json, text/javascript, */*; q=0.01',
|
|
259
|
+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
|
260
|
+
'Referer': 'https://www.iconfont.cn/search/index',
|
|
261
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
262
|
+
'Content-Length': Buffer.byteLength(postData)
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
const req = https.request(options, (res) => {
|
|
268
|
+
let data = '';
|
|
269
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
270
|
+
res.on('end', () => {
|
|
271
|
+
try {
|
|
272
|
+
const result = JSON.parse(data);
|
|
273
|
+
if (result.code === 200 && result.data && result.data.icons && result.data.icons.length > 0) {
|
|
274
|
+
const icons = result.data.icons;
|
|
275
|
+
let icon = null;
|
|
276
|
+
|
|
277
|
+
// 优先按 id 查找
|
|
278
|
+
if (config.id !== undefined) {
|
|
279
|
+
icon = icons.find(i => i.id === config.id);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// 没找到则按 index 选择,越界默认第一个
|
|
283
|
+
if (!icon) {
|
|
284
|
+
const safeIndex = index < icons.length ? index : 0;
|
|
285
|
+
icon = icons[safeIndex];
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
let svgContent = icon.show_svg;
|
|
289
|
+
|
|
290
|
+
if (!svgContent) {
|
|
291
|
+
resolve({ success: false, data: null, message: '图标没有SVG内容' });
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// 应用大小
|
|
296
|
+
const size = config.size || 48;
|
|
297
|
+
|
|
298
|
+
// 只有传入 color 时才替换颜色,否则保持原始样式
|
|
299
|
+
if (config.color) {
|
|
300
|
+
svgContent = svgContent.replace(/fill="[^"]*"/g, `fill="${config.color}"`);
|
|
301
|
+
svgContent = svgContent.replace(/style="[^"]*"/, `style="width: ${size}px; height: ${size}px; vertical-align: middle; fill: ${config.color}; overflow: hidden;"`);
|
|
302
|
+
} else {
|
|
303
|
+
// 不修改颜色,只设置宽高
|
|
304
|
+
svgContent = svgContent.replace(/style="[^"]*"/, `style="width: ${size}px; height: ${size}px; vertical-align: middle; overflow: hidden;"`);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 转换为data URI
|
|
308
|
+
const base64 = Buffer.from(svgContent).toString('base64');
|
|
309
|
+
const dataUri = `data:image/svg+xml;base64,${base64}`;
|
|
310
|
+
|
|
311
|
+
resolve({
|
|
312
|
+
success: true,
|
|
313
|
+
data: dataUri,
|
|
314
|
+
name: icon.name,
|
|
315
|
+
id: icon.id
|
|
316
|
+
});
|
|
317
|
+
} else {
|
|
318
|
+
resolve({ success: false, data: null, message: '未找到匹配的图标' });
|
|
319
|
+
}
|
|
320
|
+
} catch (e) {
|
|
321
|
+
reject(new Error(`解析响应失败: ${e.message}`));
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
req.on('error', (e) => {
|
|
327
|
+
reject(new Error(`请求失败: ${e.message}`));
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
req.setTimeout(10000, () => {
|
|
331
|
+
req.destroy();
|
|
332
|
+
reject(new Error('请求超时'));
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
req.write(postData);
|
|
336
|
+
req.end();
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
190
341
|
class McpServer {
|
|
191
342
|
constructor() {
|
|
192
343
|
this.createMap = new CreateMap();
|
|
193
344
|
this.createPopup = new CreatePopup();
|
|
345
|
+
this.createIcon = new CreateIcon();
|
|
194
346
|
this.serverInfo = {
|
|
195
347
|
name: 'mapbox-create-map-mcp',
|
|
196
348
|
version: '1.0.0',
|
|
@@ -440,6 +592,29 @@ class McpServer {
|
|
|
440
592
|
},
|
|
441
593
|
required: ['name', 'htmlContent']
|
|
442
594
|
}
|
|
595
|
+
},
|
|
596
|
+
// CreateIcon 工具
|
|
597
|
+
{
|
|
598
|
+
name: 'CreateIcon',
|
|
599
|
+
description: '从iconfont搜索图标并返回data:image/svg+xml格式的图标数据,可直接用于img标签的src属性或Mapbox图层的图标配置。',
|
|
600
|
+
inputSchema: {
|
|
601
|
+
type: 'object',
|
|
602
|
+
properties: {
|
|
603
|
+
keyword: {
|
|
604
|
+
type: 'string',
|
|
605
|
+
description: '搜索关键词,例如: "车辆", "地图", "定位", "建筑" 等'
|
|
606
|
+
},
|
|
607
|
+
color: {
|
|
608
|
+
type: 'string',
|
|
609
|
+
description: '图标颜色,十六进制格式,例如: "#FF0000", "#333333"'
|
|
610
|
+
},
|
|
611
|
+
size: {
|
|
612
|
+
type: 'number',
|
|
613
|
+
description: '图标大小,单位为像素,默认24'
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
required: ['keyword']
|
|
617
|
+
}
|
|
443
618
|
}
|
|
444
619
|
]
|
|
445
620
|
};
|
|
@@ -486,6 +661,9 @@ class McpServer {
|
|
|
486
661
|
case 'CreatePopup':
|
|
487
662
|
result = await this.createPopup.create(args);
|
|
488
663
|
break;
|
|
664
|
+
case 'CreateIcon':
|
|
665
|
+
result = await this.createIcon.search(args);
|
|
666
|
+
break;
|
|
489
667
|
default:
|
|
490
668
|
throw new Error(`Unknown tool: ${name}`);
|
|
491
669
|
}
|