引言
在上一篇文章中,我们解析了一个关于天气实时预报的MCP server,相信大家对这一块应该有不错的体感了。那么我们这一篇就会来讲解一下MCP 客户端的一些问题和配置,如果篇幅合适的话还会讲MCP的一些高级特性
如果你对前面的内容感兴趣,可以点击这里跳转
MCP (Model Context Protocol) 技术理解 - 第一篇
MCP (Model Context Protocol) 技术理解 - 第二篇
MCP (Model Context Protocol) 技术理解 - 第三篇
MCP (Model Context Protocol) 技术理解 - 第四篇
MCP (Model Context Protocol) 技术理解 - 第五篇
如何调用MCP server
很多人可能有这个误区,应该是LLM直接发出指令来调用对应的MCP server的吧,但是实际上这个想法是错误的,根本原因在于LLM没有外调的能力,即不能直接调用接口。
那么一般调用MCP server会有两种情况,但是无论是什么情况,我们都是AI应用通过MCP client来调用MCP server,LLM只负责推理输入和输出,下面我们来讲讲这两种情况,然后我们再仔细地讲讲MCP client配置。
-
安全隔离 : 这意味着你可以在 Client 层前做拦截。如果 LLM 发疯了,想执行
rm -rf /,你的 Java/Go 代码可以在发送给 Server 之前检测并拦截这个请求。 -
协议转换 : LLM 输出的是文本/Token,MCP Server 需要的是 JSON-RPC 消息。你的 Client 就是这个 Adapter (适配器) 。
场景一:作为用户在现有host中调用
如果你只是想让 Claude code 或 Cursor 等AI应用调用一个现有的 MCP Server或者你自己编写的MCP server,你不需要写MCP client代码,只需要修改配置文件。
在这种情况,host就是AI应用,已经内置写好的MCP client代码了,你配置好MCP server即可调用,会自动维护连接。
场景二:作为开发者通过代码调用
如果你想在自己的 Java 或 Go 程序中调用一个 MCP Server(例如,构建一个能调用本地工具的 AI Agent),你需要实现一个 MCP Client。
核心交互流程 (以 Stdio 为例)
- 启动进程 : 你的程序(Client)启动 MCP Server(如
npx -y @modelcontextprotocol/server-filesystem)作为子进程。 - 握手 (Initialization) : 发送
initialize请求,协商协议版本和能力。 - 发送指令 : 发送
tools/list,tools/call,resources/read等 JSON-RPC 消息
所以在这种场景下,你需要自己编写MCP client进行初始化链接,维护相关协议和连接,发送消息和处理响应等等。
一次MCP调用示例
那么大家在看完上面的示例可能还有疑惑,那么LLM到底是干嘛的?别急,我们上面说了,AI应用通过MCP client来调用MCP server,LLM只负责推理输入和输出,下面我来给大家解析一遍完整的调用链,大家一看便知!
我们先强调各个角色吧:
AI应用:负责管控全局,协调各个请求和负载均衡
MCP client:负责连接 Server,管理进程,维护对话上下文
MCP server:它是无状态的 Worker。它不知道上下文,不知道是谁在问,只负责接收指令 -> 干活 -> 返回结果
LLM :它没有手脚(不能联网、不能读文件)。它负责分析用户的自然语言,对比 AI应用 给它的"Tools list",然后生成一个结构化的 JSON 文本,告诉 AI应用:"请帮我调用这个函数,参数是 X 和 Y"
以下是一次完整的交互流程:
-
初始化 (Handshake) :
- Client 启动 Server。
- Client 询问 Server: "你有什么本事?(Tools List)"
- Server 回答: "我会读文件 (
fs.read),我会查数据库 (db.query)。"
-
用户提问:
- 用户对 Client 说: "帮我查一下
user_id=101的订单。"
- 用户对 Client 说: "帮我查一下
-
Prompt 组装 (AI应用 内部逻辑) :
- AI应用 将用户的 System Prompt + Server 提供的工具定义 (Schema) + 用户问题,打包发给 LLM。
-
LLM 决策:
-
LLM 经过推理,发现
db.query工具能解决这个问题。 -
LLM 返回给 AI应用 (而不是直接给 Server):
JSON{ "tool_use": "db.query", "params": { "sql": "SELECT * FROM orders WHERE user_id=101" } }
-
-
执行 (真正的 MCP 调用发生在这里) :
- AI应用 解析 LLM 的响应,发现它想调用工具,控制MCP client发送相关请求和数据。
- Client 通过 JSON-RPC (Stdio/SSE) 向 MCP Server 发送
tools/call请求。
-
Server 响应:
- Server 执行 SQL,返回 JSON 数据给 Client。
-
回环 (Loop Back) :
- AI应用 接收到client返回的数据,将 Server 的执行结果再次喂给 LLM。
- AI应用 说: "刚才你让我调用的工具,结果是
[Order A, Order B],请生成给用户的最终回复。"
-
最终输出:
- LLM 生成自然语言: "用户你好,ID 为 101 的用户有两笔订单..."
在AI应用里面配置MCP server
ok,我相信通过上面的解析,大家已经对整个调用过程是非常清晰的了,接下来我再按场景逐渐解析MCP client的问题。
在上面的分析中,我们已经分析了在Claude code里面,我们只需要进行MCP server的配置即可,而不需要编写MCP client的相关代码,下面我们以Claude code为例子,讲讲如何配置MCP server。
我们可以在claude_desktop_config.json的文件中进行server的配置
json
// ~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"weather": {
"command": "uv",
"args": [
"--directory",
"/absolute/path/to/weather",
"run",
"weather-server"
]
},
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/username/Documents"
]
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token_here"
}
}
}
}
你可以把每一项配置看作是在终端执行一个长连接的子进程。以下是详细的参数拆解:
1.mcpServers:根节点,是一个 Map。Key(如 weather, github)是该 Server 的唯一标识符,用于在 AI 界面显示和内部隔离。
2.command (可执行文件)
这是 Client 尝试启动的二进制文件或脚本解释器。
- 作用: 指定入口程序。
- 常见值 :
npx(Node.js),python,uv(Python 包管理器), 或者你编译好的 Go/Java 二进制文件(如/usr/local/bin/my-go-server)。
args(启动参数)
这是一个字符串数组,会被追加在 command 后面,形成完整的 shell 启动命令。
-
weather示例分析:uv --directory /path/to/weather run weather-server- 这告诉
uv切换到特定目录并运行该项目。
-
filesystem示例分析:npx -y @modelcontextprotocol/server-filesystem /Users/username/Documents-y: 自动确认安装。- 最后一个参数
/Users/...: 这是传给 Server 程序内部的参数,告知它允许访问哪个文件夹(白名单机制)。
env(环境变量)
这是子进程启动时注入的 Environment Variables。
- 作用: 用于传递敏感信息(API Keys)或配置参数,而不需要将其硬编码在代码或命令行参数中。
- 后端视角 : 就像你在 Docker 中配置
ENV或在本地.env文件中定义变量一样。 - GitHub 示例 :
GITHUB_PERSONAL_ACCESS_TOKEN会被注入到该进程的上下文中,Server 代码中通过os.Getenv("GITHUB_PERSONAL_ACCESS_TOKEN")(Go) 或System.getenv(...)(Java) 获取。
通过代码来调用MCP server
这就是我们上面说的场景二,在自己构建的AI应用中,我们需要使用官方提供的SDK来编写MCP client的相关代码。
这里多说一句,官方提供了许多SDK,其中后端开发常用的Go是由Google和Go官方来维护,Java则是Spring AI官方维护,而Python则是MCP官方进行维护

下面是使用Python SDK来编写MCP client相关代码
python
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
# 配置服务器参数
server_params = StdioServerParameters(
command="uv",
args=["--directory", "/path/to/weather", "run", "weather-server"],
)
async def main():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# 初始化连接
await session.initialize()
# 列出可用工具
tools = await session.list_tools()
print("Available tools:", tools)
# 调用工具
result = await session.call_tool(
"get_forecast",
arguments={"latitude": 37.7749, "longitude": -122.4194}
)
print("Forecast:", result)
# 列出资源
resources = await session.list_resources()
print("Available resources:", resources)
# 读取资源
config = await session.read_resource("weather://config")
print("Config:", config)
if __name__ == "__main__":
import asyncio
asyncio.run(main())
总结
这一篇我们解答了MCP client的一些问题,包括client如何调用server,还有不同场景下我们该如何调用server等等,我相信通过这一篇和前面的文章,大家也已经对MCP比较了解了,下一篇我们再讲讲MCP的高级特性和一些需要注意的点。