MCP Client(MCP 客户端)指南:概念、主流客户端与动手实现
MCP 客户端是什么、和 Host 有什么区别、主流 MCP 客户端分别支持哪些传输方式和功能,以及如何用 TypeScript 或 Python 写一个最小 MCP 客户端。
MCP 客户端(MCP Client)是 AI 应用内部的一个连接器,它与恰好一个 MCP 服务器保持连接,替这个服务器收发请求(列出工具、调用工具、读取资源),再把结果交还给应用。运行模型和界面的那个应用本身叫作 Host(宿主)。Claude Code、Cursor 或 VS Code 这样的 Host 会为你配置的每个服务器各创建一个客户端。日常说“MCP 客户端”时常常指整个应用,这样说没问题,但等你要自己动手实现一个时,就得把两者分清楚。
本文讲三件事:客户端在协议层面到底做什么,截至 2026 年 10 月各主流客户端支持哪些能力,以及如何用官方 TypeScript 和 Python SDK 写一个最小客户端。如果你还需要先补协议基础,请先读 MCP 是什么?;想看逐条消息的交互流程,请看 MCP 是如何工作的?。
Host、Client 与 Server
MCP 架构规范定义了三个角色:
| 角色 | 含义 | 示例 |
|---|---|---|
| Host | 用户直接交互的 AI 应用:运行模型、管理用户授权、决定共享哪些上下文 | Claude Code、Cursor、VS Code、ChatGPT |
| Client | 由 Host 创建的连接器,与一个服务器 1:1 绑定 | 你在 VS Code 里添加 Sentry 服务器时,VS Code 实例化的那个对象 |
| Server | 对外提供 tools、resources 和 prompts 的程序 | GitHub、Filesystem、Playwright |
所以,给 Cursor 连上三个服务器,就是一个 Host 加三个 Client。一个服务器对应一个客户端也是安全模型的一部分:服务器看不到完整对话,也“看不进”其他服务器,什么内容可以跨越这些边界由 Host 决定。(服务器这一侧的介绍见 什么是 MCP 服务器?。)
MCP 客户端实际做什么
在当前规范版本 2026-07-28 中,MCP 是无状态的。旧教程大多从 initialize 握手讲起,而现在客户端的工作方式已经变了。一个现代客户端会:
- **在每个请求上附带元数据。**每个 JSON-RPC 请求的
_meta都带有io.modelcontextprotocol/protocolVersion和io.modelcontextprotocol/clientCapabilities(均为必填),通常还带io.modelcontextprotocol/clientInfo。使用 Streamable HTTP 时,客户端还会发送与之一致的MCP-Protocol-Version请求头(规范)。 - 按需探测服务器。
server/discover一次返回服务器支持的版本、能力和使用说明。调用它不是必须的,但在 stdio 上,如果对方可能是基于握手的旧版服务器,推荐先用它探测。 - **列出并调用原语。**客户端发送
tools/list、resources/list、prompts/list,把工具定义交给模型;模型选中某个工具时,再发送tools/call。 - **响应输入请求。**服务器需要用户提供信息时,不再自己发请求,而是返回
InputRequiredResult(resultType: "input_required"),例如一个 elicitation 表单。客户端把表单展示给用户,然后带上inputResponses重试原始请求。这种模式叫作 Multi Round-Trip Requests(MRTR)。 - **监听变更。**想在工具列表变化或资源更新时收到通知,客户端会发起一个长连接的
subscriptions/listen请求,并按类型订阅需要的通知。 - **处理认证。**连接远程 HTTP 服务器时,客户端执行授权规范中定义的 OAuth 流程;stdio 服务器则从环境变量读取凭据。细节见我们的 MCP 认证指南。
Roots、Sampling 和 Logging 仍然可用,但 2026-07-28 版已将它们标记为弃用,新写的客户端不需要再实现。
主流 MCP 客户端对比
下表每一格都来自厂商当前的官方文档。“未记载”表示我们在官方文档中没有找到相关说明,并不代表该功能不存在。
| 客户端 | 本地(stdio) | 远程传输 | 服务器配置位置 | 文档中列出的原语/扩展 |
|---|---|---|---|---|
| Claude Code | 支持 | Streamable HTTP(推荐)、SSE(已弃用) | claude mcp add、~/.claude.json、项目内 .mcp.json | Tools、resources、prompts、elicitation、列表变更自动刷新、OAuth |
| Claude Desktop / claude.ai | 支持(Desktop) | 远程服务器以 Custom Connectors 形式添加 | claude_desktop_config.json;Settings → Connectors | Tools、resources、prompts |
| Cursor | 支持 | SSE、Streamable HTTP | .cursor/mcp.json、~/.cursor/mcp.json | Tools、prompts、resources、roots、elicitation、MCP Apps、OAuth |
| VS Code(Copilot) | 支持 | HTTP、SSE | 工作区 .mcp.json、用户级 mcp.json | Tools、resources、prompts、MCP Apps |
| ChatGPT | 不支持(需隧道) | SSE、streaming HTTP | Plugins → Add custom MCP server(网页版) | Tools(读写)、OAuth |
| Codex | 支持 | Streamable HTTP | codex mcp add、~/.codex/config.toml | Tools、OAuth 登录 |
文档中的几点补充:
- Claude Code 有三种作用域(local、project、user)。它在发现阶段会请求
prompts/list和resources/list,服务器发出列表变更通知时会刷新列表(文档)。配置步骤见 Claude Code MCP 指南。 - Claude Desktop 从
claude_desktop_config.json读取本地服务器:macOS 上在~/Library/Application Support/Claude/,Windows 上在%APPDATA%\Claude\。远程服务器在 Settings → Connectors 中以 Custom Connector 方式添加(文档)。见 Claude Desktop MCP 配置。 - Cursor 文档列出的功能是最全的之一,roots、elicitation 和 MCP Apps 都标为支持(文档)。见 Cursor MCP 配置。
- VS Code 现在推荐使用工作区
.mcp.json(键名mcpServers)。旧的.vscode/mcp.json(键名servers)已不建议用于新服务器。Prompts 以/<server>.<prompt>的形式调用(文档)。见 VS Code MCP 配置。 - ChatGPT 只能连接远程服务器,在网页版的 Plugins 中添加(文档)。见 ChatGPT MCP 配置。
- Codex 的 CLI、IDE 插件和 ChatGPT 桌面应用中的 Codex 共用同一个
config.toml。见 Codex MCP 配置。
Windsurf、Zed、Cline、Goose 等更多客户端,请浏览 MCP.so 客户端目录。
动手实现一个最小 MCP 客户端
只有在构建自己的 Host 时才需要自己写客户端,比如 Agent、聊天机器人、测试工具或网关。两个 Tier 1 SDK 都已在 2026 年升级到 v2,并支持无状态的新版协议。
TypeScript(@modelcontextprotocol/client v2)
npm install @modelcontextprotocol/client
import {
Client,
StreamableHTTPClientTransport,
} from '@modelcontextprotocol/client';
const client = new Client(
{ name: 'my-client', version: '1.0.0' },
{ versionNegotiation: { mode: 'auto' } }
);
await client.connect(
new StreamableHTTPClientTransport(new URL('http://localhost:3000/mcp'))
);
console.log(client.getProtocolEra()); // 'modern' or 'legacy'
const { tools } = await client.listTools();
console.log(tools.map((t) => t.name));
const result = await client.callTool({
name: 'greet',
arguments: { name: 'Ada' },
});
if (result.isError) {
console.error('Tool failed:', result.content);
} else {
console.log(result.content);
}
await client.close();
SDK 文档里有三个容易忽略的细节:
- **
versionNegotiation。**不设置时,connect()走 2025 年的旧版initialize握手。mode: 'auto'会先用server/discover探测,遇到旧服务器再回退到握手;mode: { pin: '2026-07-28' }则拒绝回退。 - **工具出错也是正常返回。**工具执行失败时返回
isError: true而不是抛异常,使用content之前要先检查。只有协议层面的失败(未知工具、超时)才会抛出。 - **
listTools()会自动翻页。**它会替你遍历所有分页,上限为listMaxPages(默认 64)。
要启动本地服务器,只需换一个 transport:
import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
await client.connect(
new StdioClientTransport({ command: 'node', args: ['server.js'] })
);
要支持 elicitation,在构造函数中声明能力(capabilities: { elicitation: { form: {} } }),再用 client.setRequestHandler('elicitation/create', ...) 注册处理函数,MRTR 的重试由 SDK 自动完成。
Python(mcp v2)
uv add "mcp[cli]"
import asyncio
from mcp import Client
async def main() -> None:
async with Client("http://localhost:8000/mcp") as client:
tools = await client.list_tools()
print([t.name for t in tools.tools])
result = await client.call_tool("add", {"a": 1, "b": 2})
print(result.structured_content)
asyncio.run(main())
传入 URL 时,Client 使用 Streamable HTTP。连接本地服务器时改传 stdio transport:Client(stdio_client(StdioServerParameters(command="python", args=["server.py"]))),这几个名称从 mcp 和 mcp.client.stdio 导入(Python SDK)。async with 覆盖了整个生命周期:进入时建立连接并协商协议版本,退出时关闭一切。
接入模型
一个实用的客户端要把 MCP 工具定义转换成你所用 LLM 的工具格式:映射 name、description 和 inputSchema,把模型发起的工具调用交给 callTool,再把结果追加回对话。官方的 build-a-client 教程用 Anthropic SDK 演示了完整流程。连接真实服务器之前,先用 MCP Inspector 测试一遍。
如何选择 MCP 客户端
- **终端里的编程 Agent:**Claude Code 或 Codex,两者都有添加服务器和 OAuth 登录的 CLI 命令。
- **IDE:**Cursor 或 VS Code。Cursor 文档列出的可选功能更多(roots、elicitation、Apps);VS Code 适合已经在用 Copilot 的团队。
- **面向非开发者的聊天:**claude.ai 或 ChatGPT,只支持远程服务器。请选择提供托管 HTTPS 端点的服务器,例如 Notion 或 Sentry。
- **你自己的产品:**使用 SDK 客户端,开启
versionNegotiation: 'auto'(或使用 Python v2 的Client),这样新旧服务器都能连。同时遵循 MCP 安全最佳实践,特别是要把工具调用展示给用户,执行任何有副作用的操作前先征得确认。
各客户端的功能支持会随版本变化。依赖 resources、prompts 或 elicitation 之前,先确认目标客户端的文档中有相关说明;否则就把同样的能力也做成一个 tool,因为所有客户端都支持 tools。
下一步
选好客户端之后,就该给它找些服务器来连了。你可以在 MCP.so 服务器目录中浏览数千个服务器,在客户端目录中对比各类应用,或者先从我们整理的最佳 MCP 服务器清单开始。
想完全在自己的电脑上运行?请看如何让本地 Ollama 模型使用 MCP 工具。
常见问题
什么是 MCP 客户端?
- MCP 客户端是 AI 应用内部的连接器,与单个 MCP 服务器保持一对一连接。它代表 Host 应用发送 tools/list、tools/call 等请求,并把结果返回给应用。
MCP Host 和 MCP Client 有什么区别?
- Host 是用户直接使用的 AI 应用,例如 Claude Code、Cursor 或 VS Code。Host 会为每个配置的服务器创建一个 MCP 客户端,每个客户端只与一个服务器通信。
有哪些应用是 MCP 客户端?
- 常见的支持 MCP 的应用包括 Claude Code、Claude Desktop、Cursor、带 Copilot 的 VS Code、ChatGPT 和 Codex。它们支持的传输方式和功能各不相同,例如 ChatGPT 只能连接远程服务器,而 Cursor 还在文档中列出了 roots、elicitation 和 MCP Apps。
如何自己开发一个 MCP 客户端?
- 使用官方 SDK,例如 TypeScript 的 @modelcontextprotocol/client 或 Python 的 mcp 包。创建 Client,通过 Streamable HTTP 或 stdio 建立连接,然后调用 listTools 和 callTool,并把工具交给你的 LLM。