UNPKG

geoapify-mcp-server

Version:

Geoapify API MCP Server for location-based services - 一键部署的地理位置服务

338 lines (282 loc) 8.88 kB
#!/usr/bin/env node /** * 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 };