
1. 为什么 MCP 接数据库值得单独写一篇MCP 这个词从 Anthropic 提出到现在讨论度一直不低但大部分教程都停在「怎么让模型读本地文件」或者「怎么接一个天气 API」。真正落到数据库查询这条链路上坑会明显变多连接参数怎么传、stdio 和 HTTP 两种传输怎么选、模型拿到表结构之后会不会瞎编字段、一次查询烧掉多少 token这些都不是配一个 JSON 就能自动解决的。我这次要做的是把 MCP 接入 MySQL 的完整链路走一遍起点是一份可复制的settings.json骨架中间用 TaoToken 统一 Key 和 API 通道终点是一次真实的数据库查询验证。适合已经用过 RAG、但想看看「不走向量检索、直接让模型查库」这条路能不能走通的人。RAG 解决的是非结构化知识的召回而 MCP 接数据库解决的是结构化数据的实时查询两者不是替代关系是互补关系。下面所有配置和命令都可以直接抄改掉你自己的库名和账号即可。2. TaoToken 前置统一 Key 与 API 通道在配 MCP Server 之前先把模型侧的通道理顺。MCP 本身只负责「工具调用」这一层真正生成 SQL、理解表结构、把结果翻译成人话的还是背后的模型。如果你每个 MCP 客户端都单独配一套 Key后面换模型、加客户端的时候会非常乱。TaoToken 在这里的作用是提供一个统一的 API 入口模型对话、编码计划、控制台、API Keys 都在同一套体系里。你需要先拿到一个可用的 Key然后把它填到 MCP 客户端的模型配置里而不是填到 MCP Server 的env里——这一点很多人第一次会搞混。MCP Server 的env只放数据库连接信息模型 Key 放在客户端侧。具体入口模型对话验证https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite长期编码 / Agent 场景https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewriteAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteClaude Code / Anthropic 兼容https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude_codeutm_campaignrewriteAPI 基础地址是https://taotoken.net/api注意这个地址不带 UTM 参数直接用于代码里的base_url。官网首页是https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content第一次了解可以先看首页。提示MCP Server 的env里绝对不要放模型 API Key那是数据库凭证的位置。模型 Key 属于客户端配置两者职责分开后面排障会轻松很多。3. 可复制的 settings.json 配置骨架MCP 客户端的配置文件通常叫settings.json或者mcp.json不同客户端路径不一样但结构基本一致。核心是mcpServers这个键——注意是mcpServers不是servers这个拼写错误是新手最高频的翻车点写错了客户端会直接忽略整段配置而且不报错。先给一份最小可用的骨架接的是 MySQL{ mcpServers: { mysql: { type: stdio, command: uvx, args: [ --from, mysql-mcp-server, mysql_mcp_server ], env: { MYSQL_HOST: 127.0.0.1, MYSQL_PORT: 3306, MYSQL_USER: readonly_user, MYSQL_PASSWORD: your_password, MYSQL_DATABASE: your_db } } } }逐字段说明一下避免你抄完不知道哪行是干嘛的字段作用常见错误type传输方式本地进程用stdio写成sse但没起 HTTP 服务command启动命令这里是uvx没装 uv命令找不到args传给命令的参数两个mysql-mcp-server少写一个env数据库连接环境变量把模型 Key 混进来args里那两个看起来重复的mysql-mcp-server是有意为之第一个是--from指定的包名第二个是要执行的入口脚本名。少任何一个uvx都拉不起来服务。我试过只写一个客户端日志里会报command not found但界面上只显示「连接失败」很容易误判成网络问题。如果你用的是 HTTP SSE 传输骨架会变成这样{ mcpServers: { mysql-http: { type: sse, url: http://127.0.0.1:8000/sse, env: {} } } }本地开发优先用stdio跨机器或者要多人共享才考虑sse。stdio的好处是进程隔离干净客户端退出服务就停不会留一堆僵尸进程。4. 从零把 MySQL MCP Server 跑起来配置文件写好了但uvx背后需要 Python 环境和依赖。这一步不做配置就是一张废纸。先装 uv它是 Rust 写的 Python 包管理器比 pip 快很多# macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # 验证 uv -VWindows 用 PowerShellpowershell -ExecutionPolicy ByPass -c irm https://astral.sh/uv/install.ps1 | iex然后准备 Python 3.11 环境mysql-mcp-server要求 Python 3.11uv python install 3.11 uv venv mcp source mcp/bin/activate python -V装依赖国内网络建议走镜像源uv pip install mysql-mcp-server --index-url https://pypi.tuna.tsinghua.edu.cn/simple装完之后先手动跑一次服务确认它能起来再交给客户端托管MYSQL_HOST127.0.0.1 \ MYSQL_PORT3306 \ MYSQL_USERreadonly_user \ MYSQL_PASSWORDyour_password \ MYSQL_DATABASEyour_db \ uvx --from mysql-mcp-server mysql_mcp_server如果终端没有立刻报错退出而是停在那里等输入说明服务起来了。这时候按 CtrlC 停掉回到客户端里点连接。注意数据库账号强烈建议用只读账号。MCP Server 暴露的工具里包含执行 SQL 的能力虽然模型一般不会主动写库但权限收窄是底线。给一个只有SELECT权限的账号比事后审计日志省心得多。5. 验证一次数据库查询链路配置连上之后别急着问复杂问题。先用一个最小查询验证链路通不通再逐步加复杂度。第一步让模型列出所有数据库请调用 mysql 工具列出当前连接下所有的数据库名称。这一步验证的是tools/list和tools/call能不能正常走通。如果模型回复里出现了真实的库名说明 MCP Server 和客户端之间的 JSON-RPC 通信没问题。第二步指定库让它读表结构在 your_db 这个库里列出所有表名并说明每张表的用途。这一步会触发resources/list模型拿到的是表结构元数据。注意观察它有没有编造字段——如果它开始说「这张表应该有 create_time 字段」但实际没有说明它在靠常识猜这时候要立刻纠正。第三步做一次真实查询查询 orders 表中最近 7 天的订单数量按天分组只返回日期和数量。这一步是完整链路模型生成 SQL → MCP Server 执行 → 结果回传 → 模型整理成自然语言。如果前面两步都正常这一步大概率能出结果。实测下来不同客户端在这条链路上的表现差异很大。轻量客户端响应快一次查询可能只花几百 token但统计类问题容易漏数据功能完整的编码客户端会严格按资源边界处理结果准确但一次查询可能烧掉十几万 token。这不是模型能力问题是客户端在「要不要把完整表结构塞进上下文」上的策略不同。如果你发现模型开始瞎编数据八成是提示词里没有限定「必须基于查询结果回答」。加一句约束你只能基于 mysql 工具返回的实际数据回答不允许推测或编造任何字段和数值。加上这句之后幻觉会明显减少。6. 本篇常见错误排查配 MCP 接数据库报错信息往往很含糊这里列几个我踩过的坑和对应解法。连接失败但没有任何日志先检查mcpServers拼写。写成servers或者mcp_servers客户端会静默忽略。这个错误没有任何提示只能靠肉眼核对。uvx: command not founduv 没装或者没进 PATH。装完之后重开终端或者手动source ~/.local/bin/env。ModuleNotFoundError: mysql_mcp_serverargs里两个mysql-mcp-server少写了一个或者依赖没装成功。回到第 4 节手动跑一次确认。能连上但工具列表是空的数据库账号权限不足或者MYSQL_DATABASE指向的库不存在。用命令行mysql -u readonly_user -p手动连一次确认账号能读到库。模型回答里出现不存在的表名这是幻觉不是 MCP 的问题。加约束提示词或者换一个更严格处理资源的客户端。查询结果和直接跑 SQL 不一致检查模型生成的 SQL 有没有加LIMIT很多客户端默认会截断结果集。让它把完整 SQL 打印出来自己拿去数据库里跑一遍对比。token 消耗异常高客户端把整个information_schema都塞进上下文了。在提示词里限定只关注指定库或者换用按需读取资源的客户端。7. 下一步怎么走数据库这条链路跑通之后你会发现 MCP 的价值不在「让模型会查库」而在「把查库这件事标准化成可复用的工具」。同一个 MCP Server换个客户端就能用不用为每个应用重写一遍对接逻辑这才是协议层统一的意义。如果你主要做长期编码或者 Agent 编排建议把模型通道切到 Coding Plan省得每次手动配 Keyhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite如果只是想先验证模型对 SQL 的理解能力用模型对话页面快速试几轮就行https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite接入过程中遇到配置报错先翻接入文档里的示例大部分settings.json的坑那里都有对照https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewriteKey 管理和额度查看在控制台https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite最后提醒一句MCP 接数据库不是要取代 RAG。文档、日志、图片这类非结构化内容还是走向量检索更合适订单、库存、用户这类结构化数据直接查库更准更快。两条路并行才是完整的上下文供给方案。