跳转到内容

聊聊我对 MCP 的一点理解

约 11 分钟阅读发布于 2026/6/18

全称模型上下文协议(Model Context Protocol)。这是由 Anthropic 推出的一项开放标准,目标是为大型语言模型和 AI 助手提供一个统一、标准化的接口,使 AI 能够轻松操作外部工具并完成更复杂的任务。

通过使用 MCP,Claude 或 ChatGPT 等 AI 应用程序可以连接到数据源(如本地文件、数据库)、工具(如搜索引擎、计算器)和工作流(如专门的提示词),从而使它们能够获取关键信息并执行任务。 可以将 MCP 想象成 AI 应用程序的 USB-C 接口。正如 USB-C 为连接电子设备提供了一种标准化方式一样,MCP 也为连接 AI 应用程序和外部系统提供了一种标准化方式。

就拿我开发的 AI LocalBase 来说吧。AI LocalBase 是一个本地化的知识库和数据管理工具,它可以帮助用户在本地存储和管理各种数据,并通过 AI 助手进行智能查询和操作。 虽然是本地化,但它也可以支持 OpenAPI 和 MCP 协议。通过 MCP 协议,AI LocalBase 可以和 Claude、Cursor、Codex 这类 AI 应用连接起来,使用户能够通过自然语言与本地知识库进行交互。

MCP 协议连接层架构示意图

放到 AI LocalBase 这个项目里看,MCP 其实没有那么玄。

本质上,它还是启动一个后端服务,然后暴露一个符合 MCP 协议的接口,给其他 AI 应用看。

只不过这个接口不是普通业务接口。

普通 HTTP API 更多是给前端页面、脚本或者其他服务调用的。调用方需要提前知道接口路径、参数格式和业务含义。

MCP 接口面对的是 AI 应用。它要让对方能够先发现能力,再决定怎么调用。

比如 AI LocalBase 后端启动后,可以暴露一个 MCP 入口。Claude、Cursor、Codex 这类工具作为 MCP Client 连进来之后,先问后端:

你有哪些工具?

你有哪些资源?

你支持哪些操作?

后端再把自己的能力按 MCP 的方式描述出去。

例如:

  • 可以列出知识库
  • 可以检索某个知识库
  • 可以读取文档片段
  • 可以生成带来源的回答
  • 可以查看索引状态
  • 在有权限时,也可以上传文档或重建索引

这样一来,AI 应用访问的就不是 AI LocalBase 的网页,而是 AI LocalBase 暴露出来的一组能力。

架构上大概就是上面这张图表达的链路:AI 应用通过 MCP Client 连到 AI LocalBase 后端暴露的 MCP 入口,再由后端去访问知识库、文档、向量索引和检索服务。

这个时候,AI LocalBase 就不只是一个可以打开的本地知识库工具了。

它还变成了其他 AI 应用可以调用的知识库后端。

这也是我理解 MCP 的一个关键点:它不是替代业务系统,而是让业务系统把自己的能力用一种标准方式暴露出去。

真正有价值的地方,不是“我又多写了一个接口”,而是这个接口背后有一套能力发现、工具描述、权限控制和调用返回的协议约定。

所以 MCP Server 不是把所有内部接口原样丢给 AI。

更好的做法是站在 AI 应用的视角重新整理能力。

比如对外暴露 search_knowledge_base,而不是暴露一堆底层查询接口。

比如返回检索结果时,不只返回文本,还要返回来源、置信度、文档 ID、chunk 信息,方便 AI 继续组织答案。

比如写入、删除、重建索引这种操作,就不能和普通查询放在同一个权限层级里。

说白了,MCP 的工程价值在于:让后端服务多了一层面向 AI 应用的能力出口。

如果用代码表达,它其实可以很朴素。

下面这些不是完整实现,更像是把核心链路拆开看:后端启动时挂一个 /mcp 入口,然后在这个入口里处理 MCP 的初始化、工具发现和工具调用。

比如在 Go + Gin 后端里,可以大概这样挂路由:

func RegisterRoutes(r *gin.Engine, cfg Config, deps Dependencies) {
api := r.Group("/api")
if cfg.MCP.Enabled {
mcp := NewMCPHandler(deps.KnowledgeBaseService, deps.SearchService)
api.POST(
"/mcp",
RequireAPIKey(),
RequireScope("mcp:read"),
mcp.Handle,
)
}
}

这里的重点不是 /api/mcp 这个路径本身。

重点是:AI LocalBase 后端启动以后,多暴露了一个 MCP 协议入口。其他 AI 应用不是直接访问页面,而是通过这个入口发现和调用后端能力。

MCP 请求底层可以理解成一类 JSON-RPC 消息。后端收到请求以后,根据 method 分发到不同处理逻辑。

type MCPRequest struct {
JSONRPC string `json:"jsonrpc"`
ID any `json:"id,omitempty"`
Method string `json:"method"`
Params json.RawMessage `json:"params,omitempty"`
}
func (h *MCPHandler) Handle(c *gin.Context) {
var req MCPRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, rpcError(req.ID, -32700, "invalid json"))
return
}
switch req.Method {
case "initialize":
c.JSON(http.StatusOK, h.initialize(req.ID))
case "tools/list":
c.JSON(http.StatusOK, h.listTools(req.ID))
case "tools/call":
c.JSON(http.StatusOK, h.callTool(c.Request.Context(), req.ID, req.Params))
default:
c.JSON(http.StatusOK, rpcError(req.ID, -32601, "method not found"))
}
}

tools/list 可以理解成 AI 应用进来以后先问一句:你这里有什么能力?

后端返回的不是普通菜单,而是一组工具描述。

func (h *MCPHandler) listTools(id any) MCPResponse {
return MCPResponse{
JSONRPC: "2.0",
ID: id,
Result: map[string]any{
"tools": []map[string]any{
{
"name": "list_knowledge_bases",
"description": "列出当前用户可以访问的知识库",
"inputSchema": map[string]any{
"type": "object",
"properties": map[string]any{},
},
},
{
"name": "search_knowledge_base",
"description": "在指定知识库中检索相关文档片段",
"inputSchema": map[string]any{
"type": "object",
"properties": map[string]any{
"knowledgeBaseId": map[string]string{"type": "string"},
"query": map[string]string{"type": "string"},
"topK": map[string]any{"type": "integer", "default": 5},
},
"required": []string{"knowledgeBaseId", "query"},
},
},
},
},
}
}

当 AI 应用决定调用 search_knowledge_base 时,后端再把这个工具调用转成内部业务服务调用。

func (h *MCPHandler) callSearchKnowledgeBase(
ctx context.Context,
args SearchKnowledgeBaseArgs,
) (MCPToolResult, error) {
hits, err := h.search.Search(ctx, SearchRequest{
KnowledgeBaseID: args.KnowledgeBaseID,
Query: args.Query,
TopK: args.TopK,
})
if err != nil {
return MCPToolResult{}, err
}
return MCPToolResult{
Content: []MCPContent{
{
Type: "text",
Text: formatSearchSummary(args.Query, hits),
},
},
Structured: map[string]any{
"query": args.Query,
"hits": hits,
},
}, nil
}

这里其实就能看出 MCP Server 的位置了。

它不是向量数据库。

它也不是 RAG 本身。

它只是把 AI LocalBase 已经有的检索能力,包装成 AI 应用能发现、能理解、能调用的工具。

客户端配置也可以很简单。比如一个支持 HTTP MCP 的 AI 应用,可能只需要知道 MCP 服务地址和访问凭证:

{
"mcpServers": {
"ai-localbase": {
"type": "http",
"url": "http://localhost:8080/api/mcp",
"headers": {
"Authorization": "Bearer lb_xxx"
}
}
}
}

这样配置之后,AI 应用就可以把 AI LocalBase 当成一个外部能力源。

用户问问题时,AI 应用可以先通过 MCP 调用 search_knowledge_base,拿到相关文档片段,再基于这些片段组织回答。

所以从代码角度看,MCP 并不是多神秘的东西。

它就是一层协议适配。

只不过这层适配面向的是 AI 应用,所以它不只要能调用,还要能描述能力、限制权限、返回结构化结果,并且让后续的 Agent 工作流继续往下走。