折腾了两天MCP协议,终于让AI帮我操作电脑了
上周有个活特别无聊:每天要从公司内网系统拉销售数据,整理成表格,再发邮件给老板。
干了三天我就烦了。能不能让AI帮我干?
说实话,我之前一直觉得所谓的"AI操作电脑"就是个营销噱头。直到我花了两个晚上把MCP协议跑通,看着它自动打开浏览器、查询数据库、生成报表,那一刻的感觉——真香。
今天把整个过程记录下来,踩过的坑、写过的代码,都在这了。
MCP是个什么东西
先别着急看代码,咱先把概念理清楚。
MCP(Model Context Protocol)是Anthropic搞出来的一套协议,本质上就是给大模型装了一套"手和脚"。
以前你跟AI聊天,它能做的只有:接收文字输入、输出文字回复。让它查个数据库?不行。让它发个邮件?别想。
MCP做的事很简单:定义了一套标准,让AI能够调用外部工具。
打个比方:你家的智能音箱能放音乐但不能开灯,因为它和灯之间没有协议。一旦有了协议(比如Matter),音箱就能控制灯了。MCP对AI来说,就是这个"智能家居协议"。
它和Function Calling有什么区别
很多人会问:OpenAI的Function Calling不也能让模型调工具吗?MCP有啥不一样?
关键区别在两个字:标准化。
Function Calling是你自己写代码定义工具、解析参数、处理返回。每换个模型都要重新适配。你写的工具只能在你的应用里用。
MCP不一样。它分了三层角色:
- MCP Host:使用AI的应用(比如你的聊天界面)
- MCP Client:和Server通信的客户端
- MCP Server:暴露具体工具的服务端
这个分层意味着:你写一个MCP Server提供"查询销售数据"的能力,任何一个支持MCP的客户端都能直接用它。不用重复造轮子。
说人话:Function Calling是你自己搭乐高,MCP是乐高给了你标准接口,随便哪个套件都能插。
动手搭一个MCP Server
理论说完了,直接上代码。
我用的是Python的mcp包,搭一个最简单的Server大概30行代码:
from mcp.server import Server, NotificationOptions
from mcp.server.models import InitializationCapabilities
from mcp.server.stdio import stdio_server
import httpx
server = Server("sales-data-server")
@server.list_tools()
async def list_tools():
return [
{
"name": "get_daily_sales",
"description": "获取指定日期的销售数据",
"inputSchema": {
"type": "object",
"properties": {
"date": {"type": "string", "description": "日期,格式YYYY-MM-DD"}
},
"required": ["date"]
}
}
]
@server.call_tool()
async def call_tool(name: str, arguments: dict):
if name == "get_daily_sales":
date = arguments["date"]
async with httpx.AsyncClient() as client:
resp = await client.get(f"http://内网API/sales?date={date}")
return {"content": [{"type": "text", "text": resp.text}]}
async def main():
async with stdio_server() as (read, write):
await server.run(read, write, InitializationCapabilities())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
跑起来之后,Claude Desktop或者其他支持MCP的客户端就能直接调用get_daily_sales这个工具了。
我踩过的坑
坑1:stdio通信搞了半天
MCP Server默认走stdio(标准输入输出),不是HTTP。我一开始按HTTP的思路去调,各种404。
后来才搞明白:MCP Client启动Server进程,通过stdin发JSON-RPC请求,从stdout读响应。跟你用subprocess.Popen通信一个原理。
坑2:工具描述写得太烂
这是让我最崩溃的点。
我第一次写工具描述的时候偷懒,就写了句"查询销售数据"。结果AI完全不知道什么时候该调用这个工具,该传什么参数。
后来我把描述改成了:
"查询指定日期的销售数据,返回包含销售额、订单数、客单价的结构化JSON。
当用户询问'今天的销售情况'或'本周业绩'时应该调用此工具。"
准确率直接从40%飙到接近100%。
这里有个经验:工具描述是AI理解你的工具的唯一途径。写工具描述要像写prompt一样认真,说清楚"什么时候用"和"怎么用"。
坑3:权限控制没做好
MCP Server默认可以访问本地文件系统。如果你的Server能读文件,AI就能读任何文件——包括.env和私钥。
我的做法是:把工具的范围限制在特定目录,禁止访问上级目录。代码里加个路径检查:
import os
SAFE_DIR = "/data/sales"
def safe_path(path: str) -> str:
full = os.path.abspath(os.path.join(SAFE_DIR, path))
if not full.startswith(os.path.abspath(SAFE_DIR)):
raise ValueError("路径越界了,你是不是想偷看我的私钥?")
return full
MCP的生态到底怎么样了
我调研了一下,目前情况是这样的:
已经比较成熟的:
- 文件系统操作(读、写、搜索文件)
- 数据库查询(SQLite、PostgreSQL)
- Web搜索和抓取
- GitHub操作(读代码、创建Issue)
还在早期的:
- 浏览器自动化(不如Puppeteer稳定)
- 复杂的GUI操作
- 实时协作场景
整体感觉:基础的工具调用已经很稳了,复杂场景还需要时间。
社区里最火的一个MCP Server叫filesystem,允许AI读文件、写文件、创建目录、搜索文件。我第一次用的时候,对着AI说"找一下项目里所有包含TODO的Python文件",它真的一个一个给我列出来了。那一刻真的很惊艳。
MCP vs A2A,别搞混了
很多人把MCP和A2A搞混,其实它们分工很明确:
- MCP:AI和工具之间的协议(一个人用工具)
- A2A:AI和AI之间的协议(多个人协作)
举例子:你要做一份行业分析报告。MCP让一个AI帮你查数据库、搜网页、生成图表。A2A让一个AI写分析文案、另一个AI做配图、第三个AI排成PPT。
现在MCP和A2A都在快速发展,看得出来这两套协议最终会融合——一个AI Agent既能调用工具,也能和其他Agent协作。
写在最后
折腾了两天MCP,我的感受是:这东西不是银弹,但确实是让AI落地的关键一步。
以前我们说"AI能做什么",答案基本是"能聊天、能写代码、能翻译"。有了MCP之后,答案变成了"能帮你干任何有API的事"。
如果你也在做AI应用,强烈建议花一个周末把MCP跑通。那种看着AI帮你干活的爽感,值得。
不过话说回来,MCP现在还比较新,文档不太全,踩坑是免不了的。建议从最简单的文件系统Server开始,跑通了再加复杂的功能。
下篇打算聊聊怎么把MCP和RAG结合起来,让AI既能查资料也能执行操作。感兴趣的可以关注一下。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)