做完之後,Codex CLI 可以回答「Launch plan 專案從昨天到現在改了什麼?」,而且不用把專案裡每則 note、每個 channel 重讀一遍。它會先問 osFoundry owner 授權了哪些資源(list_granted_resources),找出專案裡有什麼(list_project_resources),再向每個資源只要求它上次看到的 sequence 號碼之後的事件(poll_resource_events)。這些號碼存在你 repo 裡的一個小檔案,所以下一個 Codex session 會從上一個停下的地方接著做。每一次呼叫都會出現在 osFoundry 該連線的 Recent activity 裡。

誰負責什麼

Codex CLI osFoundry
登入 保管 osFoundry 的 OAuth token,osfoundry:read 就夠了 Owner 在 Connected 分頁核准一次連線
能看到什麼 list_granted_resources 回傳的內容,其他一概沒有 由 owner 決定:加到這個連線的專案,以及受邀加入的 Message channels
「上次看到哪裡」存在哪 每個資源一個整數,由 Codex 保管(這裡放在 .osfoundry/cursors.json) 每個資源一份有序的事件 log,從某個 sequence 號碼開始讀
有變更時會執行什麼 由 Codex 決定:重讀那則 note、讀 channel,或只是回報 什麼都不做。輪詢不會改動 server 上的任何東西
誰能叫停 你,只要不再問就好 Owner 移除專案、取消勾選某個 tool,或撤銷連線

設定

1. 找到 Codex 的連線

在 osFoundry 裡,標頭的鑰匙圖示會打開 Connected 分頁。如果 Codex 還沒連上,在 Assistant 選 Other MCP client,取一個顯示名稱,例如 Codex CLI,再按 Add assistant。面板上會列出要交給 Codex 的 server 位址。

範例:Connected agents 分頁,顯示一個啟用中的 Codex CLI 連線

範例:Connected agents 分頁,顯示一個啟用中的 Codex CLI 連線

在 Codex 這邊:

codex mcp add osfoundry --url https://api.osfoundry.io/api/v1/external-mcp codex mcp login osfoundry 

2. 決定 Codex 可以監看什麼

這是 owner 的工作,也是「Codex 會看到什麼?」的完整答案。選取連線後打開 Projects。在 "Choose a project" 選一個專案,按 Add to project。說明文字寫出了這樣會授權什麼:"Adding this agent to a project gives it access to supported synced content in that project and its discussion channel. Other Message channels require a separate invitation."

也就是說,一個專案會讓 Codex 拿到其中的 notes、knowledge bases、record channels、Rooms、GitNest repositories 和 sessions,再加上專案的討論 channel。其他任何 Message channel 都是另外一個明確的步驟:往下捲到 Message channels,在 "Choose a Message channel" 選好之後按 Invite。

範例:Codex CLI 連線已加入 Launch plan 專案,並受邀加入一個 Message channel

範例:Codex CLI 連線已加入 Launch plan 專案,並受邀加入一個 Message channel

在專案存取功能出現之前儲存的權限,會顯示在 "Older individual access"。list_granted_resources 也會把它們當作個別授權的資源回傳,所以在認定專案是唯一入口之前,先確認一下這個區塊。

3. 保持三個 tool 勾選

在同一個連線打開 Tools。"All supported tools are on by default." 保留勾選 list granted resources、list project resources 和 poll resource events,以及 Codex 得知有變更後需要用到的讀取工具(read note tab、read channel messages 等)。在這裡取消勾選某個 tool,會直接在 osFoundry 端把它拿掉,不管 Codex 自己的設定寫什麼。

4. 把 Codex 限縮在監看迴圈

# ~/.codex/config.toml [mcp_servers.osfoundry] url = "https://api.osfoundry.io/api/v1/external-mcp" scopes = ["osfoundry:read"] enabled_tools = [ "list_granted_resources", "list_project_resources", "poll_resource_events", "list_note_tabs", "read_note_tab", "read_channel_messages", ] 

這六個在 server 上都標記為唯讀,所以 Codex 執行時不會再問你。

5. 告訴 Codex cursor 要存在哪裡

Codex 每個 session 都是從零開始,所以每個資源最後的 sequence 必須放在它讀得到的地方。在 repo 裡放一份 AGENTS.md 就行:

## osFoundry changes - Cursors are in .osfoundry/cursors.json: {"<resource_type>:<resource_id>": <last sequence>}. - Start with list_granted_resources. Drop cursors for resources it no longer returns. - For each watched resource call poll_resource_events with after_sequence from the file and limit 100. If a page comes back full, call again from its last sequence. - Only after reporting the changes, write the new sequence back to the file. - A resource with no cursor yet: poll from after_sequence 0 once to get its current sequence. 

在回報之後才寫回 cursor,而不是之前,這樣 session 中途掛掉時,下次會再看到同樣的事件,而不是把它們弄丟。

實際跑一次

撰寫本文的機器上沒有安裝 Codex,所以下面的 session 是模擬的範例。Tool 名稱和參數名稱都來自正式環境的 server,前面加上 Codex 會自動補上的 mcp__osfoundry__ 前綴。專案、資源、sequence 號碼和結果都是示範內容。

Example (simulated) > What changed in the Launch plan project since my last check? • mcp__osfoundry__list_granted_resources {} ← project "Launch plan"; message_channel "launch-updates" (invited) • mcp__osfoundry__list_project_resources {"project_id": "…", "resource_type": "note"} ← 3 notes: "Launch checklist", "Pricing page copy", "Press list" • mcp__osfoundry__poll_resource_events {"resource_type": "note", "resource_id": "…", "after_sequence": 118, "limit": 100} (Launch checklist) ← 2 events, last sequence 120 • mcp__osfoundry__poll_resource_events {… "Pricing page copy", "after_sequence": 64 …} ← no events • mcp__osfoundry__poll_resource_events {… "Press list", "after_sequence": 9 …} ← no events • mcp__osfoundry__poll_resource_events {"resource_type": "message_channel", "resource_id": "…", "after_sequence": 311, "limit": 100} ← 5 events, last sequence 316 • mcp__osfoundry__read_note_tab {"note_id": "…", "tab_id": "…"} (Launch checklist) • mcp__osfoundry__read_channel_messages {"channel_id": "…", "limit": 5} (Codex writes 120 and 316 back to .osfoundry/cursors.json) Two things moved since yesterday. In "Launch checklist", the press embargo line now says Thursday 09:00 instead of Wednesday. In launch-updates, five messages: the pricing page is approved, and the App Store build is still in review. "Pricing page copy" and "Press list" haven't changed. 

四次 poll、兩次讀取。沒有 cursor 的話,同樣的答案得把三則 note 和 channel 全部讀完,再跟 Codex 記得的東西比對,而它什麼都不記得。

在 owner 那邊,每一次呼叫都是該連線 Recent activity 裡的一行:tool 名稱、判定結果、時間。

範例:檢查一次之後,Codex CLI 連線的 Tools 與 Recent activity

範例:檢查一次之後,Codex CLI 連線的 Tools 與 Recent activity

界線在哪裡

Codex 只看得到 list_granted_resources 列出的東西。Server 自己的 initialize 回應寫著 "Use list_granted_resources first",而且這個呼叫不接受參數:Codex 沒辦法指名要某個專案就進得去。不是專案討論 channel 的 Message channel,在 owner 邀請這個連線之前都看不到。list_project_resources 的 description 也再次強調:"Ordinary Message channels require a separate invitation."

輪詢是讀取,不是訂閱。Server 只公開 tools,所以 osFoundry 永遠不會主動叫醒 Codex。這本來就符合 Codex 的運作方式:你執行它,它才去看,而 cursor 讓「從上次到現在」變得很便宜。

poll_resource_events 一次只處理一個資源,沒有「整個專案」的 cursor。這讓每份 log 保持精簡,每項授權也彼此獨立。Owner 移除專案之後,對其資源的 poll 就會失效,下一次 list_granted_resources 也不會再列出它們。這時 Codex 應該丟掉那些 cursor,而不是重試。

Graph session 是特例。poll_resource_events 接受 graph_session,但 Graph 存在 owner 的桌面上。只有在 owner 於 "Share desktop Graph sessions" 勾選、而且桌面 app 開著並已登入時,它們才會出現在連線上。其他只存在裝置上的東西都會留在原地。initialize 回應寫著 "Local-only data is unavailable to cloud clients."

下一步,把它放進你的早晨例行公事:在有 AGENTS.md 的 repo 裡,先執行 codex exec "What changed in the Launch plan project since my last check?" 再打開其他東西。每個連線會拿到哪些 tool,以及為什麼存取權仍然是以專案為單位決定,請看 tool scope 頁面。底層的協定則在 MCP 詞彙條目。