Skip to main content

elf-mcp-knowledge

Elf Express「新增知識庫到 MCPJungle」的主流程規範:把一套冷門/內部知識(如 SqlSugar、FcDesigner)做成 docs-mcp-server 的語料(mcpjungle/books/<書名>/corpus/<id>/ + corpus.json + capability),或在必要時做成獨立知識 MCP server,再由 registrar 依 corpus.json 自動註冊到唯一入口 MCPJungle gateway、驗證 gateway 真的曝露出工具、並同步更新文件。當任務涉及新增或修改語料、corpus.json、 capabilities(cheatsheet / examples / symbol)、docs_* 工具、語料或 server 命名、gen-book-configs.mjs、registry/*.json、REGISTER_LIST、 「讓 AI 查得到某份文件 / 某個框架的知識」時觸發。

Quellinformationen

Repository
elf-express/skillshare-source
Letzte Quellaktivität
19. Oktober 2026 um 19:46
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
0
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
8 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
elf-mcp-knowledge
description
Elf Express「新增知識庫到 MCPJungle」的主流程規範:把一套冷門/內部知識(如 SqlSugar、FcDesigner)做成 docs-mcp-server 的語料(mcpjungle/books/<書名>/corpus/<id>/ + corpus.json + capability),或在必要時做成獨立知識 MCP server,再由 registrar 依 corpus.json 自動註冊到唯一入口 MCPJungle gateway、驗證 gateway 真的曝露出工具、並同步更新文件。當任務涉及新增或修改語料、corpus.json、 capabilities(cheatsheet / examples / symbol)、docs_* 工具、語料或 server 命名、gen-book-configs.mjs、registry/*.json、REGISTER_LIST、 「讓 AI 查得到某份文件 / 某個框架的知識」時觸發。
metadata
{"version":"1.2.3","owner":"Elf Express"}
# 新增知識庫到 MCPJungle(Elf Express) > 參考實作:`elf-express/mcp-library` —— `mcpjungle/docs-mcp-server/`(多語料知識 server)+ `mcpjungle/books/`(書與語料) > + `mcpjungle/registry/`(registrar 與註冊設定)+ `mcpjungle/gateway/`(gateway)。量測基準:`origin/release` @ `73b8206`。 > legacy server 已於 `0a37607` 刪除(E-126;歷史內容用 `git show 0a37607^:<路徑>` 讀)。 > 使用情境:**一台 MCPJungle gateway,底下掛很多「知識型」MCP server / 語料;AI 工具只連 gateway。** 相關 skill: - **`elf-mcp-book`** — 知識來源是「一本書」(`mcpjungle/books/<書名>/source/` 的素材)時**先看它**:素材在 `source/`、四類衍生物哪些不上架、 `import.ts` 要做到什麼、`sources.json` 怎麼從 front matter 產生(舊式語料)、上架前檢查(來源與標題可辨識性)。本 skill 負責素材挑好之後的上架流程 - `elf-mcp-gateway` — gateway 部署、registrar、nginx、GHCR、安全(本 skill 第 4 步〈註冊〉、第 5–7 步會用到) - `elf-mcp-server` — 語料模式放不下時,從零寫一個知識 MCP server 的範本與禁止簡化規則 - `elf-unit`(測試放置 / 覆蓋率)、`elf-stack`(版本)、`elf-cicd-docker`(映像) - 第三方通用 skill `mcp-builder`(Anthropic):通用 MCP 設計原則;本 skill 是它之上的團隊具體層,**衝突時以本 skill 為準** --- ## 1. 何時使用 - 「讓 AI 查得到 X 的文件」「把 Y 框架的筆記掛上 MCP」「新增一本書 / 一個語料」 - 修改既有語料的 md、`corpus.json`、`sources.json`、`examples/` - 為語料開新能力(cheatsheet / examples / symbol)或新增一種能力(新 `docs_*` 工具) - 書本註冊(registrar 依 `corpus.json` 自動產生);新增 / 修改非書本註冊檔 `mcpjungle/registry/*.json`、`REGISTER_LIST` - 檢查「gateway 上看不到新語料 / 工具」 ### 先選路線(決策樹) | 情況 | 路線 | 要改程式碼嗎 | |---|---|---| | 來源是一本書 / 一份線上文件的擷取產物(`mcpjungle/books/<書名>/source/` 底下) | **A. 新增語料**,但**先讀 `elf-mcp-book`** 挑哪一份、排除哪些 | 否 | | 知識是 markdown(可轉成 md)+可選的範例原始碼 | **A. 新增語料**(預設,90% 的情況) | 否 | | 語料需要現有能力以外的查詢方式(例:依版本號查、表格欄位查) | **B. 新增 capability + 一個 `docs_*` 工具** | 是,見 `references/add-capability.md` | | 需要即時資料(DB / 外部 API)、非文字資料、或必須另一個 runtime | **C. 獨立知識 MCP server** | 是,照 `elf-mcp-server` | **MUST NOT** 為了一本新書另寫一個 server(路線 C)——`docs-mcp-server` 的設計主軸就是「新增一本書 = 丟資料夾 + corpus.json,不改 `.ts`」。 --- ## 2. 固定規則 ### 命名(一個 gateway 底下很多 server 共存的關鍵) 1. **MUST** 語料 id = 資料夾名 = gateway server 名(策略 A)= HTTP 路徑 `/mcp/<id>`。四者**同一個字串**。 WHY:registrar 產生的註冊設定 `url` 是 `http://docs-mcp-server:5690/mcp/<id>`(`gen-book-configs.mjs:63`),gateway 工具名是 `<id>__docs_search`;任一處不同就對不上。 2. **MUST** id 用小寫 `[a-z0-9-]`,以字母開頭,**不含底線**。 WHY:MCPJungle `validateServerName` 只允許 `^[a-zA-Z0-9_-]+$`、禁止 `__`、禁止結尾 `_`(`mcpjungle/gateway/internal/service/mcp/util.go`), 因為工具以 `<server>__<tool>` 切分;不用底線就永遠不會踩到。`getCorpus` 比對不分大小寫,但 URL 與 gateway 名稱分大小寫,一律小寫才不會出現兩套。 2a. **MUST** 語料 id 格式為 **`<書名>-<語言>`**(使用者決議,2026-09-27): | 語言後綴 | 意思 | 使用時機 | |---|---|---| | `-en` | 英文 | 英文原文 | | `-zh-tw` | 繁體中文 | 中文原文或繁中譯本 | | `-zh-cn` | 簡體中文 | 簡中原文 | | `-bi` | 中英混排 | **只有**來源本身中英混排、無法拆開時 | - 同一本書有兩種語言 = **兩個語料**(`opnsense-en`、`opnsense-zh-tw`),按字母排序自然相鄰(「書放在一起」)。**MUST NOT** 再放第三份雙語版(同內容存三份、搜三次)。 - 書名本身可含 `-`(`vue-router-en`);分辨書名與語言靠 `corpus.json` 的 `book` / `language` 欄位,**不靠**拆字串。 - id 總長 **≤ 30 字元**,因 gateway 工具名為 `<id>__<tool>`,部分用戶端上限約 64 字元。 - `corpus.json` **MUST** 含 `book`、`language`(BCP 47,如 `zh-TW`)、`source`(原始網址)、`title`、`description`、`capabilities`。 - 目錄樹與完整範例見 repo 的 `mcpjungle/books/README.md`(唯一權威版本;命名在第一節 `:12-45`,目錄樹在第二節)。 `:12-45` 是整個第一節:`:12-34` 是命名規則(語言後綴表與規則表),`:36-45` 是「現有語料」表。 WHY:`.` 不在 MCPJungle 允許字元內,`_` 會和 `__` 切分衝突;語言放後綴讓同書各語言相鄰、AI 從 id 就知道語言。 3. **MUST** id 在「整台 gateway」唯一,不只是 `mcpjungle/books/` 內唯一。 現有保留名(`73b8206`):6 個語料 id `fc-zh-tw`、`nginx-en`、`opnsense-en`、`opnsense-zh-tw`、`sqlsugar-zh-tw`、`stalwart-en`(`books/README.md:38-45`);`filesystem`、`fetch`、`time`(`mcpjungle/registry/*.json`);`docs`(策略 B 整包,`mcpjungle/registry/optional/docs.json`);以及 DB 裡任何已註冊的名字(舊名 `sqlsugar`、`fc` 已改名,gateway 需先手動 `deregister` 舊名,mcp-library `mcpjungle/README.md:113`)。 WHY:重名註冊會報 `duplicate key value violates unique constraint "idx_mcp_servers_name" (SQLSTATE 23505)`;repo 內的設定(`corpus.json`、`registry/*.json`)看不出 DB 實際有什麼,要以 `list servers` 為準(mcp-library `CLAUDE.md:132`)。 `gen-book-configs.mjs:40` 擋語料 id 重複,registrar 也擋 `registry/*.json` 與語料 id 同名(`registrar.sh:4`、`:32-35`);兩者都只看 repo,擋不到 DB 裡的舊名。 4. **MUST** 用領域名(`sqlsugar`、`furion`、`fc`),**MUST NOT** 用 `docs`、`notes`、`kb`、`test`、`new` 這種泛名。 WHY:AI 端看到的工具是 `<id>__docs_search`,id 就是 AI 選工具的唯一線索。 5. **MUST NOT** 為語料新增工具名(例如 `furion_search`)。工具固定 `docs_*` 8 個,語料是**參數**。 WHY:`mcpjungle/docs-mcp-server/src/index.ts:5` 註解「語料是參數不是新工具,故工具數恆為 8」;工具數隨語料膨脹會吃爆 AI 的工具清單。 ### 語料內容 6. **MUST** 每篇 md 以 `# 標題` 開頭,前 15 行內放來源:`> 📖 官方文件:[文字](https://…)` 或 `> Source: https://…`。 WHY:`extractSourceUrl` 只掃前 15 行,只看以 `>` 開頭或含 source/来源/來源/官方 字樣的行,先取 markdown 連結、否則取裸網址(`mcpjungle/docs-mcp-server/src/corpus.ts:326-342`,註解列的就是這兩種格式);抽不到就沒有來源連結,AI 無法引用官方文件。`sources.json` 只用於覆寫(優先於自動抽取,`books/README.md:187`)。 front matter 的 `source: https://…`(不帶引號)也抽得到,所以 `import.ts` 產生、以 front matter 開頭再接 `# 標題` 的 md 也符合本條(`books/README.md:193`);帶引號會把 `"` 吃進網址,見 `elf-mcp-book` 規則 9。 7. **MUST** 開 `cheatsheet` 的語料,每篇要有標題含「速查」的段落(慣例 `## 速查表`,其上一行放 `[//]: # (<id>-cheatsheet)` 標記)。 WHY:`extractCheatsheet` 以 `^#{1,6}\s+.*速查` 找段落,切到下一個同級標題;沒有就回「沒有速查表段落」。 8. **MUST** 開 `symbol` 的語料,API / 組件名要寫成 `#`/`##`/`###` 標題(`####` 以下不進索引)。 WHY:`buildSymbolIndex` 用 `extractHeadings(content, 1)`,只收 1–3 級;U+200B/U+FEFF 已自動清掉。 9. **MUST** 範例原始碼放 `mcpjungle/books/<書名>/corpus/<id>/examples/`,副檔名限 `.cs .csproj .sln .json .ts .js`,並在 `corpus.json` 開 `examples: true`。 WHY:`listCodeFiles` 用白名單 `CODE_EXT`、略過 `bin/obj/.vs`;`listMarkdownFiles` 會跳過 `examples/`,兩者不互相污染。 10. **MUST** 單檔 < 5MB、不含真實連線字串 / 密碼 / token。 WHY:CI `basics` 擋 >5MB 檔案(`ci.yml:77`);機密掃描對 `examples/` **整個排除**(`ci.yml:95`;`notes/` 在 `73b8206` 已不在排除清單),放進 `examples/` 的機密不會被抓到,只能靠人。 11. **MUST** 分類用一層子目錄(`開發文檔/xx.md`),檔名前綴編號(`01xxx.md`)保持順序。 WHY:`docs_outline` 以頂層目錄分組、`localeCompare("zh-Hant")` 排序;多層目錄只會被歸到第一層。 ### 註冊與部署 12. **MUST** 新語料不手寫註冊檔:registrar 依 `corpus.json` 自動產生,見 `elf-mcp-gateway` 第 2 節〈註冊〉。本機先跑 `node mcpjungle/registry/gen-book-configs.mjs mcpjungle/books <暫存目錄>`,印出的 id 要包含新語料。以 `elf-mcp-gateway` 第 2 節〈註冊〉A 步驟 1、2 為準。 WHY:產生器依 capabilities 自動列齊工具(`gen-book-configs.mjs:57,62`),取代證據 E10 那種手寫漏列;任一語料不合法,registrar 不註冊任何 server 並以 1 結束(`:87-90`)。 (`:87-90` 是產生器自己以 1 結束;registrar 收到後呼叫 `fail` 整批不註冊,見 `registrar.sh:24,27`、`books/README.md:171`。) gateway dashboard 與 AI 端只看得到這段描述(E10:當時手寫的 fc 註冊檔漏列 outline / symbol),所以描述的來源 `corpus.json` 的 `description` 要寫清楚涵蓋範圍。 13. **MUST NOT** 為了新語料去改 `REGISTER_LIST`:它空白時 registrar 註冊全部書本+`registry/*.json`,有值時只註冊它列的名字(`registrar.sh:44-52`;`REGISTER_EXTRAS=0` 時空白只註冊書本,`compose.attach.yaml:25` 預設 0)。細節見 `elf-mcp-gateway` 第 2 節〈註冊〉。以 `elf-mcp-gateway` 規則 14、規則 10 為準。 WHY:書本清單由 `gen-book-configs.mjs` 掃 `books/*/corpus/*/` 產生,registrar 映像也直接帶 `books/`(`mcpjungle/registry/Dockerfile:5`);把新 id 寫進 `REGISTER_LIST` 只會讓它變成「只註冊這些」,**清單外的書反而不會註冊**。 14. **MUST** 修改既有 server 的 `url` / `description` 時,先 `mcpjungle deregister <id>` 再重新註冊。 WHY:`registrar.sh` 的 `is_registered` 看到同名就「已註冊,略過」(`registrar.sh:68-75`),改過的設定不會生效。改名既有語料時 registrar 只新增、不移除,舊名要手動 `deregister`(`books/README.md:179`)。 --- ## 3. 標準範本與步驟(新增知識庫 Step-by-step) 範本檔:`templates/corpus.json`、`templates/doc-template.md`、`templates/corpus-smoke.test.ts`。 `templates/servers-corpus.json`、`templates/servers-corpus-hardened.json` 是舊式手寫註冊檔格式,僅供對照;現行由 `gen-book-configs.mjs:59-65` 產生(兩者的差異見第 7 節待確認 9)。 ```text Step 0 選 id、查撞名 Step 1 建 mcpjungle/books/<書名>/corpus/<id>/ 與 md Step 2 corpus.json(+選用 sources.json / examples/) Step 3 本機驗證(test / build / stdio / http + 書本的上架前檢查) Step 4 註冊(registrar 依 corpus.json 自動產生;本機用 gen-book-configs.mjs 驗證) Step 5 部署(build 法或 pull 法) Step 6 驗證 gateway 真的曝露工具 Step 7 同 PR 更新文件 ``` **Step 0 — 選 id、查撞名** 在 mcp-library repo 根目錄執行(Step 0–2 都在根目錄;Step 3 才 `cd mcpjungle/docs-mcp-server`): ```bash ls mcpjungle/books/*/corpus/ mcpjungle/registry/ docker compose exec mcpjungle /mcpjungle list servers # 以 gateway 執行期清單為準(books/README.md:163) ``` **Step 1 — 語料資料夾**(`mcpjungle/books/<書名>/corpus/<id>/`) 來源是一本書時,md 由 `import.ts` 產生,照 `elf-mcp-book` 第 3 節;下面是語料資料夾本身的內容。 ```text mcpjungle/books/<書名>/corpus/<id>/ ├── corpus.json # 必放(docs-mcp-server 讀取時欄位全選填,但團隊規定六欄 book / language / source / title / description / capabilities 都要寫;book 要等於書資料夾名) ├── sources.json # 選用:只在要覆寫自動抽取的來源時放 ├── index.md # 選用:分類導航 ├── <分類>/01<主題>.md # 依 templates/doc-template.md └── examples/ # 僅 capabilities.examples=true 時 ``` **Step 2 — `corpus.json`**(`templates/corpus.json`) ```json { "book": "<書名,小寫、同一本書各語言共用>", "language": "<BCP 47:en / zh-TW / zh-CN>", "source": "https://<原始網址>", "title": "<人類可讀名稱,用該語料的語言寫>", "description": "<一句話:這是什麼、涵蓋哪些主題、附不附程式碼範例、有沒有已知缺陷(機器翻譯、失效圖片連結…)>", "capabilities": { "cheatsheet": false, "examples": false, "symbol": false } } ``` 六個欄位**都要寫**(`mcpjungle/books/README.md` 第三節 `:112-155` 的團隊規定);`source` 程式不讀;`book`/`language` docs-mcp-server 不讀,但 registrar 的 `gen-book-configs.mjs:52-55` 會驗證(`book` 要等於書資料夾名、id 要等於 `<book>-<language 小寫>` 或 `<book>-bi`),不符就整批不註冊(`registrar.sh:24,27`)。三者是回溯來源與分辨同書各語言的唯一依據。 上游授權要求保留聲明時另加 `license` 欄並在語料根目錄放 `LICENSE` 全文。 能力對照(目前,`73b8206`:`sqlsugar-zh-tw` = cheatsheet + examples;`fc-zh-tw`、`nginx-en`、`opnsense-en`、`opnsense-zh-tw`、`stalwart-en` = symbol,`books/README.md:38-45`): | capability | 能回內容的工具(未啟用時仍曝露,呼叫會回提示) | 語料需要具備 | |---|---|---| | (不需 capability) | `docs_list_corpora` `docs_search` `docs_read` `docs_outline` | md 檔 | | `cheatsheet` | `docs_cheatsheet` | 每篇有「速查」標題段落 | | `examples` | `docs_code_search` `docs_code_read` | `examples/` 下有白名單副檔名原始碼 | | `symbol` | `docs_symbol` | API / 組件名以 `#`/`##`/`###` 標題呈現 | 出處(mcp-library `origin/release` @ `2f71743`;`docs-mcp-server/src/` 自 `73b8206` 起未變,行號兩者通用):8 個工具**一律無條件註冊**(`mcpjungle/docs-mcp-server/src/index.ts:145-279`,8 次 `registerTool` 都沒有條件;同檔 `:5` 註解「故工具數恆為 8,capability-gated」),所以 **capability 決定的是「能不能回內容」,不是「工具會不會出現」**;capability 沒開時工具照樣可呼叫,只是回一段文字提示、不是錯誤: 未啟用時回提示的位置(`mcpjungle/docs-mcp-server/src/corpus.ts`): - `cheatsheet` → `:545`「未啟用速查表功能。請改用 docs_read …」(gate 在 `:544`) - `examples` → `:572`「無代碼範例(未啟用 examples)。請改用 docs_search …」(gate 在 `:571`;`docs_code_search` 走 `:579`、`docs_code_read` 走 `:639`,兩個工具共用同一段 `requireExamples`) - `symbol` → `:729`「未啟用 symbol(無符號索引)。請改用 docs_search 或 docs_outline。」(gate 在 `:728`) **Step 3 — 本機驗證**(`cd mcpjungle/docs-mcp-server`;PowerShell 用 `$env:X="..."`,mcp-library `CLAUDE.md:50-55` 也是這個寫法) ```bash npm ci && npm run build && npm test # 既有測試(73b8206 為 128 個)必須全過,數量不得減少 cp <skill>/templates/corpus-smoke.test.ts tests/<id>.test.ts # 即 mcpjungle/docs-mcp-server/tests/<id>.test.ts;把 <corpus-id> 換掉後跑 $env:DOCS_SCOPE="<id>"; npm run dev # stdio 鎖單一語料,stderr 應印「已鎖定單一語料:<id>」 # (PowerShell;Git Bash 寫成 DOCS_SCOPE=<id> npm run dev) $env:TRANSPORT="http"; npm start # 另開終端: # (PowerShell;Git Bash 寫成 TRANSPORT=http npm start) curl http://localhost:5690/health # corpora / docs 數要 +1 / +篇數 ``` 書本語料另跑 `elf-mcp-book` 第 3 節的「上架前檢查(規則 9、10、11)」:泛名標題 0 篇、來源問題 0 篇。 **Step 4 — 註冊**:註冊見 `elf-mcp-gateway` 第 2 節〈註冊〉。下面兩步即該節 A 的步驟 1、2,指令、預期與停止條件跟該節逐字一致;兩步都不起容器。 下面兩步在 mcp-library repo 根目錄執行(Step 3 停在 `mcpjungle/docs-mcp-server`,先 `cd ../..`): - **步驟 1(不手寫註冊檔)**:不新增任何註冊檔,`REGISTER_LIST` 保持空白(預設)。 指令 `docker compose config | grep REGISTER_LIST`,預期 `REGISTER_LIST: ""`(接現有 gateway 時加 `-f compose.attach.yaml`);GitOps 工具則看它的 env 編輯器有沒有設 `REGISTER_LIST`。 有值就停,見 `elf-mcp-gateway`〈註冊〉B 表第 2 列。 - **步驟 2(部署前驗證)**: 指令 `node mcpjungle/registry/gen-book-configs.mjs mcpjungle/books "$(mktemp -d)"`,預期 exit 0,印出的 id 包含 `<id>`(`73b8206` 印出 6 個 id)。
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen