理解MCP

一、MCP是什么?

MCP(Model Context Protocol,模型上下文协议)是由 Anthropic 公司在 2024 年 11 月开源发布的一个开放协议。它的核心作用是让 AI 能够安全、标准化地连接和使用外部工具与数据,以消除碎片化集成、形成生态闭环

二、两种MCP的传输通道
(1)本地通信:Stdio(标准输入/输出)
  • 原理:当 AI 应用(如 VSCode 插件)和 MCP 服务在同一台电脑上时,客户端会直接把 MCP 服务当作一个子进程启动。两者通过操作系统的管道(stdin/stdout)直接"递纸条"沟通。
  • 特点 :完全绕开了网络栈,延迟极低、配置简单,且数据不出本机,安全性高。
  • 适用场景:本地开发调试、命令行工具、桌面 AI 助手(如读取本地文件、操作本地数据库)。
(2) 远程通信:Streamable HTTP(基于 HTTP 的流式传输)
  • 原理:当 AI 应用和 MCP 服务不在同一台机器上(比如云端服务),它们通过 HTTP 协议进行跨网络通信。客户端发送 POST 请求,服务端通过长连接实时推送流式响应。
  • 特点 :支持双向实时交互,天然支持高并发,且易于穿透企业防火墙。
  • 适用场景:SaaS 应用集成、企业级多租户环境、需要实时推送数据的场景(如股票行情、实时监控)。
  • 注:早期的 SSE(Server-Sent Events)传输方式因仅支持单向推送等局限,正逐渐被更强大的 Streamable HTTP 取代。
三、uvx和npx指令对应的环境安装
(1)uvx 的环境安装

a.安装python(版本在3.8以上)

pip install uv

b.未安装python-> 在 Windows 下,打开 PowerShell 执行官方一键安装脚本即可:

powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

(2)npx的环境安装

npx 是 Node.js 的包执行器,从 Node.js v8.2.0 开始就已经内置。

  • 安装方式 :直接前往 Node.js 官网下载并安装 LTS(长期支持)版本(推荐 v18 或 v20+)。
四、天气查询实例

step1:采用uv创建一个虚拟环境

复制代码
uv venv mcp-weather-example

step2:激活虚拟环境

复制代码
mcp-weather-example\Scripts\activate

step3:初始化工程

复制代码
uv init mcp-weather

step4:进入工程,并添加 MCP(Model Context Protocol)依赖包

复制代码
cd .\mcp-weather\
uv add mcp

step5:servers的建立

复制代码
# weather_server.py
from mcp.server.fastmcp import FastMCP
import httpx
from typing import Any
import warnings
warnings.filterwarnings("ignore", category=UserWarning, module="pydantic_settings")

# 1. 创建一个名为 "weather" 的 MCP Server 实例
mcp = FastMCP("weather")

API_KEY = "c1099b122d1b7d7bcd190e3cc3c5e1cb"
BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
USER_AGENT = "weather-app/1.0"

async def fetch_weather(city: str) -> dict[str, Any] | None: 
    params = {
        "q": city,
        "appid": API_KEY,
        "units": "metric",
        "lang": "zh_cn"
    }
    headers = {"User-Agent": USER_AGENT}
    # 使用异步 HTTP 客户端发送请求
    async with httpx.AsyncClient() as client:
        try:
            # 修正了这里的拼写错误:timout -> timeout
            resp = await client.get(BASE_URL, params=params, headers=headers, timeout=30.0)
            resp.raise_for_status()  # 如果状态码不是 200,会抛出异常
            return resp.json()       # 返回字典格式的天气数据
        except Exception:
            return None              # 发生任何错误,返回 None   

def format_weather(data: dict[str, Any] | str) -> str:
    # 1. 容错处理:如果传入的是字符串(比如错误信息),直接返回
    if isinstance(data, str):
        return data
    
    # 2. 从字典中提取关键信息
    try:
        weather_desc = data["weather"][0]["description"]  # 天气状况
        temp = data["main"]["temp"]                       # 温度
        humidity = data["main"]["humidity"]               # 湿度
        city = data["name"]                               # 城市名
        
        # 3. 拼接成自然语言字符串
        return f"{city} 当前天气:{weather_desc},气温 {temp}°C,湿度 {humidity}%"
    except (KeyError, TypeError):
        return "无法解析天气数据,请检查输入格式。" 

@mcp.tool()
async def query_weather(city: str) -> str:
    """查询指定城市的当前天气。"""
    data = await fetch_weather(city)
    if data is None:
        return f"抱歉,无法获取 {city} 的天气信息。"
    return format_weather(data)  

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

step6:建立client

复制代码
import asyncio
import os
import json
from typing import Optional
from contextlib import AsyncExitStack

from openai import OpenAI
from dotenv import load_dotenv

# 修正拼写错误:StdioServerParamters -> StdioServerParameters
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

# 1. 加载 .env 文件中的环境变量
# 这行代码会读取 .env 文件,并将其中的变量加载到系统环境变量中
load_dotenv()

async def main():
    # 2. 初始化阿里云百炼客户端
    # 使用 os.getenv() 从环境变量中获取 API Key
    # 如果找不到变量,会返回 None,OpenAI 库会报错,提醒你检查配置
    client = OpenAI(
        api_key=os.getenv("DASHSCOPE_API_KEY"),
        base_url="compatible-mode/v1"
    )

    # 3. 配置 MCP Server 连接参数
    server_params = StdioServerParameters(
        command="D:\\python.exe",
        args=["e:\\mcp-servers-weather.py"]
    )

    # 4. 建立与 MCP Server 的连接
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()

            # 5. 获取 Server 提供的工具列表,并转换为 OpenAI 格式
            tools_response = await session.list_tools()
            openai_tools = [
                {
                    "type": "function",
                    "function": {
                        "name": tool.name,
                        "description": tool.description,
                        "parameters": tool.inputSchema
                    }
                }
                for tool in tools_response.tools
            ]

            # 6. 发送用户消息给大模型
            messages = [{"role": "user", "content": "Shanghai weather today"}]
            
            response = client.chat.completions.create(
                model="qwen-max",
                messages=messages,
                tools=openai_tools,
                tool_choice="auto"
            )

            # 7. 处理大模型的回复
            message = response.choices[0].message
            
            if message.tool_calls:
                for tool_call in message.tool_calls:
                    if tool_call.function.name == "query_weather":
                        args = json.loads(tool_call.function.arguments)
                        result = await session.call_tool("query_weather", arguments=args)
                        
                        messages.append(message)
                        messages.append({
                            "role": "tool",
                            "tool_call_id": tool_call.id,
                            "content": result.content[0].text
                        })
                
                final_response = client.chat.completions.create(
                    model="qwen-max",
                    messages=messages
                )
                print("AI 最终回复:", final_response.choices[0].message.content)
            else:
                print("AI 回复:", message.content)

if __name__ == "__main__":
    asyncio.run(main())
相关推荐
程序员老刘1 小时前
跨平台开发地图 | 2026年8月
flutter·ai编程·客户端
渔夫正在掘金2 小时前
Cordis 中文教程:渐进式构建插件化应用
前端·node.js·ai编程
阿文和她的Key2 小时前
把 800+ 文件的真实项目交给 XunOPC,它到底能不能真的修 Bug?
agent·ai编程
宋哥转AI2 小时前
深入理解 AI Agent · MEMORY #02:记忆的工程机制
人工智能·agent·ai编程
打呵欠的猫2 小时前
前端团队 3 个月 AI 实践复盘:哪些场景 ROI 最高,哪些是伪需求
前端·ai编程
AI编程实验室2 小时前
Agent Plugins 1.0实战:plugin.json、skills、mcp.json目录结构与迁移
ai编程
oden2 小时前
一个不会游戏开发的人,用 AI 把一款小游戏做到上线了
ai编程·cocos creator·游戏开发
程序员黑豆3 小时前
Java中的null与NullPointerException完全指南:安全处理、实战排查与面试题
java·前端·ai编程
Carson带你学Android3 小时前
Android 版 MCP 正式登场:AppFunctions
android·ai编程·jetbrains