AI 也要装插件?带你 3 分钟玩懂 MCP 协议(附 Python 版实现)

前言

为什么别人的大模型能随手调试代码、发邮件、接入内部 API 查报表、甚至生成 3D 模型;而你的大模型,却只能聊天?问它能不能查文件、查数据,总是回答“我做不到”?其实差距不在模型,而在于有没有一座桥,让模型接入更多工具。

这座桥,就是 MCP(Model Context Protocol)

MCP 协议介绍

MCP 协议 中有两个角色,工具实现端(MCP Server)跟工具调用端(MCP Client),他们之间通过 JSON-RPC 协议 来进行交互。

用户通过聊天客户端跟大模型交互时,大模型会发送特定格式的 tool_call 指令,聊天客户端(MCP Client)接收到这个指令后,会按照对应的参数去请求 MCP Server,然后将执行结果反馈给大模型,最后由大模型整合,以聊天的形式返回给用户。

MCP 协议调用流程

用户 云端 LLM (ChatGPT/Claude) MCP Client (桌面端) MCP Server (本地工具) 用户发送问题 输出 tool_call 信号 (方法 + 参数) JSON-RPC 请求 (调用 MCP 方法) JSON-RPC 响应 (返回结果) 注入结果 (作为工具调用返回) 结合结果生成最终回答 用户 云端 LLM (ChatGPT/Claude) MCP Client (桌面端) MCP Server (本地工具)

什么是 JSON-RPC 协议?跟传统的 API 调用有什么区别?

JSON-RPC 主要是定义了消息体结构,没有规定具体的传输方式,支持 WebSocketHTTPSTDIO(标准输入输出) 等形式传输。API 请求则是基于 URL 跟动作(GET、POST),来定义的资源获取方式。

JSON-RPC 2.0 规范

// 基本形式
{
  "jsonrpc": "2.0",         // 固定写 "2.0"
  "method": "subtract",     // 要调用的接口名
  "params": [42, 23],       // 参数,可用数组或对象
  "id": 1                   // 调用 ID
}

MCP Server 的简单实现(Python 形式)

安装uv 工具

uv(astral‑sh/uv)是一个由 Astral 团队开发、使用 Rust 编写的下一代 Python 包与项目管理工具,目标成为 pip、pipx、poetry、virtualenv、pyenv 等工具的升级合并替代品。

# 使用 PowerShell 管理员 模式运行
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
# 查看 uv 版本
uv --version

初始化 mcp 项目

# 项目初始化
uv init py-mcp
cd py-mcp

# 添加 MCP 工具依赖(新建 .venv 与锁文件)
uv add "mcp[cli]"

# 开发过程中启动 server
uv run python main.py


# 测试时安装额外工具作为 dev 依赖
uv add --dev pytest httpx
# 同步 lock 文件
uv sync
# 构建发行包(可选)
uv build

uv 生成的目录结构解析

uv 项目目录结构

文件 / 目录用途
.venv/项目独立虚拟环境
.gitignore忽略虚拟环境、锁文件等不需提交的内容
.python-version指定 Python 版本(用于自动创建 .venv
main.py默认入口脚本(项目执行入口)
pyproject.toml配置项目元信息、依赖、脚本命令等
README.md项目说明文档
uv.lock锁定依赖版本,保证环境可重现
src/ + __init__.py(可选)用于构建 Python 包/库的源码入口(packaged layout)

编写工具逻辑

修改 main.py,实现 D盘文件查看器 工具逻辑。

import os
from mcp.server.fastmcp import FastMCP

# 创建FastMCP服务器实例
mcp = FastMCP("D盘目录浏览器")

@mcp.tool()
def list_d_drive(path: str = "") -> str:
    """列出D盘指定目录的内容
    
    Args:
        path: 要查看的目录路径(相对于D盘根目录),默认为根目录
    
    Returns:
        目录内容的格式化字符串
    """
    try:
        # 构建完整的D盘路径
        if path:
            full_path = os.path.join("D:\\", path)
        else:
            full_path = "D:\\"
        
        # 检查路径是否存在
        if not os.path.exists(full_path):
            return f"❌ 错误:路径 '{full_path}' 不存在"
        
        # 检查是否为目录
        if not os.path.isdir(full_path):
            return f"❌ 错误:'{full_path}' 不是一个目录"
        
        # 列出目录内容
        try:
            items = os.listdir(full_path)
            items.sort()  # 按字母顺序排序
            
            if not items:
                return f"📂 目录 '{full_path}' 为空"
            
            result = f"📂 目录 '{full_path}' 的内容:\n\n"
            
            for item in items:
                item_path = os.path.join(full_path, item)
                if os.path.isdir(item_path):
                    result += f"📁 {item}/\n"
                else:
                    # 获取文件大小
                    try:
                        size = os.path.getsize(item_path)
                        if size < 1024:
                            size_str = f"{size} B"
                        elif size < 1024 * 1024:
                            size_str = f"{size / 1024:.1f} KB"
                        elif size < 1024 * 1024 * 1024:
                            size_str = f"{size / (1024 * 1024):.1f} MB"
                        else:
                            size_str = f"{size / (1024 * 1024 * 1024):.1f} GB"
                        result += f"📄 {item} ({size_str})\n"
                    except OSError:
                        result += f"📄 {item} (无法获取大小)\n"
            
            return result
            
        except PermissionError:
            return f"🔒 错误:没有权限访问目录 '{full_path}'"
        except Exception as e:
            return f"❌ 错误:读取目录时发生异常 - {str(e)}"
            
    except Exception as e:
        return f"❌ 工具执行错误:{str(e)}"

@mcp.tool()
def get_file_info(path: str) -> str:
    """获取D盘指定文件或目录的详细信息
    
    Args:
        path: 文件或目录的路径(相对于D盘根目录)
    
    Returns:
        文件或目录的详细信息
    """
    try:
        # 构建完整的D盘路径
        full_path = os.path.join("D:\\", path) if path else "D:\\"
        
        # 检查路径是否存在
        if not os.path.exists(full_path):
            return f"❌ 错误:路径 '{full_path}' 不存在"
        
        import stat
        import time
        
        # 获取文件状态
        file_stat = os.stat(full_path)
        
        # 格式化时间
        modified_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(file_stat.st_mtime))
        created_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(file_stat.st_ctime))
        
        if os.path.isdir(full_path):
            # 目录信息
            try:
                item_count = len(os.listdir(full_path))
                return f"""📁 目录信息:{full_path}
📊 包含项目:{item_count} 个
📅 修改时间:{modified_time}
📅 创建时间:{created_time}
🔑 权限:{stat.filemode(file_stat.st_mode)}"""
            except PermissionError:
                return f"""📁 目录信息:{full_path}
🔒 无法访问目录内容(权限不足)
📅 修改时间:{modified_time}
📅 创建时间:{created_time}
🔑 权限:{stat.filemode(file_stat.st_mode)}"""
        else:
            # 文件信息
            size = file_stat.st_size
            if size < 1024:
                size_str = f"{size} B"
            elif size < 1024 * 1024:
                size_str = f"{size / 1024:.1f} KB"
            elif size < 1024 * 1024 * 1024:
                size_str = f"{size / (1024 * 1024):.1f} MB"
            else:
                size_str = f"{size / (1024 * 1024 * 1024):.1f} GB"
            
            return f"""📄 文件信息:{full_path}
📏 文件大小:{size_str}
📅 修改时间:{modified_time}
📅 创建时间:{created_time}
🔑 权限:{stat.filemode(file_stat.st_mode)}"""
            
    except Exception as e:
        return f"❌ 获取文件信息时发生错误:{str(e)}"

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

使用 CherryStudio 引入自定义 MCP 服务器

mcp服务器引入
配置好 MCP Server 之后,在聊天框下方启用 MCP 功能,然后直接对话即可,AI 会自动调用服务。

mcp调用

总结

自定义的 MCP Server 可以让模型直接调用我们已有的功能逻辑,让 AI 参与到我们的工作流中,而不是仅限于聊天。它可以实现:

  • 访问你的数据库、文件系统,按自然语言做查询或汇总
  • 封装公司内部 API 或脚本,让模型能自动执行业务操作
  • 连接外部服务(邮件、GitHub、Slack 等),做自动化通知、拉取数据、创建任务
  • 把重复的本地流程(文件整理、日志分析、定时任务)交给模型一键处理

学会使用 MCP 协议,发挥想象,让 AI 发挥更大的作用!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值