大模型(LLM)正以前所未有的速度发展,它们的能力已经渗透到各个领域。如何更好地利用这些强大的模型,让它们能够访问外部信息和工具,成为了一个重要的研究方向。MCP (Model Context Protocol) 作为一种开放标准,正为大模型与外部工具的交互提供了一种高效、便捷的解决方案。本文将深入探讨如何利用 STDIO (标准输入/输出) 传输方式,快速构建一个 MCP 服务器,无需复杂的配置和部署,即可让你的大模型拥有强大的外部能力。
什么是 MCP?以及为何如此重要?
MCP (Model Context Protocol) 是一种专门为大模型设计的通信协议。它允许像 Claude 或 GPT-4 这样的 LLM 通过结构化的 API 调用外部工具。想象一下,你可以创建一个工具,让语言模型像调用函数一样使用它来进行搜索、数学计算、数据库查询,或者任何你能想到的功能。
MCP 的重要性体现在以下几个方面:
- 扩展大模型能力: 大模型本身虽然知识储备丰富,但在处理实时信息、特定领域数据以及执行复杂计算等方面存在局限性。MCP 允许大模型访问外部工具,弥补这些不足,从而大幅提升其解决问题的能力。
- 可组合性与灵活性: 通过 MCP,开发者可以构建各种各样的工具,并将它们组合起来,形成强大的工作流。例如,可以将一个搜索工具与一个数学计算工具结合,让大模型先搜索相关信息,然后进行数据分析。
- 标准化接口: MCP 提供了一套标准的接口规范,使得不同的工具可以无缝地与大模型进行交互。这降低了开发成本,并提高了系统的可维护性。
- 安全性和控制: 通过 MCP,开发者可以精确控制大模型可以访问哪些工具,以及每个工具的使用权限。这有助于保障数据的安全性和模型的稳定性。
举个例子,假设你想让大模型帮你分析某个股票的走势。如果没有 MCP,你可能需要将股票数据手动输入到模型中,并编写复杂的代码进行分析。而有了 MCP,你可以构建一个股票数据查询工具,让大模型通过 MCP 协议直接调用该工具获取实时数据,并进行分析。
STDIO:极简的 MCP 工具构建方式
在众多 MCP 传输方式中,STDIO (标准输入/输出) 无疑是最简单、最直接的一种。它允许你通过标准输入/输出来构建 MCP 兼容的工具,这意味着:
- 无需服务器: 工具直接在本地运行,无需搭建额外的服务器。
- 无需网络配置: 工具通过标准输入/输出进行通信,无需进行复杂的网络配置。
- 跨平台兼容: 只要你的机器支持标准输入/输出,就可以运行该工具。
- 易于集成: STDIO 可以无缝地与 LangChain、LangGraph 等流行的 LLM 开发框架集成。
与传统的 HTTP 方式相比,STDIO 方式更加轻量级,更加易于上手,特别适合用于快速原型开发和本地调试。
使用 Python 和 Tavily API 构建一个 STDIO MCP 服务器
接下来,我们将通过一个具体的例子,演示如何使用 Python 和 Tavily API 构建一个 STDIO MCP 服务器。这个服务器的功能是利用 Tavily API 进行网络搜索,并将搜索结果返回给大模型。
1. 准备工作
首先,你需要安装以下依赖:
pip install fastmcp requests langchain langgraph
然后,你需要获取一个 Tavily API Key,并将其设置为环境变量:
export TAVILY_API_KEY="your_real_api_key"
你可以在 Tavily 官网免费注册一个 API Key。
2. 创建 MCP 服务器
使用 FastMCP 创建一个简单的 MCP 服务器:
from mcp.server import FastMCP
mcp = FastMCP("tavily-search-server")
这段代码创建了一个名为 “tavily-search-server” 的 MCP 服务器实例。
3. 添加 Tavily Web 搜索工具
定义一个函数 tavily_search
,该函数调用 Tavily API 进行网络搜索,并将搜索结果返回:
import os
import requests
TAVILY_API_KEY = os.getenv("TAVILY_API_KEY")
@mcp.tool()
def tavily_search(query: str) -> str:
"""Use Tavily API to search the web and return the top result."""
url = "https://api.tavily.com/search"
headers = {"Authorization": f"Bearer {TAVILY_API_KEY}"}
payload = {"query": query, "max_results": 1}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
results = response.json()
return results["results"][0]["content"] if results.get("results") else "No results found."
@mcp.tool()
装饰器将该函数注册为 MCP 工具。当大模型通过 MCP 协议调用该工具时,tavily_search
函数将被执行。该函数接受一个字符串类型的参数 query
,表示搜索关键词,并返回一个字符串类型的搜索结果。函数内部调用 Tavily API 进行搜索,并将返回的 JSON 数据解析后,提取第一个结果的内容。
4. 启动服务器
添加一个简单的入口点来启动服务器:
if __name__ == "__main__":
print("✅ MCP server has started")
mcp.run()
将以上代码保存为 tavily_server.py
文件。
5. 与 LangGraph ReAct Agent 集成
现在,我们将使用 LangGraph ReAct Agent 来调用我们刚刚创建的 MCP 服务器。首先,你需要安装 langchain_mcp_adapters
包:
pip install langchain_mcp_adapters
然后,创建一个 Python 文件,例如 agent.py
,并添加以下代码:
import asyncio
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain.chat_models import ChatOpenAI
async def run_agent():
server_params = StdioServerParameters(
command=["python", "tavily_server.py"]
)
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await load_mcp_tools(session)
agent_executor = create_react_agent(
llm=ChatOpenAI(model="gpt-4"),
tools=tools,
max_iterations=5,
)
result = await agent_executor.ainvoke({
"input": "What's the latest news about AI policy in Europe?"
})
print(result["output"])
if __name__ == "__main__":
asyncio.run(run_agent())
这段代码首先创建了一个 StdioServerParameters
对象,指定了 MCP 服务器的启动命令。然后,使用 stdio_client
创建一个 STDIO 客户端,并使用 ClientSession
与服务器建立连接。load_mcp_tools
函数从 MCP 服务器加载工具,并将它们传递给 LangGraph ReAct Agent。最后,Agent 使用 Tavily 搜索工具来回答问题 “What’s the latest news about AI policy in Europe?”。
6. 运行 Agent
运行 agent.py
文件:
python agent.py
你会看到 Agent 通过 MCP 服务器调用 Tavily API 进行搜索,并返回搜索结果。
通过这个例子,我们成功地构建了一个基于 STDIO 的 MCP 服务器,并将其与 LangGraph ReAct Agent 集成。整个过程非常简单,无需复杂的配置和部署。
STDIO MCP 的优势与局限性
优势:
- 简单易用: 无需服务器,无需网络配置,易于上手。
- 轻量级: 资源占用少,适合本地调试和快速原型开发。
- 跨平台: 只要支持标准输入/输出,就可以运行。
- 集成方便: 可以与 LangChain、LangGraph 等 LLM 开发框架无缝集成。
局限性:
- 单客户端: STDIO 模式只能支持一个客户端连接。
- 不适合生产环境: STDIO 模式不适合在高并发、高可用性的生产环境中使用。
从 STDIO 到 HTTP:扩展 MCP 服务器的能力
虽然 STDIO 模式非常适合本地开发,但在实际应用中,我们往往需要构建一个可以远程访问、支持多个客户端的 MCP 服务器。这时,我们可以使用 HTTP 协议来实现 MCP 服务器。
HTTP 模式的 MCP 服务器可以部署在云端,通过网络提供服务。它支持多个客户端同时连接,并且可以实现流式响应,从而提高性能和用户体验。
例如,我们可以使用 FastAPI 构建一个 HTTP MCP 服务器,并使用 Server-Sent Events (SSE) 实现流式响应。具体实现细节可以参考后续的文章。
结论
MCP (Model Context Protocol) 为大模型与外部工具的交互提供了一种标准化的解决方案。通过 STDIO 传输方式,我们可以快速构建 MCP 服务器,无需复杂的配置和部署。这使得开发者可以更加专注于工具本身的开发,而不是底层的通信细节。
然而,STDIO 模式也存在一些局限性,例如只能支持单客户端连接。在实际应用中,我们可以根据具体需求选择合适的传输方式,例如 HTTP。
总而言之,MCP 为大模型带来了无限的可能性。通过与外部工具的结合,大模型可以更好地解决实际问题,并为各行各业带来变革。随着 MCP 标准的不断完善和普及,相信未来会有越来越多的开发者加入到 MCP 的生态中,共同推动大模型技术的发展。