以上内容摘自MCP官方文档,我觉得已经说的非常清晰直观了,但还是很多人误以为MCP是一个神奇的工具,拥有执行命令、读取文件、查询数据等等功能。
不不不,MCP只是一个协议,LLM通过这个协议来使用各个工具。不管是执行命令、读取文件、查询数据,如果你有了这些工具,没有MCP也可以使用工具;反过来说,如果没有这些工具,光有MCP什么也做不了。
MCP的意义是LLM能够使用“远程工具”:这些工具可以使用不同语言、部署在不同设备、具有不同的功能,通过MCP把它们集成一起,供LLM选用;同样的,如果你已经有一批工具,那么也可以MCP把它们提供给任何一个LLM。
总而言之,MCP像USB一样,提供了各个LLM和各个工具之间的快速接入。
MCP底层原理
规范版本:2025-03-26
传输协议:
鉴权方式:
如果MCP是在自己电脑里用,不用考虑鉴权什么的,那么stdio就够了,简单快捷。
如果你的MCP Server打算通过网络分享出去,基于HTTP则更加方便。此前MCP使用SSE来进行远程传输,在新的规范中则鼓励使用Streamable HTTP ,同时也支持了鉴权更加地安全。
报文内容:
经典的方案,这个没什么好说的,如果你不是打算重新实现MCP Client的话,暂时不需要关注报文内容的细节。
生命周期(重点):
- 初始化:client连接server端,协商版本和能力
前期有一个“握手”的阶段,这样Client 才能知道Server有哪些工具,进而提供给LLM进行使用。
有意思的是MCP为Server约定了一个采样(sampling)的能力:使用LLM进行内容生成,也就说LLM也被Client 提供给了Server进行使用。
不过当前版本的SDK中暂时没有实现采样,具体用法还要再等更新。
MCP应用实战
安装依赖
pip install mcp openai-Agents
mcp是MCP官方提供的SDK,内置了MCP Server 和 MCP Client实现,开箱即用
openai-agents是OpenAI开源的#Agent框架简化了LLM的操作细节
MCP Server声明能力
# server.py
importos
frommcp.server.fastmcpimportFastMCP
mcp = FastMCP("MCP Demo")
@mcp.tool()
defadd(a: int, b: int)-> int:
"""返回a和b相加结果"""
returna + b
@mcp.tool()
defls():
"""列出目录中的文件名"""
returnos.listdir(".")
if__name__ =='__main__':
mcp.run() # 默认使用 stdio 传输
MCP Client初始化
# client.py
frommcpimportClientSession, StdioServerParameters, types
frommcp.client.stdioimportstdio_client
# stdio 启动参数
server_params = StdioServerParameters(
command="python",
args=["server.py"],
)
asyncdefrun():
asyncwithstdio_client(server_params)as(read, write):
asyncwithClientSession(read, write)assession:
# 初始化
awaitsession.initialize()
# 查询支持的工具
result =awaitsession.list_tools()
print("支持的工具有:",)
fortoolinresult.tools:
print(f" {tool.name}{tool.description}")
# 调用工具
result =awaitsession.call_tool("add", arguments={"a":1,"b":10})
print('add的调用结果:', result.content[0].text)
if__name__ =="__main__":
importasyncio
asyncio.run(run())
执行结果(可以发现工具和使用工具):
Processing request of type ListToolsRequest
Processing request of type CallToolRequest
支持的工具有:
add 返回a和b相加结果
ls 列出目录中的文件名
add的调用结果: 11
LLM使用远程工具
使用MCP加载工具之前
# llm.py
fromagentsimportAgent, Runner
agent = Agent(
name="AI助手",
instructions="使用合适的工具,生成合适的响应", # 系统提示词
)
result = Runner.run_sync(agent,'当前目录有几个文件?')
print(result.final_output)
执行结果(无法完成,开始聊天):
请提供更具体的信息,例如:
* **操作系统:** 您使用的是 Windows, macOS, 还是 Linux?
* **您想在哪里查看文件数量?** 是在命令行 (Terminal/CMD) 还是在文件管理器中?
因为不同的操作系统和方法,查看文件数量的命令和操作方式会不同。
例如:
* **在 Linux/macOS 命令行中使用 `ls` 和 `wc` 命令:**
```bash
ls -l | grep -v ^d | wc -l
```
这个命令会列出当前目录下的所有文件 (不包括目录),并统计它们的数量。
* **在 Windows 命令行中使用 `dir` 和 `find` 命令:**
```cmd
dir /a-d | find /c "<DIR>"
```
这个命令会列出当前目录下的所有文件,并统计它们的数量。
一旦您提供了更多信息,我可以给出更准确的答案。
使用MCP加载工具之后
# llm.py
fromagentsimportAgent, Runner
fromagents.mcpimportMCPServerStdio
asyncdefrun():
asyncwithMCPServerStdio(
name="基于stdio的mcp服务器",
params={
"command":"python",
"args": ["server.py"],
},
)asmcp_server:
agent = Agent(
name="AI助手",
instructions="使用合适的工具,生成合适的响应",
mcp_servers=[mcp_server, ]
)
result =awaitRunner.run(agent,'当前目录有几个文件?')
print(result.final_output)
if__name__ =='__main__':
importasyncio
asyncio.run(run())
为了使用MCP,这里改用异步写法,对于Agent来说和之前相比只是多了一个mcp_servers参数
agent = Agent(
name="AI助手",
instructions="使用合适的工具,生成合适的响应",
++ mcp_servers=[mcp_server, ]
)
执行结果(调用工具完成任务,并输出结果):
Processing request of type ListToolsRequest
Processing request of type CallToolRequest
当前目录有 4 个文件。
实际上,我对Server能力中的资源、提示词还不太了解,鉴权也没有尝试。还有很多细节内容比如:错误处理、进度跟踪、接口测试等,都没有深入。