MCP 深入理解:协议原理与自定义开发

MCP 深入理解:协议原理与自定义开发

AI 核心技能系列 · 第 9 篇


导语

Agent 要干活,得连接外部世界------读文件、查数据库、调 API。以前每个工具都要单独写适配代码,10 个工具写 10 套,换个模型再写一遍。

MCP(Model Context Protocol) 的出现改变了这一切。它是 AI 领域的"USB-C 接口"------一个协议接所有工具。Anthropic 发起,OpenAI 和 Google 都宣布支持。三个死对头在技术标准上达成一致------这种事在互联网历史上每次发生都不是小事。


一、MCP 是什么:Agent 的"万能插头"

1.1 解决的核心问题

没有 MCP 之前,M 个 AI 应用要对接 N 个工具,需要 M×N 个集成:

markdown 复制代码
Before MCP:                    After MCP:
App1 ──┬── Tool1              App1 ──┐
       ├── Tool2              App2 ──┤     ┌── Tool1
       └── Tool3              App3 ──┼─MCP─┤── Tool2
App2 ──┬── Tool1                     │     └── Tool3
       ├── Tool2              M + N 个连接
       └── Tool3
App3 ──┬── Tool1
       ├── Tool2
       └── Tool3
M × N 个连接

1.2 MCP 发展历程

时间 事件
2024.11 Anthropic 发布 MCP 规范
2025.03 OpenAI 宣布支持 MCP
2025.04 Google Gemini 支持 MCP
2025.06 MCP 生态爆发,社区 Server 超过 1000+
2026.01 MCP 成为 Agent 工具集成的事实标准

二、MCP 协议规范详解

2.1 架构

arduino 复制代码
┌────────────┐         ┌─────────────┐         ┌──────────────┐
│   MCP Host  │         │  MCP Client  │         │  MCP Server   │
│ (如 Claude   │ ──包含─→ │ (协议客户端)  │ ──通信──→ │ (提供工具/资源) │
│  Code/IDE)  │         │              │         │              │
└────────────┘         └─────────────┘         └──────────────┘
                                                       │
                                                       ▼
                                              ┌──────────────┐
                                              │   外部服务     │
                                              │  DB/API/文件   │
                                              └──────────────┘
  • Host:用户侧应用(Claude Code、Cursor、VS Code 等)
  • Client:Host 内部的 MCP 协议客户端,负责与 Server 通信
  • Server:提供工具和资源的服务端程序

2.2 传输层

传输方式 适用场景 特点
stdio 本地 Server 最简单,通过标准输入输出通信
HTTP + SSE 远程 Server Server-Sent Events,兼容性好
Streamable HTTP 远程 Server(新) 更灵活,支持双向流

2.3 三大核心原语

MCP 定义了三种能力原语:

原语 用途 谁控制 类比
Tools 可执行的操作 模型决定调用 函数/API
Resources 可读的数据 应用决定读取 文件/数据库记录
Prompts 可复用的提示模板 用户选择使用 预设 Prompt

Tools(最常用):

json 复制代码
{
  "name": "query_database",
  "description": "查询 PostgreSQL 数据库",
  "inputSchema": {
    "type": "object",
    "properties": {
      "sql": {"type": "string", "description": "SQL 查询语句"},
      "database": {"type": "string", "description": "数据库名"}
    },
    "required": ["sql"]
  }
}

Resources

json 复制代码
{
  "uri": "file:///project/config.yaml",
  "name": "项目配置文件",
  "description": "项目的配置信息",
  "mimeType": "text/yaml"
}

Prompts

json 复制代码
{
  "name": "code_review",
  "description": "代码审查专家模板",
  "arguments": [
    {"name": "language", "description": "编程语言", "required": true},
    {"name": "code", "description": "待审查的代码", "required": true}
  ]
}

三、MCP 生态全景

3.1 热门 MCP Server

Server 功能 适用场景
@modelcontextprotocol/server-filesystem 文件读写 本地文件操作
@modelcontextprotocol/server-github GitHub API 代码管理、PR、Issues
@modelcontextprotocol/server-postgres PostgreSQL 数据库操作
@modelcontextprotocol/server-slack Slack 团队沟通
@modelcontextprotocol/server-brave-search 网页搜索 信息检索
@modelcontextprotocol/server-memory 知识图谱记忆 Agent 长期记忆

3.2 MCP Client 支持

Client 支持情况 特点
Claude Code 完整支持 Anthropic 官方,支持最全
Cursor 完整支持 IDE 集成
Windsurf 完整支持 IDE 集成
VS Code (Copilot) 支持 微软生态
Continue.dev 支持 开源 IDE 插件

四、实战:开发你的第一个 MCP Server

4.1 Python 版完整示例

python 复制代码
# weather_server.py
import json
import httpx
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent, Resource

# 创建 MCP Server
server = Server("weather-server")

# ===== 定义 Tool =====
@server.list_tools()
async def list_tools():
    return [
        Tool(
            name="get_weather",
            description="获取指定城市的当前天气信息,包括温度、湿度、天气状况。",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,如 '北京'、'Shanghai'"
                    }
                },
                "required": ["city"]
            }
        ),
        Tool(
            name="get_forecast",
            description="获取指定城市未来 3 天的天气预报。",
            inputSchema={
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"},
                    "days": {"type": "integer", "description": "预报天数,1-3", "default": 3}
                },
                "required": ["city"]
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "get_weather":
        city = arguments["city"]
        # 实际项目中调用天气 API
        weather_data = {
            "city": city,
            "temperature": 22,
            "humidity": 65,
            "condition": "晴",
            "wind": "东南风 3级"
        }
        return [TextContent(
            type="text",
            text=json.dumps(weather_data, ensure_ascii=False)
        )]
    
    elif name == "get_forecast":
        city = arguments["city"]
        days = arguments.get("days", 3)
        forecast = [
            {"date": f"Day {i+1}", "high": 22+i, "low": 12+i, "condition": "晴"}
            for i in range(days)
        ]
        return [TextContent(
            type="text",
            text=json.dumps(forecast, ensure_ascii=False)
        )]
    
    raise ValueError(f"未知工具: {name}")

# ===== 定义 Resource =====
@server.list_resources()
async def list_resources():
    return [
        Resource(
            uri="weather://cities",
            name="支持的城市列表",
            description="当前支持查询天气的所有城市",
            mimeType="application/json"
        )
    ]

@server.read_resource()
async def read_resource(uri: str):
    if uri == "weather://cities":
        cities = ["北京", "上海", "广州", "深圳", "杭州", "成都"]
        return json.dumps(cities, ensure_ascii=False)
    raise ValueError(f"未知资源: {uri}")

# ===== 启动 Server =====
async def main():
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())

4.2 配置使用

在 Claude Code 中使用,编辑 ~/.claude/claude_code_config.json

json 复制代码
{
  "mcpServers": {
    "weather": {
      "command": "python",
      "args": ["/path/to/weather_server.py"],
      "env": {
        "WEATHER_API_KEY": "your-api-key"
      }
    }
  }
}

五、MCP Server 开发最佳实践

5.1 工具描述设计原则(ACI)

ACI(Agent-Computer Interface)------为 AI 设计接口,和为人类设计 UI 一样重要。

原则 说明 示例
名称语义化 工具名一看就知道干什么 search_knowledge_base > search
描述详细 说清楚能做什么、不能做什么 "查询公司内部文档。不支持外部网页搜索。"
参数有约束 枚举、范围、默认值 enum: ["pdf", "docx"]
错误信息友好 Agent 能理解并决定下一步 "文件不存在,请检查路径" > "Error 404"

5.2 安全考量

python 复制代码
# 输入验证
import re

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "query_database":
        sql = arguments["sql"]
        
        # 1. SQL 注入防护:只允许 SELECT
        if not sql.strip().upper().startswith("SELECT"):
            return [TextContent(type="text", text="安全限制:只允许 SELECT 查询")]
        
        # 2. 禁止危险关键词
        dangerous = ["DROP", "DELETE", "UPDATE", "INSERT", "ALTER", "EXEC"]
        if any(kw in sql.upper() for kw in dangerous):
            return [TextContent(type="text", text="安全限制:检测到危险操作")]
        
        # 3. 执行查询(使用参数化查询)
        result = await db.fetch(sql)
        return [TextContent(type="text", text=json.dumps(result))]

六、MCP vs Function Calling vs API

维度 Function Calling MCP 传统 API
标准化 各平台不同 统一标准 HTTP/REST
发现机制 需要预定义 自动发现 需要文档
运行时 嵌入应用 独立进程 独立服务
生态 绑定特定平台 跨平台复用 通用
适用场景 简单工具调用 Agent 生态 服务间通信

什么时候用 MCP :构建 Agent、需要工具复用、希望跨平台兼容 什么时候直接用 FC:简单场景、不需要复用、绑定单一平台


七、职业视角

MCP 正在成为 Agent 开发的基础设施。能开发 MCP Server 是一个重要的差异化技能。

问题 核心答案要点
MCP 的架构? Host → Client → Server,三层架构
Tool vs Resource? Tool 是可执行操作(模型控制),Resource 是可读数据(应用控制)
MCP 和 FC 的关系? FC 是能力(模型决定调什么),MCP 是标准化的工具接口协议
为什么三大厂商都支持? 统一标准降低整个生态的集成成本,M×N → M+N

总结

  1. MCP 定位:AI 领域的 USB-C,统一 Agent 与工具的集成标准
  2. 三大原语:Tools(可执行操作)、Resources(可读数据)、Prompts(提示模板)
  3. 开发简单:Python/TypeScript SDK 成熟,一个 Server 几十行代码
  4. 安全重要:输入验证、权限控制、SQL 注入防护
  5. 生态繁荣:1000+ 社区 Server,主流 IDE/AI 工具都支持

本文是 AI 核心技能系列 第 9 篇,共 12 篇。上一篇:Agent 开发全流程 | 下一篇:Skills 与知识系统

关注公众号「coft」,获取完整系列更新、配套代码和学习路线图。一起交流 AI 转行经验,助力职业跃升,迈向高薪岗位。

相关推荐
Jahzo2 小时前
openclaw桌面端体验--ClawX
人工智能·github
billhan20162 小时前
Agent 开发全流程:从概念到生产
人工智能
threerocks2 小时前
过了个年,AI 圈变天了?但没人告诉你为什么
人工智能
threerocks2 小时前
Anthropic CEO Dario Amodei:海啸已在地平线上,但没人在看
人工智能
用户5191495848452 小时前
Adrenaline GPU 漏洞利用框架:突破 Android 内核内存读写限制
人工智能·aigc
hulkie2 小时前
从 AI 对话应用理解 SSE 流式传输:一项 "老技术" 的新生
前端·人工智能
鞋带松了2 小时前
openclaw + ollama本地模型 + 飞书平台 windows平台部署教程
人工智能
啥都学点的程序员3 小时前
关于langchain调用MCP确保稳定性的小经验
人工智能
billhan20163 小时前
RAG 从零到一:构建你的第一个检索增强生成系统
人工智能