MCP 协议 简单理解 与Python 简单实战

MCP 是什么?

MCP 可以简单理解为一种工具调用协议,用于客户端与服务器之间的通信。

  1. MCP 客户端与 MCP 服务器建立连接后,客户端可以获取服务器端所有可用的工具信息。

  2. 假设存在 AI,AI 就可以根据工具信息,生成对应的参数并进行调用。

如何使用 Python 进行 MCP 开发

1. 初始化项目

推荐使用 nv 初始化项目:

uv init mcp-server-demo
cd mcp-server-demo

uv add "mcp[cli]"

pip install "mcp[cli]"
uv run mcp

MCP 服务器代码示例

from mcp.server.fastmcp import FastMCP

# 创建MCP服务器
mcp = FastMCP("简单MCP服务器")

# 添加计算工具
@mcp.tool()
def calculate(expression: str) -> str:
    """计算数学表达式

    Args:
        expression: 要计算的数学表达式

    Returns:
        计算结果
    """
    try:
        result = eval(expression)
        return f"计算结果: {result}"
    except Exception as e:
        return f"计算错误: {str(e)}"

# 添加问候工具
@mcp.tool()
def greet(name: str) -> str:
    """返回问候语

    Args:
        name: 用户名

    Returns:
        问候语
    """
    return f"你好,{name}!很高兴认识你。"

# 添加动态问候资源
@mcp.resource("greeting://{name}")
def get_greeting(name: str) -> str:
    """获取个性化问候

    Args:
        name: 用户名

    Returns:
        个性化问候语
    """
    return f"你好,{name}!欢迎使用MCP服务器。"

# 运行服务器
if __name__ == "__main__":
    mcp.run(transport="stdio")  # 使用stdio传输方式运行服务器

MCP 客户端代码示例

from mcp import ClientSession, StdioServerParameters, types
from mcp.client.stdio import stdio_client

# 创建用于stdio连接的服务器参数
server_params = StdioServerParameters(
    command="python",  # 使用python解释器
    args=["server.py"],  # 运行server.py脚本作为MCP服务器
    env=None,  # 不设置额外的环境变量
)

# 创建采样回调函数,用于模拟LLM响应
async def handle_sampling_message(message: types.CreateMessageRequestParams) -> types.CreateMessageResult:
    return types.CreateMessageResult(
        role="assistant",  # 角色是assistant
        content=types.TextContent(
            type="text",  # 内容类型为文本
            text="Hello, world! from model",  # 固定的响应文本
        ),
        model="gpt-3.5-turbo",  # 模拟使用的模型名称
        stopReason="endTurn",  # 停止原因是"endTurn"
    )

# 主异步函数
async def run():
    # 使用stdio_client创建与MCP服务器的连接
    async with stdio_client(server_params) as (read, write):
        # 创建一个ClientSession对象来管理与服务器的会话
        async with ClientSession(read, write, sampling_callback=handle_sampling_message) as session:
            await session.initialize()  # 初始化连接

            # 列出服务器提供的所有可用工具
            tools = await session.list_tools()
            print(f"可用工具: {tools}")

            # 调用名为"add"的工具
            result = await session.call_tool("add", arguments={"a": 5, "b": 3})
            print(f"5 + 3 = {result}")

            # 读取"greeting://World"资源
            content, mime_type = await session.read_resource("greeting://World")
            print(f"问候内容: {content}")

if __name__ == "__main__":
    import asyncio
    asyncio.run(run())  # 运行主异步函数

Langchain MCP 使用的mcp服务

from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
import asyncio
from langchain_deepseek import ChatDeepSeek


deepseek_client = ChatDeepSeek(
    api_key="deepseek-key",
    model="deepseek-chat",
    base_url="https://api.deepseek.com/v1",
)

async def main():
    async with MultiServerMCPClient(
        {
            "math": {
                "command": "python",
                # Replace with absolute path to your math_server.py file
                "args": ["server.py"],
                "transport": "stdio",
            },
            "weather": {
                # 使用URL形式的MCP服务器
                "url": "https://server.smithery.ai/@mcp-examples/weather/mcp?api_key=edd2f6f5af0c",
                "transport": "sse",  # MultiServerMCPClient只支持'stdio'和'sse'两种传输方式
            }
        }
    ) as client:
        agent = create_react_agent(
            deepseek_client,
            client.get_tools()
        )
        # 测试本地math服务
        math_response = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "what's 3 + 5?"}]}
        )
        print("Math response:", math_response)
        
        # 测试远程weather服务
        weather_response = await agent.ainvoke(
            {"messages": [{"role": "user", "content": "what is the weather in Beijing?"}]}
        )
        print("Weather response:", weather_response)

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

你可能感兴趣的:(python,github,开发语言)