给AI装上"手脚":MCP工具入门指南

88 阅读10分钟

写在前面:还是有不少读者私信我关于如何编写一个MCP工具,虽然MCP是24年出来的产物,但也不妨在25年温故而知新

直到我了解了MCP(Model Context Protocol)——一个能让AI"长出手脚"的协议。今天就来聊聊这个能让AI真正"干活"的神器。


一、先说说AI的"残疾"问题

在聊MCP之前,我们先来看看传统AI有多"残疾":

image.png

是的,全都做不到

AI的本质局限

传统的AI模型(比如GPT、Claude)本质上是什么?是一个超级文本处理器

它能做的事情:

  • ✅ 理解你说的话
  • ✅ 根据训练知识回答问题
  • ✅ 生成文本、代码、文章
  • ✅ 分析和总结内容

它做不到的事情:

  • ❌ 知道现在几点
  • ❌ 读取你电脑上的文件
  • ❌ 帮你发送邮件
  • ❌ 查询实时股票价格
  • ❌ 操作任何外部系统

打个比方:传统AI就像一个被关在玻璃房里的天才——脑子很好使,但没有手脚,出不去,摸不到外面的世界。

💡 为什么会这样?

因为AI模型在训练完成后,就被"定格"了。它的知识来自训练数据,训练数据是什么时候截止的,它的知识就到什么时候。

而且,出于安全考虑,AI默认是不能直接访问外部系统的——毕竟谁也不想AI随便读取你的隐私文件或者乱发邮件对吧?

但问题是,这也让AI变得"不接地气"。很多实际工作,光靠"说"是完成不了的。


二、MCP是什么?给AI装"手脚"的协议

**MCP(Model Context Protocol,模型上下文协议)**是Anthropic公司在2024年11月发布的一个开放标准。

用一句话解释:

MCP就像是AI的"USB接口"——让AI可以插上各种"外设",获得新的能力。

image.png

🔌 MCP的核心思想

MCP定义了一套标准的"对话语言",让AI和外部工具可以互相"听懂"。

角色作用类比
MCP Server提供具体能力的"工具箱"USB设备(键盘、鼠标等)
MCP Client负责沟通的"中间人"USB接口
AI Model决定什么时候用什么工具电脑主机

有了MCP,AI的能力就从"只能说"变成了"能说也能做":

image.png


三、举个栗子:让AI知道"现在几点"

光说理论太抽象,我们来做一个最简单的例子——让AI能够回答"现在几点了"

整体流程

image.png

🛠️ 动手实现

好,我们来一步步实现这个功能。

第一步:准备环境

首先确保你有Python环境(推荐3.10以上版本)。

# 创建项目目录
mkdir my-first-mcp
cd my-first-mcp

# 创建虚拟环境(推荐)
python -m venv venv
source venv/bin/activate  # Mac/Linux
# 或者 venv\Scripts\activate  # Windows

第二步:安装依赖

pip install mcp

第三步:编写MCP Server

创建一个文件 time_server.py

"""
一个简单的MCP Server示例:获取当前时间
"""
from datetime import datetime
from zoneinfo import ZoneInfo
from mcp.server.fastmcp import FastMCP

# 创建MCP服务器实例
mcp = FastMCP("时间助手")

@mcp.tool()
def get_current_time(timezone: str = "Asia/Shanghai") -> str:
    """
    获取指定时区的当前时间
    
    Args:
        timezone: 时区名称,默认为中国时区(Asia/Shanghai)
    
    Returns:
        格式化的当前时间字符串
    """
    try:
        tz = ZoneInfo(timezone)
        now = datetime.now(tz)
        
        # 返回友好的时间格式
        return now.strftime("%Y年%m月%d日 %H:%M:%S")
    except Exception as e:
        return f"获取时间失败:{str(e)}"

@mcp.tool()
def get_weekday() -> str:
    """
    获取今天是星期几
    
    Returns:
        星期几的中文表示
    """
    weekdays = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
    today = datetime.now(ZoneInfo("Asia/Shanghai"))
    return weekdays[today.weekday()]

@mcp.tool()
def time_until(target_time: str) -> str:
    """
    计算距离目标时间还有多久
    
    Args:
        target_time: 目标时间,格式为 HH:MM
    
    Returns:
        距离目标时间的描述
    """
    try:
        now = datetime.now(ZoneInfo("Asia/Shanghai"))
        target = datetime.strptime(target_time, "%H:%M").replace(
            year=now.year, month=now.month, day=now.day,
            tzinfo=ZoneInfo("Asia/Shanghai")
        )
        
        # 如果目标时间已过,算到明天
        if target < now:
            target = target.replace(day=now.day + 1)
        
        diff = target - now
        hours, remainder = divmod(int(diff.total_seconds()), 3600)
        minutes, _ = divmod(remainder, 60)
        
        return f"距离 {target_time} 还有 {hours}小时{minutes}分钟"
    except Exception as e:
        return f"计算失败:{str(e)}"

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

第四步:运行测试

python time_server.py

如果没有报错,说明MCP Server已经启动成功了!

第五步:配置Claude Desktop(可选)

如果你使用Claude Desktop,可以在配置文件中添加这个MCP Server。

找到配置文件位置:

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

添加以下配置:

{
  "mcpServers": {
    "time-server": {
      "command": "python",
      "args": ["/你的路径/time_server.py"]
    }
  }
}

重启Claude Desktop后,你就可以问它"现在几点"了,它会真的告诉你准确时间!


四、MCP工具的工作原理详解

上面我们跑通了一个例子,现在来深入理解一下MCP是怎么工作的。

完整通信流程

sequenceDiagram
    participant U as 用户
    participant C as Claude
    participant MC as MCP Client
    participant MS as MCP Server
    
    U->>C: 现在几点了?
    C->>C: 分析:需要获取实时时间
    C->>MC: 请求调用 get_current_time
    MC->>MS: 发送工具调用请求
    MS->>MS: 执行 Python 代码获取系统时间
    MS->>MC: 返回:2025年12月30日 15:25:30
    MC->>C: 返回时间数据
    C->>C: 组织自然语言回复
    C->>U: 现在是2025年12月30日下午3点25分30秒

MCP工具的三要素

每个MCP工具都需要定义三个东西:

要素作用在代码中的体现
名称工具的唯一标识函数名,如 get_current_time
描述告诉AI这个工具能干嘛docstring,AI根据描述决定是否调用
参数工具需要的输入函数参数,如 timezone: str
@mcp.tool()
def get_current_time(timezone: str = "Asia/Shanghai") -> str:
    """
    获取指定时区的当前时间  ← 这是描述,AI会读这个
    
    Args:
        timezone: 时区名称  ← 这是参数说明
    """
    # 实际执行的代码
    ...

🧠 AI是怎么决定用哪个工具的?

这是很多人好奇的问题。答案是:AI根据工具的描述来判断

当你问"现在几点"时,AI会:

  1. 看到 get_current_time 工具的描述是"获取指定时区的当前时间"
  2. 判断这个工具能回答你的问题
  3. 决定调用这个工具

所以,写好工具描述非常重要!描述写得好,AI才能在正确的时候调用正确的工具。


五、更多实用MCP工具示例

光有时间工具还不够,再给大家展示几个实用的MCP工具思路:

示例一:文件读取工具 📁

@mcp.tool()
def read_file(file_path: str) -> str:
    """
    读取指定路径的文本文件内容
    
    Args:
        file_path: 文件的完整路径
    """
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return f"文件不存在:{file_path}"
    except Exception as e:
        return f"读取失败:{str(e)}"

示例二:天气查询工具 🌤️

import requests

@mcp.tool()
def get_weather(city: str) -> str:
    """
    查询指定城市的当前天气
    
    Args:
        city: 城市名称,如"北京"、"上海"
    """
    # 这里用免费的天气API
    api_url = f"https://wttr.in/{city}?format=3"
    try:
        response = requests.get(api_url, timeout=10)
        return response.text
    except Exception as e:
        return f"查询天气失败:{str(e)}"

示例三:计算器工具

@mcp.tool()
def calculate(expression: str) -> str:
    """
    计算数学表达式的结果
    
    Args:
        expression: 数学表达式,如 "2 + 3 * 4"
    """
    try:
        # 安全地计算表达式
        result = eval(expression, {"__builtins__": {}}, {})
        return f"{expression} = {result}"
    except Exception as e:
        return f"计算失败:{str(e)}"

示例四:翻译工具

@mcp.tool()
def translate_to_english(text: str) -> str:
    """
    将中文翻译成英文
    
    Args:
        text: 要翻译的中文文本
    """
    # 这里可以接入翻译API
    # 示例使用免费的API
    ...

六、MCP工具开发最佳实践

用了MCP一段时间,总结了一些开发技巧:

技巧一:工具描述要写清楚

# ❌ 不好的写法
@mcp.tool()
def do_something(x):
    """处理数据"""  # 太模糊,AI不知道什么时候用
    ...

# ✅ 好的写法
@mcp.tool()
def calculate_monthly_salary(base_salary: float, bonus: float) -> str:
    """
    计算月薪总额(基本工资+奖金)
    
    当用户询问薪资计算、月薪总额、工资加奖金等问题时使用此工具
    
    Args:
        base_salary: 基本工资,单位为元
        bonus: 奖金,单位为元
    
    Returns:
        月薪总额的详细说明
    """
    ...

技巧二:做好错误处理

@mcp.tool()
def read_file(file_path: str) -> str:
    """读取文件内容"""
    try:
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()
    except FileNotFoundError:
        return f"❌ 文件不存在:{file_path}"
    except PermissionError:
        return f"❌ 没有权限读取:{file_path}"
    except Exception as e:
        return f"❌ 读取出错:{str(e)}"

技巧三:返回结构化信息

# ❌ 不好的返回
return "15:25"

# ✅ 好的返回
return f"当前时间:2025年12月30日 15:25:30(北京时间)"

技巧四:合理拆分工具

image.png

方式优点缺点
一个大工具简单AI难以准确调用
多个小工具AI容易选择正确的代码稍多

七、MCP vs 传统方案对比

可能有人会问:用API不也能实现这些功能吗?

确实可以,但MCP有独特的优势:

image.png

详细对比

维度传统API调用MCP协议
AI集成需要自己写调用逻辑AI自动判断和调用
标准化每个API格式不同统一的协议标准
发现机制需要预先知道有哪些APIAI自动发现可用工具
权限控制各自实现协议层面支持
错误处理需要自己处理标准化的错误格式

总结:MCP不是要替代API,而是在AI和API之间建立一个标准化的"翻译层",让AI能更聪明地使用各种工具。


八、MCP生态:现成的工具推荐

如果你不想自己开发,社区已经有很多现成的MCP工具可以直接用:

工具名称功能适用场景
filesystem文件系统操作读写文件、创建目录
githubGitHub操作创建Issue、PR、查看代码
postgres数据库操作查询和操作PostgreSQL
brave-search网络搜索实时搜索互联网信息
puppeteer浏览器自动化网页截图、自动化测试
slackSlack消息发送消息、管理频道

这些工具都可以在 MCP官方仓库 找到。


九、常见问题解答

❓ Q1:MCP安全吗?会不会泄露我的数据?

:MCP本身只是一个协议,安全性取决于你如何实现。建议:

  • 只授权必要的权限
  • 敏感操作加确认机制
  • 本地运行的工具只在本地工作

❓ Q2:MCP支持哪些AI模型?

:目前主要支持Claude。不过因为是开放协议,其他模型也在逐步支持中。

❓ Q3:不会写代码能用MCP吗?

:可以用社区现成的工具。配置一下就能用,不需要自己写代码。

❓ Q4:MCP和Function Calling有什么区别?

:Function Calling是各家AI自己的实现,格式不统一。MCP是开放标准,更通用。


十、最后说几句

MCP的出现,让AI从"只会说"变成了"能说能做"。这是一个重要的进化。

image.png

我们正处在AI 3.0的早期阶段。MCP就是这个阶段的关键技术之一。

从一个简单的"获取当前时间"开始,你可以给AI装上越来越多的"手脚"——读文件、查数据库、发邮件、控制智能家居...

AI不再是玻璃房里的天才,而是真正能帮你干活的助手。

这才是AI应该有的样子。


相关资源:

彩蛋:

其实"让AI调用工具"这个想法并不新鲜。早在ChatGPT的插件系统就在尝试了。但那个系统比较封闭,而且后来还被砍了。

MCP的聪明之处在于:它是一个开放标准。任何人都可以基于这个标准开发工具,任何AI都可以接入这个协议。

开放带来繁荣。期待看到MCP生态越来越丰富的那一天。


如果这篇文章对你有帮助,欢迎分享给需要的朋友~