
使用 Terraform 管理 Onyx MCP 服务器onyx_mcp_server资源配置与最佳实践【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswerOnyx 支持接入 MCPModel Context Protocol服务器让外部工具通过标准协议挂载到 Agent 上。本文以 onyx_mcp_server 资源文档 为核心系统讲解如何在terraform-provider-onyx中创建、认证、授权与导入 MCP 服务器并深入mcp_server_resource.go与write_only.go等源码剖析其配置校验、凭证生命周期与 API 调用链。读完本文你将能够用纯声明式配置管理 Onyx 的 MCP 服务器接入包括共享令牌、按用户密钥、Craft 可用性与访问控制并规避 Terraform 与浏览器式登录、敏感信息状态存储等关键陷阱。一、资源定位与适用边界onyx_mcp_server描述的是Onyx 连接到的 MCP 服务器其价值在于把该服务器的工具挂载到 Agent 上。在 Onyx 的整个 MCP 体系里此资源只负责服务器本身的注册与授权不负责服务器暴露的工具清单——工具由 Onyx 主动调用服务器后自行学习discover与工具选择tool selection以及 Craft 审批策略approval policies相关的配置都只对 Onyx 已经发现过的工具生效。文档明确划定了本资源可管理的能力边界支持无需交互式登录的认证方式NONE无凭证与API_TOKEN令牌。拒绝 OAuth 服务器文档声明 An OAuth server is refused while the plan is built因为 OAuth 流程需要浏览器往返browser round-trip这是 Terraform 无法执行的。从客户端源码 mcp_server.go 可看到完整的认证类型枚举除NONE、API_TOKEN外还有OAUTH与PT_OAUTH后两者均被拒于 plan 阶段详见下文配置校验一节。因此对于需要 OAuth 交互式登录的服务器应先在 Onyx 管理后台手工添加再用 Terraform 管理部署的其余部分——这是官方文档给出的明确指引。二、完整示例三种典型用法原文档提供了三个覆盖不同认证与授权形态的完整配置示例应作为实战起点三个示例可直接合并到同一.tf文件中# 一个无需任何凭证的公共 MCP 服务器。 resource onyx_mcp_server docs { name Docs description Public documentation search server_url https://mcp.example.com/mcp } # 一个使用共享 API 令牌的服务器。Onyx 返回令牌时会被掩码处理因此 # 配置文件是令牌的唯一记录轮换令牌时请改这里不要在 UI 中改。 resource onyx_mcp_server weather { name Weather server_url https://weather.example.com/mcp auth_type API_TOKEN auth_performer ADMIN api_token var.weather_api_token # 仅允许 Craft agent 访问该服务器。 available_in_craft true is_public false } # 每个用户各自提供密钥的服务器。模板声明用户需要填写的字段 # admin_credentials 是应用该配置的管理员自己的值。 resource onyx_mcp_server tickets { name Tickets server_url https://tickets.example.com/mcp auth_type API_TOKEN auth_performer PER_USER auth_template_headers { X-Api-Key {api_key} } admin_credentials { api_key var.tickets_admin_api_key } }三个示例分别对应三类部署形态形态auth_typeauth_performer凭证字段公共无凭证NONE默认ADMIN默认无需设置共享令牌API_TOKENADMINapi_token或api_token_wo按用户密钥API_TOKENPER_USERauth_template_headersadmin_credentials或_wo变体三、Schema 全解必填、可选与只读属性原文档给出的 Schema 定义已相当完整下表在保留全部字段的基础上补充了默认值与底层含义字段默认值均来自 mcp_server_resource.go 的 Schema 定义Required必填参数类型说明nameString显示名称。Onyx 不要求唯一两个服务器可以同名server_urlStringOnyx 调用该服务器的 URL。无论 SSRF 保护级别如何Onyx 都会拒绝 loopback 与 link-local 地址因此部署在 Onyx 宿主本机的服务器无法通过主机名被访问Optional可选参数类型默认值说明descriptionString自由文本描述transportStringSTREAMABLE_HTTPSTREAMABLE_HTTP或已弃用的SSEauth_typeStringNONENONE或API_TOKENauth_performerStringADMIN凭证提供方ADMIN表示单一共享令牌PER_USER表示每个用户各自提供令牌api_tokenStringSensitive—共享 API 令牌用于API_TOKENADMIN组合。Onyx 返回时掩码Terraform 永不读回配置值是唯一记录导入的服务器没有该值。优先使用api_token_wo二者不能同时设置api_token_woStringSensitiveWrite-only—仅存于配置中的共享令牌。每次 apply 都会发送状态中不存储任何内容。与api_token_wo_version配合轮换。需要 Terraform 1.11 或更高版本api_token_wo_versionNumber—api_token_wo的轮换计数器。Terraform 不存储 write-only 值无法感知密钥变化提升该数字使下次 apply 发送当前值。不要用密钥本身派生它——与密钥不同该数字保留在 state 中auth_template_headersMap of StringSensitive—用于PER_USER的请求头模板。值中的{placeholder}声明每个用户需填写的字段。共享令牌场景下由 Onyx 自行写入该模板若请求未声明Onyx 会保留已有值——因此从按用户切换到共享令牌后原按用户头仍会残留需重建服务器才能清零admin_credentialsMap of StringSensitive—auth_template_headers占位符的值PER_USER下必填、其他形态下被拒绝共享令牌走api_token。Onyx 按应用该配置的身份而非服务器存储它们返回时掩码。优先使用admin_credentials_wo二者不能同时设置admin_credentials_woMap of StringSensitiveWrite-only—仅存于配置的模板字段值。Terraform 每次 apply 发送、不存储任何内容。与admin_credentials_wo_version配合轮换。需要 Terraform 1.11admin_credentials_wo_versionNumber—admin_credentials_wo的轮换计数器语义同api_token_wo_versionis_publicBooleantrue是否所有用户都可用。为false时仅users与groups指定的对象可用groupsSet of Number—服务器非公开时允许使用的用户组 id。Onyx 拒绝内置的Admin组遇到该场景应改用公开服务器。该列表由配置拥有从配置中移除会清空服务器上的组包括管理后台添加的usersSet of String—服务器非公开时允许使用的用户 idUUID。同样由配置拥有移除即清空available_in_craftBooleanfalseCraft agent 是否可以使用该服务器。该字段由 Onyx 存放在独立端点因此设置它需要额外一次 API 调用Read-Only只读参数类型说明idString服务器 id由 Onyx 分配ownerString配置该服务器的身份。对 Terraform 运行而言是 API key 的合成地址而非真实邮箱statusString连接状态由 Onyx 自行流转CREATED、AWAITING_AUTH、FETCHING_TOOLS、CONNECTED或DISCONNECTEDtool_countNumberOnyx 在该服务器上已发现的工具数量last_refreshed_atStringOnyx 最近一次列出该服务器工具的时间注意Write-only 参数*_wo依赖 Terraform 1.11 及以后版本才支持的 Write-only Arguments 特性使用前请确认 CLI 版本满足要求。四、配置校验Apply 之前的本地交叉检查ValidateConfigmcp_server_resource.go在 plan 构建阶段即执行全部本地校验无需已配置的客户端其检查顺序与组合逻辑值得关注先校验auth_performer再校验auth_type因为后续检查依赖 performer 是否已知且对 Onyx 不认识的 performer无论auth_type解析为何值都是错误的。performer 必须是ADMIN或PER_USER否则直接报Unknown authentication performer。拒绝 OAuth当auth_type为OAUTH或PT_OAUTH时直接报错提示需要在 Onyx 管理后台添加服务器。这正是前文OAuth 被拒绝于 plan 阶段的源码级实现。auth_type合法值仅允许NONE与API_TOKEN其余值报Unknown authentication type。认证矩阵交叉检查核心逻辑按 performer 分支auth_type NONE任何凭证类字段api_token/api_token_wo、admin_credentials/admin_credentials_wo、auth_template_headers一旦被设置即报Credentials set on a server that takes noneADMIN共享令牌必须设置api_token或api_token_wo否则报Missing api_token不允许设置auth_template_headersOnyx 会自行写入共享令牌的模板与admin_credentials共享令牌本身就是凭证PER_USER按用户必须设置auth_template_headers声明用户填写字段的模板与admin_credentials/admin_credentials_wo应用管理员自己的字段值禁止设置api_token/api_token_wo那是共享令牌专用。源码中eitherAttributeIsSetwrite_only.go把普通敏感字段与其 write-only 孪生字段折叠为一次是否存在判断任一侧有值即视为已设置仅当两侧都未知时才返回 unknown——这保证了api_token与api_token_wo互斥但等效。配套的ConflictsWith校验器stringvalidator.ConflictsWith与mapvalidator.ConflictsWith则确保成对字段不能同时出现。五、凭证生命周期掩码、write-only 与轮换本资源在凭证处理上有三个设计要点直接决定了你的使用方式1. Onyx 返回的凭证永远被掩码。客户端模型注释明确指出管理员的 API 令牌在回读时是一串 bullet 字符mcp_server.go因此没有任何响应字段适合回写进 upsert。资源在刷新时刻意跳过api_token与admin_credentialsapplyRemoteMCPServer以免把一屏掩码写进 state 覆盖真实配置值。2. Write-only 孪生字段让密钥彻底离开 state。Terraform 会把 write-only 值从 plan 与 state 中剥离密钥只存在于配置文件write_only.go。由于 Onyx 的 API 在更新时会整体替换字段resolveWriteOnly保证每次 apply 都能拿到配置中的值发送不会因更新而清空已存密钥。该机制由markWriteOnlySource/writeOnlySourceMarked通过 private state 标记记录来源确保刷新时不会把密钥误写回 state。3. 轮换通过版本计数器触发。Terraform 无法 diff 一个它从不存储的值所以单独修改_wo字段不会产生任何 plan。writeOnlyVersionAttributewrite_only.go为此提供了配套的*_wo_version计数器提升数字才会产生 diff从而驱动下一次 apply 发送当前密钥同时用AlsoRequires校验器强制该计数器必须伴随对应_wo字段使用。文档特别警告不要用密钥本身派生版本号——版本号留在 state 中密钥不在。六、访问控制公开、用户、组与 Craft 可用性is_public true默认所有用户可用false时仅users与groups所列对象可用。二者均可同时配置形成白名单。groups使用用户组数字 id且Onyx 拒绝内置Admin组遇到全员可用需求请直接设is_public true。这两个集合遵循配置即权威原则从配置中删除某个用户/组apply 时会同步清空服务器上的对应项——包括在管理后台手工添加的。实现上writeFromModelmcp_server_resource.go在配置缺省时发送空列表而非省略字段因为 Onyx 把缺省解读为保持原样而配置语义是没有访问列表若不显式发送空列表从配置中移除的列表会残留在服务器上并在下次 read 时与已删除它们的 plan 产生永久 diff。available_in_craft走独立端点upsert 请求体MCPServerWrite不携带该字段只有 PATCH 端点/admin/mcp/server/{id}MCPServerPatch接受它因此完整定义一台服务器需要两次调用mcp_server.go。资源在创建/更新后会调用applyCraftAvailability补齐该字段并容忍服务器已建好但 PATCH 失败的中间态——先记录 id 再报错避免留下孤儿服务器。七、工具发现与状态流转资源本身不含工具清单。Onyx 通过调用服务器来学习其工具tool_count反映已发现工具数量last_refreshed_at记录最近一次工具列表刷新时间status则由 Onyx 独立流转CREATED → AWAITING_AUTH → FETCHING_TOOLS → CONNECTED或DISCONNECTED。这与 Onyx 后端 MCP 服务器生命周期管理一致——连接建立、工具拉取、鉴权等待均由服务端异步完成Terraform 只负责注册与配置。正因如此文档强调工具选择与 Craft 审批策略只对 Onyx已经见过的工具生效配置中引用未发现工具会被拒绝。八、导入既有服务器资源支持terraform import按数字 id 导入与后端 APIGET /admin/mcp/servers/{id}的寻址方式一致#!/bin/sh # 按数字服务器 id 导入。凭证返回时为掩码状态因此导入的服务器 # 不携带任何凭证请在下次 apply 前把 api_token 或 admin_credentials # 补回配置文件中。 terraform import onyx_mcp_server.weather 3导入后需要特别留意凭证状态掩码机制意味着导入的服务器没有凭证记录若不补回api_token/admin_credentials后续 apply 可能因缺少凭证而失败或被 Onyx 拒绝Onyx 会直接拒绝掩码值。九、底层 API 调用链从 mcp_server.go 可以完整还原资源的 REST 调用链均为/admin管理端点操作HTTP 方法与路径说明创建 / 更新POST /admin/mcp/servers/createUpsertMCPServer同一请求体通过existing_server_id区分新建与更新返回摘要仅 server id完整记录需再读一次读取GET /admin/mcp/servers/{id}GetMCPServer404 表示不存在PATCHPATCH /admin/mcp/server/{id}PatchMCPServer仅补available_in_craft删除DELETE /admin/mcp/server/{id}DeleteMCPServer真实删除重复删除返回 404资源生命周期Create/Read/Update/Delete/ImportState见 mcp_server_resource.go严格对应上述端点Read遇到 404 会从 state 中移除资源Delete同样容忍 404幂等删除。十、测试验证行为即规格仓库中的验收测试直接印证了上述行为mcp_server_resource_test.go 验证了无凭证服务器的默认值auth_type NONE、auth_performer ADMIN、transport STREAMABLE_HTTP、is_public true、available_in_craft在 create 时通过后续 PATCH 生效、未设置的集合groups/users/auth_template_headers保持未设置以避免永久 diff以及重命名、清空描述、翻转标志后的更新行为。同一文件的TestAccMCPServerResourceAPIToken验证了共享令牌的完整生命周期创建 → 不轮换的 apply 产生空 plan → 轮换后新值生效并断言共享令牌场景下 Onyx 自行写入的模板头为Authorization: Bearer {api_key}。测试还确认了server_url只需通过结构性校验即可创建数据库写入 URL 结构检查不会真正连接服务器但必须为外部地址——这与文档中Onyx 拒绝 loopback 地址的约束一致。小结onyx_mcp_server是terraform-provider-onyx中把外部 MCP 工具接入 Onyx Agent 体系的关键资源。使用时要始终牢记三条主线认证矩阵NONE/API_TOKEN×ADMIN/PER_USER决定了凭证字段的合法组合OAuth 必须走管理后台凭证只活在配置里掩码回读 write-only 孪生字段 版本计数器轮换state 中永远没有明文密钥配置即权威users/groups列表删除即清空缺省列表会被显式置空以保持一致。掌握这些规则后你就能把 MCP 服务器接入纳入完全声明式的 IaC 工作流。【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考