MCP基础--从概念到动手实践
文章目录
第一:MCP是什么?为什么它被称为“AI的USB-C接口”?
从一个问题说起
想象这样一个场景:你正在VS Code里用AI助手写代码,随口问了一句:“PR #72的状态是什么?”AI助手信心满满地给出了一个答案——听起来很合理,但其实是错的,因为它根本无法直接访问GitHub获取实时信息。
这不是AI不够聪明,而是它被“关在”了一个信息孤岛里。
大语言模型(LLM)的能力再强,如果无法连接到外部工具和数据源,它的作用就大打折扣。而过去几年,开发者们一直在用各种“土办法”来解决这个问题:为每个AI应用、每个数据源单独写集成代码,费时费力,重复劳动严重。
模型上下文协议(Model Context Protocol,简称MCP) 正是为了解决这个问题而诞生的。
什么是MCP?
MCP是由Anthropic公司在2024年11月推出并开源的一种开放标准。它的核心目标很简单:标准化AI应用与外部数据源、工具之间的交互方式。
通俗地说,MCP就像给AI应用装了一个“通用插口”。无论你是想让AI读取本地文件、查询数据库、调用API,还是操作各种软件工具,只要这些工具和数据源也支持MCP,AI就能“即插即用”。
正因如此,MCP被广泛称为**“AI的USB-C接口”**。就像USB-C统一了各种电子设备的连接方式一样,MCP要统一AI与外部世界的连接方式。
为什么我们需要MCP?
在MCP出现之前,AI应用的集成方式可以用一个词概括:碎片化。
每个AI应用(比如Claude Desktop、ChatGPT、各种Agent框架)要为每个工具和数据源编写专门的集成代码。如果有N个AI应用要对接M个数据源,就需要开发N×M个不同的连接方案——这就是所谓的“N×M问题”。
这不仅带来了巨大的重复劳动,还导致:
- 系统扩展性差,每接入一个新工具就要重新开发
- 维护成本高,接口一变就要到处改
- 安全性和一致性难以保障
而MCP的出现,把N×M的问题简化成了N+M:AI应用只需要支持MCP协议,数据源也只需要暴露MCP接口,两者就能自动连通。
MCP的核心架构
MCP采用的是客户端-服务器(Client-Server)架构,整个体系包含三个核心角色:
1. MCP主机(Host) :希望访问外部数据的AI应用,比如Claude Desktop、VS Code、Cursor等。
2. MCP客户端(Client) :运行在主机内部,与MCP服务器保持1对1连接,负责协议的通信。
3. MCP服务器(Server) :一个轻量级程序,通过MCP协议对外暴露特定的功能——比如读取数据库、调用API、操作文件等。
当你在AI应用里提出一个请求时,流程大致是这样的:
- 主机将你的自然语言问题转化为语义请求
- 客户端将其打包为标准的MCP请求
- 服务器从对应的数据源获取真实数据,以结构化格式返回
整个过程对用户来说是完全透明的——你只需要用自然语言提问,AI就能自动获取所需信息并给出回答。
MCP能做什么?
MCP的想象空间很大。官方文档列举了几个典型场景:
- 个人助理:AI可以访问你的Google日历和Notion,成为一个真正了解你日程的智能助手
- 设计开发:Claude Code可以根据Figma设计稿直接生成完整的Web应用
- 企业数据分析:企业聊天机器人可以连接组织内的多个数据库,用户通过聊天就能完成数据分析
- 跨领域操作:AI模型可以在Blender中创建3D设计,并直接通过3D打印机打印出来
在实际应用中,开发者已经用MCP构建了各种有趣的功能。比如在Cursor这个代码编辑器里,你可以通过Slack MCP服务器把它变成Slack客户端,或者通过邮件MCP服务器直接发送邮件——你不需要离开自己的工作环境,就能完成各种跨应用的任务。
第二:深入MCP核心——Resources、Tools与Prompts
了解了MCP的宏观概念后,我们来深入它的能力内核。MCP的魔力来源于三个核心原语(Primitives) :Resources(资源) 、Tools(工具) 和Prompts(提示) 。
这三个原语分别对应了AI与外部世界交互的三种基本方式:读取信息、执行操作、引导对话。
三者速览:谁控制谁?
在深入细节之前,先看一张官方给出的对比表格:
| 原语 | 控制方 | 描述 | 示例 |
|---|---|---|---|
| Prompts | 用户控制 | 由用户选择的交互式模板 | 斜杠命令、菜单选项 |
| Resources | 应用控制 | 由客户端附加和管理的上下文数据 | 文件内容、Git历史 |
| Tools | 模型控制 | 暴露给LLM执行操作的函数 | API POST请求、文件写入 |
这个“控制层级”非常关键——它决定了谁来决定什么时候使用什么。接下来我们逐一拆解。
Resources(资源):让AI“知道”什么
Resources是MCP中用于向AI提供只读数据的原语。简单说,就是让AI能够“看到”某些信息,但不能修改它们。
- 核心特点:只读(Read-only)、由URI唯一标识、应用控制
- 典型场景:本地文件内容、数据库表结构、Git提交历史、API文档说明
Resources是被动的——它们静静地躺在那里,等待被读取,不会主动做任何事情。
Tools(工具):让AI“做”什么
如果说Resources是让AI“知道”,那Tools就是让AI“行动” 。Tools是MCP中用于执行操作、产生副作用的原语。
- 核心特点:可执行(Executable)、有副作用(Side Effects)、由LLM自主决定调用、需要参数Schema
- 典型场景:调用外部API、写入或修改文件、执行数据库操作、触发业务流程
Tools是主动的——它们被调用时真的会“做事”。
Prompts(提示):引导AI“怎么”做
Prompts是MCP中用于预定义对话模板和指令的原语。它们不直接读取数据也不执行操作,而是告诉AI“在这种场景下应该怎么做” 。
- 核心特点:模板化(Template-based)、纯数据(Pure Data)、由用户主动触发、提供指导框架
- 典型场景:代码审查流程(
/review-pr)、项目日报生成(/daily-report)、特定领域的分析模板
Prompts是指导性的——它们不亲自做事,但告诉AI“按照这个套路来”。
三者如何协同工作?
理解了三者各自的角色,我们来看一个完整的协作示例:
假设你正在开发一个项目,对AI说:“帮我审查一下PR #72的代码变更。”
- Resources发挥作用:AI通过MCP服务器读取PR #72的代码变更内容(只读数据)
- Prompts发挥作用:你输入了
/review-pr命令,一个预定义的审查流程Prompt被加载,告诉AI应该从哪些维度进行审查 - Tools发挥作用:AI根据Prompt的指引,调用各种Tool——可能是
check_style检查代码规范、scan_vulnerabilities扫描安全漏洞,最后post_comment把审查结果发布到PR上
整个过程行云流水:Resources提供数据,Prompts提供方法,Tools执行操作。
第三:动手搭建你的第一个MCP服务器——从代码到实战
理论讲完了,这一篇我们来动手。从零搭建一个属于自己的MCP服务器,并让AI助手真正能够“调用外部工具”。
准备工作
请确保你的环境满足以下条件:
- Python 3.10或更高版本
- uv(推荐的Python包管理工具)
安装uv——这是一个快速的Python包管理工具:
curl -LsSf https://astral.sh/uv/install.sh | sh
创建项目并安装依赖:
mkdir weather-mcp-server
cd weather-mcp-server
uv init .
uv add "mcp[cli]" httpx
编写第一个MCP服务器
创建一个文件 weather.py,写入以下代码:
import httpx
from mcp.server.fastmcp import FastMCP
# 创建MCP服务器实例
mcp = FastMCP("Weather Server")
# 定义工具1:获取天气预警
@mcp.tool()
async def get_alerts(state: str) -> str:
"""获取指定州的天气预警信息"""
url = f"https://api.weather.gov/alerts/active?area={state}"
async with httpx.AsyncClient() as client:
response = await client.get(url, timeout=30.0)
response.raise_for_status()
data = response.json()
if not data.get("features"):
return "当前没有活跃的天气预警"
alerts = [f"【{alert['properties']['headline']}】"
for alert in data["features"]]
return "\n".join(alerts)
# 定义工具2:获取天气预报
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""获取指定经纬度的天气预报"""
# 先获取气象站信息
points_url = f"https://api.weather.gov/points/{latitude},{longitude}"
async with httpx.AsyncClient() as client:
response = await client.get(points_url, timeout=30.0)
response.raise_for_status()
data = response.json()
forecast_url = data["properties"]["forecast"]
# 再获取预报数据
async with httpx.AsyncClient() as client:
response = await client.get(forecast_url, timeout=30.0)
response.raise_for_status()
data = response.json()
periods = data["properties"]["periods"][:5]
forecasts = [f"{p['name']}: {p['detailedForecast']}"
for p in periods]
return "\n\n".join(forecasts)
# 启动服务器
if __name__ == "__main__":
mcp.run(transport="streamable-http")
这段代码做了三件事:创建服务器实例、通过 @mcp.tool() 装饰器将函数变成AI可调用的工具、启动服务器。注意函数签名中的类型注解和文档字符串——它们会被自动解析为工具的输入参数描述和功能说明。
测试你的服务器
先用 MCP Inspector 进行测试——这是官方提供的交互式调试工具。
首先启动服务器:
uv run weather.py
然后在另一个终端窗口运行Inspector:
npx -y @modelcontextprotocol/inspector
浏览器会自动打开 localhost:6274,你可以在Tools面板中看到刚刚定义的两个工具,直接运行它们就能验证功能是否正常。
接入AI客户端
以接入Claude Desktop为例,找到配置文件:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
添加配置:
{
"mcpServers": {
"weather": {
"command": "uv",
"args": ["--directory", "/path/to/your/weather-mcp-server", "run", "weather.py"]
}
}
}
重启Claude Desktop,你就可以在对话中让AI查询天气了——比如问“加州现在有什么天气预警?”AI会自动调用工具获取实时数据并回答你。
最佳实践与注意事项
在实际开发中,有几个要点值得注意:
1. 日志处理要小心
如果你的服务器使用STDIO传输模式,千万不要向stdout打印任何内容——这会破坏MCP的JSON-RPC消息通信。正确的做法是使用stderr或专门的日志库。
2. 工具设计要清晰
- 为每个工具编写清晰的文档字符串——它会被LLM用来理解工具的用途
- 使用类型注解明确输入参数的类型
- 工具的名称要直观,让AI能准确判断何时该调用哪个工具
3. 安全第一
MCP服务器本质上是在给AI“打开一扇通往外部世界的门”。务必注意:
- 最小权限原则:服务器只暴露必要的功能
- 输入验证:对来自LLM的所有参数进行校验
- 敏感操作需人工确认:对于写入、删除等操作,建议增加确认机制
4. 选择合适的传输模式
| 模式 | 适用场景 | 特点 |
|---|---|---|
| STDIO | 本地开发、桌面应用 | 简单直接,通过标准输入输出通信 |
| Streamable HTTP | 云端部署、远程调用 | 支持网络访问,便于扩展和容器化 |
结语
回顾整个系列,我们从三个层面完整地认识了MCP:
- 概念层面:MCP是“AI的USB-C接口”,通过标准化协议解决了AI应用与外部工具集成的碎片化问题
- 原语层面:Resources(知道)、Tools(行动)、Prompts(怎么行动)三大原语构建了MCP的能力基石
- 实践层面:通过Python和FastMCP,我们可以轻松搭建自己的MCP服务器,并将其接入主流AI客户端
更多推荐



所有评论(0)