做完之後,Codex CLI 可以在 osFoundry 的 GitNest repository 上做兩件事。它會把你終端機 session 裡的檔案寫到一個 branch 上,也能把完成的 change set 以 pull request 送出去,可以是在 GitNest 裡,也可以是 GitHub 或 GitLab 上的 draft。Codex 本身不會 commit 或 push 任何東西。每件工作都會變成 Codex CLI 連線上「Needs your approval」底下的一張卡片,上面印著檔案、branch 或確切的 commit。在 repository owner 按下去之前,什麼都不會發生。
誰負責什麼
| Codex CLI | osFoundry | |
|---|---|---|
| 登入 | 你的 Codex 登入。Codex 持有帶 osfoundry:read 和 osfoundry:write 的 osFoundry OAuth token | Owner 已在 Connected 分頁核准過一次這個連線 |
| 能送出什麼 | 一個 branch 最多 20 個 UTF-8 檔案,總共 200 KB。或是一個鎖定到某個版本和某個 composed commit 的 change set ID | 把每個請求存成有期限的提案 |
| 誰來核准 | Codex 在每次寫入呼叫前都會問你(default_tools_approval_mode = "writes") | 連線的 owner 在仍具有 repository 角色的前提下,按下 Approve and create 或 Approve and publish |
| 誰來寫入 | Codex 這一側沒有人 | 核准後由 osFoundry 建立 commit,或開啟 pull request |
| Provider token | 從不送出 | 核准時使用 owner 已連結的 GitHub 或 GitLab 帳號,而且只用在該 change set 自己的 branch |
| Merge | 碰不到 | 留給人來做,在 GitNest 或 provider 上 |
設定
1. 把 Codex 限縮到 GitNest 工具
連線的建立方式和平常一樣:header 的鑰匙圖示、Connected 分頁、Other MCP client,再取一個像 Codex CLI 這樣的顯示名稱。每張卡片和每則通知都會顯示這個名稱,所以請挑 owner 一看就認得的。
Codex 這邊:
codex mcp add osfoundry --url https://api.osfoundry.io/api/v1/external-mcp # ~/.codex/config.toml [mcp_servers.osfoundry] url = "https://api.osfoundry.io/api/v1/external-mcp" scopes = ["osfoundry:read", "osfoundry:write"] default_tools_approval_mode = "writes" enabled_tools = [ "list_granted_resources", "read_gitnest_repository", "list_gitnest_work", "list_gitnest_checks", "propose_gitnest_file_import", "propose_gitnest_native_publication", "propose_gitnest_provider_publication", ] codex mcp login osfoundry Server 一共列出 59 個工具,這篇教學只需要這七個。三個 propose_ 工具是唯一沒有標成 read-only 的,所以在 "writes" 模式下,Codex 會自己執行四個讀取工具,並在每個提案前停下來問你。也就是連續兩道核准:先是你在終端機裡的,再來是 owner 在 osFoundry 裡的。如果你自己就是 owner,第一道只是確認 Codex 要提出的正是你想要的。
2. 把 repository 放進連線所在的 project
連線只能透過 project 看到 GitNest repository。在 GitNest 打開 repository,找到 Project 區塊。只有 repository owner 會看到選擇器。選好 project 後,toast 會顯示「Repository project updated」。接著在 Connected 分頁選取 Codex CLI,在 Projects 底下對同一個 project 按 Add to project。
檔案匯入另外需要原生的 GitNest repository,也就是 Git 存放在 osFoundry 裡的那種。工具說明寫得很直白:「Repository GitNest must be enabled.」只是 mirror GitHub 的 repository,則改走 change set 和 provider 發布那條路。
3. 用 GitHub 或 GitLab 時,先連結 provider 帳號
propose_gitnest_provider_publication 會在 owner 核准的那一刻,用 owner 已連結的 Git provider 帳號來 push。如果沒有連結任何帳號,這次核准就沒有東西可以拿來 push。整個過程中 Codex 都不需要 GitHub token。
實際跑一次
撰寫本文的電腦上沒有安裝 Codex,所以下面的 session 是模擬的 Example。工具名稱和參數名稱都來自實際運作中 server 的 tools/list,並加上 Codex 自動補的 mcp__osfoundry__ 前綴。Repository、檔案、ID 和回覆都是示範內容。
Example (simulated) > shop-api has no CI. In osFoundry, put a GitHub Actions workflow that runs `make test` on pull requests, plus the Makefile target, on a branch codex/ci-workflow. • mcp__osfoundry__list_granted_resources {} ← project "Checkout" · GitNest repository "shop-api" • mcp__osfoundry__read_gitnest_repository {"repository_id": "…"} ← native, GitNest enabled, default branch main • mcp__osfoundry__propose_gitnest_file_import { "repository_id": "…", "branch": "codex/ci-workflow", "message": "Add CI workflow and make test target", "files": [ {"path": ".github/workflows/ci.yml", "content": "name: ci\non: [pull_request]\n…"}, {"path": "Makefile", "content": "test:\n\tpython -m pytest -q\n"}], "idempotency_key": "codex-shop-api-ci-0001"} [Codex asks: allow this tool call? → yes] ← proposal waiting for the owner I prepared one commit for shop-api on codex/ci-workflow with two files. Nothing is committed yet. The owner approves it in osFoundry. 在 osFoundry 裡,鈴鐺會顯示「Codex CLI proposes GitNest file changes」。在連線的面板上,卡片寫著「Commit GitNest files in shop-api」,接著是「Commit to branch: codex/ci-workflow」和 commit 訊息。展開「Review all proposed files (2)」會看到每個檔案的完整內容,而不是 diff 摘要。Approve and create 會建立 commit,Decline 則直接丟棄。
範例:shop-api 的 Commit GitNest files 卡片,兩個提議的檔案都已展開
同一天稍晚,GitNest 裡已經有一個 compose 好的 change set:
Example (simulated) > Is the "Add CI workflow" change set green? If so, open it on GitHub as a draft PR. • mcp__osfoundry__list_gitnest_work {"repository_id": "…", "kind": "changes"} ← "Add CI workflow" · version 3 • mcp__osfoundry__list_gitnest_checks {"repository_id": "…", "change_set_id": "…"} ← composed commit 73e59f27bc4f…: unit passed · lint passed • mcp__osfoundry__propose_gitnest_provider_publication { "repository_id": "…", "change_set_id": "…", "expected_change_set_version": 3, "expected_composition_oid": "73e59f27bc4f…", "idempotency_key": "codex-shop-api-ci-pr-0001"} [Codex asks: allow this tool call? → yes] ← proposal waiting for the owner Both checks passed on the composed commit. I asked for a draft GitHub PR of version 3; it opens when the owner approves it in osFoundry. Codex 不會替 pull request 指定 branch、標題或目標。Schema 只接受 change set、它讀到的版本,以及它讀到的 composed commit。要求 draft: false 或換一個 target_branch,在請求送到任何人之前就會被擋下。
這張卡片的標題是「Open a draft GitHub or GitLab pull request in shop-api」。上面顯示「Change set: … · expected version 3」、「Reviewed commit: 73e59f27bc4f…」、一個「Review change set before approving」連結,以及一行說明核准會做什麼:它「uses your linked Git provider account to push this change-set branch and open a draft pull request」。按鈕是 Approve and publish。對於存放在 GitNest 裡的 repository,propose_gitnest_native_publication 會產生對應的另一張卡片「Publish GitNest pull request」,它「creates a publication branch and opens a pull request in this native repository」。
範例:Needs your approval 底下的一張 provider pull request 卡片和一張原生發布卡片
卡片上的連結會在 GitNest 裡打開該 change set。它的 composed commit 的 check 就放在最上方、review 分頁的上面,讓 owner 在決定之前看到和 Codex 一樣的東西。
界線在哪裡
檔案匯入只帶文字。每個項目就是一個路徑加上它的完整內容,沒有別的。沒有檔案權限模式、不能刪除、不能放二進位檔,而且整個 commit 都限制在 20 個檔案、200 KB 以內。這樣卡片上的每個 byte 都讀得到。Owner 自己在 GitNest 用瀏覽器上傳的上限則寬得多(2,000 個檔案、每個 8 MB、總共 32 MB),因為那是人在 commit 自己的檔案。
發布是從 compose 好的 change set 出發,而不是從 Codex 指定的 branch。卡片會鎖定 Codex 看過的版本和 commit。如果在按下去之前 change set 被重新 compose,osFoundry 的重新檢查會拒絕這個提案,而不是發布一個沒人 review 過的東西。核准時它也會檢查目前的權限、repository 的風險等級和必要 check,以及目標。這些規則是人在 GitNest 的 Risk tiers 和 Required checks 底下設定的,Codex 碰不到。
在 GitHub 或 GitLab 上,只有 change set 自己的 branch 會動。Pull request 以 draft 開啟,push 則在核准當下使用 owner 已連結的帳號。Codex 從頭到尾看不到那個 token,你的其他 branch 也不在 push 範圍內。
Merge 不在清單上。這些提案最多只走到一個開啟中的 pull request。由誰來 merge,以及 merge 之後會觸發什麼,都留給 repository 上的人決定。
兩個發布工具在 tools/list 裡都帶有 openWorldHint: true,檔案匯入則沒有。Pull request 是對話以外的人也看得到的東西。設計良好的 client 會把這當成先問一聲的理由,就像這裡的 Codex 一樣。
下一步,可以在一個還沒人用的 branch 上試試匯入。請 Codex 只提議一個新檔案,例如 CONTRIBUTING.md 或一個 CI workflow,在卡片上打開「Review all proposed files」,然後核准。GitNest 頁面 說明了 change set、check 和發布在 repository 這一側是怎麼搭在一起的。


