news 2026/10/4 9:48:30

什么是MCP|工作原理是什么|怎么使用MCP|图解MCP:从JSON-RPC到TaoToken统一Key的实战拆解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
什么是MCP|工作原理是什么|怎么使用MCP|图解MCP:从JSON-RPC到TaoToken统一Key的实战拆解

1. 从一次“工具调用失败”说起:MCP 到底解决了什么问题

你可能遇到过这种场景:在 Cline 或者 Claude Code 里配好了一个 MCP Server,让它帮忙查一下本地数据库、发一封邮件、读一个日志文件,结果模型回你一句“我无法直接访问你的文件系统”,或者干脆卡在local proxy failed上不动了。这不是模型笨,而是它和外部工具之间缺少一套双方都认得的“接头暗号”。MCP(Model Context Protocol,模型上下文协议)就是这套暗号。

用一句话说清楚:MCP 是一套让大语言模型(LLM)通过标准化方式调用外部工具和数据源的开放协议。它规定了 Client 怎么把工具清单告诉模型、模型怎么发起调用、Server 怎么返回结果,全部走 JSON-RPC 2.0 消息格式。适合谁?适合所有想把 LLM 从“只会聊天”变成“能干活”的开发者,尤其是用 Go 写后端、又想在 Cline / Claude Code / Codex 里挂自定义工具的人。

我试过在没有统一协议之前,每个工具都要单独写一套适配层,邮件一套、数据库一套、文件操作又一套,改一个参数要动三四个地方。MCP 把这些收敛成一份tools/list和tools/call,模型侧只认协议不认实现,工具侧只实现协议不关心谁来调。这篇文章就按“图解链路 → 拆 JSON-RPC → Go 实现 → 配置验证 → 排错”的顺序走一遍,最后在 TaoToken 统一 Key 的 API 通道下完成一次端到端调用。

先给一张链路图(文字版,方便你对照):

用户输入 │ ▼ Host(Cline / Claude Code / 桌面应用) │ 内置 MCP Client ▼ MCP Client ──JSON-RPC 2.0──▶ MCP Server(本地 stdio 或远程 SSE) │ │ │ ├─ Tools(可被 LLM 调用) │ ├─ Resources(静态资源) │ └─ Prompts(提示词模板) ▼ LLM(通过 TaoToken 统一 Key 调用)

关键点在于:LLM 本身不直接连 MCP Server,它只负责“决定调哪个工具、传什么参数”,真正把 JSON-RPC 请求发给 Server 的是 MCP Client。Host 负责把 Client 暴露的工具清单塞进模型的上下文,模型返回一个 tool_call,Client 翻译成 JSON-RPC 发给 Server,Server 执行完把结果回传,Client 再喂回模型。整条链路里,模型和工具是解耦的,这就是 MCP 的价值。

2. 拆开 JSON-RPC:MCP 的消息格式与 Go 实现要点

MCP 的通信底座是 JSON-RPC 2.0,所有交互都是“请求-响应”或“通知”两种形态。理解这一点,后面看任何报错都能定位到是哪一层出了问题。

一个标准的请求长这样:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "send_email", "arguments": { "email": "someone@example.com", "content": "hello from mcp" } } }

成功的响应:

{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "Send successfully" } ] } }

失败的响应:

{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32602, "message": "Invalid params", "data": "email must be a string" } }

MCP 常用的几个 method 你要记住:initialize握手、tools/list拉工具清单、tools/call调工具、resources/list和resources/read读资源、prompts/list和prompts/get取提示词。Client 启动 Server 后第一件事就是initialize,协商协议版本和能力,然后tools/list把工具注册进模型上下文。

用 Go 实现时,社区主流是mark3labs/mcp-go。核心就三步:建 Server、注册 Tool、启动 stdio 服务。

package main import ( "context" "errors" "fmt" "github.com/mark3labs/mcp-go/mcp" "github.com/mark3labs/mcp-go/server" ) func main() { s := server.NewMCPServer("Email Sender", "1.0.0") tool := mcp.NewTool("send_email", mcp.WithDescription("Send an email to someone"), mcp.WithString("email", mcp.Required(), mcp.Description("target email address")), mcp.WithString("content", mcp.Required(), mcp.Description("email body")), ) s.AddTool(tool, emailHandler) if err := server.ServeStdio(s); err != nil { fmt.Printf("Server error: %v\n", err) } } func emailHandler(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { email, ok := req.Params.Arguments["email"].(string) if !ok { return nil, errors.New("email must be a string") } content, ok := req.Params.Arguments["content"].(string) if !ok { return nil, errors.New("content must be a string") } // 这里替换成你真实的发送逻辑 return mcp.NewToolResultText(fmt.Sprintf("Send %s with content %q successfully", email, content)), nil }

编译成可执行文件:

go mod init mcp-email go get github.com/mark3labs/mcp-go go build -o mcp-email main.go

mcp-email这个二进制文件就是后面配置里要填的“服务地址”。注意ServeStdio意味着它通过标准输入输出和 Client 通信,所以你不能在 Server 里往 stdout 打日志,否则会污染 JSON-RPC 流,导致 Client 解析失败。日志一律走 stderr。

3. 可复制配置:在 Cline / Claude Code 里挂上你的 MCP Server

工具写完了,得让 Client 认识它。不同 Client 的配置文件位置不一样,但核心三件套永远是:Base URL、Key、Model ID。这里我把 MCP Server 配置和 TaoToken 的模型通道分开讲,避免混淆。

先说 MCP Server 配置。Cline 在 VS Code 里,点开 MCP Servers 面板,选 Installed,编辑配置文件,路径通常是:

~/.config/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json

内容:

{ "mcpServers": { "email-sender": { "command": "/absolute/path/to/mcp-email", "args": [], "env": { "SMTP_HOST": "smtp.example.com", "SMTP_USER": "your_user" }, "disabled": false, "autoApprove": [] } } }

Claude Code 的配置在项目根目录或用户目录的.mcp.json:

{ "mcpServers": { "email-sender": { "command": "/absolute/path/to/mcp-email", "args": [] } } }

Codex 用的是~/.codex/auth.json加config.toml,MCP 部分写在config.toml:

[mcp_servers.email-sender] command = "/absolute/path/to/mcp-email" args = []

注意command必须是绝对路径,相对路径在 Client 启动子进程时工作目录不确定,很容易报spawn ENOENT。

再说模型通道。MCP 负责工具调用,模型本身还是要走 API。在 TaoToken 的统一 Key 下,你只需要在 Client 的模型设置里填三样:

配置项值
Base URLhttps://taotoken.net/api
API Key在 API Keys 页面 生成
Model ID按你用的模型填,比如claude-sonnet-4-5或gpt-4o

Cline 里对应的是 API Provider 选 OpenAI Compatible,Base URL 填上面那个,Key 填你的,Model ID 填模型名。Claude Code 则通过环境变量:

export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_API_KEY="sk-你的key"

这样模型走 TaoToken 通道,工具走本地 MCP Server,两条链路各司其职。如果你还没生成 Key,先去 API Keys 拿一个,接入细节看接入文档。

4. 本地验证:从 initialize 到 tools/call 的完整请求

配置完别急着在对话框里试,先用命令行手动跑一遍 JSON-RPC,确认 Server 本身没问题。这一步能帮你把“Server 的锅”和“Client 的锅”分开。

启动你的 Server:

./mcp-email

它会在 stdio 上等输入。手动喂一条 initialize:

echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"manual-test","version":"1.0"}}}' | ./mcp-email

正常会返回:

{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"Email Sender","version":"1.0.0"}}}

接着拉工具清单:

echo '{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | ./mcp-email

应该能看到send_email的完整 schema,包括email和content两个必填参数。如果这里返回空列表,说明AddTool没生效,检查工具名有没有拼错。

最后调一次工具:

echo '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"send_email","arguments":{"email":"test@example.com","content":"hello"}}}' | ./mcp-email

返回result.content[0].text里带 “successfully” 就说明 Server 端通了。这一步过了,再去 Client 里试。在 Cline 对话框里输入“帮我给 test@example.com 发一封内容为 hello 的邮件”,模型会先返回一个 tool_call,你点 Approve,Client 把 JSON-RPC 发给 Server,Server 执行完回传,模型再总结结果。整个过程你能在 Cline 的 MCP 日志里看到完整的请求和响应。

如果你用的是 TaoToken 的模型对话页面做纯模型验证,可以先不挂 MCP,确认 Key 和 Base URL 能正常出结果,再回到 Cline 挂工具。分两步走,排错范围小很多。

5. 常见报错排查:401、local proxy failed、reading choices、OAuth

这一节按真实报错来对号入座。

401 Unauthorized:Key 没填对,或者 Base URL 少了/api。TaoToken 的 API 地址是https://taotoken.net/api,不是根域名。检查环境变量ANTHROPIC_API_KEY或 Cline 里的 API Key 字段有没有多余空格。另外 Key 过期也会 401,去 API Keys 重新生成一个。

local proxy failed:这个多半是 MCP Server 进程没起来。检查command路径是不是绝对路径、二进制有没有执行权限(chmod +x mcp-email)、依赖的动态库在不在。还有一种情况是 Server 往 stdout 打了日志,Client 解析 JSON-RPC 失败,误报成 proxy failed。把 Server 里所有fmt.Println改成fmt.Fprintln(os.Stderr, ...)。

reading choices 相关报错:通常是模型返回的响应格式和 Client 预期不一致,常见于 Base URL 指向了不兼容的端点。确认你填的是https://taotoken.net/api,并且 Model ID 是通道支持的模型名。如果用的是 Claude Code,检查ANTHROPIC_BASE_URL有没有被其他配置覆盖。

OAuth 报错:Claude Code 某些版本会尝试走 OAuth 流程,如果你用的是 API Key 模式,需要在配置里显式禁用 OAuth,或者设置ANTHROPIC_API_KEY后不再触发登录。Codex 的auth.json里如果残留了旧的 OAuth token,也会冲突,清掉重新用 Key 认证。

tools/call 返回 Invalid params:参数类型不对。Go 里req.Params.Arguments是map[string]interface{},JSON 数字会解析成float64,如果你期望int要做转换。字符串参数用.(string)断言,失败就返回明确的错误信息,别让模型猜。

Server 启动了但 Client 看不到工具:tools/list返回了但 Client 没刷新。重启 Client,或者在 Cline 里点一下刷新 MCP 按钮。有些 Client 会缓存工具清单,改完 Server 要重启才生效。

6. 把 MCP 用起来:从单工具到 Coding Plan 的落地路径

单跑一个发邮件工具只是热身。真正有意思的是把 MCP 和日常编码流程结合:让模型通过 MCP 读你的项目文件、查数据库 schema、跑测试命令,然后基于结果改代码。这时候模型通道的稳定性和额度就很重要了,频繁的 tool_call 会消耗不少 token。

如果你打算长期在 Cline 或 Claude Code 里挂多个 MCP Server 做 Agent 式开发,可以看下 Coding Plan,它针对这种高频工具调用的场景做了额度优化。配置方式还是那三件套:Base URL 填https://taotoken.net/api,Key 用你生成的,Model ID 按需选。MCP Server 那边不用改,协议层是通的。

最后留一个我踩过的坑:MCP Server 的autoApprove别一上来就全开。发邮件、删文件这类有副作用的工具,让模型每次调用都经过你批准,否则一个幻觉就可能把测试邮件发给真实客户。把autoApprove留空,手动点 Approve,虽然多一步,但安全。

到这一步,你应该能独立写出一个 Go MCP Server、在 Cline 里挂上、用 TaoToken 的 Key 跑通一次完整的工具调用。剩下的就是按你的业务往里加工具了,协议不变,加一个 Tool 就是加一段AddTool。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/4 9:46:29

缠论程序化入门:用Python实现分型与笔的识别

缠论这套技术分析体系,这些年讨论热度一直不低,很多人一开始都是被“分型、笔、线段、中枢”这些概念给唬住了,感觉门槛很高。但真要说程序化落地,第一步其实没有想象中那么玄乎。把分型和笔的定义搞清楚,用Python写一…

作者头像 李华
网站建设 2026/10/4 9:44:49

简笔记录 - 安装“龙虾”OpenClaw 报错排查与 TaoToken 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 9:42:01

eNSP企业网实例复现指南:从拓扑拆解到NAT配置与排错

简介:这份资源是面向网络规划设计与网络安全方向学习者、网络工程师及教学人员的 eNSP 企业网模拟实例,以精品拓扑为核心,帮助读者在无真实设备的环境下完成企业网络的搭建、配置与安全策略验证。压缩包共 32 个文件,约 2.62MB&am…

作者头像 李华
网站建设 2026/10/4 9:41:50

指针和数组的关系

指针和数组的关系 C语言中,指针和数组的关系亲密得几乎"合二为一"——数组名就是一个指向首元素的指针,指针可以用下标访问,数组名也可以做指针运算。搞懂它们的关系,C语言的一半疑惑就解开了。 一、数组名就是指针 int arr[] = {10, 20, 30, 40, 50}

作者头像 李华
网站建设 2026/10/4 9:38:19

阿里Qwen3.5-Flash实测:轻量MoE大模型的API调用与TaoToken统一接入

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/4 9:37:45

Moli是什么:专为AI Agent打造的Rust开源无头浏览器终极指南

Moli是什么:专为AI Agent打造的Rust开源无头浏览器终极指南 【免费下载链接】moli Best headless browser for AI agents. Lite, Fast, High-Compatibility. Built in Rust 项目地址: https://gitcode.com/gh_mirrors/moli/moli Moli 是一款专为 AI Agent 打…

作者头像 李华