---
url: /agents/mcp.md
description: >-
  面向前端工程师讲清 MCP（模型上下文协议）：M×N 的工具适配爆炸、它统一的是「工具怎么被描述和调用」而不是模型内部、host/client/server
  三个角色、最小 server 的 JSON 配置、stdio 与远程两种接法，以及它和 Function Calling 的关系与安全边界。
---

# MCP 入门：模型上下文协议解决了什么问题

模型本身调不动你的接口，于是每个模型厂商都自己定了一套工具描述格式；你有几个工具、几个模型，就得维护几份适配。这篇讲清 MCP（Model Context Protocol，模型上下文协议）到底想统一哪一层、谁在维护它、一个最小 server 长什么样，以及接上之后权限该怎么收。

## 工具适配的 M×N 爆炸

前端对这一幕太熟了：LSP（Language Server Protocol，语言服务器协议）出现之前，每种编辑器都得为每种语言写一份补全和跳转插件，5 个编辑器 × 5 种语言就是 25 份适配，谁都不想做。现在工具的处境就是 LSP 之前。你写了个「查订单」的能力，想接进三个模型，就得按三家的字段格式各写一份定义，再各写一份调用解析；明天加第四个模型，成本再来一遍。模型数量是 M，工具数量是 N，工作量是 M×N。

## MCP 统一的是接口层，不是模型

关键认知：MCP 不碰模型内部，它不改变模型怎么理解、怎么推理，也不承诺模型会用对工具。它统一的是工具被描述和被调用这一段：一个工具叫什么名字、描述怎么写、参数用什么 JSON Schema（JSON 结构规范）约束，调用请求怎么发、结果怎么回。消息统一用 JSON-RPC 2.0（基于 JSON 的远程调用格式）编码，所以它天然和 HTTP、和进程通信都能接。

## 三个角色：host、client、server

host（宿主，也就是那个 AI 应用，比如编辑器和聊天客户端）内部为每个 server 起一个 client（客户端）去连接；server（服务端）是真正提供能力的一方。server 对外提供三类东西：tools（工具，可被模型调用）、resources（资源，可读取的上下文，用 URI 标识）、prompts（提示模板，给人挑着用）。大概的分工是 tools 由模型决定调用、resources 由应用决定读取、prompts 由用户决定使用。概念名和版本都以官方规范为准。

## 一个最小 server 长什么样

配置文件是入门最省事的起点，本质就是「用什么命令把 server 跑起来」：

```json
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/project"]
    }
  }
}
```

命令行启动的写法也常见：

```bash
npx -y @modelcontextprotocol/server-filesystem /Users/me/project
```

server 起来后，client 先列清单再调用，工具定义就是一段带 schema 的数据：

```ts
// tools/list 返回的单个工具，字段名以官方规范为准
{
  name: "read_file",
  description: "读取指定路径的文件内容，用户要查看文件时使用",
  inputSchema: { type: "object", properties: { path: { type: "string" } }, required: ["path"] }
}
```

## 本地 stdio 与远程两种接法

规范里的标准传输就两种。stdio（标准输入输出）是本地接法：client 把 server 当子进程拉起来，用 stdin/stdout 交换换行分隔的消息，只适合跑在本机，好处是不用开端口。远程走 Streamable HTTP（可流式 HTTP），所有消息都 POST 到同一个 MCP 端点；早期那套 HTTP+SSE 传输已经废弃，老教程里的写法别照抄。远程场景通常还要配 OAuth 授权，别再靠一把长期密钥。

## 和 Function Calling 什么关系

MCP 不是 Function Calling 的替代品。模型侧该吐工具调用意图还是吐，链路没变；MCP 管的是这份工具清单从哪来、调用结果怎么回去，即工具的供给协议。没有 MCP，工具定义写死在你的应用代码里，换模型就得改；有了 MCP，定义放在 server 上，任何支持 MCP 的 host 接上就能用。反过来，只用一个模型、工具就七八个，直接手写 Function Calling 更简单，引协议纯属加层。

## 安全边界：接上就能被调用

工具一旦挂到模型上，就等于把这段能力的使用权交出去了，剩下的只是模型什么时候想起用它。所以权限要收窄到最小粒度：只给只读就别给写，只给一个目录就别给整个文件系统，能删能付能发的接口要单独走人工确认。此外，远端 server 返回的内容一律当不可信数据看，别让它变成下一条指令。

::: warning 常见坑 / 什么时候不需要 MCP

* 需求只有三五个工具、只接一个模型，手写 Function Calling 更短更可控，不必上协议。
* 别把整个数据库或整台机器的 shell 包成一个 server 图省事，那等于开放全部权限。
* 配置文件里的密钥别提交进 git，环境变量和远端授权才是正路。
* 版本和概念名以官方规范为准，MCP 变得快，二手教程经常停留在旧版本。
  :::
