共计 2705 个字符,预计需要花费 7 分钟才能阅读完成。
关于MCP网上的资料非常多,但是真正能结合实际操作的少之又少,导致即使看了很多资料之后,对于MCP的概念还是云里雾里,本文将拨云见日,通过理论结合实操探索MCP的真正底层逻辑。
写在最前
最近MCP很火,国内很多厂商也第一时间开发了基于自身服务的MCP Server,比如高德地图、百度地图、Github等。
其实最近自媒体把MCP炒的很火,但是我们探究底层原理之后,会发现MCP其实也就是一个调用协议,类似于RestAPI的概念,将LLM与工具之间的调用方式标准化,以致于未来在生态上,各大厂商都基于MCP的标准协议提供服务入口,各大AI基础模型也都能基于这些服务进行快速调用。
还是脚踏实地,对于自媒体的文章一定要祛魅,认真看待底层逻辑。
MCP的概念
模型上下文协议(MCP)是一种开放协议,旨在为大型语言模型(LLM)提供标准化的上下文访问方式。官方举例说,MCP 犹如 AI 应用的 “USB-C 端口”,使 LLM 能够通过统一的接口无缝连接至多种数据源和工具(如文件系统、数据库或外部 API)。
MCP的组成部分
- MCP HOST
- MCP Client
- MCP Server
总体上的调用逻辑为:用户基于MCP HOST工具,跟LLM的交互过程中,MCP HOST会将用户输入的问题,交给LLM判断是否需要调用外部工具,如果需要调用外部工具,则利用LLM提取出众多工具中的具体某一个Tool以及对应的parameter(参数),接着HOST调用Client去连接对应的Server获取调用结果,返回给LLM组成上下文后,继续迭代是否需要调用外部工具的循环,直到不需要调用外部工具后,由LLM基于context返回结果给用户。
MCP HOST
整个交互的核心过程控制由HOST决定,其中HOST的主循环逻辑如下:
# Host 主循环逻辑
async def handle_user_query(user_input):
# 1. 获取当前会话的可用工具列表
tools = await mcp_client.request("tools/list")
# 2. 将工具描述注入 LLM 上下文
llm_context = build_llm_prompt(user_input, tools)
# 3. 启动多轮交互循环
while True:
# 请求 LLM 生成响应(可能包含工具调用指令)
llm_response = await llm.generate(llm_context)
if not llm_response.requires_tool_call:
break # 直接返回最终响应
# 4. 解析工具调用请求
tool_name, params = parse_tool_call(llm_response)
# 5. 执行工具调用(通过 MCP Client)
tool_result = await mcp_client.request(
"tools/call",
{"name": tool_name, "params": params}
)
# 6. 将结果注入下一轮 LLM 上下文
llm_context.append({"role": "tool_result", "content": tool_result})
return llm_response.final_output
MCP Client
Client用来连接Server的工具,Client集成在HOST里面的,HOST在LLM判断需要调用工具的时候会使用Client去连接Server。
MCP Server
核心模块为:
- Tools
- Resources
- Prompts
这个模块我会直接贴代码给大家举例子,例子为:sqlite的MCP Server
Tools
最常用且最实用的模块,Tools 是 MCP 里的“执行者”,简单说,就是服务器提供一些函数或者 API,LLM 可以直接调用去完成具体任务。比如:发邮件、查天气、执行SQL等。
比如以下代码就是列出当前Server支持的所以tools:
代码路径为:servers/src/sqlite/src/mcp_server_sqlite/server.py
包括每个tool的name、description以及相应的inputSchema。
以上接口是返回所有的tools给LLM,由LLM根据tool的描述以及用户的输入来决定调用哪个tool,调用的时候使用Client发送请求,Server端的逻辑如下:
代码路径为:servers/src/sqlite/src/mcp_server_sqlite/server.py
核心逻辑就是基于输入的tool name以及相应的入参执行具体的程序。
Resources
Resources 是 MCP 里用来提供数据资源的核心,你可以把它想象成一个只读的数据库接口或者文件系统,里面装的是静态或者半动态的信息,比如日志文件、用户配置文件、股票价格啥的。
同样Server端代码也有两个接口,分别是list_resources
、read_resource
:
代码路径为:servers/src/sqlite/src/mcp_server_sqlite/server.py
Prompts
Prompts模块提供一些标准化的提示词以供LLM调用,这样就不用每次修改提示词的时候都需要修改核心代码了,LLM每次从MCP Server里面取到的都是标准化的Prompts,填入相应的参数后即可调用LLM。好处是写一次,到处用,省得每次都从头编 Prompt。
同样也有两个接口:
首先还是获取Prompts列表以及对应的需要的参数,调用的时候传入Prompts的name以及arguments,返回完整的提示词供LLM直接使用。
MCP的使用示例
本文的示例调用的MCP Server为高德地图提供的Server,包含以下接口:
单次交互
询问某地的坐标,LLM直接调用maps_geo接口完成回复
多轮交互
当我问到一个复杂的问题,需要多次调用MCP Server提供的工具时,MCP HOST会多次调用相应的接口,组装成LLM的上下文进行用户回复。
其实多轮交互的回答还是比较惊艳的,先不论回答得精准度,就论LLM能够多次自主地决定是否调用工具以及调用哪个工具去完成用户指定的任务,就已经完成地非常不错了。
MCP一些资源
- MCP.so
MCP Server的搜索引擎 - MCP的资源精选
- Awsome MCP Client
参考资料: