MCP 协议实战让你的 AI Agent 像调用函数一样操作本地文件、数据库和 API读完这篇你就能搭一个能读写文件、查数据库、调外部 API 的 AI Agent——不用写一堆胶水代码靠 MCP 协议一个标准搞定。一、为什么你需要关注 MCP2024 年底Anthropic 开源了MCPModel Context Protocol。简单说它是 AI 模型与外部工具之间的USB-C 接口——定义了统一的客户端-服务端通信协议让任何 AI 应用都能用同一种方式调用任何工具。以前想让 GPT 读你的本地文件你得自己写一套文件操作函数 → 注册成 function calling tool → 处理权限 → 格式化返回。每个工具都这样来一遍累死。MCP 之后社区已经提供了几十个现成的 MCP Server——文件系统、数据库、GitHub、浏览器、Slack……你只需一行配置Agent 就能直接调用。自己写一个 MCP Server 也不到 100 行代码。本文用 Python 带你从零搭一个能用的 MCP Server然后连上 AI Agent让它操作你的本地文件。二、MCP 协议架构三板斧讲明白AI 应用 (Host) | -- MCP Client (文件工具) | | | -- JSON-RPC over stdio -- 文件系统 Server | -- MCP Client (数据库工具) | | | -- JSON-RPC over stdio -- 数据库 Server | -- MCP Client (API工具) | -- JSON-RPC over HTTP/SSE -- 第三方 API Server角色做什么类比HostAI 应用本体Claude Desktop / 你的 Python 脚本手机MCP Client与 Server 通信的协议客户端每个 Client 连一个 ServerUSB-C 数据线MCP Server提供具体能力的服务端文件 / 数据库 / API外设U盘 / 键盘 / 显示器三个核心概念概念说明你的理解方式ResourcesServer 暴露的只读数据相当于GET请求Agent 读取文件内容、查表结构ToolsServer 暴露的可执行操作相当于POST请求Agent 创建文件、执行 SQL、调 APIPromptsServer 预置的提示词模板相当于快捷指令Agent 可以直接用它来引导对话通信协议是JSON-RPC 2.0传输层支持两种stdio本机进程通信适合本地工具HTTP SSE远程服务适合部署到服务器三、从零搭建 MCP Server让 Agent 操作你的文件系统3.1 安装 MCP SDKpipinstallmcp3.2 先写一个最小 Server读取文件内容server.pyimportasynciofrommcp.serverimportServerfrommcp.server.stdioimportstdio_serverfrommcp.typesimportTool,TextContent# 创建 MCP Server 实例serverServer(my-filesystem-tools)# 注册一个 Tool读取文件 server.list_tools()asyncdefhandle_list_tools()-list[Tool]:return[Tool(nameread_file,description读取指定路径的文件内容。返回文件中的全部文本。,inputSchema{type:object,properties:{filepath:{type:string,description:要读取的文件绝对路径}},required:[filepath]})]server.call_tool()asyncdefhandle_call_tool(name:str,arguments:dict)-list[TextContent]:ifnameread_file:filepatharguments[filepath]try:withopen(filepath,r,encodingutf-8)asf:contentf.read()return[TextContent(typetext,textcontent)]exceptFileNotFoundError:return[TextContent(typetext,textf错误文件不存在 -{filepath})]exceptPermissionError:return[TextContent(typetext,textf错误没有读取权限 -{filepath})]raiseValueError(f未知工具:{name})# 启动 Server asyncdefmain():asyncwithstdio_server()as(read_stream,write_stream):awaitserver.run(read_stream,write_stream,server.create_initialization_options())if__name____main__:asyncio.run(main())运行测试——用 MCP 自带的 Inspector 工具调试npx modelcontextprotocol/inspector python server.py浏览器打开会看到一个调试界面你可以直接调用read_file工具输入路径看返回值。3.3 扩展加上写文件和列出目录# 在 handle_list_tools 中添加两个新 ToolTool(namewrite_file,description将内容写入指定路径的文件。会覆盖已有文件。,inputSchema{type:object,properties:{filepath:{type:string,description:要写入的文件绝对路径},content:{type:string,description:要写入的文本内容}},required:[filepath,content]}),Tool(namelist_directory,description列出指定目录下的所有文件和子目录,inputSchema{type:object,properties:{dirpath:{type:string,description:目录绝对路径留空则列出当前工作目录}}})# 在 handle_call_tool 中添加对应处理elifnamewrite_file:filepatharguments[filepath]contentarguments[content]os.makedirs(os.path.dirname(filepath)or.,exist_okTrue)withopen(filepath,w,encodingutf-8)asf:f.write(content)return[TextContent(typetext,textf✅ 已写入{len(content)}个字符到{filepath})]elifnamelist_directory:dirpatharguments.get(dirpath)oros.getcwd()entriesos.listdir(dirpath)result\n.join(f{ifos.path.isdir(os.path.join(dirpath,e))else}{e}foreinentries)return[TextContent(typetext,textf目录{dirpath}的内容\n{result})]现在你的 MCP Server 已经能读、写、列目录了——总共不到 80 行。四、接入 AI Agent让 Claude 操作你的文件MCP Server 写好了接下来让 AI 用起来。这里演示两个主流方案。4.1 方案一Claude Desktop 直接接入最省事Claude Desktop 原生支持 MCP。编辑配置文件macOS:~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:%APPDATA%\Claude\claude_desktop_config.json{mcpServers:{my-filesystem:{command:python,args:[/path/to/server.py]}}}重启 Claude Desktop你会看到工具图标亮起 。然后直接对 Claude 说“帮我读取 ~/projects/README.md 的内容总结出项目结构然后新建一个 NOTES.md 把总结写进去。”Claude 会自动调用你的read_file读 README分析内容生成总结调用你的write_file写入 NOTES.md全程不需要你写任何胶水代码。4.2 方案二用 Python 代码自主控制如果你想在自己的应用中集成 MCP不用 Claude Desktop# client.py - 在你的 Python 应用中调用 MCP Serverimportasynciofrommcp.clientimportClientfrommcp.client.stdioimportstdio_client,StdioServerParametersasyncdefmain():# 连接到本地 MCP Serverserver_paramsStdioServerParameters(commandpython,args[server.py])asyncwithstdio_client(server_params)as(read,write):clientClient(read,write)awaitclient.initialize()# 列出可用工具toolsawaitclient.list_tools()print(f可用工具:{[t.namefortintools]})# 调用 read_file 工具resultawaitclient.call_tool(read_file,{filepath:/Users/me/test.txt})print(f文件内容:{result.content[0].text})asyncio.run(main())五、进阶接入数据库Agent 能查 MySQL 了真正有用的 Agent 必须能跟数据打交道。写一个 SQLite MCP Serverimportsqlite3frommcp.serverimportServerfrommcp.server.stdioimportstdio_serverfrommcp.typesimportTool,TextContent serverServer(sqlite-tools)DB_PATH./app.dbserver.list_tools()asyncdefhandle_list_tools()-list[Tool]:return[Tool(nameexecute_sql,description执行一条 SQL 查询语句仅支持 SELECT。返回查询结果的 JSON 格式。,inputSchema{type:object,properties:{query:{type:string,description:要执行的 SELECT SQL 语句}},required:[query]}),Tool(namelist_tables,description列出数据库中所有表及其字段信息,inputSchema{type:object,properties:{}})]server.call_tool()asyncdefhandle_call_tool(name:str,arguments:dict)-list[TextContent]:connsqlite3.connect(DB_PATH)cursorconn.cursor()ifnamelist_tables:cursor.execute(SELECT name FROM sqlite_master WHERE typetable)tablescursor.fetchall()result[]for(table_name,)intables:cursor.execute(fPRAGMA table_info({table_name}))columnscursor.fetchall()cols_str, .join(f{c[1]}({c[2]})forcincolumns)result.append(f{table_name}:{cols_str})conn.close()return[TextContent(typetext,text\n.join(result)or数据库为空)]elifnameexecute_sql:queryarguments[query].strip()ifnotquery.upper().startswith(SELECT):conn.close()return[TextContent(typetext,text⚠️ 安全限制仅允许 SELECT 查询)]try:cursor.execute(query)rowscursor.fetchall()columns[desc[0]fordescincursor.description]result[dict(zip(columns,row))forrowinrows]conn.close()return[TextContent(typetext,textstr(result))]exceptExceptionase:conn.close()return[TextContent(typetext,textfSQL 错误:{str(e)})配上 Claude Desktop 配置{mcpServers:{sqlite-db:{command:python,args:[/path/to/sqlite_server.py]}}}然后你就能对 Claude 说“数据库里的 users 表帮我查一下注册超过 30 天但还没激活的用户数量。”Agent 会先调list_tables看表结构再调execute_sql写查询全程自动。六、MCP 现状能打了吗维度状态备注协议成熟度✅ 稳定JSON-RPC 2.0无 breaking changesPython SDK✅ 可用pip install mcp即可TypeScript SDK✅ 可用modelcontextprotocol/sdk社区 Server 数量 30文件系统、GitHub、Postgres、Slack、Brave Search 等Claude Desktop 集成✅ 原生配置即用GPT / OpenAI 原生支持❌ 暂不支持需通过 LangChain / 自建 Client 桥接远程部署 (HTTP) 实验性2026 年中刚出生产慎用结论本地 Agent 场景已经完全可以投产。远程部署还需观望但本地文件/数据库/API 的工具链已经足够你搭出很能打的 Agent。七、三个生产环境注意点1. 权限隔离上面那个文件系统 Server 可以读写任意路径——Agent 如果被注入恶意 prompt可能读你的~/.ssh/id_rsa。上线前必须加沙箱ALLOWED_DIRS[/home/user/projects,/home/user/downloads]defis_safe_path(filepath:str)-bool:abs_pathos.path.abspath(filepath)returnany(abs_path.startswith(d)fordinALLOWED_DIRS)2. 并发处理MCP Server 默认单线程。如果 Agent 同时调两个工具会串行执行。高并发场景用asyncio或上 HTTP 传输# 用 HTTP SSE 替代 stdiofrommcp.server.sseimportSseServerTransport3. 错误粒度Agent 的决策质量高度依赖工具返回的错误信息。别只返回操作失败要给 Agent 足够的信息去调整策略# ❌ 差return[TextContent(typetext,text操作失败)]# ✅ 好return[TextContent(typetext,textf文件{filepath}不存在。同目录下有以下文件{siblings}。要读取其中某一个吗)]八、总结MCP 的价值一句话你不用再为每个工具写胶水代码了。定义好 Tool 的 schema → Agent 自己决定什么时候调用、传什么参数、怎么利用返回值。下一步值得做的是给你的工具加Resources比如把数据库表结构暴露为 resourceAgent 启动时就能感知上下文尝试Multi-Server架构——一个 Agent 同时连文件系统 Server 数据库 Server API Server协作完成复杂任务关注 MCP 的Remote Server进展——一旦稳定你就能把 MCP Server 部署到云上多个 Agent 共享同一套工具下一篇预告用 LangGraph 把 MCP Server 串成 Multi-Agent 流水线——爬虫 Agent 采集数据 → 分析 Agent 处理 → 报告 Agent 输出全程自动。关注不迷路。