环境说明:Windows + Trae + KES MCP Server + DeepSeek(OpenAI 兼容 API),后端连 KingbaseES V9,端口 54321

image.png

一、平时写代码经常遇到的一个情况

先讲一个我几乎天天都会碰到的情况。

写业务代码的时候,有时候我想确认一下一张表的字段类型是什么。我得切到数据库客户端里面去。先找库,再找 schema,然后双击表。看半天字段和约束。那如果我想知道某条查询为什么慢呢?又要去复制建表语句。还得拉出索引清单,跑一下执行计划。接着把这堆信息拷回 IDE 里面,粘进 AI 对话框。让大模型帮忙分析。一次排查弄下来,鼠标在 IDE、数据库客户端、AI 网页这三个窗口之间来回点,点个七八次是很常见的情况。

更别扭的情况其实还有。我喂给 ChatGPT 的那些表结构和执行计划,全是我手工搬运过来的静态文本。AI 看到的其实不是真实的库。它看到的就是我复制下来的那点文本。它给的建议听着好像是对的。但是呢,一旦我漏贴了某个索引,或者线上的表结构其实早就改过了。它给出的结果就是错的。信息这样搬来搬去,效率很低,而且特别容易出现信息丢失的情况。

于是我就一直琢磨一个问题。有没有这种可能呢?就是我直接在写代码的 IDE 里面问一句,orders 表有哪些字段和索引,或者帮我看看这个库健不健康。然后 AI 就能基于真实的、当前的数据库环境来回答我。而不是靠我自己手动去复制文本给它。

让我比较意外的是,金仓官方其实已经把这个东西做出来了。也就是KES MCP Server。这篇文章的话,我就带着你在 Trae 里面把它跑起来。完整体验一下用自然语言去操作金仓数据库的过程。看完这篇文章,你能拿到一套可以直接用的部署配置。还有四个真实场景的操作例子。以及几个一次性就能写对的关键配置要点。

二、KES MCP Server 到底是什么:先说一下原理

要玩明白它的话,得先搞懂 MCP 是什么意思。

MCP(Model Context Protocol,模型上下文协议),它其实就是一套协议。这套协议是用来让大模型跟外部工具或者数据源进行标准化对接的。以前的情况是什么样的呢。每个应用如果想让自己的能力被 AI 调用,都得自己单独写一套对接的代码。有了 MCP 之后呢,大家都遵循同一套标准格式。AI 客户端就可以直接去发现并调用任何 MCP Server 暴露出来的能力了。

它跑起来的链路其实是这样的:

  1. 我在 Trae 里面用自然语言提问;
  2. Trae 这个时候是作为 MCP Client 的。它会先去问 Server 有哪些工具,每个工具要什么参数。然后把这些工具清单,还有我的问题,一起交给后面的大模型;
  3. 大模型拿到之后会去判断,该调哪个工具,参数填什么。接着生成一次工具调用的请求;
  4. KES MCP Server 收到这个请求。它先做参数校验和访问控制。做完这些之后,再用它自己持有的数据库连接去 KES 里面执行;
  5. 数据库把结果返回来。经过 Server 回传给大模型。大模型整理一下,用人话讲给我听。
    image.png

这里有一个最关键的地方,也是特别容易被忽略的。那就是开发工具永远不会绕过 MCP Server 直连数据库。AI 手里是没有数据库连接串的。它能做的事情,往往仅仅只是请求 Server 帮忙执行某个工具而已。这其实就带出了一个问题。为什么非要中间夹这一层呢?为什么不让 AI 直接连库?

原因其实就在于安全。如果让大模型直接拿着数据库连接。它生成的任何 SQL 都会被直接执行出去。比如你说删掉所有测试数据,它要是理解偏了,那就是线上的生产事故了。中间加上 MCP Server 这一层呢,就是用来做限制的。它会对 SQL 做类型白名单的校验。碰到高危的写操作会直接拦截。能访问什么能力也是限定好的。AI 负责理解你的意图,Server 负责把关执行。这两件事是分开的。

如果从分层的角度来看的话。整条链路大概可以分成五层:开发工具→ 大模型→ MCP 协议层 → KES MCP Server(校验与访问控制)→ KingbaseES 数据库。AI 能做的事情,就是被这样一层一层收窄的。
image.png

它对外一共暴露了 9 个标准工具。我按照它们能干的事情,分成了四类:

  • 结构探索list_schemas(用来列 schema)、list_objects(用来列表、视图这些对象)、get_object_details(看某个对象具体的字段、约束还有索引详情的情况)
  • 查询与计划execute_sql(执行查询)、explain_query(看执行计划)
  • 运维诊断analyze_db_health(做 7 个维度的健康检查)、get_top_queries(基于 sys_stat_statements 查出 Top N 的慢查询)
  • 索引优化analyze_workload_indexesanalyze_query_indexes(用来给索引提建议)
    image.png

这篇文章主要就是体验一下前三类的自然语言操作。索引优化那两个工具的话,背后其实是一整套深度调优的方法。这个不是这篇文章的重点。传输方式的话,它支持 Stdio,这个本地开发比较推荐,因为不需要开端口。还支持 SSEStreamable HTTP,后面这两个是面向远程的情况。安全方面它分了两种模式:restricted(SQL 白名单、拦截高危写操作,演示或者生产环境都强烈推荐用这个)和 unrestricted(全权限,要慎用)。我这篇文章里面全程都是用 restricted 模式的。

三、环境准备:给 AI 一个「只读的沙盒」

先别急着敲代码。准备环境这步得先做。我单独建了一个演示库 ai_demo。跟别的项目隔离开来的。这种情况下面,就算 AI 出了什么错,别的数据也不会受影响。

1)建演示库、造点业务数据。建表的话,我弄了个 orders 表。接着就是造数据。用 generate_series 去生成 5000 行随机数据,其实就是用来模拟平时业务里那些订单的:

CREATE DATABASE ai_demo;
\c ai_demo
CREATE TABLE orders (
    id serial PRIMARY KEY,
    user_id int,
    product varchar(64),
    amount numeric(10,2),
    status varchar(16),
    created_at timestamp DEFAULT now()
);
INSERT INTO orders (user_id, product, amount, status)
SELECT (random()*1000)::int,
       (ARRAY['平板电脑T10','智能手表Pro','显示器27寸','空气净化器A5','无线耳机X1'])[floor(random()*5+1)],
       round((random()*3000)::numeric,2),
       (ARRAY['pending','paid','done'])[floor(random()*3+1)]
FROM generate_series(1,5000);

image.png

2)为 AI 建一个最小权限账号 ai_reader。这一步其实是我觉得最不能省的。官方文档里也特意提了这个。MCP Server 它能管一些事情。但真要说防住问题,靠的还是数据库账号权限本身。白名单如果出了漏洞被绕过了怎么办?只要这个账号是只读的,也就是说没有任何写权限。那么 AI 就算想删数据或者改数据,也是做不到的。安全这东西,不能只靠一个地方去拦,得多弄几道关卡:

CREATE USER ai_reader WITH PASSWORD '<强密码>';
GRANT CONNECT ON DATABASE ai_demo TO ai_reader;
GRANT USAGE ON SCHEMA public TO ai_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_reader;

-- 为运维诊断工具补一组「只读监控」权限(全是读权限、零写)
GRANT sys_monitor TO ai_reader;                                     -- 读系统监控视图(含慢查询 SQL 文本)
GRANT USAGE ON SCHEMA sys_hm TO ai_reader;                          -- 健康体检用到的 sys_hm 模式
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA sys_hm TO ai_reader;
GRANT SELECT, USAGE ON ALL SEQUENCES IN SCHEMA public TO ai_reader; -- 序列健康检查

后面那四条代码,我多解释一下。像 analyze_db_health 还有 get_top_queries 这些东西,它们是运维诊断用的。它们得去读系统的监控视图,还得读 sys_hm 模式,序列信息也要看。光给表的 SELECT 权限是不够用的。所以得额外补一组只读监控权限。sys_monitor 这个东西,它是金仓里面自带的一个只读监控角色。如果你用的版本里这个角色名字不一样,那你换成你自己版本里的只读角色就行了。但这里有个重点。那就是它们全是读权限、不含任何写。最小权限的核心并没有变,AI 还是改不了数据,也删不了数据。给 AI 分配权限的话,我就认死一个理,够用就好,能少给就少给。这次对接的所谓第三方,其实也就是个大模型而已。

3)装上假设索引扩展 sys_hypoexplain_query 这个功能,它是用来模拟情况的。模拟什么呢?就是假如你建了某个索引,情况会变成什么样。这个时候就会用到这个扩展。另外慢查询需要用的 sys_stat_statements,这个的话我库里其实已经装好了:

CREATE EXTENSION IF NOT EXISTS sys_hypo;

四、安装 KES MCP Server

前置条件:Python 3.12–3.13、包管理器 uv、Trae。金仓要求 KES V8R6 及以上,我的 V9R1C10 满足。整个安装分三步走,一步一步来,uv 比传统 pip + venv 舒服不少。

1)先装好 uv Windows 下用官方一键脚本最省事,在 PowerShell 里执行:

powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

装完 uv 会落在 C:\Users\<你的用户名>\.local\bin,脚本会提示把这个目录加进 PATH。这里有个小细节:装完要新开一个终端窗口PATH 才会生效。新窗口里用 uv --version 能打印版本号,就说明 uv 就位了。

2)克隆仓库、建环境、装依赖。 仓库 clone 到任意一个工作目录即可(最好跟金仓的安装目录分开,互不干扰)。装之前先用 uv venv 建一个项目专属的虚拟环境,再把项目装进去:

git clone https://gitee.com/king-db/kingbase-mcp
cd kingbase-mcp
uv venv              # 建项目专属虚拟环境 .venv
uv pip install .     # 把 kingbase-mcp 及其依赖装进该环境

77e605f0-def5-4287-aa11-c4a7cac32e89.png

为什么要先 uv venvuv pip install 需要一个明确的目标环境,它不会默认往系统 Python 里装东西。先建好 .venv,依赖就全隔离在项目目录里,不污染全局 Python;后面 uv run 也会自动认这个 .venv
6673a823b061c984adef6de405523306.png

3)手动起一次,确认能连通。 正式使用时连接串由下一节的 Trae 通过环境变量注入;想在命令行先验证一把,临时设好 DATABASE_URI 再运行即可(ai_reader 就是第三章建的那个最小权限账号):

set DATABASE_URI=kingbase://ai_reader:<你的密码>@<服务器IP>:54321/ai_demo
uv run kingbase-mcp --access-mode restricted

终端依次打印出 Starting KingbaseES MCP Server in RESTRICTED modeSuccessfully connected to database and initialized connection pool,就说明依赖装好、也成功连上了金仓(Windows 下会附带一句 Signal handling not supported on Windows,是平台差异、不影响使用;Ctrl+C 退出即可)。
d20befd1a31c30451eecdeb348162a79.png

五、在 Trae 中配置 MCP:保存即自动加载 9 个工具

打开 Trae 的 MCP 管理面板,手动添加一段 JSON。
886558ab46c1fccb35fb6f1a1f5716d4.png

要点有三:commanduv--directory 指向刚 clone 的仓库绝对路径DATABASE_URI 填演示库和最小权限账号 ai_reader,访问模式锁死 restricted

{
  "mcpServers": {
    "kingbase-mcp": {
      "command": "uv",
      "args": [
        "--directory", "F:\\CodeDir\\mcp\\kingbase-mcp",
        "run", "kingbase-mcp",
        "--access-mode", "restricted"
      ],
      "env": {
        "DATABASE_URI": "kingbase://ai_reader:<强密码>@<服务器IP>:54321/ai_demo"
      }
    }
  }
}

填写提醒<强密码><服务器IP> 是占位符,替换时要连同尖括号 <> 一起去掉,只留真实值。要是把 <> 留在串里,它们会被当成密码和主机名的一部分,直接导致连接失败。

保存的一瞬间就能感受到 MCP 的「即插即用」:kingbase-mcp 亮起绿灯,展开它,前面讲的 9 个工具被自动加载列了出来——我没写一行对接代码,Trae 就完成了「工具发现」。这正是第二节说的:Client 向 Server 问一句「你有啥能力」,剩下的全自动。
9f54944dff479fb36a24ffbcd05345d0.png

建一个「智能体」,让工具真正被调用

工具加载出来,还差最后一步:在 Trae 里,MCP 工具不是在普通对话里直接就能用的,得先挂到一个智能体(Agent) 上。进入「智能体 → 创建智能体」,给它起个名字(我叫「KES 中间服务代理」),在下方工具区把 kingbase-mcp 勾上,保存。
5dc41b46efd18c8c1e4e19815e4f76b2.png

之后在对话框用 @ 选中这个智能体,它就能按需调用那 9 个工具了;对话模型我接的是 DeepSeek(任意 OpenAI 兼容 API 都行)。
c2bb47dac863dbda122df1d69cc2a164.png

配置要点:--directory 的路径写法。 这段 JSON 里最需要留意的就是 --directory 的值,两点写对就能一次亮绿灯:一是填绝对路径(如 F:\CodeDir\mcp\kingbase-mcp),Trae 会以它为工作目录拉起子进程,相对路径容易定位不到项目;二是 Windows 路径的反斜杠在 JSON 里要双写 \\(单个 \ 会被 JSON 转义吃掉)。填对这两点,保存后 kingbase-mcp 立刻亮起绿灯。(MCP 面板还能查看子进程 stderr 日志,是核对配置的好帮手。)

六、实战一:用自然语言探索库结构

前面的配置弄完没问题的话,我们就可以开始试了。我当时是在 Trae 那个对话框里直接敲了这行字:

列出 public schema 下所有的表。
4e68eba4e378bcdf6213e7f05fd85c61.png

它知道我想干嘛,然后就去调了 list_objects,最后把真实的表单给列出来了。这中间有个细节。我在 Trae 界面上能清清楚楚看到一行提示,写着「正在调用 kingbase-mcp / list_objects」。这个事情很关键,它不是凭记忆编的,是真去库里查的。接着我又问了一句:

查看 orders 表的字段、约束和索引。

这回它换了个方法,调的是 get_object_details。它把字段类型还有约束、索引这些信息分开了列出来(orders 的主键在这里头,是以 orders_pkey 索引的样子放在了「索引」这一栏里面的),这些东西直接来自当前 KES 实例,我根本不用提前去把建表语句给复制过来贴进去。
326a602e46026b7171e357ec5850c6b6.png

那么到底省了哪些事呢?要是按以前的习惯,我得先把窗口切到数据库客户端那边。然后一级一级去点开。点完还得手动敲一个 \d orders。现在就是一句话的事。表结构直接就显示在我写代码的这个界面里了。其实这种只用一句话就能搞定的感觉,到这一步就已经有了。

七、实战二:用自然语言查询业务数据

看表结构其实只是个开头。我们平时干活,查数据才是最经常干的事。我一行 SQL 都没写,就是直接把需求打字说出来:

查询本月销售额排名前 5 的商品。

它把我们说的话转成了 SQL。具体怎么转的呢?它先按 product 去做了分组。然后用了 SUM(amount) 算总和。接着它用 date_trunc('month', created_at) = date_trunc('month', current_date) 把时间范围框在了「本月」(也就是说按自然月来算的)。最后加上了 ORDER BY total_sales DESC LIMIT 5。这些代码通过 execute_sql 在金仓里面跑了起来。跑完之后,它把结果给整理成了表格的样子给我看。这次它把写出来的 SQL 还有那 Top 5 的结果一起放在了那儿。看得很清楚。

不过这里我要多嘴说一句。这也是我自己平时一直保持的一个习惯:AI 生成的 SQL 一定要人工核对。你仔细想想,它说的「本月」到底是指自然月呢,还是往前推30天的那种滚动月份?还有这个金额,要不要把订单状态给区分开?比如那些没支付的 pending 状态的订单,到底算不算在销售额里面?这些业务上的细节,模型往往是仅仅只是靠猜的。我个人的话,一般会要求它把生成的 SQL 一并贴出来。我自己先扫一眼里头的逻辑,然后再去看它返回的结果。用起来是挺方便的,但是绝对不能直接就信了。

1fe5c95035f62cdc05940a3d8fd74893.png

八、实战三:一句话给数据库做健康体检

如果是运维那种情况的话,MCP 的用处就更明显了。我当时敲了这句:

检查一下数据库的健康状况。

49c949049da1edbe8ad480744ef824a7.png

它去调用了 analyze_db_health。它从缓冲还有缓存、索引、连接、序列与约束、主从复制、Vacuum 这些多个维度去做了检查。最后给我返回了一份有格式的报告。我实际测下来,这个库整体给出的结论是「良好」。缓冲命中的数据挺好看的。索引缓存命中率有 99.8%。表缓存命中率是 99.0%。这两个数字都远远超出了 95% 那个健康及格线。这就说明大部分数据直接从内存里就能读到。另外索引这边也没有出现什么失效的、重复的或者膨胀没用的。连接、序列、约束这些也全都在正常的情况里。不过它还标了一个值得关注的地方。它说系统表 sys_catalog._kingbase_loginfo 那里有个事务 ID 回卷(Wraparound)的提示。这个得注意一下,这是系统内部表。并不是我们自己的业务表。通常来说这种情况是由数据库自己去维护的。但是连这种系统底下的隐患都能扫出来,说明它确实是在认真查。要搁在以前,这些指标得靠自己写一堆系统视图的查询语句,然后手动拼到一起。现在就是一句话的事,体检单就出来了。

查完这些,我顺手又让它去把耗时间长的查询找出来:

找出最近总耗时最高的 5 条 SQL。

1c61c45f5b8d30a7ac23c9cf27800252.png

这一步它用的是 get_top_queries。它底下靠的是之前装好的 sys_stat_statements(这个插件会把整个实例的 SQL 执行统计给记下来)。它把总耗时排在最前面的 5 条给拉出来了。每条里面都带着总耗时、执行次数、平均耗时、返回行数和 SQL 原文。我实际看到排在前面的,是 ANALYZE 还有 CREATE INDEX 这种维护或者叫 DDL 的操作。这种操作只跑一次,耗时多一点也是正常的。排在后面的才是 SELECT * FROM ... WHERE ... 这种我们写的业务查询。时间到底花在哪了,看一眼就知道了。如果在这里头发现了有问题的 SQL,按理说是可以接着让它跑一下 explain_query 去看执行计划的。但是呢,执行计划怎么读、索引怎么调、参数怎么设,那是一整套 DBA 的深度活儿,不在本文范围。我这里想说的其实就是那个使用感受。从脑子里想做个体检,到最后拿到这份体检单。中间完全不用去切换任何别的窗口。

九、实战四:Restricted 模式的安全边界——删数据被拦下

数据库这东西在企业层级里是很底层的设施。肯定不能让 AI 随便去操作。前面我提了好几次的安全设计。这一节我们就来测测到底有没有用。我整个过程都是开着 restricted 模式的。这个模式里面有个 SQL 类型的白名单。遇到那种危险的写操作,它就会给拦住。我当时故意让它去干一件有风险的事:

把 orders 表里 status 为 pending 的订单都删掉。

972f07ea8ba38e2fca7a94b2850aa881.png

restricted 模式下,这种写入或者删除的操作直接就被挡住了。这个请求根本没有机会碰到数据库。这就是第二节里说的那个控制机制在起作用。退一步讲,就算这层没拦住。我们用的 ai_reader 这个账号,它全都是只读的权限。就连监控那些也是只能读不能写。那么到了数据库那一层,一样会把请求拒绝掉。Server 白名单 + 账号最小权限双保险叠加。只有做到这样,我才敢把一个大模型接到我自己的库上去。

实际测下来,这句删除的话刚发出去就被拦了。AI 返回了「请求已被拒绝」这几个字。并且给了一段审计的信息。里面写着操作类型是 DELETE。目标对象是 public.orders。拦截的原因写的是「未授权的访问尝试」。后面还写得很清楚,说「当前配置的系统权限和 MCP 数据库接口(execute_sql)仅允许执行只读操作,禁止通过此通道执行 DELETE/UPDATE/INSERT 等修改或删除数据的写操作」。也就是说请求根本没落到数据上。orders 表里面一行数据都没少。

十、体验总结:它是助手,不是 DBA 替身

这么一整圈搞下来。我最直接的一个感觉就是:排查数据库问题,不用再在 IDE 和客户端之间来回切了。 不管你是要看表结构、查业务数据还是看健康情况。只要打一句人说的话就能拿到。而且这些答案全都是从真实的金仓实例里出来的。

我们可以回想一下开头说的那个对比。老做法是「手工在客户端查结构,复制粘贴给 ChatGPT 分析」。这两个做法最大的区别,其实不在于你省去了几次复制粘贴的动作。区别在于另外一点。在老做法里面,AI 看到的东西,是我手动搬过去的。那些东西很有可能是过期的,或者是不全的静态快照。但是用了 KES MCP Server 之后呢,AI 面对的就是当前真实、完整、实时的库环境。它查出来是什么就是什么。不会因为我自己漏贴了一个索引,它就分析错了。这个变化是很实在的。

  • 适合谁:那些平时经常要查库、排查 SQL 问题的开发人员。还有一些想要把数据库操作门槛给降下来的团队。
  • 要注意什么:在演示或者生产环境里面,一定要开 restricted 模式,然后配上最小权限的账号。另外 explain_query 这个功能需要用到 sys_hypo。慢查询分析得靠 sys_stat_statements。在用之前记得先把这些给装好。如果是本地开发的话,优先去用 Stdio 传输。
  • 它的边界:AI 生成的 SQL 还是得靠人去对一下业务口径(这个在实战二里面已经说过了)。那些比较复杂的深度调优,比如执行计划分析啊、索引体系怎么弄啊、参数怎么调啊,这些活还是得 DBA 来干。MCP 其实更像是一个「能读懂你数据库的助手」。它帮你把那些繁琐的查询和探索用一句话给弄完。它并不能去代替 DBA 做出专业的判断。

从「数据库替代」到「让 AI 直接读懂数据库」,KES MCP Server 让金仓在 AI 时代的开发体验上又往前走了一步。这大概就是「不止于替代」最具体、也最好玩的一种样子。

更多推荐