MCP协议的简介和简单实现

​模型上下文协议(Model Context Protocol,简称 MCP)一种开放的、通用的标准化协议, 旨在标准化大型语言模型(LLM)与外部数据源或工具之间的交互方式。

MCP 的本质是为 AI 模型提供统一的交互标准;

MCP 由三个核心组件构成:Host、Client 和 Server。

Host 主机: 大模型的应用程序, 负责接收你的提问并与 大模型交互,比如聊天机器人。

MCP Client 客户端:运行在主机(host)里的客户端,当有需要的时候被激活,与MCP Server 建立连接(客户端和服务器是一对一连接)。

MCP Server 服务器:负责向客户端(MCP Client )提供 资源、提示 和 工具 的服务器。

工作流程:

举个栗子: 问聊天机器人 明天天气怎么样?

① 用户提问:用户通过聊天机器人询问 "明天天气怎么样?"。

②意图解析: 聊天机器人(Host主机)将问题发给大模型,分析可用的工具,并决定用哪一个工具,如查询天气的工具;

③ 工具调用: 聊天机器人(Host主机)使用MCP Client 客户端向MCP Server 服务器发出请求,调用工具

④结果整合: 工具调用的结果送回给大模型, 结合执行结果生成自然语言的回应。

⑤自然语言输出: 最终展示给用户

MCP 协议内置了两种标准传输方式:标准输入/输出(stdio) 和 Server-Sent Events(SSE) 。

stdio 传输通过 标准输入输出流 实现客户端与服务器之间的通信,适用于本地集成与命令行工具。

SSE 传输 通过 HTTP POST 请求实现 客户端到服务器通信,同时支持 服务器到客户端流式传输 。

MCP协议建立在 JSON-RPC 2.0 之上,定义了AI模型与外部工具之间的标准通信规范。

底层传输协议可以是 http/https、WebSocket ,tcp等

使用langchain实现一个简单的demo
stdio类型

mcp_server_stdio.py

(程序不需要启动)

复制代码
from fastmcp import FastMCP

mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> str:
    """Add two numbers"""
    return str(a + b)

@mcp.tool()
def multiply(a: int, b: int) -> str:
    """Multiply two numbers"""
    return str(a * b)

if __name__ == "__main__":
    mcp.run(transport="stdio")

sse类型

mcp_server_sse.py , 这个需要启动

复制代码
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Weather")

@mcp.tool()
async def get_weather(location: str) -> str:
    """Get weather for location."""
    print(f"Getting weather for {location}")
    return "It's always sunny in New York"

if __name__ == "__main__":
    mcp.run(transport="streamable-http")

客户端

mcp_client.py

偶尔可能因为网络不好, 启动时注册阿里mcp会导致失败, 重新启动一下

复制代码
import asyncio
from typing import List
from langchain_mcp_adapters.client import MultiServerMCPClient  
from langchain.agents import create_agent,AgentState
from langchain_core.messages import AIMessage,ToolMessage
from langchain_openai import ChatOpenAI

QWEN_OPENAI_API_BASE = "https://dashscope.aliyuncs.com/compatible-mode/v1" #OPENAI API  
QWEN_API_KEY = "sk-*************************************"  
QWEN_MODEL = "qwen-plus"

# 设置DeepSeek API Key和基础地址
llm = ChatOpenAI(
    model=QWEN_MODEL,
    openai_api_key=QWEN_API_KEY,
    openai_api_base=QWEN_OPENAI_API_BASE,  # 关键配置
    temperature=0.7,
)

from langchain.agents.middleware import after_model,before_model,before_agent,after_agent,wrap_tool_call
from langchain.tools import tool, ToolRuntime
from langgraph.runtime import Runtime


#  这里是因为返回的ToolMessage中content类型是List, 而langchain中需要的是str类型
@before_model
async def before_model_messages(state: AgentState, runtime: Runtime) -> dict | None:
    """Remove old messages to keep conversation manageable."""
    message_list = state["messages"]
    for message in message_list:
         if isinstance(message, ToolMessage):
             if type( message.content) is not str:
                message.content = str(message.content)
    return {"messages": message_list}

async def main():
    client = MultiServerMCPClient(  
        {
            "mcp_sever_stdio": {
                "transport": "stdio",  
                "command": "python",
                # Absolute path to your math_server.py file
                "args": ["D:/MyWork/demo/mcp_server_stdio.py"],
            },
            "mcp_sever_http": {
                "transport": "streamable_http",  # 就是启动后的 mcp_server_sse.py
                # Ensure you start your weather server on port 8000
                "url": "http://localhost:8000/mcp",
            },
             "ali_news_mcp": {  #阿里云百炼_联网搜索
                 "transport":"sse",   # 根据实际填写   stdio/sse/streamable_http/ 也可能有http
                "url": "https://dashscope.aliyuncs.com/api/v1/mcps/WebSearch/sse",
                "headers": {"Authorization": "Bearer sk-*************************************""}
             },
            "ali_logistics_mcp": {  #阿里MCP服务 阿里云百炼_全国快递物流查询
                "transport":"streamable_http",   # 根据实际填写   stdio/sse/streamable_http/ 也可能有http
                "url": "https://dashscope.aliyuncs.com/api/v1/mcps/market-cmapi021863/mcp",
                "headers": {"Authorization": "Bearer sk-*************************************""}
             }
  }
    )


    mcp_tools = await client.get_tools()
   # print(mcp_tools)  
    agent = create_agent(
        model=llm,
        tools = mcp_tools,
        middleware=[before_model_messages],
        debug= True,
    )
    math_response = await agent.ainvoke({"messages": [{"role": "user", "content": "what's (3 + 5) x 12?"}]})
    print("\n math response:", math_response)
    print("\n math response:", math_response["messages"][-1].content)

    weather_response = await agent.ainvoke({"messages": "what is the weather in nyc?"})
    print("\n Weather response:", weather_response)
    print("\n Weather response:", weather_response["messages"][-1].content)


    hz_response = await agent.ainvoke({"messages": "查询一下杭州今日天气"})
    print("\n hz_response response:", hz_response)
    print("\n hz_response response:", hz_response["messages"][-1].content)

    
    logistics_response = await agent.ainvoke({"messages": "查询一快递 434*********"})
    print("\n logistics_response response:", logistics_response)
    print("\n logistics_response response:", logistics_response["messages"][-1].content)

if __name__ == "__main__":
    asyncio.run(main())

相关包版本

复制代码
python 3.12
mcp>=1.24.0
fastmcp>=2.14.1
langchain>=1.0.7
langchain-mcp-adapters>=0.2.1
相关推荐
Luminbox紫创测控1 分钟前
车载LiDAR强光测试的实验设计方法与数据分析
人工智能·数据挖掘·数据分析·车载系统·安全性测试·太阳光模拟器
建筑工程企业管理系统1 小时前
工程进度统计管理系统自动化汇总数据,解决施工企业手工对账误差难题
大数据·人工智能·自动化
唠点键盘之外的1 小时前
27 存量系统接大模型:旁挂一个 AI 微服务,老架构一行不改
人工智能·微服务·架构
kaixin_啊啊2 小时前
【用于更准确 G×E 基因组预测的大规模作物数据集与基于深度学习的多模态融合框架】论文学习
人工智能·深度学习·学习
GOWIN革文品牌咨询2 小时前
工业测量品牌系统化搭建指南:从内容架构到长期治理的全流程
大数据·人工智能·架构
OnlineProxy2 小时前
为 LangChain 和 CrewAI 构建自定义工具:将代理 IP 轮换封装至智能体函数中
网络协议·tcp/ip·langchain
拿本唠嗑AI研究2 小时前
本体工程实战指南:从建模到可维护的完整落地路径
java·人工智能·python·jena·ontology
deepseek232 小时前
AI 模型隐藏任意能力拆解:把加密神经网络塞进宿主权重,能力评估为什么在密码学上抓不到
人工智能·深度学习·神经网络·密码学·模型安全
揽秀亭长2 小时前
从音频到五线谱,自动扒谱的完整技术流程
人工智能
Smoothcloud润云2 小时前
PyTorch推理服务模型热切换与失败回滚实战:降低版本更新中断
服务器·人工智能·pytorch·python·深度学习·gpu