Mcp是个啥

什么是 MCP

Model Context Protocol (MCP) 是一个开放协议,它使 LLM 应用与外部数据源和工具之间的无缝集成成为可能。无论你是构建 AI 驱动的 IDE、改善 chat 交互,还是构建自定义的 AI 工作流,MCP 提供了一种标准化的方式,将 LLM 与它们所需的上下文连接起来。

目前,MCP 已经积累了足够的临界规模和动能,因此它被视为 2023-2025 年“代理开放标准”之争的潜在赢家。有人预计,按照当前的速度,MCP 将在 7 月超OpenAPI:

在这里插入图片描述

MCP 如何工作

通用架构

MCP 的核心是一个 client-server 架构,host 应用程序可以连接到多个服务器:
在这里插入图片描述

MCP Hosts: 像 Claude Desktop、IDEs 或 AI 工具这样的程序,它们希望通过 MCP 访问资源MCP Clients: 维护与服务器 1:1 连接的协议客户端MCP Servers: 轻量级程序,通过标准化的 Model Context Protocol 暴露特定功能Local Resources: 你的计算机资源(数据库、文件、服务),MCP 服务器可以安全地访问这些资源Remote Resources: 通过互联网可用的资源(例如,通过 APIs),MCP 服务器可以连接到这些资源
在这里插入图片描述

MCP 客户端

MCP客户端是模型上下文协议(MCP)架构中的核心组件,负责建立和管理与MCP服务器的连接。它实现了协议的客户端部分,处理以下功能:

协议版本协商以确保与服务器的兼容性能力协商以确定可用功能消息传输和JSON-RPC通信工具发现和执行资源访问和管理提示系统交互可选功能如根目录管理和采样支持
MCP client 的工作流程如下:

MCP client 首先从 MCP server 获取可用的工具列表。将用户的查询连同工具描述通过 function calling 一起发送给 LLM。LLM 决定是否需要使用工具以及使用哪些工具。如果需要使用工具,MCP client 会通过 MCP server 执行相应的工具调用。工具调用的结果会被发送回 LLM。LLM 基于所有信息生成自然语言响应。最后将响应展示给用户。

MCP 服务端

MCP服务器是模型上下文协议(MCP)架构中的基础组件,为客户端提供工具、资源和功能。它实现了协议的服务器端,负责:

暴露客户端可以发现和执行的工具管理基于URI的资源访问模式提供提示模板并处理提示请求支持与客户端的能力协商实现服务器端协议操作管理并发客户端连接提供结构化日志和通知

上手实战

SQLite 实现一个集中示例

在这里插入图片描述

Claude Desktop 作为我们的 MCP 客户端一个 SQLite MCP 服务器提供安全的数据库访问你的本地 SQLite 数据库存储实际数据
SQLite MCP 服务器和你的本地 SQLite 数据库之间的通信完全发生在你的机器上 — 你的 SQLite 数据库不会暴露在互联网上。Model Context Protocol 确保 Claude Desktop 只能通过定义良好的接口执行批准的数据库作。这为你提供了一种安全的方式,让 Claude 分析和交互你的本地数据,同时完全控制它可以访问的内容。

前提条件

  • macOS 或 Windows
  • 安装最新版本的 Claude Desktop
  • UV 0.4.18 或更高版本( 检查)uv --version
  • Git( 检查)git --version
  • SQLite( 检查)sqlite3 --version

例如安装(Windows):

# 使用 winget
winget install --id=astral-sh.uv -e
winget install git.git sqlite.sqlite

# 或直接下载:
# uv: https://docs.astral.sh/uv/  下载解压后, 将ux.exe所在目录配置到环境变量
# Git: https://git-scm.com
# SQLite: https://www.sqlite.org/download.html

检查uv是否安装成功
在这里插入图片描述

  1. 安装
    创建一个简单Windows的 SQLite 数据库进行测试:
# 创建一个新的 SQLite 数据库
$sql = @'
CREATE TABLE products (
  id INTEGER PRIMARY KEY,
  name TEXT,
  price REAL
);

INSERT INTO products (name, price) VALUES
  ('Widget', 19.99),
  ('Gadget', 29.99),
  ('Gizmo', 39.99),
  ('Smart Watch', 199.99),
  ('Wireless Earbuds', 89.99),
  ('Portable Charger', 24.99),
  ('Bluetooth Speaker', 79.99),
  ('Phone Stand', 15.99),
  ('Laptop Sleeve', 34.99),
  ('Mini Drone', 299.99),
  ('LED Desk Lamp', 45.99),
  ('Keyboard', 129.99),
  ('Mouse Pad', 12.99),
  ('USB Hub', 49.99),
  ('Webcam', 69.99),
  ('Screen Protector', 9.99),
  ('Travel Adapter', 27.99),
  ('Gaming Headset', 159.99),
  ('Fitness Tracker', 119.99),
  ('Portable SSD', 179.99);
'@

cd ~
& sqlite3 test.db $sql

打开powerSheel, 输入以上代码
在这里插入图片描述

  1. 下载并配置 Claude Desktop
    遗憾的是国内目前无法安装Claude Desktop,假如你可以,那么继续
    在文本编辑器中打开 中的 Claude Desktop 应用配置。%APPDATA%\Claude\claude_desktop_config.json

例如,如果你安装了 VS Code:

code $env:AppData\Claude\claude_desktop_config.json\

添加以下配置(将 YOUR_USERNAME 替换为你的实际用户名):

{
  "mcpServers": {
    "sqlite": {
      "command": "uvx",
      "args": [
        "mcp-server-sqlite",
        "--db-path",
        "C:\\Users\\YOUR_USERNAME\\test.db"
      ]
    }
  }
}

这告诉 Claude Desktop:

  • 有一个名为 “sqlite” 的 MCP 服务器
  • 通过运行 启动它uvx mcp-server-sqlite
  • 将其连接到你的测试数据库 保存文件,并重新启动 Claude Desktop。
  1. 测试
    问题:
你能连接到我的 SQLite 数据库并告诉我有哪些产品及其价格吗?

Claude Desktop 将会:

连接到 SQLite MCP 服务器查询你的本地数据库格式化并展示结果
在这里插入图片描述

原理解析
背后发生了什么?

当你使用 MCP 与 Claude Desktop 交互时:

  • 服务器发现:Claude Desktop 在启动时连接到你配置的 MCP 服务器
  • 协议握手:当你询问数据时,Claude Desktop:

确定哪个 MCP 服务器可以提供帮助(在本例中是 sqlite)
通过协议协商能力
从 MCP 服务器请求数据或作

  • 交互流程:
    在这里插入图片描述

  • 安全性:

MCP 服务器仅暴露特定、受控的功能
MCP 服务器在你的机器上本地运行,它们访问的资源不会暴露在互联网上
Claude Desktop 需要用户确认以进行敏感作

Python 创建一个简单的 MCP 服务器

先决条件
您需要 Python 3.10 或更高版本:

python --version # Should be 3.10 or higher

通过 homebrew 安装 uv

brew install uv
 uv --version # Should be 0.4.18 or higher 
 有关更多信息,请参阅 https://docs.astral.sh/uv/

使用 MCP 项目创建器创建新项目

uvx create-mcp-server --path weather_service cd weather_service

安装其他依赖项

uv add httpx python-dotenv

设置环境

OPENWEATHER_API_KEY=your-api-key-here #创造:.env

创建您的服务器
添加基本导入和设置
在weather_service/src/weather_service/server.py

 import os
import json
import logging
from datetime import datetime, timedelta
from collections.abc import Sequence
from functools import lru_cache
from typing import Any

import httpx
import asyncio
from dotenv import load_dotenv
from mcp.server import Server
from mcp.types import (
    Resource,
    Tool,
    TextContent,
    ImageContent,
    EmbeddedResource,
    LoggingLevel
)
from pydantic import AnyUrl

# Load environment variables
load_dotenv()

# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("weather-server")

# API configuration
API_KEY = os.getenv("OPENWEATHER_API_KEY")
if not API_KEY:
    raise ValueError("OPENWEATHER_API_KEY environment variable required")

API_BASE_URL = "http://api.openweathermap.org/data/2.5"
DEFAULT_CITY = "London"
CURRENT_WEATHER_ENDPOINT = "weather"
FORECAST_ENDPOINT = "forecast"

# The rest of our server implementation will go here

添加天气获取功能

 # Create reusable params
http_params = {
    "appid": API_KEY,
    "units": "metric"
}

async def fetch_weather(city: str) -> dict[str, Any]:
    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"{API_BASE_URL}/weather",
            params={"q": city, **http_params}
        )
        response.raise_for_status()
        data = response.json()

    return {
        "temperature": data["main"]["temp"],
        "conditions": data["weather"][0]["description"],
        "humidity": data["main"]["humidity"],
        "wind_speed": data["wind"]["speed"],
        "timestamp": datetime.now().isoformat()
    }


app = Server("weather-server")

实现资源处理程序
将这些与资源相关的处理程序添加到我们的 main 函数中:

 app = Server("weather-server")

@app.list_resources()
async def list_resources() -> list[Resource]:
    """List available weather resources."""
    uri = AnyUrl(f"weather://{DEFAULT_CITY}/current")
    return [
        Resource(
            uri=uri,
            name=f"Current weather in {DEFAULT_CITY}",
            mimeType="application/json",
            description="Real-time weather data"
        )
    ]

@app.read_resource()
async def read_resource(uri: AnyUrl) -> str:
    """Read current weather data for a city."""
    city = DEFAULT_CITY
    if str(uri).startswith("weather://") and str(uri).endswith("/current"):
        city = str(uri).split("/")[-2]
    else:
        raise ValueError(f"Unknown resource: {uri}")

    try:
        weather_data = await fetch_weather(city)
        return json.dumps(weather_data, indent=2)
    except httpx.HTTPError as e:
        raise RuntimeError(f"Weather API error: {str(e)}")

实施工具处理程序
添加以下与工具相关的处理程序:

 app = Server("weather-server")


# Resource implementation ...

@app.list_tools()
async def list_tools() -> list[Tool]:
    """List available weather tools."""
    return [
        Tool(
            name="get_forecast",
            description="Get weather forecast for a city",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "City name"
                    },
                    "days": {
                        "type": "number",
                        "description": "Number of days (1-5)",
                        "minimum": 1,
                        "maximum": 5
                    }
                },
                "required": ["city"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: Any) -> Sequence[TextContent | ImageContent | EmbeddedResource]:
    """Handle tool calls for weather forecasts."""
    if name != "get_forecast":
        raise ValueError(f"Unknown tool: {name}")

    if not isinstance(arguments, dict) or "city" not in arguments:
        raise ValueError("Invalid forecast arguments")

    city = arguments["city"]
    days = min(int(arguments.get("days", 3)), 5)

    try:
        async with httpx.AsyncClient() as client:
            response = await client.get(
                f"{API_BASE_URL}/{FORECAST_ENDPOINT}",
                params={
                    "q": city,
                    "cnt": days * 8,  # API returns 3-hour intervals
                    **http_params,
                }
            )
            response.raise_for_status()
            data = response.json()

        forecasts = []
        for i in range(0, len(data["list"]), 8):
            day_data = data["list"][i]
            forecasts.append({
                "date": day_data["dt_txt"].split()[0],
                "temperature": day_data["main"]["temp"],
                "conditions": day_data["weather"][0]["description"]
            })

        return [
            TextContent(
                type="text",
                text=json.dumps(forecasts, indent=2)
            )
        ]
    except httpx.HTTPError as e:
        logger.error(f"Weather API error: {str(e)}")
        raise RuntimeError(f"Weather API error: {str(e)}")

添加 main 函数
将此添加到 的末尾:weather_service/src/weather_service/server.py

 async def main():
    # Import here to avoid issues with event loops
    from mcp.server.stdio import stdio_server

    async with stdio_server() as (read_stream, write_stream):
        await app.run(
            read_stream,
            write_stream,
            app.create_initialization_options()
        )```

在 init.py 中检查您的切入点
将此添加到 的末尾:weather_service/src/weather_service/init.py
from . import server

import asyncio

def main():
   """Main entry point for the package."""
   asyncio.run(server.main())

# Optionally expose other important items at package level
__all__ = ['main', 'server']
 

连接到 Claude Desktop

更新 Claude 配置
搭:claude_desktop_config.json

 {
  "mcpServers": {
    "weather": {
      "command": "uv",
      "args": [
        "--directory",
        "path/to/your/project",
        "run",
        "weather-service"
      ],
      "env": {
        "OPENWEATHER_API_KEY": "your-api-key"
      }
    }
  }
}

重启 Claude

彻底退出 Claude
再次启动 Claude
在🔌菜单中查找您的天气服务器

测试
问天气:

What’s the current weather in San Francisco? Can you analyze the conditions and tell me if it’s a good day for outdoor activities?

比较天气

Can you analyze the forecast for both Tokyo and San Francisco and tell me which city would be better for outdoor photography this week?

总结

寻找国内Claude Desktop平替, 实现mcp强大的ai扩展能力

<think>好的,我现在需要回答用户关于MCP协议的定义、功能和介绍的问题。首先,我需要查看用户提供的引用资料,看看里面有哪些相关的信息。 根据引用[1],MCP是Model Context Protocol的缩写,使用基于能力的协商系统,客户端和服务器在初始化时声明支持的功能。这说明MCP协议的核心在于能力协商,确定可用的协议功能和原语。 引用[2]提到MCP协议与JSON-RPC 2.0相关,可能涉及通信方式,但具体细节需要进一步确认。 引用[3]和[4]提供了更全面的架构信息,包括MCP协议的目标是解决数据孤岛问题,促进AI模型间的协作。架构上分为客户端、服务器、协议层和数据层,优势包括开放性、兼容性、安全性等。 引用[5]指出MCP通过MCPServer扩展能力,类似于插件机制,但受限于服务器数量。 接下来,我需要整理这些信息,分点回答定义、核心功能和架构。需要注意使用正确的LaTeX格式,比如协议名称用$MCP$,但根据用户示例,可能不需要变量符号,直接使用MCP即可。需要检查是否有数学表达式,但当前内容可能不涉及,所以主要关注结构和引用。 用户还要求生成相关问题,我需要根据内容提出关于架构、应用场景、优缺点、选择标准等的问题。最后,确保引用正确,每个引用标识对应正确的内容,并且自然添加在段落末尾。</think>### MCP协议介绍 #### 一、定义与背景 **MCP(Model Context Protocol)** 是一种面向AI模型协作的上下文协议,旨在解决AI领域的数据孤岛问题,促进不同模型、平台间的数据流通与任务协同。其核心是通过标准化接口实现模型能力的动态协商与上下文共享[^4][^1]。 #### 二、核心功能 1. **能力协商机制** 采用基于$Capabilities$的声明系统,客户端与服务器在初始化阶段明确声明支持的功能,如自然语言处理、图像识别等,协议层根据协商结果动态启用对应功能[^1]。 2. **分层架构** $$ \text{架构层} = \begin{cases} \text{客户端:发起请求的AI模型/服务} \\ \text{服务器:提供数据与功能的MCPServer节点} \\ \text{协议层:处理通信与能力协商} \\ \text{数据层:统一格式的上下文存储} \end{cases} $$ [^4] 3. **插件式扩展** 通过添加MCPServer节点扩展协议能力,每个节点相当于一个功能插件(如接入数据库、专业计算模块等),但整体能力受节点数量限制[^5]。 #### 三、关键特性 - **跨平台集成**:支持不同框架(TensorFlow/PyTorch)模型互操作 - **动态上下文管理**:会话期间保持共享上下文状态 - **安全隔离**:通过沙箱机制控制数据访问权限[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赤胜骄阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值