MCP协议实战:从零搭建你的第一个AI Agent工具链
MCP协议实战:从零搭建你的第一个AI Agent工具链
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 mcp 再 pip 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()
几个注意点:
@mcp.tool()注册工具,函数签名就是工具的schema- docstring别偷懒——AI靠这个理解你的工具是干啥的,写不清楚它就调不对
- 类型注解必须有,不然MCP生成的schema里参数类型是空的
- 我第一次没加
[: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跑通了的。跑不通的话评论区说下你的环境,帮你看。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)