1. 原理
1.1 mcp协议规范
-
相关文档:
json-rpc 2.0协议规范:JSON-RPC 2.0 Specification
mcp文档:Overview - Model Context Protocol
mcp实践规范中与原始json-rpc 2.0有区别的地方参见:Overview - Model Context Protocol
mcp初始化握手通信中的协议版本说明:Lifecycle - Model Context Protocol
mcp初始化握手通信中的capability说明:Lifecycle - Model Context Protocol
由于mcp协议中的host部分实际上做的是client/server/模型等组件的编排工作,不涉及实际通信,故此部分略去,放到2. 利用MCP构建agent的工程实践 部分。

mcp协议通信本身与模型没有任何关系,以npx方式启动的高德地图的server为例,你可以直接在终端做如下操作:
➜ ~ export AMAP_MAPS_API_KEY="*"
➜ ~ npx -y @amap/amap-maps-mcp-server
Amap Maps MCP Server running on stdio
(然后你就可以直接发消息了,下面的“请求:”和“响应:”都是为了说明消息来源,冒号后面才是终端里真正的请求和响应)
请求:{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"mcp-agent","version":"1.0.0"}}}
响应:{"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"mcp-server/amap-maps","version":"0.1.0"}},"jsonrpc":"2.0","id":1}
请求:{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
响应:{"result":{"tools":[{"name":"maps_regeocode","description":"将一个高德经纬度坐标转换为行政区划地址信息","inputSchema":{"type":"object","properties":{"location":{"type":"string","description":"经纬度"}},"required":["location"]}},{"name":"maps_geo","description":"将详细的结构化地址转换为经纬度坐标。支持对地标性名胜景区、建筑物名称解析为经纬度坐标","inputSchema":{"type":"object","properties":{"address":{"type":"string","description":"待解析的结构化地址信息"},"city":{"type":"string","description":"指定查询的城市"}},"required":["address"]}},{"name":"maps_ip_location","description":"IP 定位根据用户输入的 IP 地址,定位 IP 的所在位置","inputSchema":{"type":"object","properties":{"ip":{"type":"string","description":"IP地址"}},"required":["ip"]}},{"name":"maps_weather","description":"根据城市名称或者标准adcode查询指定城市的天气","inputSchema":{"type":"object","properties":{"city":{"type":"string","description":"城市名称或者adcode"}},"required":["city"]}},{"name":"maps_search_detail","description":"查询关键词搜或者周边搜获取到的POI ID的详细信息","inputSchema":{"type":"object","properties":{"id":{"type":"string","description":"关键词搜或者周边搜获取到的POI ID"}},"required":["id"]}},{"name":"maps_bicycling","description":"骑行路径规划用于规划骑行通勤方案,规划时会考虑天桥、单行线、封路等情况。最大支持 500km 的骑行路线规划","inputSchema":{"type":"object","properties":{"origin":{"type":"string","description":"出发点经纬度,坐标格式为:经度,纬度"},"destination":{"type":"string","description":"目的地经纬度,坐标格式为:经度,纬度"}},"required":["origin","destination"]}},{"name":"maps_direction_walking","description":"步行路径规划 API 可以根据输入起点终点经纬度坐标规划100km 以内的步行通勤方案,并且返回通勤方案的数据","inputSchema":{"type":"object","properties":{"origin":{"type":"string","description":"出发点经度,纬度,坐标格式为:经度,纬度"},"destination":{"type":"string","description":"目的地经度,纬度,坐标格式为:经度,纬度"}},"required":["origin","destination"]}},{"name":"maps_direction_driving","description":"驾车路径规划 API 可以根据用户起终点经纬度坐标规划以小客车、轿车通勤出行的方案,并且返回通勤方案的数据。","inputSchema":{"type":"object","properties":{"origin":{"type":"string","description":"出发点经度,纬度,坐标格式为:经度,纬度"},"destination":{"type":"string","description":"目的地经度,纬度,坐标格式为:经度,纬度"}},"required":["origin","destination"]}},{"name":"maps_direction_transit_integrated","description":"公交路径规划 API 可以根据用户起终点经纬度坐标规划综合各类公共(火车、公交、地铁)交通方式的通勤方案,并且返回通勤方案的数据,跨城场景下必须传起点城市与终点城市","inputSchema":{"type":"object","properties":{"origin":{"type":"string","description":"出发点经度,纬度,坐标格式为:经度,纬度"},"destination":{"type":"string","description":"目的地经度,纬度,坐标格式为:经度,纬度"},"city":{"type":"string","description":"公共交通规划起点城市"},"cityd":{"type":"string","description":"公共交通规划终点城市"}},"required":["origin","destination","city","cityd"]}},{"name":"maps_distance","description":"距离测量 API 可以测量两个经纬度坐标之间的距离,支持驾车、步行以及球面距离测量","inputSchema":{"type":"object","properties":{"origins":{"type":"string","description":"起点经度,纬度,可以传多个坐标,使用竖线隔离,比如120,30|120,31,坐标格式为:经度,纬度"},"destination":{"type":"string","description":"终点经度,纬度,坐标格式为:经度,纬度"},"type":{"type":"string","description":"距离测量类型,1代表驾车距离测量,0代表直线距离测量,3步行距离测量"}},"required":["origins","destination"]}},{"name":"maps_text_search","description":"关键词搜,根据用户传入关键词,搜索出相关的POI","inputSchema":{"type":"object","properties":{"keywords":{"type":"string","description":"搜索关键词"},"city":{"type":"string","description":"查询城市"},"types":{"type":"string","description":"POI类型,比如加油站"}},"required":["keywords"]}},{"name":"maps_around_search","description":"周边搜,根据用户传入关键词以及坐标location,搜索出radius半径范围的POI","inputSchema":{"type":"object","properties":{"keywords":{"type":"string","description":"搜索关键词"},"location":{"type":"string","description":"中心点经度纬度"},"radius":{"type":"string","description":"搜索半径"}},"required":["location"]}}]},"jsonrpc":"2.0","id":2}
请求:{"jsonrpc": "2.0", "method": "notifications/initialized"}
(最后一条是做完初始化通信之后,client向server发送的初始化完成通知,这条server是不会回复的,经过这样一番通信初始化就算结束了,后面就是正常的业务通信)
请求:{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "maps_geo", "arguments": {"address": "上海虹桥机场"}}}
响应:{'result': {'content': [{'type': 'text', 'text': '{\\n "return": [\\n {\\n "country": "中国",\\n "province": "上海市",\\n "city": "上海市",\\n "citycode": "021",\\n "district": "闵行区",\\n "street": [],\\n "number": [],\\n "adcode": "310112",\\n "location": "121.317357,31.194540",\\n "level": "公交地铁站点"\\n }\\n ]\\n}'}], 'isError': False}, 'jsonrpc': '2.0', 'id': 3}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "search_papers", "arguments": {"topic": "multiple agents", "max_results": 10}}}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "extract_info", "arguments": {"paper_id": "2411.04578v1"}}}
关于版本协商,文档中提到:
In the
initializerequest, the client MUST send a protocol version it supports. This SHOULD be the latest version supported by the client.在initialize请求中,客户端必须发送其支持的协议版本。该版本必须是客户端支持的最新版本。If the server supports the requested protocol version, it MUST respond with the same version. Otherwise, the server MUST respond with another protocol version it supports. This SHOULD be the latest version supported by the server.
如果服务器支持请求的协议版本,则必须以相同的版本进行响应。否则,服务器必须以其支持的其他协议版本进行响应。该版本必须是服务器支持的最新版本。
If the client does not support the version in the server’s response, it SHOULD disconnect
.如果客户端不支持服务器响应中的版本,则应该 断开。
696

被折叠的 条评论
为什么被折叠?



