基于阿里云Dify的高德地图MCP服务器完整配置教程

准备工作

第一步:获取高德地图API Key

  1. 访问 高德开放平台
  2. 注册并登录账号
  3. 进入控制台 → 应用管理 → 我的应用
  4. 创建新应用:
    • 应用名称:Dify地图服务
    • 应用类型:Web服务
  5. 获取并保存API Key
    在这里插入图片描述
    替换以下JSON中key,并保存MCP Server配置地址,便于后续使用。
{
  "mcpServers": {
    "amap-amap-sse": {
      "url": "https://mcp.amap.com/sse?key=您在高德开放平台上申请的key"
    }
  }
}

第二步:准备阿里云轻量应用服务器

  1. 登录阿里云控制台
  2. 购买轻量应用服务器(推荐2核4G配置)
  3. 选择Ubuntu 20.04操作系统
  4. 配置安全组,开放端口:80、443、3000、8000

部署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控制台
  1. 在浏览器中访问:http://你的服务器IP
  2. 创建管理员账号
  3. 完成初始化设置
2.2 配置大模型
  1. 进入设置 → 模型供应商
  2. 添加OpenAI或其他模型提供商
  3. 输入API Key并测试连接

安装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配置地址示例如下:
在这里插入图片描述
在这里插入图片描述

步骤四:验证插件安装

  1. 登录Dify控制台
  2. 进入设置 → 插件管理
  3. 确认以下插件已安装并启用:
    • Agent策略(支持 MCP 工具)
    • MCP SSE

配置高德地图MCP服务器

步骤五:创建高德地图MCP服务器

z

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 创建智能助手应用
  1. 登录Dify控制台
  2. 创建新应用 → 选择"智能助手"
  3. 设置应用名称:“地图助手”
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工具
  1. 在智能助手设置中,找到"工具"部分
  2. 点击"添加工具" → 选择"MCP SSE"
  3. 配置MCP服务器:
    • 服务器URL:http://你的服务器IP:3000/mcp
    • 或者使用stdio方式:node /opt/amap-mcp-server/server.js
6.4 配置Agent策略
  1. 在应用设置的"Agent"部分
  2. 选择策略:选择安装的"Agent策略(支持 MCP 工具)"
  3. 配置工具调用权限

步骤七:部署和优化

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应用中测试以下查询:

  1. “查询天安门广场的坐标”
  2. “116.397128,39.916527这个位置在哪里”
  3. “搜索天安门广场周边的酒店”
8.2 业务规则测试

测试回复格式是否符合要求:

  1. 询问某地的土地四至
  2. 询问某地的方位信息
  3. 询问交通状况等

常见问题解决

插件安装问题

如果遇到插件验证错误,确保在.env中添加:

FORCE_VERIFYING_SIGNATURE=false

MCP连接问题

  1. 检查MCP服务器是否正常运行
  2. 确认端口是否正确开放
  3. 查看日志排查错误

API调用限制

  1. 检查高德地图API配额
  2. 合理设置调用频率
  3. 考虑缓存机制优化

安全建议

  1. API Key安全:不要在代码中硬编码API Key
  2. 服务器安全:及时更新系统和依赖包
  3. 访问控制:配置防火墙和访问限制
  4. 日志监控:设置日志记录和监控告警

完成以上配置后,你就拥有了一个完整的基于阿里云和Dify的高德地图MCP服务器系统,可以为用户提供专业的地理位置查询服务!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐