title: MCP协议实战:从零搭建一个MCP Server,让你的AI编程工具学会自定义技能
slot: csdn-main
date: 2026-05-17
direction: 教程
words: 3200

上个月在Claude Code里写了一个数据库查询工具,写完我突然意识到——这玩意儿不应该只在Claude里能用。Cursor能不能用?TRAE呢?甚至我自己的Python脚本呢?

答案是:都能用,只要你用的是MCP协议。

MCP(Model Context Protocol)是Anthropic在2024年底推出的开放标准,2026年已经是AI编程工具的标配了。Claude Code、Cursor、TRAE、甚至OpenClaw,全部原生支持。它的核心思路很简单:你写一次MCP Server,所有AI客户端都能直接调用

这篇文章从零开始,一步步搭一个能用的MCP Server,接入Claude Code和Cursor。全程Python,十分钟跑通。

MCP到底在解决什么问题

在MCP出现之前,每个AI工具都有自己的插件机制。Cursor用.cursorrules,Claude靠Project Knowledge,VSCode Copilot有自己的extension API。如果我想给这三个工具都加上"查公司内部API文档"的能力,我得写三套代码。

MCP把这些统一了。你的Server暴露Tools(工具)、Resources(资源)、Prompts(提示模板),客户端通过JSON-RPC 2.0协议跟它通信。部署一次,到处可用。

可以把MCP理解成"AI界的USB-C接口"——设备(AI客户端)和配件(你的工具)之间有了标准协议,不用各造一套方案。

环境准备

需要Python 3.10+。其他什么都不需要——MCP的FastMCP封装把复杂度全藏起来了。

mkdir my-mcp-server && cd my-mcp-server
python -m venv .venv
source .venv/bin/activate
pip install "mcp[cli]"

mcp[cli]装的是MCP Python SDK + CLI工具。装完之后跑一下版本确认:

python -c "import mcp; print(mcp.__version__)"

不出意外你应该看到1.x.x。2026年5月最新稳定版是1.x线。

第一个MCP Server:30行代码跑通

新建server.py,写一个最简单的Server,暴露一个加法工具:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("MyFirstServer")

@mcp.tool()
def add(a: int, b: int) -> int:
    """把两个数加在一起"""
    return a + b

@mcp.tool()
def get_weather(city: str) -> str:
    """查询某个城市的当前天气(模拟)"""
    return f"{city},晴天,22°C,湿度45%"

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

看着像Flask?对,FastMCP的装饰器风格就是冲着易用性设计的。@mcp.tool()把函数注册成一个可被AI调用的工具,函数的类型注解和docstring自动成为工具的Schema描述。

跑起来:

python server.py

终端没输出?这是对的。STDIO模式下Server默默等待客户端的JSON-RPC请求。按Ctrl+C退出。

验证Server是否工作

MCP CLI自带一个mcp dev调试工具:

mcp dev server.py

这会启动一个Web调试界面(默认http://localhost:5173)。打开浏览器,能看到你的Server暴露了两个Tool:addget_weather。可以直接在界面上测试调用。

如果不想开浏览器,也可以用mcp run单次调试:

echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | python server.py

但说实话,mcp dev的Web界面更直观,推荐用它。

一个更实用的工具:读取本地文件

加法工具太玩具了。来点真的——让AI能读取你本地项目的README文件:

import os
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("FileReader")

@mcp.tool()
def read_project_file(filepath: str) -> str:
    """读取指定文件的完整内容"""
    if not os.path.exists(filepath):
        return f"文件不存在: {filepath}"
    if not os.path.isfile(filepath):
        return f"路径不是文件: {filepath}"
    try:
        with open(filepath, "r", encoding="utf-8") as f:
            return f.read()
    except Exception as e:
        return f"读取失败: {str(e)}"

@mcp.tool()
def list_directory(dirpath: str = ".") -> str:
    """列出目录下的文件和文件夹"""
    if not os.path.exists(dirpath):
        return f"目录不存在: {dirpath}"
    items = os.listdir(dirpath)
    result = []
    for item in items:
        full = os.path.join(dirpath, item)
        icon = "📁" if os.path.isdir(full) else "📄"
        result.append(f"{icon} {item}")
    return "\n".join(result)

这个Server跑起来之后,AI就能直接读你项目里的代码文件了。不用手动复制粘贴,AI自己调用read_project_file去拿内容。

接入Claude Code

Claude Code是MCP的"亲儿子",支持最完整。配置放在claude_desktop_config.json里。

macOS:

mkdir -p ~/Library/Application\ Support/Claude/

编辑~/Library/Application Support/Claude/claude_desktop_config.json

{
  "mcpServers": {
    "my-file-reader": {
      "command": "python",
      "args": ["/绝对路径/my-mcp-server/server.py"]
    }
  }
}

Linux/WSL(Claude Code CLI):

claude mcp add my-file-reader -- python /绝对路径/server.py

或者手动编辑~/.claude/settings.json

{
  "mcpServers": {
    "my-file-reader": {
      "command": "python",
      "args": ["/home/you/my-mcp-server/server.py"]
    }
  }
}

配置好后重启Claude Code,输入/mcp就能看到已连接的Server。然后直接说"读取当前目录下所有的Python文件"——Claude会调用你的list_directoryread_project_file工具完成。

接入Cursor

Cursor 2026版也原生支持MCP。

打开Cursor Settings → Features → MCP Servers → Add Server:

  • Name: my-file-reader
  • Type: command
  • Command: python /绝对路径/server.py

或者直接编辑~/.cursor/mcp.json

{
  "mcpServers": {
    "my-file-reader": {
      "command": "python",
      "args": ["/绝对路径/my-mcp-server/server.py"]
    }
  }
}

配置完后,在Cursor的Composer里跟AI说"帮我重构这个文件",它会自动通过MCP读取文件内容,分析完再返回修改建议。全程零手动复制。

STDIO vs HTTP:什么时候该用什么

MCP支持两种通信模式:

STDIO模式(上面一直在用的):Server作为子进程启动,通过标准输入输出通信。

  • 优势:零网络配置,安全(只对本机程序可见),启动快
  • 适合:本地开发工具、个人工作流

HTTP模式(Streamable HTTP):Server作为Web服务运行,客户端通过HTTP连接。

  • 优势:可以远程访问,多客户端共享,适合团队
  • 适合:团队成员共享的API网关、CI/CD流水线、生产环境

切到HTTP模式只需改一行:

# 在 server.py 末尾替换
if __name__ == "__main__":
    mcp.run(transport="streamable-http", port=8000)

客户端配置里把command+args换成url

{
  "mcpServers": {
    "my-file-reader": {
      "url": "http://你的服务器:8000/mcp"
    }
  }
}

HTTP模式下可以用Docker部署、负载均衡、甚至接入k8s。适合团队共享的公共服务。

调试避坑指南

1. 日志别用print

STDIO模式下,标准输出是协议通道。print()输出的内容会被客户端当成JSON-RPC消息解析,导致"协议解析错误"。

# ❌ 千万不要
print("add 被调用了")

# ✅ 应该这样
import sys
print("add 被调用了", file=sys.stderr)

2. 路径用绝对路径

客户端配置里的args路径一定要写绝对路径。相对路径在不同工作目录下表现不一致,Claude Code可能找不到你的Server。

3. 虚拟环境路径

Server启动了虚拟环境,客户端配置里command要指向虚拟环境里的Python:

{
  "command": "/绝对路径/.venv/bin/python",
  "args": ["/绝对路径/server.py"]
}

或者在Server代码里指定shebang:

#!/绝对路径/.venv/bin/python

4. 热更新

修改server.py后,需要重启客户端才能生效。Claude Code里输入/restart,Cursor需要重启进程。

5. 不要暴露危险操作

你的AI工具能调什么,完全取决于你注册了什么Tool。不要注册exec_shell_commanddelete_file_recursive这种工具到生产环境的MCP Server上。STDIO模式只对本机可见问题不大,但HTTP模式部署到公网时,一定要加认证。

进阶:自定义Knowledge Base MCP Server

把上面的文件读取工具扩展一下,可以搭一个团队知识库MCP Server。原理是扫描指定目录的Markdown文件,构建一个简单的倒排索引,让AI能搜索知识库内容。

import os
import re
from collections import defaultdict
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("KnowledgeBase")
KB_DIR = "/path/to/your/knowledge-base"

def build_index():
    index = defaultdict(list)
    for root, _, files in os.walk(KB_DIR):
        for f in files:
            if f.endswith(".md"):
                path = os.path.join(root, f)
                with open(path, "r", encoding="utf-8") as fh:
                    content = fh.read()
                # 简单分词 + 索引
                words = set(re.findall(r'\w+', content.lower()))
                for word in words:
                    index[word].append(path)
    return index

_index = build_index()

@mcp.tool()
def search_knowledge(query: str) -> str:
    """搜索知识库,返回匹配的文档列表和摘要"""
    words = re.findall(r'\w+', query.lower())
    if not words:
        return "请输入搜索关键词"
    matched = set()
    for w in words:
        matched.update(_index.get(w, []))
    if not matched:
        return f"未找到包含「{query}」的文档"
    results = []
    for path in sorted(matched)[:5]:
        with open(path, "r", encoding="utf-8") as f:
            first_line = f.readline().strip()
        results.append(f"- {path}{first_line}")
    return "\n".join(results)

当在Claude Code里问"我们的数据库连接规范是什么",它会自动调search_knowledge,在知识库里找到对应的Markdown文档,读取内容后回答你。

总结

MCP把AI编程工具的扩展能力标准化了。写一次Server,Claude Code、Cursor、TRAE都能用。整个协议的设计理念是"让AI学会用你的工具,而不是你为AI写胶水代码"。

几个关键结论:

  1. FastMCP封装了99%的协议细节,把MCP Server开发简化成了写几个带装饰器的Python函数
  2. STDIO模式适合个人开发,HTTP模式适合团队共享
  3. 类型注解和docstring就是Schema,写清楚它们,AI才能正确调用你的工具
  4. 调试用mcp dev,比手动构造JSON-RPC请求快10倍

MCP生态正在爆炸式增长——2026年5月MCP协议的月下载量已经突破9700万次,超过1万个活跃Server在生产环境运行。如果你团队还没接入MCP,现在是时候了。

从今天这个30行的文件读取Server开始,你就能让AI读懂你的项目。接下来想加什么功能,都只是加一个@mcp.tool()的事。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐