☰
深入理解 MCP 协议:从 JSON-RPC 底层通信到 MySQL 实战接入 TaoToken
2026/9/30 19:44:08 网站建设 项目流程

1. 为什么你的 MySQL 查询总在 MCP 里断联

很多人第一次接触 MCP 协议,脑子里装的全是“AI 的 USB-C 接口”这种比喻,真到动手把 MySQL 接进去的时候,发现连不上、报错看不懂、工具调不动。我试过用最笨的办法排查:先确认 MCP 服务端到底有没有把tools/list暴露出来,再确认客户端发出去的 JSON-RPC 请求长什么样,最后才去看 MySQL 连接本身。这个顺序能帮你省掉大量瞎猜的时间。

MCP 全称 Model Context Protocol,它要解决的核心问题很具体:让任何支持该协议的 AI 客户端,都能用同一套标准去调用你写的外部工具。你写一次 MySQL 查询服务端,Claude Desktop、Cursor、Cline 这些宿主应用都能直接接。它底层用的消息格式是 JSON-RPC 2.0,传输通道有 stdio 和 HTTP 两种。你不需要理解全部规范,但必须搞清楚三件事:请求长什么样、服务端怎么启动、客户端配置写在哪里。

这篇文章面向的是已经会写 Python、手头有 MySQL 库、想让 AI 直接查数据的开发者。我会从 JSON-RPC 的消息结构讲起,然后给你一份可复制的config.toml和settings.json骨架,接着用 TaoToken 的统一 API 通道把服务端接进去,最后用真实的 JSON-RPC 请求验证 MySQL 工具调用是否生效。全程不绕弯,每一步都有命令和结果说明。

先说清楚 TaoToken 在这里的角色。TaoToken 提供统一的 API Key 和模型接入通道,官网是 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,API 入口是 https://taotoken.net/api 。你写好的 MCP 服务端通过它来调用模型能力,这样你不需要在本地维护多个厂商的 Key,一个 Key 就能跑通整个链路。下面进入正题。

2. JSON-RPC 消息格式与 stdio/HTTP 传输通道拆解

MCP 的通信层没有魔法,它就是 JSON-RPC 2.0。一条请求由四个字段组成:jsonrpc固定为"2.0",id用来匹配请求和响应,method是你要调用的方法名,params是参数对象。服务端返回时带上同样的id,把结果放在result里,出错则放在error里。

MCP 定义了几个核心方法,你写服务端时最常打交道的是这三个:initialize用于握手协商能力,tools/list用于暴露工具清单,tools/call用于实际执行某个工具。客户端启动后会先发initialize,再发tools/list拿到你注册的所有工具,之后模型决定调用哪个工具时,客户端就发tools/call。

一条tools/call请求的真实样子是这样的:

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "query_data", "arguments": { "sql": "SELECT id, name FROM users LIMIT 3" } } }

服务端执行完 MySQL 查询后返回:

{ "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "[{\"id\": 1, \"name\": \"张三\"}, {\"id\": 2, \"name\": \"李四\"}]" } ] } }

注意result.content是一个数组,里面每个元素有type和text。这是 MCP 规定的返回结构,模型读到text字段后把它转成自然语言给你。你写服务端时只要保证返回这个结构,客户端就能正确解析。

接下来是传输通道。stdio 模式下,MCP 服务端作为宿主应用的子进程运行,双方通过标准输入输出交换 JSON-RPC 消息。它的优点是配置极简,不需要开端口,本地开发首选。缺点是只能本机用,没法远程访问。HTTP 模式下,服务端作为独立进程监听端口,客户端通过 HTTP POST 发送 JSON-RPC 请求,可选 SSE 做流式推送。它适合多客户端连接和远程部署,但配置项更多。

这里有个我踩过的坑:早期 MCP 用的是 SSE 传输,后来协议做了破坏性更新,改成 Streamable HTTP。如果你照着老教程配 SSE,连接会一直断。判断方法很简单,运行pip show mcp看版本,0.9.0 以上才支持新的传输规范。版本不对就升级,别在旧实现上浪费时间。

两种通道的选择逻辑很清晰:本地单机调试用 stdio,需要多人共用或远程访问用 HTTP。下面两节我会分别给出可复制的配置。

3. 可复制配置:config.toml 与 settings.json 骨架

这一节给你两份能直接改改就用的配置骨架。第一份是 MCP 服务端的config.toml,第二份是客户端侧的settings.json。两份配置里的 Base URL、Key、Model ID 三件套必须写全,缺一个都会在验证阶段报错。

先看服务端的config.toml。这个文件放在你的 MCP 项目根目录,用来管理数据库连接和 TaoToken 通道参数:

# config.toml - MCP MySQL 服务端配置 [server] name = "mysql-assistant" version = "0.1.0" transport = "stdio" # 可选 stdio 或 http [transport.http] host = "0.0.0.0" port = 8000 path = "/mcp" [database] host = "127.0.0.1" port = 3306 user = "root" password = "your_password" database = "your_db" charset = "utf8mb4" [taotoken] base_url = "https://taotoken.net/api" api_key = "sk-你的TaoToken密钥" model_id = "claude-3-5-sonnet"

transport字段决定用哪种通道。改成http后,服务端会读取[transport.http]段启动 HTTP 监听。[taotoken]段里的base_url固定写https://taotoken.net/api,api_key从 TaoToken 控制台生成,model_id填你要用的模型标识。

再看客户端侧的settings.json。如果你用的是 Cline 或 Claude Code 这类支持 MCP 的客户端,配置写在这里:

{ "mcpServers": { "mysql-assistant": { "command": "python", "args": ["/绝对路径/mysql_mcp_server.py"], "env": { "TAOTOKEN_BASE_URL": "https://taotoken.net/api", "TAOTOKEN_API_KEY": "sk-你的TaoToken密钥", "TAOTOKEN_MODEL_ID": "claude-3-5-sonnet" } } } }

如果你走 HTTP 模式,settings.json改成 URL 形式:

{ "mcpServers": { "mysql-assistant": { "url": "http://127.0.0.1:8000/mcp", "headers": { "Authorization": "Bearer sk-你的TaoToken密钥" } } } }

三件套的对应关系是:Base URL 填https://taotoken.net/api,Key 填你生成的sk-开头密钥,Model ID 填模型标识。这三个值在 stdio 模式下通过env传入,在 HTTP 模式下通过headers传入。写错任何一个,验证阶段都会看到 401 或模型找不到的报错。

配置写完后,stdio 模式直接启动 Python 脚本即可,HTTP 模式需要先启动服务端再启动客户端。切换步骤在下一节结合验证一起讲。

4. 验证请求:用 JSON-RPC 确认 MySQL 工具调用生效

配置写完不等于接通,必须用真实的 JSON-RPC 请求验证一遍。我习惯分三步走:先验证服务端能列出工具,再验证工具能查到数据,最后验证模型能通过 TaoToken 通道调用工具。

第一步,验证tools/list。如果你走 HTTP 模式,服务端启动后直接用 curl 发请求:

curl -X POST http://127.0.0.1:8000/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的TaoToken密钥" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {} }'

正常返回会列出你注册的所有工具,比如query_data、get_table_schema、list_tables。如果返回空数组,说明工具注册没生效,检查@mcp.tool()装饰器有没有写对。

第二步,验证tools/call能查到 MySQL 数据:

curl -X POST http://127.0.0.1:8000/mcp \ -H "Content-Type: application/json" \ -H "Authorization: Bearer sk-你的TaoToken密钥" \ -d '{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "query_data", "arguments": { "sql": "SELECT id, name FROM users LIMIT 3" } } }'

返回的result.content[0].text里应该有你数据库里的真实数据。如果返回“数据库错误”,先检查config.toml里的数据库账号密码,再确认 MySQL 服务是否在跑。

第三步,验证模型调用链路。在客户端里直接问:“帮我查一下 users 表里前三条记录”。客户端会先发tools/list拿到工具清单,模型决定调用query_data,客户端发tools/call,服务端查完 MySQL 返回结果,模型再把结果转成自然语言。整个过程你能在客户端日志里看到完整的 JSON-RPC 消息流。

stdio 模式的验证方式略有不同,因为消息走标准输入输出,没法用 curl。你可以在服务端加一行日志,把收到的每条请求打印出来,然后在客户端触发一次查询,看日志里有没有tools/call进来。确认有请求进来且返回了数据,就说明链路通了。

验证通过后,你可以把transport从stdio改成http,重启服务端,把客户端的settings.json从command形式改成url形式,再跑一遍上面三步。两种模式切换的核心就是改配置里的传输字段和客户端的连接方式,工具代码本身不用动。

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

这一节列出我实际遇到过的几类报错,以及对应的排查动作。你按顺序对照,基本能覆盖九成以上的接入问题。

第一类,401 Unauthorized。这个最直接,就是 Key 不对或没传。检查三处:config.toml里的api_key是不是sk-开头且没有多余空格,settings.json里的TAOTOKEN_API_KEY或Authorization头有没有写对,HTTP 模式下Bearer后面有没有跟空格。如果 Key 是从控制台复制的,注意别把换行符带进去。

第二类,local proxy failed。这个报错通常出现在客户端尝试连接 MCP 服务端时。排查顺序是:先确认服务端进程有没有真的启动,ps aux | grep mysql_mcp_server看一眼;再确认端口有没有被占用,lsof -i :8000检查;最后确认settings.json里的路径或 URL 写对了。stdio 模式下最常见的原因是 Python 路径不对,args里必须写绝对路径。

第三类,reading choices 相关报错。这个一般出现在模型返回阶段,说明模型返回的内容格式不符合预期。检查model_id有没有写错,以及 TaoToken 通道是否正常。你可以先用模型对话功能单独测一下模型能不能正常返回,确认通道没问题后再排查 MCP 侧。

第四类,OAuth 相关报错。如果你用的是 Claude Code 这类带 OAuth 流程的客户端,可能会遇到 token 过期或回调失败。这类问题的排查重点是确认客户端的登录状态,以及settings.json里的配置有没有覆盖掉 OAuth 流程。如果你走的是 TaoToken 的 Key 通道,一般不会触发 OAuth,遇到这类报错先检查是不是配置写混了。

第五类,工具调用返回空结果。JSON-RPC 请求发出去了,服务端也返回了,但result.content是空的。这种情况多半是工具函数的返回值没有按 MCP 规范包装。记住返回结构必须是{"content": [{"type": "text", "text": "..."}]},直接返回字符串或字典都不行。

排查时有个通用技巧:把服务端的日志级别调到 DEBUG,把每条收到的 JSON-RPC 请求和返回都打出来。这样你能清楚看到请求有没有进来、参数对不对、返回结构符不符合规范。大部分问题看一眼日志就能定位。

6. 把 MySQL 查询接进你的 AI 工作流

走到这里,你已经有了一个能跑的 MCP MySQL 服务端,两种传输通道都验证过,常见报错也能自己排查。接下来就是把它接进日常开发流程。

如果你只是偶尔查一下数据,stdio 模式足够用,配置简单,启动快。如果你要和团队共用,或者需要远程访问,就切到 HTTP 模式,把服务端部署在一台内网机器上,其他人通过 URL 接入。切换时记得同步改客户端的settings.json,stdio 用command,HTTP 用url。

TaoToken 的接入点在这里:你的 MCP 服务端通过https://taotoken.net/api调用模型能力,一个 Key 管所有模型。需要生成或管理 Key 就去 API Keys 页面,接入细节看接入文档。如果你要验证模型返回效果,用模型对话功能单独测。如果你打算长期跑编码类 Agent 任务,Coding Plan 更适合。

最后留一个实用建议:工具描述(docstring)比工具代码本身更影响实际可用性。模型是通过读你的描述来决定调不调、怎么调的。描述里写清楚“只允许 SELECT”“查询前先用 get_table_schema 了解表结构”,模型的行为会准确很多。这个细节很多教程不提,但它直接决定你的 MCP 服务端好不好用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询