MCP Toolbox for Databases 的 Couchbase 数据源配置详解:从连接串到参数化 SQL 工具
2026/9/14 15:37:41 网站建设 项目流程

MCP Toolbox for Databases 的 Couchbase 数据源配置详解:从连接串到参数化 SQL 工具

【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox

在 mcp-toolbox 中接入 Couchbase 集群的核心,是声明一个type: couchbase的 source,再配合couchbase-sql工具执行参数化 SQL 查询。本文完整梳理 Couchbase Source 官方文档 中的连接配置、参考字段与注意事项,并结合 internal/sources/couchbase/couchbase.go 与 internal/tools/couchbase/couchbase.go 的源码实现,讲解每个配置项在底层如何生效,帮助你从零写出可运行的 Couchbase 接入配置并理解其安全与一致性行为。

Couchbase Source 的定位

couchbasesource 建立与 Couchbase 集群的连接,使挂载在其上的工具能够针对该集群执行 SQL 查询(Couchbase 的 N1QL 查询服务,默认作用域为 bucket 内的 scope)。从源码看,source 注册入口在 couchbase.go#L37-L41,通过sources.Register(SourceType, newConfig)"couchbase"类型名注册配置解析器;解析成功后,Initialize方法完成两件事:

  1. 调用createCouchbaseOptions()根据 YAML 配置构造gocb.ClusterOptions(认证、TLS、连接 profile);
  2. 执行gocb.Connect(r.ConnectionString, opts)建立集群连接,并通过cluster.Bucket(r.Bucket).Scope(r.Scope)定位到目标 scope(见 couchbase.go#L73-L90)。

Source结构体最终只暴露一个*gocb.Scope字段(外加配置本身),所有工具查询都收敛到该 scope 上——这也解释了为什么bucketscope都是必填项:Couchbase 的 N1QL 查询以scope.collection为命名空间,不指定它们就无法定位数据。

最小可用配置示例

官方文档给出的标准示例如下,使用 Couchbase 官方 sample buckettravel-sample中的inventoryscope:

kind: source name: my-couchbase-instance type: couchbase connectionString: couchbase://localhost bucket: travel-sample scope: inventory username: Administrator password: password

各字段的必填性与源码中的校验一一对应:Config结构体上NameTypeConnectionStringBucketScope都带有validate:"required"标签(见 couchbase.go#L51-L67)。单元测试 couchbase_test.go#L106-L152 验证了两类解析失败场景:

  • 缺失必填字段(如省略connectionString)会触发Field validation for 'ConnectionString' failed on the 'required' tag错误;
  • 出现未定义字段(如foo: bar)会因 YAML 严格模式报unknown field "foo",配置解析失败。

这意味着 mcp-toolbox 对 source 配置是"零容忍"的:写错字段名会直接让服务启动失败,而不是静默忽略。

完整字段参考表

以下参考表继承自 source.md,并补充了源码层面的行为说明:

字段类型必填说明
typestringtrue必须为"couchbase"
connectionStringstringtrueCouchbase 集群连接串,如couchbase://localhostcouchbases://host1:18018,host2:18018
bucketstringtrue要连接的 bucket 名称。
scopestringtruebucket 内的 scope 名称(如_default)。
usernamestringfalse认证用户名。
passwordstringfalse认证密码。
clientCertstringfalse客户端证书文件路径(TLS 双向认证)。
clientCertPasswordstringfalse客户端证书密码。
clientKeystringfalse客户端密钥文件路径。
clientKeyPasswordstringfalse客户端密钥密码。
caCertstringfalseCA 证书文件路径。
noSslVerifybooleanfalse为 true 时跳过服务端证书校验。警告:仅可用于开发/测试环境,生产环境禁用,否则连接存在中间人攻击风险。
profilestringfalse要应用的连接 profile 名称(如serverless)。
queryScanConsistencyintegerfalse索引扫描一致性级别。1=not_bounded(最快,但结果可能不含最新写入);2=request_plus(最高一致性,包含查询开始前的所有已提交操作,但有性能开销)。不指定时使用 Couchbase Go SDK 的默认值。

TLS 与认证配置在源码中的实现

createCouchbaseOptions()(couchbase.go#L140-L211)展示了各 TLS 字段的组装逻辑,理解它有助于正确使用证书相关字段:

  • 用户名/密码认证:只要username非空,就构造gocb.PasswordAuthenticator并设为cbOpts.Authenticator
  • 证书认证clientCertclientKeycaCert三个路径会被os.ReadFile读入内存(任一文件读取失败都会使 source 初始化失败),随后交给tlsutil.NewConfig生成 TLS 配置;若clientCert已设置,认证器替换为gocb.CertificateAuthenticator(X.509 证书认证)。
  • 信任锚caCert提供后,SecurityConfig.TLSRootCAs指向该 CA 池;noSslVerify为 true 时则设置TLSSkipVerify。注意源码中仅当clientCertcaCert至少有一个非空时,才走 TLS 解析分支(couchbase.go#L172-L203)。
  • 证书/密钥密码getCertKeyPassword的取舍规则是——clientKeyPassword非空时优先使用它,否则回退到clientCertPassword(couchbase.go#L213-L220)。因此当证书与密钥共用同一密码时,只填clientCertPassword即可。

一个完整的 TLS 配置示例(取自 couchbase_test.go#L58-L91 的测试用例):

kind: source name: my-couchbase-instance type: couchbase connectionString: couchbases://localhost bucket: travel-sample scope: inventory clientCert: /path/to/cert.pem clientKey: /path/to/key.pem clientCertPassword: password clientKeyPassword: password caCert: /path/to/ca.pem noSslVerify: false queryScanConsistency: 2

关于连接串中的多节点备选地址与自定义端口,官方文档提示可参考 Couchbase Go SDK 的 Managing Connections 指南(Couchbase 官方文档,此处不附外链);mcp-toolbox 侧直接将connectionString原样透传给gocb.Connect,因此 SDK 支持的一切地址格式(多主机、备地址、自定义端口)在此均适用。

profile:连接性能档位

profile字段最终调用cbOpts.ApplyProfile(gocb.ClusterConfigProfile(r.Profile))(couchbase.go#L204-L209)。这是 Go SDK 提供的连接配置档位(如serverless),用于按部署环境(本地开发、云、Serverless)调整重连、连接池等参数;不指定时使用 SDK 默认。

queryScanConsistency:一致性换性能

该字段在RunSQL中直接映射为gocb.QueryOptions.ScanConsistency(couchbase.go#L119-L123):

results, err := s.CouchbaseScope().Query(statement, &gocb.QueryOptions{ ScanConsistency: gocb.QueryScanConsistency(s.CouchbaseQueryScanConsistency()), NamedParameters: params.AsMap(), })
  • 设为1not_bounded):允许索引扫描读取未提交/未同步的条目,最快,适合对实时性不敏感的探索性查询;
  • 设为2request_plus):保证扫描到查询发起前已提交且已向主节点请求过的所有操作,适合要求"读到最近写入"的场景;
  • 不设置:透传 Go SDK 默认值(SDK 默认为 request_plus 语义的自动级别)。

仓库的集成测试在testcontainers启动的 Couchbase 容器上固定使用queryScanConsistency: 2(见 tests/couchbase/couchbase_integration_test.go 的getCouchbaseVars),可以作为可复现的参考配置。

与 Source 配套的工具:couchbase-sql

source 声明连接,工具声明"能做什么"。mcp-toolbox 中面向 Couchbase 的工具是couchbase-sql,完整文档见 couchbase-sql.md。它执行一条预定义的 SQL 语句,且以参数化语句方式运行:语句中的$name占位符会被同名参数替换。

工具配置参考表(来自 couchbase-sql.md):

字段类型必填说明
typestringtrue必须为"couchbase-sql"
sourcestringtrue工具所执行的 source 名称。
descriptionstringtrue传递给 LLM 的工具描述。
statementstringtrue要执行的 SQL 语句。
parameters参数列表false与 SQL 语句配合使用的命名参数。
templateParameters参数列表false在执行前直接插入 SQL 语句的模板参数。
authRequiredarray[string]false使用该工具所需的服务端认证服务列表。

基础参数示例(来自官方文档):

kind: tool name: search_products_by_category type: couchbase-sql source: my-couchbase-instance statement: | SELECT p.name, p.price, p.description FROM products p WHERE p.category = $category AND p.price < $max_price ORDER BY p.price DESC LIMIT 10 description: | Use this tool to get a list of products for a specific category under a maximum price. Takes a category name, e.g. "Electronics" and a maximum price e.g 500 and returns a list of product names, prices, and descriptions. Do NOT use this tool with invalid category names. Do NOT guess a category name, Do NOT guess a price. Example: { "category": "Electronics", "max_price": 500 } parameters: - name: category type: string description: Product category name - name: max_price type: integer description: Maximum price (positive integer)

注意description的写法:它同时面向 LLM 说明参数边界("不要猜 category 或 price"),这种"约束性描述"能显著降低模型生成越界调用的概率,值得在自定义工具时借鉴。

源码视角:参数化查询如何防注入

工具侧的执行链路在 internal/tools/couchbase/couchbase.go#L109-L130 的Invoke方法中,分三步:

  1. parameters.ResolveTemplateParams(...):先对statement做 Go template 渲染,处理templateParameters
  2. parameters.GetParams(...):从 LLM 传入的参数值中提取parameters声明的命名参数;
  3. source.RunSQL(newStatement, newParams):将最终语句与NamedParameters一并交给 Couchbase 查询引擎,由引擎完成参数绑定。

由于parameters走的是数据库侧的命名参数绑定(gocb.QueryOptions.NamedParameters),参数值永远不会被拼进 SQL 文本,这是防注入的根本保证。而templateParameters则相反——它允许把值直接插入语句文本(包括表名、列名等标识符位置),官方工具文档 明确警告这会使语句更易受 SQL 注入影响,"出于性能与安全考虑,推荐只使用基础 parameters"。相关参数机制的完整定义(含escape等字段)见 工具配置文档。

工具还会在ValidateSource中校验 source 是否实现了compatibleSource接口(要求提供CouchbaseScope()RunSQL,见 couchbase.go#L46-L49),因此只有couchbase类型的 source 能被couchbase-sql工具使用,配置错配会在启动阶段报错而非运行期才暴露。

结果如何返回

RunSQL(couchbase.go#L119-L138)将每行结果以json.RawMessage原样收集为[]any返回,即工具输出是一个 JSON 数组,每个元素是一行 Couchbase 查询结果。这意味着 MCP 客户端(如 Gemini CLI、Claude)拿到的就是与 N1QL 查询服务一致的 JSON 行集,无需二次转换。

端到端验证方式

仓库为这条链路提供了两级测试可作参考:

  • 配置解析单测:internal/sources/couchbase/couchbase_test.go 验证基础配置与 TLS 配置的 YAML 解析,以及未知字段、缺失必填字段的报错信息;internal/tools/couchbase/couchbase_test.go 验证couchbase-sql工具(含 templateParameters 混合场景)的解析结果;
  • 集成测试:tests/couchbase/couchbase_integration_test.go 通过 testcontainers 拉起真实 Couchbase 集群(默认_defaultscope、test-bucketAdministrator账号),跑通 source +couchbase-sql工具的实际查询。

阅读这两个测试文件,可以快速复制一份"最小验证配置":connectionString指向容器地址、scope: _defaultqueryScanConsistency: 2

小结

  • 一个type: couchbase的 source 由connectionString+bucket+scope三要素定位数据,认证支持用户名/密码与 X.509 证书两种方式,noSslVerify仅限开发环境使用;
  • queryScanConsistency是显式的一致性/性能权衡开关,1 =not_bounded,2 =request_plus,缺省交给 Go SDK 默认值;
  • 工具侧统一使用couchbase-sqlparameters走引擎侧命名参数绑定(防注入),templateParameters直接改写语句文本(灵活但有注入风险),生产配置优先只用前者;
  • 所有字段行为均可在 internal/sources/couchbase/couchbase.go 与 internal/tools/couchbase/couchbase.go 中逐行核对,出错时结合 couchbase_test.go 中的报错样例可快速定位配置问题。

【免费下载链接】mcp-toolboxMCP Toolbox for Databases is an open source MCP server for databases.项目地址: https://gitcode.com/GitHub_Trending/ge/mcp-toolbox

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

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

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

立即咨询