Python
悠悠
2025年12月30日

那个让Claude直接操控我电脑的MCP协议,到底是个什么鬼东西?

昨晚熬夜折腾了一宿,头发又掉了几十根,总算把Anthropic搞的那个MCP(Model Context Protocol)给摸透了。

说实话,刚听到这个词的时候,我内心是拒绝的。这年头,概念造得比母猪下崽还快,今天Agent,明天RAG,后天又来个什么Chain。咱们干运维的,最怕这种听着高大上、落地一地鸡毛的玩意儿。

但是!

这次好像真不一样。当我第一次在Claude Desktop里,直接让它“读取我本地的Nginx日志并分析502错误原因”,然后它真的直接读了我硬盘里的文件并且给出分析结果时,我承认,我有点起鸡皮疙瘩了。

这玩意儿不是单纯的插件,它更像是一个给大模型开的“USB接口”。

以前我们怎么用AI?复制粘贴代码,或者把日志脱敏了再喂给它,要么就是费劲巴拉地写个脚本调用API。现在好了,MCP直接把这个过程标准化了。

废话不多说,今天咱们就来扒一扒这个MCP到底是个啥,以及作为一个手痒的IT人,怎么自己动手撸一个MCP服务,让AI变成你的私人定制运维专家。


啥是MCP?别给我整虚的

官方文档写得那叫一个晦涩,什么“开放标准”、“上下文交互”,看着就困。

其实你把它想象成电脑的USB协议就完事了。

以前(没有MCP的时候),你想让ChatGPT连你的数据库,你得自己写个特殊的插件;你想让Claude连你的Jira,又得写另一套代码。这就好比以前的手机充电口,诺基亚是圆孔,三星是扁口,苹果是宽口,乱得一塌糊涂。

MCP就是Type-C接口。

只要你的数据源(比如你的运维平台、你的本地文件夹、你的Postgres数据库)实现了MCP协议,不管是Claude,还是最近很火的Cursor编辑器,亦或是Zed,都能直接插上用。

这里面有两个核心角色:

  1. MCP Host(主机):比如Claude Desktop客户端,或者Cursor编辑器。它是大脑,负责提问和处理。
  2. MCP Server(服务端):这就是我们要开发的东西。它负责干活,比如去查数据库、去执行个ls -l、去读个文件。

这一打通,事情就变得有意思了。你可以写个Server,专门查你们公司的服务器负载。然后你在Claude里问:“现在哪台机器CPU飙高了?”Claude就通过MCP协议,调你的Server查数据,然后告诉你结果。

听起来是不是有点像API?是,也不是。它比API更“智能”,因为它把工具的定义、资源的模板都标准化了,AI一看就知道怎么用,不需要你写那种几百行的Prompt去教它。

准备动手:环境这块得支棱起来

咱们是搞技术的,光说不练假把式。只要你会点Python,这事儿就不难。虽说官方也支持TypeScript,但咱们运维圈子,Python才是亲爹。

先把环境弄好。我假设你电脑上已经有Python 3.10以上了。没有的话自己去面壁。

我最近特别喜欢用 uv 这个包管理工具,速度快得离谱,比pip那种老牛拉破车强多了。当然,你习惯用pip也行。

先建个目录,假装我们要搞一个“运维百宝箱”:

mkdir ops-mcp-server
cd ops-mcp-server
python -m venv .venv
source .venv/bin/activate  # Windows下是 .venv\Scripts\activate

接下来安装核心库。Anthropic官方出了个SDK,叫 mcp

pip install mcp[cli]

装完之后,咱们别急着写代码。很多教程一上来就让你写类、写继承,那太累了。咱们用个偷懒的方法——FastMCP。这玩意儿就像FastAPI一样,装饰器一挂,代码跑起来,贼爽。

对了,还得装个 uvicorn 之类的吗?其实MCP通常是走标准输入输出(Stdio)通信的,特别是在本地跑的时候,这样最安全,不需要暴露端口。这也是我觉得它设计得精妙的地方——它默认不是为了做成HTTP微服务,而是做成一个本地的“插件进程”。

第一个吃螃蟹:写个“查进程”的工具

咱们的目标很简单:让Claude能查我电脑上运行的进程。

新建个文件 server.py

代码大概长这样,逻辑我都写注释里了,仔细看:

from mcp.server.fastmcp import FastMCP
import psutil

# 初始化一个Server,名字随便起,就叫 "OpsTools"
mcp = FastMCP("OpsTools")

@mcp.tool()
def list_top_processes(limit: int = 5) -> str:
    """
    列出当前系统占用CPU最高的几个进程。
    
    Args:
        limit: 要显示的进程数量,默认为5个
    """
    # 既然是实战,就得真去读系统信息
    # psutil这库搞运维的应该都熟
    procs = []
    for proc in psutil.process_iter(['pid', 'name', 'username', 'cpu_percent']):
        try:
            # 这是一个坑,psutil获取cpu_percent有时候第一次是0,但这只是个demo,无所谓了
            procs.append(proc.info)
        except (psutil.NoSuchProcess, psutil.AccessDenied):
            pass
            
    # 按CPU使用率降序排序
    procs.sort(key=lambda x: x['cpu_percent'], reverse=True)
    
    # 咱们搞得人性化一点,格式化一下输出
    result = "TOP CPU 进程列表:\n"
    result += f"{'PID':<10} {'名称':<20} {'用户':<15} {'CPU%':<10}\n"
    result += "-" * 60 + "\n"
    
    for p in procs[:limit]:
        result += f"{p['pid']:<10} {p['name']:<20} {p['username']:<15} {p['cpu_percent']:<10}\n"
        
    return result

@mcp.tool()
def kill_process_by_pid(pid: int) -> str:
    """
    通过PID杀掉某个进程(慎用!)。
    """
    try:
        p = psutil.Process(pid)
        p_name = p.name()
        p.terminate() # 温柔一点,先terminate
        return f"成功终止进程: {p_name} (PID: {pid})"
    except psutil.NoSuchProcess:
        return f"找不到PID为 {pid} 的进程,是不是已经挂了?"
    except psutil.AccessDenied:
        return f"权限不足!你是不是没sudo?杀不掉 PID {pid}"
    except Exception as e:
        return f"出事了,杀进程失败: {str(e)}"

# 这一行是启动的关键
if __name__ == "__main__":
    mcp.run()

代码很简单对吧?

这里面有个特别关键的点,就是 @mcp.tool() 这个装饰器。

你不需要写任何Prompt告诉AI“我有这个工具,参数是什么什么”。FastMCP会自动读取你的函数签名(Type Hints)和文档字符串(Docstring),自动生成MCP协议所需的Schema。

也就是说,你注释写得越清楚,AI用得越顺手。这简直是“代码即文档”的最高境界啊。

怎么连上Claude?这才是坑最大的地方

代码写好了,你直接运行 python server.py,你会发现...什么反应都没有,或者程序直接挂在那不动。

别慌,这是正常的。因为它是设计成通过Stdio(标准输入输出)交互的,它在等指令呢。

要让Claude Desktop用上它,你得去改配置文件。

这个配置文件通常藏得很深。

  • Mac用户在:~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows用户在:%APPDATA%\Claude\claude_desktop_config.json

你要是找不到,就在Claude Desktop的菜单里找找“Settings” -> “Developer”之类的选项,通常有个按钮能直接打开这个配置目录。

打开这个JSON文件,加上这一段:

{
  "mcpServers": {
    "my-ops-tools": {
      "command": "/你的路径/ops-mcp-server/.venv/bin/python",
      "args": ["/你的路径/ops-mcp-server/server.py"]
    }
  }
}

注意!敲黑板了!

这里千万别直接写 python。一定要写你那个虚拟环境里的绝对路径!因为Claude启动的时候,它不知道你的环境变量是啥,如果用系统的python,很可能找不到 mcp 或者 psutil 库,然后就默默失败,连个报错都没有,急死你。

Windows用户记得要把路径里的反斜杠 \ 写成双斜杠 \\,不然JSON解析会报错。这种低级错误我当年刚入行的时候没少犯,现在想起来还觉得蠢。

改完配置文件,重启Claude Desktop。

这时候,你会看到输入框旁边多了一个小锤子的图标(或者是类似连接的图标)。点开它,如果你看到了 list_top_processeskill_process_by_pid,恭喜你,你的第一个MCP Server跑通了!

见证奇迹的时刻

现在,你在对话框里输入:“帮我看看现在电脑上哪个进程最吃CPU?”

你会看到Claude稍微停顿一下(它在思考用哪个工具),然后它会显示“Used list_top_processes”。接着,它会把你代码里返回的那个格式化好的字符串展示出来,甚至还会基于这个结果给你一点建议。

比如它可能会说:“兄弟,你的 chrome 占用太高了,要不要关几个标签页?”

接着你回:“把那个PID为 12345 的进程给我杀了。”

它就会调用 kill_process_by_pid

这种感觉,怎么形容呢?就像是你给AI装了一双手。以前它只能动嘴皮子,现在它能干活了。

进阶:Resource和Prompts又是啥?

光有Tool(工具)还不够。MCP协议里还有两个重要的概念:Resources(资源)和Prompts(提示词)。

Resources 理解起来就是“数据源”。
比如你有一个经常变动的日志文件,或者一个API返回的实时JSON数据。你可以把它定义成一个Resource。

@mcp.resource("file://logs/app.log")
def read_log() -> str:
    # 实际上这里可以写得很复杂,比如只读最后100行
    with open("app.log", "r") as f:
        return f.read()

这样,AI就可以像订阅RSS一样,随时获取这个资源的内容,而不需要通过“调用函数”这种动作。它更像是一种被动的上下文注入。

Prompts 则是给人用的模板。
比如你经常让AI帮你写SQL语句。你可以定义一个Prompt叫 sql-expert,里面预设好你们公司的表结构描述。

在MCP里定义好Prompt后,你在Claude的界面里就能直接选这个Prompt,省去了每次都要复制粘贴一大堆背景信息的麻烦。

说实话,对于咱们个人开发者或者小团队运维来说,Tool 是最有用的。Resource和Prompt在大规模协作的时候才显威力。

遇到的那些坑(血泪史)

别看我写得挺顺,实际开发的时候全是坑。

  1. 调试极其困难:因为Server是Claude作为子进程启动的,你看不到它的控制台输出。如果你的代码里有 print("hello"),完了,这会破坏Stdio的通信协议,导致连接直接断开。

    • 解决办法:用 sys.stderr.write() 来打印日志,或者专门配个logging写文件。千万别往stdout打杂七杂八的东西。
  2. 超时问题:如果你的工具执行时间太长(比如去爬个网页),Claude可能会觉得Server挂了。

    • 解决办法:搞异步。FastMCP支持 async def。尽量把耗时的操作做成异步的。
  3. 依赖地狱:刚才说了,路径一定要写对。而且,如果你用了像 pandas 这种重型库,加载时间过长,有时候也会导致连接超时。
  4. 安全隐患:兄弟们,这玩意儿是直接在你的环境里跑代码啊!你要是写了个 rm -rf / 的工具,然后AI抽风了给你执行了,那画面太美我不敢看。

    • 忠告:所有的写操作、删除操作,一定要在代码里做二次确认,或者干脆只给AI只读权限。别太相信大模型的节操,它们有时候会幻觉,明明你没让它删,它觉得删了比较好,就给你动手了。

这东西对运维意味着什么?

MCP这东西,可能会彻底改变我们做运维工具的方式。

以前我们做个运维平台,得画前端页面,得写后端API,得做鉴权,得写文档教同事怎么用。

以后呢?

我可能只需要写几个Python函数,把它们暴露成MCP Server。同事们想查数据、想重启服务,直接对着他们的Claude或者IDE说话就行了。

“帮我把测试环境的数据库回滚到昨天的快照。”
“帮我查一下昨天晚上8点到9点的错误日志。”

根本不需要GUI界面了!Chat Interface(聊天界面)就是新的GUI。

而且,这东西还能联动。比如你用Cursor写代码,你可以搞一个Gitlab的MCP Server。你在写代码的时候,直接问Cursor:“这个函数是谁在哪次提交里改的?”Cursor直接通过MCP调Gitlab API查出来告诉你。这效率,提升的不是一星半点。

当然,现在MCP还在早期阶段,生态还比较乱。但我敢打赌,2026年这玩意儿会遍地开花。各种SaaS软件都会自带MCP接口。

总结

这篇博客写得有点散,主要是想把那种探索过程中的兴奋和踩坑的痛感分享给你们。

简单回顾一下:

  1. MCP是AI连接数据的USB接口。
  2. 用Python的 mcp 库配合 FastMCP 可以快速开发。
  3. 通过 claude_desktop_config.json 进行配置。
  4. 切记别用 print 调试,路径要写绝对路径。
  5. 安全第一,别给AI太大权限。

这就是我眼里的MCP。它不神秘,它就是个干活的工具。但是把它用好了,你的AI就不再是个只会陪聊的傻白甜,而是一个手里拿着扳手和螺丝刀的真正助手。

如果你也想试试,赶紧动手吧。哪怕写个简单的“查询本地天气”或者“读取每日记事本”的工具,那种成就感也是爆棚的。

行了,今天就唠到这。代码要是跑不通,或者遇到了奇葩报错,欢迎在后台留言,咱们一起脱发,一起进步。


最后,如果你觉得这篇文章对你有那么一点点启发,或者只是觉得我吐槽得比较在理,麻烦动动发财的小手:

公众号:运维躬行录
个人博客:躬行笔记

文章目录

博主介绍

热爱技术的云计算运维工程师,Python全栈工程师,分享开发经验与生活感悟。
欢迎关注我的微信公众号@运维躬行录,领取海量学习资料

微信二维码