一、环境搭建
1.1 高德地图 api 申请
使用高德地图开放的 MCP Server 服务需要申请一个高德地图的 API Key,按如下方式申请:
1. 进入 高德开放平台官网 (https://lbs.amap.com/), 点击右上角控制台,注册成为开发者,注册完成后点击确认即可。
2. 进入控制台后,点击左侧的应用管理,点击下拉栏中我的应用一项,点击创建新应用
3. 创建一个新应用后点击右上角添加 Key, 按命名规范要求输入 Key 名称,并选择 “Web 服务” 选项,勾选 “阅读并同意……”,最后点击 “提交” 按钮,稍等片刻得到高德地图的 API Key。
1.2 VsCode + Cline + DeepSeek API
我们需要在 VsCode 中安装 Cline 插件,并在 Cline 中配置 DeepSeek 的 API Key。之前的文章
零门槛!手把手教你用 VS Code + DeepSeek 免费玩转 AI 编程!(5 分钟编写部署个人网站)详细介绍了 VsCode+Cline+DeepSeek API 的安装步骤和配置,这里不再赘述。完成后效果如下:
1.3 node.js 下载安装
node.js 的下载安装方式非常多,此处省略
1.4 Cline 连接高德地图 MCP Server
Cline 除了连接 DeepSeek 大模型还需要连接高德地图 MCP Server 获得高德地图提供的多种能力。
1. 访问 MCP Servers 官方网站 (https://mcp.so/), 打开高德地图 Amap Maps, 点击 Content,其中介绍了高德地图 MCP 的接入配置:
{ "mcpServers": { "amap-maps": { "command": "npx", "args": [ "-y", "@amap/amap-maps-mcp-server" ], "env": { "AMAP_MAPS_API_KEY": "您在高德官网上申请的key" } } }}
2. 首先点击 Vs Code 中的 Cline,然后点击 MCP Servers 小图标,再点击 Installed 选项,点击 Configure MCP Servers 打开 MCP Servers 配置文件,将上述配置粘贴到该配置文件中
3. 测试高德地图 MCPServer, 连接成功之后会在右下角出现 Cline 的消息提示 amap-maps MCP Server connected, 同时在 Cline 的 MCP Server Tools 列表中可以高德地图 MCP Server 暴露出的 12 种方法,大家可以看到关于这些方法的具体介绍。
以上就是本项目需要的全部配置。
二、两步搞定高德地图 MCP 出行规划
完成上述配置后通过一个具体场景带大家两步学会使用高德地图 MCP 进行出行规划:
2.1 项目背景
又到周末啦!和工作日的牛马不同,周末要化身 “爱妻超人” 带女朋友去潇洒了。不说了,女朋友电话来了
女朋友:“宝贝春天了,周末我想去公园玩,有没有好玩的公园呀~”
我: “春天要去踏青了,我们就去玉渊潭看花吧”
女朋友:“玉渊潭去过好多次了,我想换个公园,要不找个咱俩中间地点的公园吧~”
我: “中间的公园,这…”
女朋友: “你竟然没有计划我们的周末行程,还吹牛说自己对北京很熟悉,我要生气啦~”
我: “当然不是,哎呀我当然计划了,只是只是,给我 5min~”
这时的我迅速打开 VsCode+Cline, 连接好高德地图 MCP Server, 开始了我的骚操作
2.2 设计提示词
提问大模型的第一步首先要说明我们的需求,设计明确的提示词。打开 VsCode, 点击小机器人图标打开 Cline, 在 Type your task here 中输入如下提示词:
我住在北京海淀区永丰地铁站附近,女朋友在北京市海淀区魏公村地铁站附近,帮我推荐几个与两个人距离相近,方便停车的,景色优美的公园。并给出公园的具体信息。
输入提示词之后,Cline 会通过 DeepSeek 大模型组织串联高德地图 MCP Server 的多种工具帮我们挑选公园,在调用接口时如果我们没有勾选 auto approve
选项,需要我们人工确定是否调用这些接口,我们一路点击 Approve 即可。
DeepSeek 会梳理调用 MCP Server 获得的各种信息,返回给我们最后的推荐。可以看到最后 DeepSeek 帮我们推荐了三个公园分别是圆明园遗址公园,清河之源滨水公园和厢黄旗公园。
2.3 生成可视化网页
这就完啦?当然没有,对于一个优秀的 “爱妻” 程序员来说,不能只会规划,还要用一种更惊喜的方式把这些信息展示出来,还记得我有篇文章不写一行代码使用
零门槛!手把手教你用 VS Code + DeepSeek 免费玩转 AI 编程!(5 分钟编写部署个人网站),我们让 Cline 根据返回结果帮我们制作一个精美的网站展示页,继续输入如下提示词:
上面的推荐内容,能不能帮我生成一个html文件,用好看的图像表达出来,方便大家美观的查看
输入如上提示词后,Cline 开始自动给我们生成 html 代码了:
生成完毕后点击 run command 查看网页的生成效果,还是很漂亮的。
得到 html 代码后,我们使用 HTMLPUT (https://www.htmlput.com/) 网站把我们的静态代码粘贴进去(拿临时邮箱注册一个账号即可),访问权限选择公开访问,点击立即托管。在历史记录之中点击查看,然后把链接分享给别人,大家就可以在线看到网页了,也可以通过二维码分享,我生成的网页链接是 (用电脑打开):北京海淀公园推荐 – 永丰 & 魏公村
三、 Cline 接入 MCP Server 原理解析
3.1 Cline MCP 客户端和服务端通信方式
Cline 接入 MCP 究竟是如何得到这么神奇的效果呢,大家如果看过我的文章:理论 + 代码一文带你深入浅出 MCP:人工智能大模型与外部世界交互的革命性突破 脑海中应该有个整体思路,Cline + 大模型相当于 MCP 的客户端,高德地图是 MCP 服务端,不过它们之间是如何通信的呢?
大家还记得上面 Cline 配置高德地图 MCP 的配置项,该配置项相当于执行了 npx -y @amap/amap-maps-mcp-server
命令
{ "mcpServers": { "amap-maps": { "command": "cmd", "args": [ "/c", "npx", "-y", "@amap/amap-maps-mcp-server" ], "env": { "AMAP_MAPS_API_KEY": "你的高德地图API Key" }, "disabled": false, "autoApprove": [ "maps_geo", "maps_around_search", "maps_search_detail" ] } }}
我们在本地命令行 cmd 窗口运行 npx -y @amap/amap-maps-mcp-server
, 注意在运行前要设置环境变量 set AMAP_MAPS_API_KEY="你的高德地图API Key"
为你高德地图的 API Key, 效果如下:
很明显的看到高德地图 MCP 服务端是通过 stdio 标准输入输出方式与 Cline 大模型 MCP 客户端相互通信的。
3.2 接入自定义 Client
既然高德地图 MCP Server 是通过 stdio 标准输入输出方式与 MCP Client 相连的,我们能不能利用
理论 + 代码一文带你深入浅出 MCP:人工智能大模型与外部世界交互的革命性突破 中使用 python 编写的 client.py,将高德地图 MCP Server 作为它的子进程进行通信呢?赶快来试一下~
完整代码为:
import asyncioimport jsonfrom typing import Optionalfrom contextlib import AsyncExitStackfrom openai import OpenAI from mcp import ClientSession, StdioServerParametersfrom mcp.client.stdio import stdio_client class MCPClient: def __init__(self): """初始化MCP客户端""" self.exit_stack = AsyncExitStack() self.opanai_api_key = "你注册的deepseek api_key" # 调用模型的api_key self.base_url = "https://api.deepseek.com" # 调用模型url, 这里以deepseek作演示 self.model = "deepseek-chat" # 调用deepseek-v3模型 self.client = OpenAI(api_key=self.opanai_api_key, base_url=self.base_url) self.session: Optional[ClientSession] = None # Optional提醒用户该属性是可选的,可能为None self.exit_stack = AsyncExitStack() # 用来存储和清楚对话中上下文的,提高异步资源利用率 async def connect_to_server(self): """连接到MCP服务器并列出MCP服务器的可用工具函数""" server_params = StdioServerParameters( command="npx", args=["-y", "@amap/amap-maps-mcp-server"], env={ "AMAP_MAPS_API_KEY": "你注册的高德地图api key" } ) # 设置启动服务器的参数, 这里是要用python执行server.py文件 # 启动MCP服务器并建立通信 stdio_transport = await self.exit_stack.enter_async_context(stdio_client(server_params)) self.stdio, self.write = stdio_transport self.session = await self.exit_stack.enter_async_context(ClientSession(self.stdio, self.write)) await self.session.initialize() # 与服务器建立stdio连接 # 列出MCP服务器上的工具 response = await self.session.list_tools() tools = response.tools print("\n已连接到服务器,支持以下工具:", [tool.name for tool in tools])#打印服务端可用的工具 async def process_query(self, query:str)->str: """使用大模型处理查询并调用MCP Server可用的MCP工具""" messages = [{"role":"user", "content":query}] response = await self.session.list_tools() available_tools = [{ "type": "function", "function": { "name": tool.name, "description": tool.description, "input_schema": tool.inputSchema } } for tool in response.tools] response = self.client.chat.completions.create( model=self.model, messages=messages, tools=available_tools ) # 处理返回内容 content = response.choices[0] if content.finish_reason == "tool_calls": # 返回结果是使用工具的建议,就解析并调用工具 tool_call = content.message.tool_calls[0] tool_name = tool_call.function.name tool_args = json.loads(tool_call.function.arguments) # 执行工具 result = await self.session.call_tool(tool_name, tool_args) print(f"\n\n[Calling tool {tool_name} with args {tool_args}]\n\n") # 将模型返回的调用工具的对话记录保存在messages中 messages.append(content.message.model_dump()) messages.append({ "role": "tool", "content": result.content[0].text, "tool_call_id": tool_call.id, }) # 将上面的结果返回给大模型用于生产最终结果 response = self.client.chat.completions.create( model=self.model, messages=messages ) return response.choices[0].message.content return content.message.content async def chat_loop(self): """运行交互式聊天""" print("\n MCP客户端已启动!输入quit退出") while True: try: query = input("\n用户:").strip() if query.lower() == 'quit': break response = await self.process_query(query) print(f"\nDeepSeek-V3-0324: {response}") except Exception as e: print(f"发生错误: {str(e)}") async def clean(self): """清理资源""" await self.exit_stack.aclose() async def main(): client = MCPClient() try: await client.connect_to_server() await client.chat_loop() finally: await client.clean() if __name__ == "__main__": import sys asyncio.run(main())