基于阿里云Dify的高德地图MCP服务器完整配置教程
准备工作
第一步:获取高德地图API Key
- 应用名称:Dify地图服务
- 应用类型:Web服务

{
"mcpServers": {
"amap-amap-sse": {
"url": "https://mcp.amap.com/sse?key=您在高德开放平台上申请的key"
}
}
}
第二步:准备阿里云轻量应用服务器
部署Dify平台
步骤一:部署Dify
1.1 连接服务器
# SSH连接到你的阿里云服务器
ssh root@你的服务器IP
1.2 安装Docker和Docker Compose
# 更新系统
apt update && apt upgrade -y
# 安装Docker
curl -fsSL https://get.docker.com | bash
# 安装Docker Compose
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)–$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
# 启动Docker服务
systemctl start docker
systemctl enable docker
1.3 部署Dify
# 克隆Dify项目
git clone https://github.com/langgenius/dify.git
cd dify/docker
# 复制环境变量文件
cp .env.example .env
# 编辑环境变量
vim .env
1.4 配置.env文件
# 基础配置
CONSOLE_WEB_URL=http://你的服务器IP
CONSOLE_API_URL=http://你的服务器IP/console/api
SERVICE_API_URL=http://你的服务器IP/v1
APP_WEB_URL=http://你的服务器IP/app
# 数据库配置
POSTGRES_HOST=db
POSTGRES_PORT=5432
POSTGRES_DB=dify
POSTGRES_USER=postgres
POSTGRES_PASSWORD=difyai123456
# Redis配置
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=
# 重要:允许安装未验证插件
FORCE_VERIFYING_SIGNATURE=false
# 其他配置
SECRET_KEY=sk-9f73s3ljTXVcMT3Blb3ljTqtsKiGHXVcMT3BlbkFJLK7U
ENCRYPT_PUBLIC_KEY=你的加密公钥
1.5 启动Dify
# 启动所有服务
docker-compose up -d
# 查看服务状态
docker-compose ps
步骤二:登录Dify和接入大模型
2.1 访问Dify控制台
2.2 配置大模型
安装MCP插件
步骤三:安装必要的MCP插件
3.1 安装Agent策略插件(支持MCP工具)
# 进入Dify容器
docker exec -it docker-api-1 bash
# 下载插件安装脚本
curl -o install_plugin.py https://raw.githubusercontent.com/junjiem/dify-plugin-agent-mcp_sse/main/scripts/install_plugin.py
# 安装Agent策略插件
python install_plugin.py https://github.com/junjiem/dify-plugin-agent-mcp_sse/releases/download/v0.0.6/junjiem-agent_mcp_sse-0.0.6.difypkg
# 重启API容器
exit
docker-compose restart api
3.2 安装MCP SSE工具插件
# 再次进入容器
docker exec -it docker-api-1 bash
# 安装MCP SSE工具插件
python install_plugin.py https://github.com/junjiem/dify-plugin-tools-mcp_sse/releases/download/v0.0.6/junjiem-mcp_sse-0.0.6.difypkg
# 重启API容器
exit
docker-compose restart api
安装MCP SEE插件后,Dify可以通过HTTP with SSE或Streamable HTTP传输方式使用MCP协议发现和调用MCP服务端工具。 也可以在Dify的顶部菜单中,单击工具,然后在搜索框中输入mcp。 单击安装,根据界面提示安装MCP SSE / StreamableHTTP。
然后单次授权
在弹出设置授权对话框中,将步骤一获取的MCP Server配置地址粘贴后,单击保存。
MCP Server配置地址示例如下:
步骤四:验证插件安装
- Agent策略(支持 MCP 工具)
- MCP SSE
配置高德地图MCP服务器
步骤五:创建高德地图MCP服务器
5.1 创建MCP服务器项目
# 在服务器上创建项目目录
mkdir -p /opt/amap-mcp-server
cd /opt/amap-mcp-server
# 初始化Node.js项目
npm init -y
# 安装依赖
npm install @modelcontextprotocol/sdk axios dotenv
5.2 创建MCP服务器代码
创建 server.js 文件:
#!/usr/bin/env node
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import axios from 'axios';
import 'dotenv/config';
const AMAP_API_KEY = process.env.AMAP_API_KEY;
const AMAP_BASE_URL = 'https://restapi.amap.com/v3';
class AmapMCPServer {
constructor() {
this.server = new Server(
{
name: 'amap-mcp-server',
version: '0.1.0',
},
{
capabilities: {
tools: {},
},
}
);
this.setupToolHandlers();
// Error handling
this.server.onerror = (error) => console.error('[MCP Error]', error);
process.on('SIGINT', async () => {
await this.server.close();
process.exit(0);
});
}
setupToolHandlers() {
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'geocode',
description: '地理编码:将地址转换为经纬度坐标',
inputSchema: {
type: 'object',
properties: {
address: {
type: 'string',
description: '要查询的地址',
},
city: {
type: 'string',
description: '城市名称(可选)',
},
},
required: ['address'],
},
},
{
name: 'regeocode',
description: '逆地理编码:将经纬度坐标转换为地址信息',
inputSchema: {
type: 'object',
properties: {
location: {
type: 'string',
description: '经纬度坐标,格式:经度,纬度',
},
},
required: ['location'],
},
},
{
name: 'around_search',
description: '周边搜索:搜索指定位置周边的POI',
inputSchema: {
type: 'object',
properties: {
location: {
type: 'string',
description: '中心点坐标,格式:经度,纬度',
},
keywords: {
type: 'string',
description: '搜索关键词',
},
radius: {
type: 'integer',
description: '搜索半径(米),默认1000',
default: 1000,
},
},
required: ['location', 'keywords'],
},
},
],
}));
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
try {
switch (name) {
case 'geocode':
return await this.geocode(args.address, args.city);
case 'regeocode':
return await this.regeocode(args.location);
case 'around_search':
return await this.aroundSearch(args.location, args.keywords, args.radius);
default:
throw new Error(`未知工具: ${name}`);
}
} catch (error) {
return {
content: [
{
type: 'text',
text: `调用工具时出错: ${error.message}`,
},
],
};
}
});
}
async geocode(address, city) {
const params = {
key: AMAP_API_KEY,
address: address,
};
if (city) {
params.city = city;
}
const response = await axios.get(`${AMAP_BASE_URL}/geocode/geo`, { params });
if (response.data.status === '1' && response.data.geocodes.length > 0) {
const result = response.data.geocodes[0];
return {
content: [
{
type: 'text',
text: JSON.stringify({
address: result.formatted_address,
location: result.location,
level: result.level,
province: result.province,
city: result.city,
district: result.district,
}, null, 2),
},
],
};
} else {
return {
content: [
{
type: 'text',
text: '该地址无查询结果,请人工填写,或确认地址准确',
},
],
};
}
}
async regeocode(location) {
const params = {
key: AMAP_API_KEY,
location: location,
};
const response = await axios.get(`${AMAP_BASE_URL}/geocode/regeo`, { params });
if (response.data.status === '1') {
const result = response.data.regeocode;
return {
content: [
{
type: 'text',
text: JSON.stringify({
formatted_address: result.formatted_address,
addressComponent: result.addressComponent,
pois: result.pois.slice(0, 5), // 只返回前5个POI
}, null, 2),
},
],
};
} else {
return {
content: [
{
type: 'text',
text: '该坐标无查询结果,请人工填写,或确认坐标准确',
},
],
};
}
}
async aroundSearch(location, keywords, radius = 1000) {
const params = {
key: AMAP_API_KEY,
location: location,
keywords: keywords,
radius: radius,
};
const response = await axios.get(`${AMAP_BASE_URL}/place/around`, { params });
if (response.data.status === '1' && response.data.pois.length > 0) {
const pois = response.data.pois.slice(0, 10).map(poi => ({
name: poi.name,
type: poi.type,
address: poi.address,
location: poi.location,
distance: poi.distance,
}));
return {
content: [
{
type: 'text',
text: JSON.stringify(pois, null, 2),
},
],
};
} else {
return {
content: [
{
type: 'text',
text: '该位置周边无相关查询结果',
},
],
};
}
}
async run() {
const transport = new StdioServerTransport();
await this.server.connect(transport);
console.error('高德地图 MCP 服务器已启动');
}
}
const server = new AmapMCPServer();
server.run().catch(console.error);
5.3 配置环境变量
创建 .env 文件:
AMAP_API_KEY=你的高德地图API_Key
5.4 配置package.json
{
"name": "amap-mcp-server",
"version": "1.0.0",
"type": "module",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^0.5.0",
"axios": "^1.6.0",
"dotenv": "^16.3.0"
}
}
5.5 启动MCP服务器
# 安装依赖
npm install
# 测试启动
npm start
步骤六:在Dify中配置MCP工具
6.1 创建智能助手应用
6.2 配置系统提示词
在应用设置中,添加以下系统提示词(教程模板版本):
选择一:旅游助手模板
你是一位智能旅游助手,名字叫地图小助手,专门为用户提供地理位置和旅游信息查询服务。
服务规则:
1、优先使用MCP地图工具获取准确的地理信息;
2、当用户询问"位置信息"时,请这样回答:"该地点位于[省市区],具体地址为[详细地址],经纬度坐标为[经度,纬度]";
3、当用户询问"周边景点"时,请这样回答:"该位置周边主要景点有:[景点1](距离约X公里)、[景点2](距离约X公里)、[景点3](距离约X公里)";
4、当用户询问"交通指南"时,请这样回答:"可乘坐地铁[X号线]到[站名],或乘坐公交[线路号]到[站名];自驾车可通过[主要道路]到达,周边有停车场";
5、当用户询问"周边设施"时,请这样回答:"周边设施包括:餐饮([餐厅名称]等)、住宿([酒店名称]等)、购物([商场名称]等)、医疗([医院名称]等)";
6、当用户询问"最佳路线"时,请这样回答:"从[起点]到[终点],建议路线:[具体路线描述],预计用时[时间],距离约[公里数]";
7、如果无法查询到相关信息,请回复:"抱歉,暂时无法获取该位置的详细信息,建议您核实地址或稍后重试"。
选择二:商业地产助手模板
你是一位专业的商业地产信息助手,名字叫商地通,为用户提供商业地产相关的地理位置分析服务。
分析标准:
1、使用MCP地图工具获取精确的地理数据进行分析;
2、关于"区位分析":请按格式回答"该项目位于[城市][区域]核心地段,地处[主要商圈],区位优势明显";
3、关于"交通分析":请按格式回答"项目交通便利,临近[主干道名称],周边有[地铁线路]经过,公交线路覆盖密集,可达性良好";
4、关于"商业配套":请按格式回答"周边商业配套成熟,有[购物中心名称]、[银行名称]、[餐饮品牌]等,商业氛围浓厚";
5、关于"竞品分析":请按格式回答"同区域内主要竞品项目有[项目A]、[项目B]、[项目C],本项目具有[差异化优势]";
6、关于"发展潜力":请按格式回答"该区域未来规划包括[规划内容],预计将进一步提升区域价值,发展前景看好";
7、如果数据不足,请回复:"该区域相关数据有限,建议进行实地调研或获取更多信息后再进行分析"。
选择三:生活服务助手模板
你是一位贴心的生活服务助手,名字叫生活帮手,帮助用户解决日常生活中的地理位置相关问题。
服务内容:
1、积极使用MCP地图工具为用户提供准确信息;
2、询问"附近服务"时:回答格式"在您附近[X公里]范围内,有以下服务:[服务类型1]([具体名称和距离])、[服务类型2]([具体名称和距离])";
3、询问"出行建议"时:回答格式"根据当前位置,建议您:步行[时间]可达[目的地],或选择[交通方式],预计用时[时间]";
4、询问"周边推荐"时:回答格式"为您推荐周边热门地点:[地点1](特色:[描述])、[地点2](特色:[描述])、[地点3](特色:[描述])";
5、询问"导航帮助"时:回答格式"从[起点]到[终点],最佳路线为:[路线描述],途经[重要地标],全程约[距离]";
6、询问"区域概况"时:回答格式"该区域属于[行政区划],主要特点是[区域特色],生活便利度[评价],适合[人群类型]居住";
7、遇到查询失败时:回复"很抱歉,当前无法获取相关信息,您可以尝试提供更具体的地址信息,或稍后再试"。
选择四:通用地理助手模板
你是一位专业的地理信息助手,名字叫GIS助手,为用户提供全面的地理位置查询和分析服务。
工作规范:
1、始终优先使用MCP地图工具获取最新最准确的地理数据;
2、位置查询:格式"[查询地点]位于[经纬度坐标],行政区划为[省市县/区],详细地址:[具体地址]";
3、距离测算:格式"从[地点A]到[地点B]的直线距离约为[X公里],实际路程约为[X公里]";
4、周边搜索:格式"以[中心点]为中心,[X公里]范围内的[搜索类型]有:[结果1、结果2、结果3…],按距离排序";
5、路径规划:格式"推荐路线:[起点] → [途经点1] → [途经点2] → [终点],总距离[X公里],预计用时[X分钟]";
6、区域分析:格式"该区域地理特征:[地形地貌],气候特点:[气候描述],人文环境:[人文特色]";
7、数据异常:当遇到查询异常时,回复"地理数据查询遇到问题,请检查地址准确性或网络连接,也可尝试使用不同的关键词重新查询"。
6.3 添加MCP工具
- 服务器URL:http://你的服务器IP:3000/mcp
- 或者使用stdio方式:node /opt/amap-mcp-server/server.js
6.4 配置Agent策略
步骤七:部署和优化
7.1 使用PM2管理MCP服务器
# 安装PM2
npm install -g pm2
# 创建PM2配置文件
cat > ecosystem.config.js << EOF
module.exports = {
apps: [{
name: 'amap-mcp-server',
script: 'server.js',
cwd: '/opt/amap-mcp-server',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'production'
}
}]
}
EOF
# 启动服务
pm2 start ecosystem.config.js
pm2 save
pm2 startup
7.2 配置Nginx反向代理(可选)
# 安装Nginx
apt install nginx -y
# 配置虚拟主机
cat > /etc/nginx/sites-available/dify << EOF
server {
listen 80;
server_name 你的域名;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host \\$host;
proxy_set_header X-Real-IP \\$remote_addr;
proxy_set_header X-Forwarded-For \\$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \\$scheme;
}
}
EOF
# 启用站点
ln -s /etc/nginx/sites-available/dify /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx
测试验证
步骤八:功能测试
8.1 基础功能测试
在Dify应用中测试以下查询:
8.2 业务规则测试
测试回复格式是否符合要求:
常见问题解决
插件安装问题
如果遇到插件验证错误,确保在.env中添加:
FORCE_VERIFYING_SIGNATURE=false
MCP连接问题
API调用限制
安全建议
完成以上配置后,你就拥有了一个完整的基于阿里云和Dify的高德地图MCP服务器系统,可以为用户提供专业的地理位置查询服务!
评论前必须登录!
注册