MCP协议实战:从零搭建你的第一个AI Agent工具链

上周想给Claude接个本地数据库查询,翻了两天的文档和GitHub issue,最后发现MCP就是干这个的。比我想的简单,但踩的坑也不少,写出来省得你们再踩。

MCP是个啥

MCP全称Model Context Protocol,Anthropic搞的开源协议。你把它当成AI的USB口就行——以前每接一个外部工具得单独写对接代码,现在统一走MCP,写一次就行。

核心就三个角色:

  • Host:你用的AI应用,Claude Desktop、Cursor这些
  • Client:跟Server通信的中间层,协议内部实现,不用管
  • Server:你写的,把工具注册上去给AI调

你要干的事就一件:写一个MCP Server。

环境准备

Python方案,Node.js也能搞但Python示例多些。

mkdir mcp-demo && cd mcp-demo
python -m venv venv
source venv/bin/activate

pip install mcp

装完确认一下:

pip show mcp
# Version: 1.6.0 或更高就行

这里有个坑:PyPI上有个同名的包,不是Anthropic那个。如果装完import报错,先 pip uninstall mcppip install "mcp[cli]" 试试。我就因为这事浪费了半小时。

写个文件搜索工具

我们做一个实用的——让AI能搜你本地的文件。场景很简单:你跟Claude说"帮我找一下projects目录下有哪些config文件",它就能搜。

# server.py
import os
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("file-search")


@mcp.tool()
def search_files(directory: str, keyword: str) -> list:
    """搜索目录下文件名包含关键词的文件

    Args:
        directory: 目录路径
        keyword: 文件名关键词

    Returns:
        匹配的文件路径列表
    """
    results = []
    for root, dirs, files in os.walk(directory):
        for f in files:
            if keyword.lower() in f.lower():
                results.append(os.path.join(root, f))
    return results[:20]


@mcp.tool()
def read_file_head(filepath: str, lines: int = 10) -> str:
    """读文件前N行

    Args:
        filepath: 文件路径
        lines: 读取行数,默认10

    Returns:
        文件前N行内容
    """
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            head = []
            for i, line in enumerate(f):
                if i >= lines:
                    break
                head.append(line)
            return "".join(head)
    except Exception as e:
        return "读取失败: " + str(e)


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

几个注意点:

  1. @mcp.tool() 注册工具,函数签名就是工具的schema
  2. docstring别偷懒——AI靠这个理解你的工具是干啥的,写不清楚它就调不对
  3. 类型注解必须有,不然MCP生成的schema里参数类型是空的
  4. 我第一次没加 [:20] 限制返回条数,搜home目录返回3000多条,直接截断了

接入Claude Desktop

单独跑 python server.py 只是验证服务能起来,实际要用得接入Host。Claude Desktop的配置文件在这:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

改配置:

{
  "mcpServers": {
    "file-search": {
      "command": "/你的路径/mcp-demo/venv/bin/python",
      "args": ["/你的路径/mcp-demo/server.py"]
    }
  }
}

改完重启Claude Desktop,在对话里试试:

帮我搜一下~/projects目录下所有包含config的文件

Claude会自动调search_files,拿到结果后可能还会接着调read_file_head看内容。这个链式调用是它自己决定的,你只管描述需求。

加个资源接口

Tool是AI主动调的,Resource是AI可以浏览的静态数据。加一个目录结构浏览:

@mcp.resource("dir:///{directory}")
def list_directory(directory: str) -> str:
    """列出目录结构"""
    try:
        tree = []
        for root, dirs, files in os.walk(directory):
            level = root.replace(directory, "").count(os.sep)
            indent = "  " * level
            tree.append(indent + os.path.basename(root) + "/")
            subindent = "  " * (level + 1)
            for f in files[:10]:
                tree.append(subindent + f)
        return "\n".join(tree[:100])
    except Exception as e:
        return "读目录失败: " + str(e)

保存重启后,AI在你提到某个目录时就能主动看它的结构了。

我踩的3个坑

函数签名没写类型注解

我一开始的search_files长这样:

def search_files(directory, keyword):

MCP生成的schema里参数类型是空的,AI根本不知道该传什么。加上 directory: str, keyword: str 就好了。

返回数据太大被截断

没加数量限制的时候搜home目录,3000多个结果。MCP单次返回有大小限制(大概100KB),超了就截断,AI拿到的数据不全。所以不管你写什么工具,记得做截断或分页。

配置文件路径写法

Windows用户注意:JSON里的反斜杠要双写 C:\\Users\\xxx,或者直接用正斜杠 C:/Users/xxx。同事用正斜杠一次过了,我用反斜杠调了一小时。

后续

基于MCP还能做不少事:数据库查询工具、API封装、代码沙箱执行、批量文件操作。我下一篇打算写MCP连MySQL的实战,还有多Server协同的玩法。


代码在macOS + Python 3.11 + mcp 1.6.0跑通了的。跑不通的话评论区说下你的环境,帮你看。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐