geoapify-mcp-server
Version:
Geoapify API MCP Server for location-based services - 一键部署的地理位置服务
338 lines (282 loc) • 8.88 kB
JavaScript
/**
* NPX 使用示例
* 演示如何通过编程方式调用 geoapify-mcp-server
*/
const { spawn } = require('child_process');
const http = require('http');
// 颜色输出
const colors = {
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
cyan: '\x1b[36m',
reset: '\x1b[0m'
};
function log(color, message) {
console.log(`${colors[color]}${message}${colors.reset}`);
}
// 运行NPX命令
function runNpxCommand(command, args = []) {
return new Promise((resolve, reject) => {
log('blue', `执行: npx geoapify-mcp-server ${command} ${args.join(' ')}`);
const child = spawn('npx', ['geoapify-mcp-server', command, ...args], {
stdio: 'inherit'
});
child.on('close', (code) => {
if (code === 0) {
resolve();
} else {
reject(new Error(`Command failed with code ${code}`));
}
});
child.on('error', reject);
});
}
// HTTP请求
function makeRequest(url, options = {}) {
return new Promise((resolve, reject) => {
const urlObj = new URL(url);
const requestOptions = {
hostname: urlObj.hostname,
port: urlObj.port || 80,
path: urlObj.pathname,
method: options.method || 'GET',
headers: {
'Content-Type': 'application/json',
...options.headers
}
};
const req = http.request(requestOptions, (res) => {
let data = '';
res.on('data', chunk => data += chunk);
res.on('end', () => {
try {
const result = JSON.parse(data);
resolve({ statusCode: res.statusCode, data: result });
} catch (e) {
resolve({ statusCode: res.statusCode, data });
}
});
});
req.on('error', reject);
if (options.body) {
req.write(JSON.stringify(options.body));
}
req.end();
});
}
// 等待服务启动
async function waitForService(url, maxAttempts = 30) {
for (let i = 0; i < maxAttempts; i++) {
try {
const result = await makeRequest(url);
if (result.statusCode === 200) {
return true;
}
} catch (error) {
// 忽略连接错误,继续等待
}
await new Promise(resolve => setTimeout(resolve, 2000));
}
return false;
}
// 示例1: 快速部署和测试
async function example1() {
log('cyan', '=== 示例1: 快速部署和测试 ===');
try {
// 部署服务
log('yellow', '1. 部署服务...');
await runNpxCommand('deploy', ['--local']);
// 启动服务(后台)
log('yellow', '2. 启动服务...');
const serverProcess = spawn('npx', ['geoapify-mcp-server', 'start'], {
detached: true,
stdio: 'ignore'
});
serverProcess.unref();
// 等待服务启动
log('yellow', '3. 等待服务启动...');
const isReady = await waitForService('http://localhost:50001/health');
if (isReady) {
log('green', '✓ 服务启动成功');
// 运行测试
log('yellow', '4. 运行测试...');
await runNpxCommand('test');
log('green', '✓ 示例1完成');
} else {
log('red', '✗ 服务启动失败');
}
} catch (error) {
log('red', `示例1失败: ${error.message}`);
}
}
// 示例2: 自定义配置
async function example2() {
log('cyan', '=== 示例2: 自定义配置 ===');
try {
// 使用自定义端口启动
log('yellow', '1. 使用自定义端口8080启动...');
const serverProcess = spawn('npx', [
'geoapify-mcp-server',
'start',
'--port', '8080',
'--verbose'
], {
detached: true,
stdio: 'ignore'
});
serverProcess.unref();
// 等待服务启动
log('yellow', '2. 等待服务启动...');
const isReady = await waitForService('http://localhost:8080/health');
if (isReady) {
log('green', '✓ 服务在端口8080启动成功');
// 测试自定义端口
log('yellow', '3. 测试自定义端口...');
await runNpxCommand('test', ['--url', 'http://localhost:8080']);
log('green', '✓ 示例2完成');
} else {
log('red', '✗ 服务启动失败');
}
} catch (error) {
log('red', `示例2失败: ${error.message}`);
}
}
// 示例3: API调用演示
async function example3() {
log('cyan', '=== 示例3: API调用演示 ===');
try {
// 确保服务运行
const isReady = await waitForService('http://localhost:50001/health', 5);
if (!isReady) {
log('yellow', '服务未运行,启动服务...');
const serverProcess = spawn('npx', ['geoapify-mcp-server', 'start'], {
detached: true,
stdio: 'ignore'
});
serverProcess.unref();
await waitForService('http://localhost:50001/health');
}
log('yellow', '1. 测试健康检查...');
const healthResult = await makeRequest('http://localhost:50001/health');
log('green', `健康检查: ${JSON.stringify(healthResult.data)}`);
log('yellow', '2. 测试地理编码...');
const geocodeResult = await makeRequest('http://localhost:50001/tools/geocode_address', {
method: 'POST',
body: {
arguments: {
address: "上海市外滩",
language: "zh"
}
}
});
if (geocodeResult.data.success) {
const location = geocodeResult.data.data.results[0];
log('green', `地理编码成功: ${location.formatted}`);
log('green', `坐标: ${location.lat}, ${location.lon}`);
}
log('yellow', '3. 测试地点搜索...');
const placesResult = await makeRequest('http://localhost:50001/tools/search_places', {
method: 'POST',
body: {
arguments: {
categories: "catering.restaurant",
filter: "circle:121.4944,31.2397,1000",
limit: 3
}
}
});
if (placesResult.data.success) {
const places = placesResult.data.data.features;
log('green', `找到 ${places.length} 个餐厅`);
places.forEach((place, index) => {
log('green', ` ${index + 1}. ${place.properties.name || '未知名称'}`);
});
}
log('green', '✓ 示例3完成');
} catch (error) {
log('red', `示例3失败: ${error.message}`);
}
}
// 示例4: 批量操作
async function example4() {
log('cyan', '=== 示例4: 批量操作 ===');
try {
const addresses = [
"北京市天安门广场",
"上海市外滩",
"广州市珠江新城",
"深圳市南山区"
];
// 确保服务运行
const isReady = await waitForService('http://localhost:50001/health', 5);
if (!isReady) {
log('red', '服务未运行,请先启动服务');
return;
}
log('yellow', '批量地理编码...');
for (const address of addresses) {
try {
const result = await makeRequest('http://localhost:50001/tools/geocode_address', {
method: 'POST',
body: {
arguments: {
address,
language: "zh"
}
}
});
if (result.data.success) {
const location = result.data.data.results[0];
log('green', `${address} -> ${location.lat}, ${location.lon}`);
} else {
log('red', `${address} -> 编码失败`);
}
} catch (error) {
log('red', `${address} -> 错误: ${error.message}`);
}
}
log('green', '✓ 示例4完成');
} catch (error) {
log('red', `示例4失败: ${error.message}`);
}
}
// 主函数
async function main() {
log('cyan', '🌍 Geoapify MCP Server NPX 使用示例');
console.log('');
const examples = [
{ name: '快速部署和测试', fn: example1 },
{ name: '自定义配置', fn: example2 },
{ name: 'API调用演示', fn: example3 },
{ name: '批量操作', fn: example4 }
];
// 获取命令行参数
const args = process.argv.slice(2);
const exampleIndex = parseInt(args[0]) || 0;
if (exampleIndex > 0 && exampleIndex <= examples.length) {
// 运行指定示例
const example = examples[exampleIndex - 1];
log('yellow', `运行示例${exampleIndex}: ${example.name}`);
await example.fn();
} else {
// 显示所有示例
log('yellow', '可用示例:');
examples.forEach((example, index) => {
console.log(` ${index + 1}. ${example.name}`);
});
console.log('');
log('cyan', '使用方法:');
log('cyan', ' node examples/npx-usage.js [示例编号]');
log('cyan', ' 例如: node examples/npx-usage.js 1');
}
}
if (require.main === module) {
main().catch(error => {
log('red', `运行失败: ${error.message}`);
process.exit(1);
});
}
module.exports = { example1, example2, example3, example4 };