器:`onyx_mcp_server` 資源配置與最佳實踐)
使用 Terraform 管理 Onyx MCP 服務(wù)器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服務(wù)器讓外部工具通過標(biāo)準(zhǔn)協(xié)議掛載到 Agent 上。本文以 onyx_mcp_server 資源文檔 為核心系統(tǒng)講解如何在terraform-provider-onyx中創(chuàng)建、認(rèn)證、授權(quán)與導(dǎo)入 MCP 服務(wù)器并深入mcp_server_resource.go與write_only.go等源碼剖析其配置校驗、憑證生命周期與 API 調(diào)用鏈。讀完本文你將能夠用純聲明式配置管理 Onyx 的 MCP 服務(wù)器接入包括共享令牌、按用戶密鑰、Craft 可用性與訪問控制并規(guī)避 Terraform 與瀏覽器式登錄、敏感信息狀態(tài)存儲等關(guān)鍵陷阱。一、資源定位與適用邊界onyx_mcp_server描述的是Onyx 連接到的 MCP 服務(wù)器其價值在于把該服務(wù)器的工具掛載到 Agent 上。在 Onyx 的整個 MCP 體系里此資源只負(fù)責(zé)服務(wù)器本身的注冊與授權(quán)不負(fù)責(zé)服務(wù)器暴露的工具清單——工具由 Onyx 主動調(diào)用服務(wù)器后自行學(xué)習(xí)discover與工具選擇tool selection以及 Craft 審批策略approval policies相關(guān)的配置都只對 Onyx 已經(jīng)發(fā)現(xiàn)過的工具生效。文檔明確劃定了本資源可管理的能力邊界支持無需交互式登錄的認(rèn)證方式NONE無憑證與API_TOKEN令牌。拒絕 OAuth 服務(wù)器文檔聲明 An OAuth server is refused while the plan is built因為 OAuth 流程需要瀏覽器往返browser round-trip這是 Terraform 無法執(zhí)行的。從客戶端源碼 mcp_server.go 可看到完整的認(rèn)證類型枚舉除NONE、API_TOKEN外還有OAUTH與PT_OAUTH后兩者均被拒于 plan 階段詳見下文配置校驗一節(jié)。因此對于需要 OAuth 交互式登錄的服務(wù)器應(yīng)先在 Onyx 管理后臺手工添加再用 Terraform 管理部署的其余部分——這是官方文檔給出的明確指引。二、完整示例三種典型用法原文檔提供了三個覆蓋不同認(rèn)證與授權(quán)形態(tài)的完整配置示例應(yīng)作為實戰(zhàn)起點三個示例可直接合并到同一.tf文件中# 一個無需任何憑證的公共 MCP 服務(wù)器。 resource onyx_mcp_server docs { name Docs description Public documentation search server_url https://mcp.example.com/mcp } # 一個使用共享 API 令牌的服務(wù)器。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 訪問該服務(wù)器。 available_in_craft true is_public false } # 每個用戶各自提供密鑰的服務(wù)器。模板聲明用戶需要填寫的字段 # admin_credentials 是應(yīng)用該配置的管理員自己的值。 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 } }三個示例分別對應(yīng)三類部署形態(tài)形態(tài)auth_typeauth_performer憑證字段公共無憑證NONE默認(rèn)ADMIN默認(rèn)無需設(shè)置共享令牌API_TOKENADMINapi_token或api_token_wo按用戶密鑰API_TOKENPER_USERauth_template_headersadmin_credentials或_wo變體三、Schema 全解必填、可選與只讀屬性原文檔給出的 Schema 定義已相當(dāng)完整下表在保留全部字段的基礎(chǔ)上補充了默認(rèn)值與底層含義字段默認(rèn)值均來自 mcp_server_resource.go 的 Schema 定義Required必填參數(shù)類型說明nameString顯示名稱。Onyx 不要求唯一兩個服務(wù)器可以同名server_urlStringOnyx 調(diào)用該服務(wù)器的 URL。無論 SSRF 保護級別如何Onyx 都會拒絕 loopback 與 link-local 地址因此部署在 Onyx 宿主本機的服務(wù)器無法通過主機名被訪問Optional可選參數(shù)類型默認(rèn)值說明descriptionString自由文本描述transportStringSTREAMABLE_HTTPSTREAMABLE_HTTP或已棄用的SSEauth_typeStringNONENONE或API_TOKENauth_performerStringADMIN憑證提供方ADMIN表示單一共享令牌PER_USER表示每個用戶各自提供令牌api_tokenStringSensitive—共享 API 令牌用于API_TOKENADMIN組合。Onyx 返回時掩碼Terraform 永不讀回配置值是唯一記錄導(dǎo)入的服務(wù)器沒有該值。優(yōu)先使用api_token_wo二者不能同時設(shè)置api_token_woStringSensitiveWrite-only—僅存于配置中的共享令牌。每次 apply 都會發(fā)送狀態(tài)中不存儲任何內(nèi)容。與api_token_wo_version配合輪換。需要 Terraform 1.11 或更高版本api_token_wo_versionNumber—api_token_wo的輪換計數(shù)器。Terraform 不存儲 write-only 值無法感知密鑰變化提升該數(shù)字使下次 apply 發(fā)送當(dāng)前值。不要用密鑰本身派生它——與密鑰不同該數(shù)字保留在 state 中auth_template_headersMap of StringSensitive—用于PER_USER的請求頭模板。值中的{placeholder}聲明每個用戶需填寫的字段。共享令牌場景下由 Onyx 自行寫入該模板若請求未聲明Onyx 會保留已有值——因此從按用戶切換到共享令牌后原按用戶頭仍會殘留需重建服務(wù)器才能清零admin_credentialsMap of StringSensitive—auth_template_headers占位符的值PER_USER下必填、其他形態(tài)下被拒絕共享令牌走api_token。Onyx 按應(yīng)用該配置的身份而非服務(wù)器存儲它們返回時掩碼。優(yōu)先使用admin_credentials_wo二者不能同時設(shè)置admin_credentials_woMap of StringSensitiveWrite-only—僅存于配置的模板字段值。Terraform 每次 apply 發(fā)送、不存儲任何內(nèi)容。與admin_credentials_wo_version配合輪換。需要 Terraform 1.11admin_credentials_wo_versionNumber—admin_credentials_wo的輪換計數(shù)器語義同api_token_wo_versionis_publicBooleantrue是否所有用戶都可用。為false時僅users與groups指定的對象可用groupsSet of Number—服務(wù)器非公開時允許使用的用戶組 id。Onyx 拒絕內(nèi)置的Admin組遇到該場景應(yīng)改用公開服務(wù)器。該列表由配置擁有從配置中移除會清空服務(wù)器上的組包括管理后臺添加的usersSet of String—服務(wù)器非公開時允許使用的用戶 idUUID。同樣由配置擁有移除即清空available_in_craftBooleanfalseCraft agent 是否可以使用該服務(wù)器。該字段由 Onyx 存放在獨立端點因此設(shè)置它需要額外一次 API 調(diào)用Read-Only只讀參數(shù)類型說明idString服務(wù)器 id由 Onyx 分配ownerString配置該服務(wù)器的身份。對 Terraform 運行而言是 API key 的合成地址而非真實郵箱statusString連接狀態(tài)由 Onyx 自行流轉(zhuǎn)CREATED、AWAITING_AUTH、FETCHING_TOOLS、CONNECTED或DISCONNECTEDtool_countNumberOnyx 在該服務(wù)器上已發(fā)現(xiàn)的工具數(shù)量last_refreshed_atStringOnyx 最近一次列出該服務(wù)器工具的時間注意Write-only 參數(shù)*_wo依賴 Terraform 1.11 及以后版本才支持的 Write-only Arguments 特性使用前請確認(rèn) CLI 版本滿足要求。四、配置校驗Apply 之前的本地交叉檢查ValidateConfigmcp_server_resource.go在 plan 構(gòu)建階段即執(zhí)行全部本地校驗無需已配置的客戶端其檢查順序與組合邏輯值得關(guān)注先校驗auth_performer再校驗auth_type因為后續(xù)檢查依賴 performer 是否已知且對 Onyx 不認(rèn)識的 performer無論auth_type解析為何值都是錯誤的。performer 必須是ADMIN或PER_USER否則直接報Unknown authentication performer。拒絕 OAuth當(dāng)auth_type為OAUTH或PT_OAUTH時直接報錯提示需要在 Onyx 管理后臺添加服務(wù)器。這正是前文OAuth 被拒絕于 plan 階段的源碼級實現(xiàn)。auth_type合法值僅允許NONE與API_TOKEN其余值報Unknown authentication type。認(rèn)證矩陣交叉檢查核心邏輯按 performer 分支auth_type NONE任何憑證類字段api_token/api_token_wo、admin_credentials/admin_credentials_wo、auth_template_headers一旦被設(shè)置即報Credentials set on a server that takes noneADMIN共享令牌必須設(shè)置api_token或api_token_wo否則報Missing api_token不允許設(shè)置auth_template_headersOnyx 會自行寫入共享令牌的模板與admin_credentials共享令牌本身就是憑證PER_USER按用戶必須設(shè)置auth_template_headers聲明用戶填寫字段的模板與admin_credentials/admin_credentials_wo應(yīng)用管理員自己的字段值禁止設(shè)置api_token/api_token_wo那是共享令牌專用。源碼中eitherAttributeIsSetwrite_only.go把普通敏感字段與其 write-only 孿生字段折疊為一次是否存在判斷任一側(cè)有值即視為已設(shè)置僅當(dāng)兩側(cè)都未知時才返回 unknown——這保證了api_token與api_token_wo互斥但等效。配套的ConflictsWith校驗器stringvalidator.ConflictsWith與mapvalidator.ConflictsWith則確保成對字段不能同時出現(xiàn)。五、憑證生命周期掩碼、write-only 與輪換本資源在憑證處理上有三個設(shè)計要點直接決定了你的使用方式1. Onyx 返回的憑證永遠(yuǎn)被掩碼??蛻舳四P妥⑨屆鞔_指出管理員的 API 令牌在回讀時是一串 bullet 字符mcp_server.go因此沒有任何響應(yīng)字段適合回寫進 upsert。資源在刷新時刻意跳過api_token與admin_credentialsapplyRemoteMCPServer以免把一屏掩碼寫進 state 覆蓋真實配置值。2. Write-only 孿生字段讓密鑰徹底離開 state。Terraform 會把 write-only 值從 plan 與 state 中剝離密鑰只存在于配置文件write_only.go。由于 Onyx 的 API 在更新時會整體替換字段resolveWriteOnly保證每次 apply 都能拿到配置中的值發(fā)送不會因更新而清空已存密鑰。該機制由markWriteOnlySource/writeOnlySourceMarked通過 private state 標(biāo)記記錄來源確保刷新時不會把密鑰誤寫回 state。3. 輪換通過版本計數(shù)器觸發(fā)。Terraform 無法 diff 一個它從不存儲的值所以單獨修改_wo字段不會產(chǎn)生任何 plan。writeOnlyVersionAttributewrite_only.go為此提供了配套的*_wo_version計數(shù)器提升數(shù)字才會產(chǎn)生 diff從而驅(qū)動下一次 apply 發(fā)送當(dāng)前密鑰同時用AlsoRequires校驗器強制該計數(shù)器必須伴隨對應(yīng)_wo字段使用。文檔特別警告不要用密鑰本身派生版本號——版本號留在 state 中密鑰不在。六、訪問控制公開、用戶、組與 Craft 可用性is_public true默認(rèn)所有用戶可用false時僅users與groups所列對象可用。二者均可同時配置形成白名單。groups使用用戶組數(shù)字 id且Onyx 拒絕內(nèi)置Admin組遇到全員可用需求請直接設(shè)is_public true。這兩個集合遵循配置即權(quán)威原則從配置中刪除某個用戶/組apply 時會同步清空服務(wù)器上的對應(yīng)項——包括在管理后臺手工添加的。實現(xiàn)上writeFromModelmcp_server_resource.go在配置缺省時發(fā)送空列表而非省略字段因為 Onyx 把缺省解讀為保持原樣而配置語義是沒有訪問列表若不顯式發(fā)送空列表從配置中移除的列表會殘留在服務(wù)器上并在下次 read 時與已刪除它們的 plan 產(chǎn)生永久 diff。available_in_craft走獨立端點upsert 請求體MCPServerWrite不攜帶該字段只有 PATCH 端點/admin/mcp/server/{id}MCPServerPatch接受它因此完整定義一臺服務(wù)器需要兩次調(diào)用mcp_server.go。資源在創(chuàng)建/更新后會調(diào)用applyCraftAvailability補齊該字段并容忍服務(wù)器已建好但 PATCH 失敗的中間態(tài)——先記錄 id 再報錯避免留下孤兒服務(wù)器。七、工具發(fā)現(xiàn)與狀態(tài)流轉(zhuǎn)資源本身不含工具清單。Onyx 通過調(diào)用服務(wù)器來學(xué)習(xí)其工具tool_count反映已發(fā)現(xiàn)工具數(shù)量last_refreshed_at記錄最近一次工具列表刷新時間status則由 Onyx 獨立流轉(zhuǎn)CREATED → AWAITING_AUTH → FETCHING_TOOLS → CONNECTED或DISCONNECTED。這與 Onyx 后端 MCP 服務(wù)器生命周期管理一致——連接建立、工具拉取、鑒權(quán)等待均由服務(wù)端異步完成Terraform 只負(fù)責(zé)注冊與配置。正因如此文檔強調(diào)工具選擇與 Craft 審批策略只對 Onyx已經(jīng)見過的工具生效配置中引用未發(fā)現(xiàn)工具會被拒絕。八、導(dǎo)入既有服務(wù)器資源支持terraform import按數(shù)字 id 導(dǎo)入與后端 APIGET /admin/mcp/servers/{id}的尋址方式一致#!/bin/sh # 按數(shù)字服務(wù)器 id 導(dǎo)入。憑證返回時為掩碼狀態(tài)因此導(dǎo)入的服務(wù)器 # 不攜帶任何憑證請在下次 apply 前把 api_token 或 admin_credentials # 補回配置文件中。 terraform import onyx_mcp_server.weather 3導(dǎo)入后需要特別留意憑證狀態(tài)掩碼機制意味著導(dǎo)入的服務(wù)器沒有憑證記錄若不補回api_token/admin_credentials后續(xù) apply 可能因缺少憑證而失敗或被 Onyx 拒絕Onyx 會直接拒絕掩碼值。九、底層 API 調(diào)用鏈從 mcp_server.go 可以完整還原資源的 REST 調(diào)用鏈均為/admin管理端點操作HTTP 方法與路徑說明創(chuàng)建 / 更新POST /admin/mcp/servers/createUpsertMCPServer同一請求體通過existing_server_id區(qū)分新建與更新返回摘要僅 server id完整記錄需再讀一次讀取GET /admin/mcp/servers/{id}GetMCPServer404 表示不存在PATCHPATCH /admin/mcp/server/{id}PatchMCPServer僅補available_in_craft刪除DELETE /admin/mcp/server/{id}DeleteMCPServer真實刪除重復(fù)刪除返回 404資源生命周期Create/Read/Update/Delete/ImportState見 mcp_server_resource.go嚴(yán)格對應(yīng)上述端點Read遇到 404 會從 state 中移除資源Delete同樣容忍 404冪等刪除。十、測試驗證行為即規(guī)格倉庫中的驗收測試直接印證了上述行為mcp_server_resource_test.go 驗證了無憑證服務(wù)器的默認(rèn)值auth_type NONE、auth_performer ADMIN、transport STREAMABLE_HTTP、is_public true、available_in_craft在 create 時通過后續(xù) PATCH 生效、未設(shè)置的集合groups/users/auth_template_headers保持未設(shè)置以避免永久 diff以及重命名、清空描述、翻轉(zhuǎn)標(biāo)志后的更新行為。同一文件的TestAccMCPServerResourceAPIToken驗證了共享令牌的完整生命周期創(chuàng)建 → 不輪換的 apply 產(chǎn)生空 plan → 輪換后新值生效并斷言共享令牌場景下 Onyx 自行寫入的模板頭為Authorization: Bearer {api_key}。測試還確認(rèn)了server_url只需通過結(jié)構(gòu)性校驗即可創(chuàng)建數(shù)據(jù)庫寫入 URL 結(jié)構(gòu)檢查不會真正連接服務(wù)器但必須為外部地址——這與文檔中Onyx 拒絕 loopback 地址的約束一致。小結(jié)onyx_mcp_server是terraform-provider-onyx中把外部 MCP 工具接入 Onyx Agent 體系的關(guān)鍵資源。使用時要始終牢記三條主線認(rèn)證矩陣NONE/API_TOKEN×ADMIN/PER_USER決定了憑證字段的合法組合OAuth 必須走管理后臺憑證只活在配置里掩碼回讀 write-only 孿生字段 版本計數(shù)器輪換state 中永遠(yuǎn)沒有明文密鑰配置即權(quán)威users/groups列表刪除即清空缺省列表會被顯式置空以保持一致。掌握這些規(guī)則后你就能把 MCP 服務(wù)器接入納入完全聲明式的 IaC 工作流?!久赓M下載鏈接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM項目地址: https://gitcode.com/GitHub_Trending/da/danswer創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考