mapbox-create-map-mcp 1.2.0 → 1.3.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/package.json +1 -1
- package/src/popui.js +209 -0
- package/src/server.js +250 -5
package/package.json
CHANGED
package/src/popui.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CreatePopup - 弹框样式配置生成工具
|
|
3
|
+
* 用于生成Mapbox弹框(Popup)的样式配置
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class CreatePopup {
|
|
7
|
+
constructor() {
|
|
8
|
+
/**
|
|
9
|
+
* 参数元数据定义
|
|
10
|
+
*/
|
|
11
|
+
this.metadata = {
|
|
12
|
+
name: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
required: true,
|
|
15
|
+
default: '默认样式',
|
|
16
|
+
description: '弹框样式名称'
|
|
17
|
+
},
|
|
18
|
+
closeButton: {
|
|
19
|
+
type: 'boolean',
|
|
20
|
+
required: false,
|
|
21
|
+
default: true,
|
|
22
|
+
description: '是否显示右上角的关闭按钮'
|
|
23
|
+
},
|
|
24
|
+
closeOnClick: {
|
|
25
|
+
type: 'boolean',
|
|
26
|
+
required: false,
|
|
27
|
+
default: true,
|
|
28
|
+
description: '点击地图任意地方时是否自动关闭Popup'
|
|
29
|
+
},
|
|
30
|
+
closeOnMove: {
|
|
31
|
+
type: 'boolean',
|
|
32
|
+
required: false,
|
|
33
|
+
default: false,
|
|
34
|
+
description: '地图移动(拖动或缩放)时是否自动关闭Popup'
|
|
35
|
+
},
|
|
36
|
+
anchor: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
required: false,
|
|
39
|
+
default: 'top',
|
|
40
|
+
enum: ['auto', 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'],
|
|
41
|
+
description: 'Popup箭头朝向锚点位置'
|
|
42
|
+
},
|
|
43
|
+
offset: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
required: false,
|
|
46
|
+
default: [0, 0],
|
|
47
|
+
description: '偏移量,用于微调Popup位置,格式为[x, y],单位为像素'
|
|
48
|
+
},
|
|
49
|
+
maxWidth: {
|
|
50
|
+
type: 'number',
|
|
51
|
+
required: false,
|
|
52
|
+
default: 240,
|
|
53
|
+
min: 100,
|
|
54
|
+
max: 800,
|
|
55
|
+
description: '弹框最大宽度,单位为像素(px)'
|
|
56
|
+
},
|
|
57
|
+
className: {
|
|
58
|
+
type: 'string',
|
|
59
|
+
required: false,
|
|
60
|
+
default: '',
|
|
61
|
+
description: '给Popup添加自定义CSS class名'
|
|
62
|
+
},
|
|
63
|
+
altitude: {
|
|
64
|
+
type: 'number',
|
|
65
|
+
required: false,
|
|
66
|
+
default: 0,
|
|
67
|
+
min: 0,
|
|
68
|
+
max: 10000,
|
|
69
|
+
description: '弹窗在地图表面上方的海拔高度(米)'
|
|
70
|
+
},
|
|
71
|
+
htmlContent: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
required: true,
|
|
74
|
+
default: '<div style="padding: 10px;"><h3>标题</h3><p>内容</p></div>',
|
|
75
|
+
description: '弹框的HTML内容,支持完整的HTML标签和内联样式'
|
|
76
|
+
},
|
|
77
|
+
theme: {
|
|
78
|
+
type: 'string',
|
|
79
|
+
required: false,
|
|
80
|
+
default: 'light',
|
|
81
|
+
enum: ['light', 'dark', 'minimal', 'custom'],
|
|
82
|
+
description: '预设主题样式:light(浅色)、dark(深色)、minimal(简约)、custom(自定义)'
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* 预设主题样式模板
|
|
88
|
+
*/
|
|
89
|
+
this.themeTemplates = {
|
|
90
|
+
light: {
|
|
91
|
+
className: 'light-popup',
|
|
92
|
+
htmlWrapper: '<div style="padding: 10px; background: #fff; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">{{content}}</div>'
|
|
93
|
+
},
|
|
94
|
+
dark: {
|
|
95
|
+
className: 'dark-popup',
|
|
96
|
+
htmlWrapper: '<div style="padding: 15px; background: #2d2d2d; color: #fff; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.3);">{{content}}</div>'
|
|
97
|
+
},
|
|
98
|
+
minimal: {
|
|
99
|
+
className: 'minimal-popup',
|
|
100
|
+
htmlWrapper: '<div style="padding: 8px 12px; background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 2px; font-size: 12px;">{{content}}</div>'
|
|
101
|
+
},
|
|
102
|
+
custom: {
|
|
103
|
+
className: '',
|
|
104
|
+
htmlWrapper: '{{content}}'
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 验证参数
|
|
111
|
+
*/
|
|
112
|
+
validate(config) {
|
|
113
|
+
const errors = [];
|
|
114
|
+
|
|
115
|
+
// 验证必填参数
|
|
116
|
+
if (!config.name || typeof config.name !== 'string') {
|
|
117
|
+
errors.push('name 是必填字段,且必须是字符串');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!config.htmlContent || typeof config.htmlContent !== 'string') {
|
|
121
|
+
errors.push('htmlContent 是必填字段,且必须是字符串');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 验证anchor枚举值
|
|
125
|
+
if (config.anchor) {
|
|
126
|
+
const validAnchors = ['auto', 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
127
|
+
if (!validAnchors.includes(config.anchor)) {
|
|
128
|
+
errors.push(`anchor 必须是以下值之一: ${validAnchors.join(', ')}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 验证theme枚举值
|
|
133
|
+
if (config.theme) {
|
|
134
|
+
const validThemes = ['light', 'dark', 'minimal', 'custom'];
|
|
135
|
+
if (!validThemes.includes(config.theme)) {
|
|
136
|
+
errors.push(`theme 必须是以下值之一: ${validThemes.join(', ')}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 验证offset格式
|
|
141
|
+
if (config.offset) {
|
|
142
|
+
if (!Array.isArray(config.offset) || config.offset.length !== 2) {
|
|
143
|
+
errors.push('offset 必须是包含两个数字的数组 [x, y]');
|
|
144
|
+
} else if (typeof config.offset[0] !== 'number' || typeof config.offset[1] !== 'number') {
|
|
145
|
+
errors.push('offset 数组中的值必须是数字');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// 验证maxWidth范围
|
|
150
|
+
if (config.maxWidth !== undefined) {
|
|
151
|
+
if (typeof config.maxWidth !== 'number' || config.maxWidth < 100 || config.maxWidth > 800) {
|
|
152
|
+
errors.push('maxWidth 必须是100到800之间的数字');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// 验证altitude范围
|
|
157
|
+
if (config.altitude !== undefined) {
|
|
158
|
+
if (typeof config.altitude !== 'number' || config.altitude < 0 || config.altitude > 10000) {
|
|
159
|
+
errors.push('altitude 必须是0到10000之间的数字');
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return errors;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* 创建弹框配置
|
|
168
|
+
* @param {Object} config - 弹框配置参数
|
|
169
|
+
* @returns {Promise<Object>} 弹框配置对象
|
|
170
|
+
*/
|
|
171
|
+
async create(config) {
|
|
172
|
+
// 验证参数
|
|
173
|
+
const errors = this.validate(config);
|
|
174
|
+
if (errors.length > 0) {
|
|
175
|
+
throw new Error(`参数验证失败: ${errors.join('; ')}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 获取主题模板
|
|
179
|
+
const theme = config.theme || 'light';
|
|
180
|
+
const themeTemplate = this.themeTemplates[theme] || this.themeTemplates.light;
|
|
181
|
+
|
|
182
|
+
// 应用主题包装(如果htmlContent不是完整的HTML结构)
|
|
183
|
+
let finalHtmlContent = config.htmlContent;
|
|
184
|
+
if (theme !== 'custom' && !config.htmlContent.includes('style=')) {
|
|
185
|
+
finalHtmlContent = themeTemplate.htmlWrapper.replace('{{content}}', config.htmlContent);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// 构建弹框配置对象
|
|
189
|
+
const popupConfig = {
|
|
190
|
+
name: config.name || this.metadata.name.default,
|
|
191
|
+
closeButton: config.closeButton !== undefined ? config.closeButton : this.metadata.closeButton.default,
|
|
192
|
+
closeOnClick: config.closeOnClick !== undefined ? config.closeOnClick : this.metadata.closeOnClick.default,
|
|
193
|
+
closeOnMove: config.closeOnMove !== undefined ? config.closeOnMove : this.metadata.closeOnMove.default,
|
|
194
|
+
anchor: config.anchor || this.metadata.anchor.default,
|
|
195
|
+
offset: config.offset || this.metadata.offset.default,
|
|
196
|
+
maxWidth: config.maxWidth || this.metadata.maxWidth.default,
|
|
197
|
+
className: config.className || themeTemplate.className || this.metadata.className.default,
|
|
198
|
+
altitude: config.altitude !== undefined ? config.altitude : this.metadata.altitude.default,
|
|
199
|
+
htmlContent: finalHtmlContent
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
return {
|
|
203
|
+
success: true,
|
|
204
|
+
config: popupConfig
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export default CreatePopup;
|
package/src/server.js
CHANGED
|
@@ -19,9 +19,178 @@ try {
|
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/**
|
|
23
|
+
* CreatePopup - 弹框样式配置生成工具
|
|
24
|
+
*/
|
|
25
|
+
class CreatePopup {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.metadata = {
|
|
28
|
+
name: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
required: true,
|
|
31
|
+
default: '默认样式',
|
|
32
|
+
description: '弹框样式名称'
|
|
33
|
+
},
|
|
34
|
+
closeButton: {
|
|
35
|
+
type: 'boolean',
|
|
36
|
+
required: false,
|
|
37
|
+
default: true,
|
|
38
|
+
description: '是否显示右上角的关闭按钮'
|
|
39
|
+
},
|
|
40
|
+
closeOnClick: {
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
required: false,
|
|
43
|
+
default: true,
|
|
44
|
+
description: '点击地图任意地方时是否自动关闭Popup'
|
|
45
|
+
},
|
|
46
|
+
closeOnMove: {
|
|
47
|
+
type: 'boolean',
|
|
48
|
+
required: false,
|
|
49
|
+
default: false,
|
|
50
|
+
description: '地图移动(拖动或缩放)时是否自动关闭Popup'
|
|
51
|
+
},
|
|
52
|
+
anchor: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
required: false,
|
|
55
|
+
default: 'top',
|
|
56
|
+
enum: ['auto', 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'],
|
|
57
|
+
description: 'Popup箭头朝向锚点位置'
|
|
58
|
+
},
|
|
59
|
+
offset: {
|
|
60
|
+
type: 'array',
|
|
61
|
+
required: false,
|
|
62
|
+
default: [0, 0],
|
|
63
|
+
description: '偏移量,用于微调Popup位置,格式为[x, y],单位为像素'
|
|
64
|
+
},
|
|
65
|
+
maxWidth: {
|
|
66
|
+
type: 'number',
|
|
67
|
+
required: false,
|
|
68
|
+
default: 240,
|
|
69
|
+
min: 100,
|
|
70
|
+
max: 800,
|
|
71
|
+
description: '弹框最大宽度,单位为像素(px)'
|
|
72
|
+
},
|
|
73
|
+
className: {
|
|
74
|
+
type: 'string',
|
|
75
|
+
required: false,
|
|
76
|
+
default: '',
|
|
77
|
+
description: '给Popup添加自定义CSS class名'
|
|
78
|
+
},
|
|
79
|
+
altitude: {
|
|
80
|
+
type: 'number',
|
|
81
|
+
required: false,
|
|
82
|
+
default: 0,
|
|
83
|
+
min: 0,
|
|
84
|
+
max: 10000,
|
|
85
|
+
description: '弹窗在地图表面上方的海拔高度(米)'
|
|
86
|
+
},
|
|
87
|
+
htmlContent: {
|
|
88
|
+
type: 'string',
|
|
89
|
+
required: true,
|
|
90
|
+
default: '<div style="padding: 10px;"><h3>标题</h3><p>内容</p></div>',
|
|
91
|
+
description: '弹框的HTML内容,支持完整的HTML标签和内联样式'
|
|
92
|
+
},
|
|
93
|
+
theme: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
required: false,
|
|
96
|
+
default: 'light',
|
|
97
|
+
enum: ['light', 'dark', 'minimal', 'custom'],
|
|
98
|
+
description: '预设主题样式:light(浅色)、dark(深色)、minimal(简约)、custom(自定义)'
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
this.themeTemplates = {
|
|
103
|
+
light: {
|
|
104
|
+
className: 'light-popup',
|
|
105
|
+
htmlWrapper: '<div style="padding: 10px; background: #fff; border-radius: 4px; box-shadow: 0 2px 8px rgba(0,0,0,0.1);">{{content}}</div>'
|
|
106
|
+
},
|
|
107
|
+
dark: {
|
|
108
|
+
className: 'dark-popup',
|
|
109
|
+
htmlWrapper: '<div style="padding: 15px; background: #2d2d2d; color: #fff; border-radius: 8px; box-shadow: 0 4px 16px rgba(0,0,0,0.3);">{{content}}</div>'
|
|
110
|
+
},
|
|
111
|
+
minimal: {
|
|
112
|
+
className: 'minimal-popup',
|
|
113
|
+
htmlWrapper: '<div style="padding: 8px 12px; background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 2px; font-size: 12px;">{{content}}</div>'
|
|
114
|
+
},
|
|
115
|
+
custom: {
|
|
116
|
+
className: '',
|
|
117
|
+
htmlWrapper: '{{content}}'
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
validate(config) {
|
|
123
|
+
const errors = [];
|
|
124
|
+
if (!config.name || typeof config.name !== 'string') {
|
|
125
|
+
errors.push('name 是必填字段,且必须是字符串');
|
|
126
|
+
}
|
|
127
|
+
if (!config.htmlContent || typeof config.htmlContent !== 'string') {
|
|
128
|
+
errors.push('htmlContent 是必填字段,且必须是字符串');
|
|
129
|
+
}
|
|
130
|
+
if (config.anchor) {
|
|
131
|
+
const validAnchors = ['auto', 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
132
|
+
if (!validAnchors.includes(config.anchor)) {
|
|
133
|
+
errors.push(`anchor 必须是以下值之一: ${validAnchors.join(', ')}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (config.theme) {
|
|
137
|
+
const validThemes = ['light', 'dark', 'minimal', 'custom'];
|
|
138
|
+
if (!validThemes.includes(config.theme)) {
|
|
139
|
+
errors.push(`theme 必须是以下值之一: ${validThemes.join(', ')}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (config.offset) {
|
|
143
|
+
if (!Array.isArray(config.offset) || config.offset.length !== 2) {
|
|
144
|
+
errors.push('offset 必须是包含两个数字的数组 [x, y]');
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (config.maxWidth !== undefined) {
|
|
148
|
+
if (typeof config.maxWidth !== 'number' || config.maxWidth < 100 || config.maxWidth > 800) {
|
|
149
|
+
errors.push('maxWidth 必须是100到800之间的数字');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (config.altitude !== undefined) {
|
|
153
|
+
if (typeof config.altitude !== 'number' || config.altitude < 0 || config.altitude > 10000) {
|
|
154
|
+
errors.push('altitude 必须是0到10000之间的数字');
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return errors;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async create(config) {
|
|
161
|
+
const errors = this.validate(config);
|
|
162
|
+
if (errors.length > 0) {
|
|
163
|
+
throw new Error(`参数验证失败: ${errors.join('; ')}`);
|
|
164
|
+
}
|
|
165
|
+
const theme = config.theme || 'light';
|
|
166
|
+
const themeTemplate = this.themeTemplates[theme] || this.themeTemplates.light;
|
|
167
|
+
let finalHtmlContent = config.htmlContent;
|
|
168
|
+
if (theme !== 'custom' && !config.htmlContent.includes('style=')) {
|
|
169
|
+
finalHtmlContent = themeTemplate.htmlWrapper.replace('{{content}}', config.htmlContent);
|
|
170
|
+
}
|
|
171
|
+
const popupConfig = {
|
|
172
|
+
name: config.name || this.metadata.name.default,
|
|
173
|
+
closeButton: config.closeButton !== undefined ? config.closeButton : this.metadata.closeButton.default,
|
|
174
|
+
closeOnClick: config.closeOnClick !== undefined ? config.closeOnClick : this.metadata.closeOnClick.default,
|
|
175
|
+
closeOnMove: config.closeOnMove !== undefined ? config.closeOnMove : this.metadata.closeOnMove.default,
|
|
176
|
+
anchor: config.anchor || this.metadata.anchor.default,
|
|
177
|
+
offset: config.offset || this.metadata.offset.default,
|
|
178
|
+
maxWidth: config.maxWidth || this.metadata.maxWidth.default,
|
|
179
|
+
className: config.className || themeTemplate.className || this.metadata.className.default,
|
|
180
|
+
altitude: config.altitude !== undefined ? config.altitude : this.metadata.altitude.default,
|
|
181
|
+
htmlContent: finalHtmlContent
|
|
182
|
+
};
|
|
183
|
+
return {
|
|
184
|
+
success: true,
|
|
185
|
+
config: popupConfig
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
22
190
|
class McpServer {
|
|
23
191
|
constructor() {
|
|
24
192
|
this.createMap = new CreateMap();
|
|
193
|
+
this.createPopup = new CreatePopup();
|
|
25
194
|
this.serverInfo = {
|
|
26
195
|
name: 'mapbox-create-map-mcp',
|
|
27
196
|
version: '1.0.0',
|
|
@@ -62,6 +231,12 @@ class McpServer {
|
|
|
62
231
|
async handleRequest(request) {
|
|
63
232
|
const { id, method, params } = request;
|
|
64
233
|
|
|
234
|
+
// 通知类型的消息不需要返回响应
|
|
235
|
+
if (method && method.startsWith('notifications/')) {
|
|
236
|
+
// 处理通知,不返回任何内容
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
|
|
65
240
|
try {
|
|
66
241
|
let result;
|
|
67
242
|
|
|
@@ -82,6 +257,10 @@ class McpServer {
|
|
|
82
257
|
result = this.handleResourcesList();
|
|
83
258
|
break;
|
|
84
259
|
|
|
260
|
+
case 'ping':
|
|
261
|
+
result = {};
|
|
262
|
+
break;
|
|
263
|
+
|
|
85
264
|
default:
|
|
86
265
|
this.sendError(-32601, `Method not found: ${method}`, id);
|
|
87
266
|
return;
|
|
@@ -203,6 +382,64 @@ class McpServer {
|
|
|
203
382
|
},
|
|
204
383
|
required: ['title', 'description', 'layers']
|
|
205
384
|
}
|
|
385
|
+
},
|
|
386
|
+
// CreatePopup 工具
|
|
387
|
+
{
|
|
388
|
+
name: 'CreatePopup',
|
|
389
|
+
description: '根据配置生成Mapbox弹框(Popup)样式配置。支持多种预设主题(浅色、深色、简约),返回完整的弹框配置对象。',
|
|
390
|
+
inputSchema: {
|
|
391
|
+
type: 'object',
|
|
392
|
+
properties: {
|
|
393
|
+
name: {
|
|
394
|
+
type: 'string',
|
|
395
|
+
description: '弹框样式名称'
|
|
396
|
+
},
|
|
397
|
+
closeButton: {
|
|
398
|
+
type: 'boolean',
|
|
399
|
+
description: '是否显示右上角的关闭按钮'
|
|
400
|
+
},
|
|
401
|
+
closeOnClick: {
|
|
402
|
+
type: 'boolean',
|
|
403
|
+
description: '点击地图任意地方时是否自动关闭Popup'
|
|
404
|
+
},
|
|
405
|
+
closeOnMove: {
|
|
406
|
+
type: 'boolean',
|
|
407
|
+
description: '地图移动(拖动或缩放)时是否自动关闭Popup'
|
|
408
|
+
},
|
|
409
|
+
anchor: {
|
|
410
|
+
type: 'string',
|
|
411
|
+
enum: ['auto', 'center', 'top', 'bottom', 'left', 'right', 'top-left', 'top-right', 'bottom-left', 'bottom-right'],
|
|
412
|
+
description: 'Popup箭头朝向锚点位置'
|
|
413
|
+
},
|
|
414
|
+
offset: {
|
|
415
|
+
type: 'array',
|
|
416
|
+
items: { type: 'number' },
|
|
417
|
+
description: '偏移量,用于微调Popup位置,格式为[x, y],单位为像素'
|
|
418
|
+
},
|
|
419
|
+
maxWidth: {
|
|
420
|
+
type: 'number',
|
|
421
|
+
description: '弹框最大宽度,单位为像素(px),范围100-800'
|
|
422
|
+
},
|
|
423
|
+
className: {
|
|
424
|
+
type: 'string',
|
|
425
|
+
description: '给Popup添加自定义CSS class名'
|
|
426
|
+
},
|
|
427
|
+
altitude: {
|
|
428
|
+
type: 'number',
|
|
429
|
+
description: '弹窗在地图表面上方的海拔高度(米),范围0-10000'
|
|
430
|
+
},
|
|
431
|
+
htmlContent: {
|
|
432
|
+
type: 'string',
|
|
433
|
+
description: '弹框的HTML内容,支持完整的HTML标签和内联样式'
|
|
434
|
+
},
|
|
435
|
+
theme: {
|
|
436
|
+
type: 'string',
|
|
437
|
+
enum: ['light', 'dark', 'minimal', 'custom'],
|
|
438
|
+
description: '预设主题样式: light(浅色), dark(深色), minimal(简约), custom(自定义)'
|
|
439
|
+
}
|
|
440
|
+
},
|
|
441
|
+
required: ['name', 'htmlContent']
|
|
442
|
+
}
|
|
206
443
|
}
|
|
207
444
|
]
|
|
208
445
|
};
|
|
@@ -239,12 +476,20 @@ class McpServer {
|
|
|
239
476
|
async handleToolsCall(params) {
|
|
240
477
|
const { name, arguments: args } = params;
|
|
241
478
|
|
|
242
|
-
if (name !== 'CreateMap') {
|
|
243
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
479
|
try {
|
|
247
|
-
|
|
480
|
+
let result;
|
|
481
|
+
|
|
482
|
+
switch (name) {
|
|
483
|
+
case 'CreateMap':
|
|
484
|
+
result = await this.createMap.create(args);
|
|
485
|
+
break;
|
|
486
|
+
case 'CreatePopup':
|
|
487
|
+
result = await this.createPopup.create(args);
|
|
488
|
+
break;
|
|
489
|
+
default:
|
|
490
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
491
|
+
}
|
|
492
|
+
|
|
248
493
|
return {
|
|
249
494
|
content: [
|
|
250
495
|
{
|