跳到正文
MCP 协议实战:给你的 AI 装上真正的手和眼
0%
工具评测 · · 1,144 字 · 漫游君 · 深度 · 🟡 中级 · Claude Code 实战 9/9 · ·

MCP 协议实战:给你的 AI 装上真正的手和眼

AI 最大的局限之一:它只能用你喂给它的信息。

你问它今天的新闻,它不知道。你让它查你的数据库,它做不到。你希望它操作你的文件系统,它只能靠猜。

MCP(Model Context Protocol)就是为了解决这个问题而生的——给 AI 装上手和眼,让它能真正触及外部世界。


MCP 是什么

MCP 是 Anthropic 提出的开放协议,定义了 AI 模型与外部工具/数据源之间的通信标准。

简单理解:它是一套规范,让任何人都能写一个”工具服务器”,AI 客户端(如 Claude Code)可以发现这些服务器并调用里面的工具。

Claude Code ←→ MCP 协议 ←→ MCP 服务器(你写的)
                               ├── 读取文件
                               ├── 查询数据库
                               ├── 调用 API
                               └── 执行命令

MCP 之前,每个 AI 工具都要自己定义工具调用格式,彼此不兼容。MCP 之后,写一次服务器,所有支持 MCP 的客户端都能用。


核心概念:三种能力

MCP 服务器可以暴露三种能力:

Tools(工具)

AI 可以主动调用的函数。类似 function calling,但标准化了。

{
  "name": "search_posts",
  "description": "搜索博客文章",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": { "type": "string" }
    }
  }
}

Resources(资源)

AI 可以读取的数据。文件、数据库记录、API 响应都可以包装成 Resource。

{
  "uri": "file:///data/posts.json",
  "mimeType": "application/json",
  "description": "所有博客文章的元数据"
}

Prompts(提示模板)

预置的对话模板,用户可以通过斜杠命令触发。

这三者可以单独使用,也可以混合——一个 MCP 服务器通常同时提供 Tools 和 Resources。


动手:搭一个最小 MCP 服务器

用 Python 官方 SDK(mcp),实现一个能查询本地 markdown 文章的工具服务器:

安装

pip install mcp

代码

# blog_mcp_server.py
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp.types import Tool, TextContent
import json
import os
from pathlib import Path

app = Server("blog-tools")

POSTS_DIR = Path("./src/content/blog")

@app.list_tools()
async def list_tools():
    return [
        Tool(
            name="search_posts",
            description="在博客文章中搜索关键词,返回匹配的文章标题和摘要",
            inputSchema={
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "搜索关键词"
                    }
                },
                "required": ["query"]
            }
        ),
        Tool(
            name="get_post",
            description="读取指定 slug 的文章全文",
            inputSchema={
                "type": "object",
                "properties": {
                    "slug": {
                        "type": "string",
                        "description": "文章的 slug(文件名不含 .md)"
                    }
                },
                "required": ["slug"]
            }
        )
    ]

@app.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "search_posts":
        query = arguments["query"].lower()
        results = []
        for f in POSTS_DIR.glob("*.md"):
            content = f.read_text(encoding="utf-8")
            if query in content.lower():
                # 提取标题(frontmatter 第一行 title:)
                title = next((l.split(":", 1)[1].strip().strip("'\"")
                              for l in content.splitlines()
                              if l.startswith("title:")), f.stem)
                results.append({"slug": f.stem, "title": title})
        return [TextContent(type="text", text=json.dumps(results, ensure_ascii=False))]

    elif name == "get_post":
        slug = arguments["slug"]
        post_file = POSTS_DIR / f"{slug}.md"
        if not post_file.exists():
            return [TextContent(type="text", text=f"文章 {slug} 不存在")]
        return [TextContent(type="text", text=post_file.read_text(encoding="utf-8"))]

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

注册到 Claude Code

~/.claude/claude_desktop_config.json(或 Claude Code 的 MCP 配置文件)里添加:

{
  "mcpServers": {
    "blog-tools": {
      "command": "python",
      "args": ["/path/to/blog_mcp_server.py"]
    }
  }
}

重启 Claude Code,现在你可以直接说:

“搜索所有关于 Agent 的文章” “读一下 one-person-ai-company 这篇文章”

Claude 会自动调用你的工具,而不是凭印象回答。


真实用例:我在用的 MCP 工具

context7 — 实时文档查询

这是我用得最多的 MCP 工具。当 Claude Code 需要某个库的最新 API 时,context7 直接从源头拉文档,不靠训练数据里的旧知识。

# Claude.md 里配置
使用 context7 获取最新文档,避免用过时的 API

效果:Astro 5 的新语法、Vercel 的最新配置,全部实时准确。

文件系统工具

Claude Code 内置的文件读写工具本质上就是 MCP 工具——这也是为什么它能直接编辑你的代码而不只是生成代码片段。

自定义飞书工具

我给系统里的 Agent 写了飞书 MCP 工具,让 Claude 能直接发消息到飞书群、读取最近的对话记录。

核心工具:

  • send_feishu_message(chat_id, text) — 发消息
  • get_recent_messages(chat_id, count) — 读最近 N 条
  • create_task(title, assignee) — 创建飞书任务

这让”AI 回复飞书消息”变成了可靠的工作流,而不是脆弱的字符串拼接。


设计好 MCP 工具的原则

用了一段时间之后,几点心得:

1. 工具描述要像写给人看的

AI 通过 description 字段决定什么时候用这个工具。描述不清楚,工具就会被误用或不被使用。

"description": "查询数据""description": "按关键词全文搜索博客文章,返回匹配文章的 slug 和标题列表"

2. 一个工具做一件事

不要写”万能工具”:do_everything(action, params)。 每个工具的参数应该类型明确、数量少、意图单一。

3. 返回结构化数据,不要返回散文

AI 能更可靠地处理 JSON 数组,而不是”找到 3 篇文章,分别是……”这种自然语言描述。

4. 错误信息要有意义

# ❌
return [TextContent(type="text", text="Error")]

# ✅
return [TextContent(type="text", text=json.dumps({
    "error": "post_not_found",
    "slug": slug,
    "available_slugs": [f.stem for f in POSTS_DIR.glob("*.md")][:5]
}))]

当工具出错时,好的错误信息能让 AI 自动修正,而不是卡住。


MCP vs 直接 function calling

有人会问:直接用 OpenAI 的 function calling 不就够了,为什么要 MCP?

维度Function CallingMCP
标准化厂商各自定义统一协议
复用性绑定特定模型/SDK任意支持 MCP 的客户端都能用
服务发现需要在代码里硬编码客户端自动发现服务器能力
资源支持仅 ToolsTools + Resources + Prompts
生态各厂商各自为政快速增长的统一生态

MCP 的核心价值是可移植性:今天写的工具服务器,未来换了 AI 客户端照样能用。


下一步

MCP 生态正在快速增长。如果你用 Claude Code,现在就可以开始:

  1. 找几个高质量的社区 MCP 服务器(mcp.so 有索引)
  2. 为你最常用的内部工具写一个 MCP 服务器
  3. 把常用的 MCP 工具注册进 Claude Code 的配置

当 AI 能真正触及你的数据和工具,那种”终于有个靠谱助手”的感觉才会真正到来。


系列文章:Claude Code 实战 · 相关阅读:Claude Code 的记忆架构

这篇文章对你有帮助吗?

分享这篇文章

X / Twitter

感谢阅读这篇文章

约花了 20 分钟。如果对你有帮助,欢迎订阅 RSS 或收藏待读。

讨论

这篇文章让你感觉

评分

喜欢这篇文章?

订阅 RSS,第一时间收到新文章推送

订阅 RSS

私人笔记

仅保存在本地浏览器

讨论

评论加载中...