云计算百科
云计算领域专业知识百科平台

MCP 实战系列(Day 2)- 动手搓个文件系统 MCP 服务器

上期回顾:MCP 实战系列(Day 1)- 什么是 MCP?

在上期文章中,我们详细介绍了 Model Context Protocol(MCP)的基本概念和应用场景。本节将带领大家开发一个简易的 Filesystem MCP Server,通过代码示例逐步讲解实现细节。

本期目标:掌握 MCP Server 开发的基础框架,实现一个支持基本文件系统操作的服务器。

开源地址:https://github.com/jinzcdev/mcp-demos

请添加图片描述

开发环境准备

官方提供了 Python、Node、Java、Kotlin、C# 五种语言的 MCP 服务器 SDK。本文以 Python 为例进行开发,其他语言的实现方式类似。读者可根据实际项目需求选择熟悉的开发语言。

MacOS/Linux 系统

  • 安装 uv 工具
  • curl -LsSf https://astral.sh/uv/install.sh | sh

  • 创建项目目录并安装依赖
  • # 创建项目目录并进入
    uv init simple-filesystem-server-python
    cd simple-filesystem-server-python

    # 创建虚拟环境并激活
    uv venv
    source .venv/bin/activate

    # 安装 MCP 相关依赖
    uv add "mcp[cli]"

    # 创建 MCP Server 文件
    touch simple_filesystem.py

    说明:uv 是一个高效的 Python 包管理工具,功能类似 pip。如果更熟悉 pip,也可以使用 pip install "mcp[cli]" 安装依赖或创建虚拟环境。mcp[cli] 中的 cli 表示额外安装 typer 和 python-dotenv 两个库,前者用于创建命令行界面,后者用于加载环境变量(可通过查看 mcp 依赖库源代码中的 project.optional-dependencies 配置项找到这两个额外依赖)。最后创建的 simple_filesystem.py 文件是定义 MCP 服务的核心源文件,我们将在其中创建相关工具。

    编写 MCP Server 代码

    我们将实现一个简易的 Filesystem MCP Server,支持在指定目录中进行文件查找、读写等操作。

    值得一提的是,Claude 官方已经提供了一个功能完备的 Node.js 版本 Filesystem MCP Server,包含了丰富的文件系统操作工具。本文选择使用 Python 重新实现,目的是帮助读者更清晰地理解 MCP Server 的 开发流程 和 工具设计思路,而非重复造轮子。

    接下来,让我们逐步实现这个服务器。

    1. 导入必要模块并初始化服务器

    完成前面的准备步骤后,我们首先在 simple_filesystem.py 中导入所需模块,并通过命令行参数指定允许访问的目录:

    from mcp.server.fastmcp import FastMCP
    import os
    import os.path as osp
    import argparse

    parser = argparse.ArgumentParser(description="Simple Filesystem MCP Server")
    parser.add_argument("allowed_dirs", nargs="+", help="List of allowed directories for file operations")
    args = parser.parse_args()

    allowed_directories = [osp.abspath(dir_path) for dir_path in args.allowed_dirs]

    mcp = FastMCP("SimpleFileSystemMCPServer", log_level="ERROR")

    说明:使用 argparse 解析命令行参数,在 MCP 服务启动时指定可访问的目录(防止 LLM 访问系统中的任意目录)。这里 FastMCP 初始化了一个名为 Simple Filesystem MCP Server 的服务器实例,日志级别设为 ERROR(测试时发现 Cline 客户端因为服务运行时输出的 INFO 日志导致无法列举服务工具,但不影响工具调用)。

    2. 实现工具逻辑

    使用 @mcp.tool 装饰器定义以下功能工具,这里的 @mcp.tool 可以理解为在 MCP Server 中注册一个工具,不定义 name 的情况下,工具名默认为函数名称:

    (1) list_directory – 查找文件和目录

    @mcp.tool(
    description="获取指定路径下的所有文件和目录的详细列表。返回结果会通过 [FILE] 和 [DIR] 前缀明确区分文件类型。该工具对于了解目录结构及查找特定文件非常实用。仅限在允许访问的目录中操作。"
    )
    async def list_directory(dir_path) > str:
    if not osp.exists(dir_path) or not osp.isdir(dir_path):
    raise ValueError(f"{dir_path} is not a valid directory")

    entries = os.listdir(dir_path)
    formatted = []
    for entry in entries:
    entry_path = osp.join(dir_path, entry)
    if osp.isdir(entry_path):
    formatted.append(f"[DIR] {entry}")
    else:
    formatted.append(f"[FILE] {entry}")

    return "\\n".join(formatted)

    该工具返回指定目录下的文件和子目录列表,使用 [DIR] 和 [FILE] 前缀区分。当目录不存在时抛出异常,帮助模型理解当前文件系统状态。

    最初定义工具时,我采用了 os.walk 递归调用的方式来实现目录遍历,但目录中可能包含大量依赖文件(如 node_modules),浪费 Token 数,所以我们只需要返回第一层的文件和目录列表即可,必要时让模型继续向下搜索即可。

    (2) read_file – 读取文件内容

    @mcp.tool(
    description="读取文件系统中的完整文件内容。支持处理多种文本编码格式,若读取失败将返回详细错误信息。适用于需要检查单个文件内容的场景。仅可在允许访问的目录中操作。"
    )
    async def read_file(file_path) > str:
    if not osp.exists(file_path) or not osp.isfile(file_path):
    raise ValueError(f"{file_path} is not a valid file")

    with open(file_path, "r") as file:
    content = file.read()
    return content

    该工具读取单个文件内容,当文件不存在或无效时抛出异常。

    注意:如果文件内容过大也可能导致 Token 数溢出,实际开发中可设置字符数限制,超过则截断或做其他处理。

    (3) write_file – 写入文件

    @mcp.tool(
    description="创建新文件或完全覆盖现有文件内容。使用时需谨慎,此操作将直接覆盖目标文件且无警告提示。支持正确处理文本编码,仅限在允许的目录内执行。"
    )
    async def write_file(file_path, content) > str:
    if not osp.exists(osp.dirname(file_path)):
    raise ValueError(f"Directory for {file_path} does not exist")

    with open(file_path, "w") as file:
    file.write(content)
    return f"Successfully wrote to {file_path}"

    该工具实现文件写入功能,在目标目录不存在时抛出异常,成功则返回确认信息。

    注意:写文件是危险操作,建议在 MCP 工具调用时确认是否执行该操作,避免误操作导致数据丢失。

    (4) read_multiple_files – 批量读取文件

    @mcp.tool(
    description="同时读取多个文件的内容。当需要分析或比较多个文件时,这种方式比逐个读取更高效。每个文件的内容将与其路径一并返回,便于追溯。即使个别文件读取失败,也不会中断整体操作。仅限在允许的目录内执行。"
    )
    async def read_multiple_files(file_paths) > str:
    results = []
    for file_path in file_paths:
    try:
    if not osp.exists(file_path) or not osp.isfile(file_path):
    results.append(f"{file_path}: Error – Not a valid file")
    continue
    with open(file_path, "r") as file:
    content = file.read()
    results.append(f"{file_path}:\\n{content}")
    except Exception as e:
    results.append(f"{file_path}: Error – {str(e)}")

    return "\\n—\\n".join(results)

    该工具支持批量文件读取操作,使用分隔符区分不同文件内容(保持数据结构化便于模型理解)。为保证健壮性,单文件读取失败不会中断整个操作,并将错误信息返回给模型处理。

    说明:为了便于读者理解,我在上述 4 个工具的 description 部分使用了中文描述,在实际测试中,发现中英文描述均不影响模型理解工具含义。

    3. 启动服务器

    在文件末尾添加启动代码:

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

    最后,在项目根目录下,运行命令启动 MCP 服务器:

    uv run simple_filesystem.py /path/to/dir1 /path/to/dir2

    服务启动后不会有输出,这属于正常现象。下面我们将使用 MCP 客户端测试服务器。

    测试 Filesystem MCP Server

    常用的 MCP 客户端包括 Claude for Desktop、Cursor、Cline、GitHub Copilot(现已支持 MCP)、Cheery Studio 等。由于 Claude 客户端可能存在国内网络访问问题,而 Cline 与 GitHub Copilot 都内置了文件读取工具,不便测试,因此我们选择 Cherry Studio 进行测试。

    安装并配置客户端

    从官网 https://cherry-ai.com/ 下载最新版 Cherry Studio。

    配置服务器

    1、打开 Cherry Studio 的 设置,点击 MCP 服务器 2、手动 添加服务器 或点击 编辑 MCP 配置,将以下配置添加到配置文件中:

    请添加图片描述 请添加图片描述

    {
    "mcpServers": {
    "simplefilesystem": {
    "isActive": true,
    "name": "Filesystem MCP Server",
    "type": "stdio",
    "description": "用于获取本地目录列表、读写本地文件的 MCP Server",
    "registryUrl": "https://pypi.tuna.tsinghua.edu.cn/simple",
    "command": "uv",
    "args": [
    "–directory",
    "/ABSOLUTE/PATH/TO/simple-filesystem-server-python",
    "run",
    "simple_filesystem.py",
    "/path/to/dir1",
    "/path/to/dir2"
    ]
    }
    }
    }

    注意:上述配置中的命令行参数 args,需修改为真实的项目地址与允许服务访问的目录。

    3、在 设置-模型服务 中选择模型并输入 API Key(需开启函数调用功能),这里选择了 DeepSeek V3:

    在这里插入图片描述

    4、返回聊天页面,在输入框下启用 MCP 服务

    功能验证

    请添加图片描述

    通过多次工具调用,模型成功读取了本地文件并执行了内容总结。


    完整代码已经上传到我的 GitHub 仓库,并封装了更多文件操作的工具,可通过以下命令获取源代码:

    git clone https://github.com/jinzcdev/mcp-demos.git

    总结

    本文详细介绍了如何使用 Python 开发一个简易的 Filesystem MCP Server,实现了四个核心功能工具:

  • list_directory – 目录内容列表
  • read_file – 单文件读取
  • write_file – 文件写入
  • read_multiple_files – 批量文件读取
  • 通过 Cherry Studio 客户端的测试验证了 Filesystem MCP Server 的功能。开发过程中我总结了以下创建 MCP Server Tools 的核心经验:

  • 详尽的工具描述:清晰说明工具功能和使用场景,提升模型调用准确率
  • 明确的错误反馈:工具调用失败时返回具体错误信息,辅助模型调整策略
  • 保证工具健壮性:局部错误不要中断整体操作,返回部分成功结果

  • 本文是 《从原理到实战:掌握 MCP》 系列的第二篇文章,间隔时间较长了。如果文章对你有帮助欢迎收藏、转发,您的关注是我更新的最大动力。如有疑问欢迎在评论区留言。

    往期推荐:

  • MCP 实战系列(Day 1):什么是 MCP?
  • VS Code 预览版 Copilot 终于支持 MCP 了:试试使用 MCP 快速查询 GitHub Issues 吧
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » MCP 实战系列(Day 2)- 动手搓个文件系统 MCP 服务器
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!