MCP 起源于 2024 年 11 月 25 日 Anthropic 发布的文章:Introducing the Model Context Protocol。代表了 AI 与外部工具和数据交互的标准建立。和 LSP(语言服务器协议)的思想很像,都是 M×NM \times N 的问题变成 M+NM + N 的问题:

假设你正在使用 Claude Desktop (Host) 询问:“我桌面上有哪些文档?”

  • Host:Claude Desktop 作为 Host,负责接收你的提问并与 Claude 模型交互。
  • Client:当 Claude 模型决定需要访问你的文件系统时,Claude Desktop 中内置的 MCP Client 会被激活。这个 Client 负责与适当的 MCP Server 建立连接。
  • Server:在这个例子中,文件系统 MCP Server 会被调用。它负责执行实际的文件扫描操作,访问你的桌面目录,并返回找到的文档列表。

比如说我们可以手写一个 MCP Server 然后把它集成到 Claude Desktop 里面:

输入 prompt:“能推测我当前桌面上 txt 文件名的含义吗?”

可以看到输出里说了,“让我先获取桌面上的 txt 文件列表。”,也可以看到其调用了 txt_counter server 的一些数据。

自然而然你可能会问一个问题:大模型是怎么把我们输入的 prompt 对应到哪一个 server (比如 txt_counter)的哪一个 function(比如 list_desktop_txt_files)上面的?可能是函数下面的注释做匹配度吧。

MCP 代码:

import os
from pathlib import Path
from mcp.server.fastmcp import FastMCP

# 创建 MCP Server
mcp = FastMCP("桌面 TXT 文件统计器")

@mcp.tool()
def count_desktop_txt_files() -> int:
    """Count the number of .txt files on the desktop."""
    # Get the desktop path
    username = os.getenv("USER") or os.getenv("USERNAME")
    desktop_path = Path(f"/Users/{username}/Desktop")

    # Count .txt files
    txt_files = list(desktop_path.glob("*.txt"))
    return len(txt_files)

@mcp.tool()
def list_desktop_txt_files() -> str:
    """Get a list of all .txt filenames on the desktop."""
    # Get the desktop path
    username = os.getenv("USER") or os.getenv("USERNAME")
    desktop_path = Path(f"/Users/{username}/Desktop")

    # Get all .txt files
    txt_files = list(desktop_path.glob("*.txt"))

    # Return the filenames
    if not txt_files:
        return "No .txt files found on desktop."

    # Format the list of filenames
    file_list = "\n".join([f"- {file.name}" for file in txt_files])
    return f"Found {len(txt_files)} .txt files on desktop:\n{file_list}"

if __name__ == "__main__":
    # Initialize and run the server
    mcp.run()

MCP (Model Context Protocol),一篇就够了。 - 知乎