我的工作日分散在許多互不關聯的工具中:Google 日曆、Linear、Gmail、Google 文件、GitHub、Slack 和 Granola 會議記錄。沒有一個單一的視圖可以回答「我現在應該做什麼?」這個問題。
人工智慧正在迅速改變我們的工作方式。 MCP 伺服器、代理程式以及像 Claude Cowork 這樣的功能可以連接到許多資源,並透過對話、隨時可用的 MCP 伺服器和工具整合來幫助你規劃一天的工作。但我一直以來都是自己安排工作優先級,主要依靠各種清單、專案管理工具、Slack 提醒、Gmail 標籤和日曆區塊等組合方式。
這總是很混亂,但這混亂是我自己造成的。現有的AI代理可以幫我匯總資料,但我仍然需要對所有事情進行優先排序和分析。這不是工具可用性的問題,而是推理能力的問題。對我來說,始終重要的是,這必須是我自己的推理。我想要的是一個儀表板,它不僅能顯示所有訊息,還能替我思考,並且以我的方式思考。
所以我開發了一個人工智慧代理,它可以讀取我所有的工作工具,並幫助我規劃一天的工作。但很多人都做過類似的事情,所以更重要的是:我沒為此抓狂,也沒在身分驗證部分苦苦掙扎數週。
Plan My Today 是一個每日計畫儀錶板,內建一個名為「Todaygent」的聊天機器人。 Plan My Today 的 MCP 伺服器會呼叫多個資料來源,尋找待辦事項,並將它們整合到一個統一的、按優先順序排序的視圖中。然後,Todaygent 會利用真實資料,分析我的優先順序、障礙以及會議準備。
https://www.youtube.com/watch?v=76xm1awRKOA
雖然我花了很多時間來定義 Todaygent 的功能,但同樣重要的是,我也要清楚說明 Todaygent 的限制。我一直有點受虐傾向,因為我的任務清單總是亂糟糟的……而且我喜歡手動勾選完成任務後那種多巴胺帶來的快感。我不希望任何代理來移動我的任務,或把任務標記為「已完成」。
我想要的只是一個足夠聰明的工具,能夠像我擁有大量空閒時間時那樣進行計劃和安排(當然,誰又有那麼多空閒時間呢?)。它甚至不需要計劃超過一天的事情。如果說我從自己的計畫習慣中學到了什麼,那就是我每天的安排都在不斷變化。任何超過一天的計劃都會被我拋諸腦後。我喜歡自己管理任務,只是需要一些幫助來應對在各種繁雜的工具中進行每日計劃的問題。
Todaygent 對所有資料來源都擁有唯讀權限,而且它清楚自身的限制。它使用本地儲存來允許我忽略那些無法在源頭忽略的內容(例如會議記錄或 Slack 提及)。
我也意識到(透過大量使用),我需要根據自身作為個體所擁有的、無法從冷冰冰的硬資料中捕捉到的語境,來調整特定任務的優先順序。 MCP 伺服器為每項操作都提供了相應的工具,並將更新寫入本機 JSON 儲存以追蹤我的操作。至於其他所有事項(例如我特意標記的 Linear、GitHub、Gmail、日曆和 Slack 訊息),我則負責在來源應用程式中手動更改狀態。 Todaygent 不需要對外部工具擁有寫入權限即可規劃我的行程。
應用程式儀表板有兩種視圖:基於優先順序(緊急/高/中/低)和基於來源的分組,以及淺色/深色/系統主題、搜尋、篩選和排序。


Plan My Today 的架構如下:

所有 MCP 工具均透過中央註冊表進行管理。涉及外部 API 的工具遵循以下模式:Zod 模式 → 非同步處理程序 → 提取授權資訊 →金鑰卡令牌交換 → MCP 格式的回應。每個工具對應一個文件,並透過TOOL_REGISTRY陣列註冊。
list-all-tasks-today這就是它:一個可以從所有第三方來源提取資訊、對優先順序進行評分、並透過交叉引用豐富任務的工具。
所有資料來源都透過Promise.allSettled()並發取得。每次取得都會進行獨立的 Keycard 令牌交換(更多詳情請參閱身份驗證部分)。每個任務都會獲得一個優先級分數。每個資料來源都有其自身的評分演算法,包含不同的基礎分數和訊號權重,這些權重是我精心調校的。如果我發現任何異常,我會根據需要調整權重和評分。 Todaygent 的運作邏輯與我一致,如果它不認同…我會強制它這麼做。 MCP 伺服器會交叉引用相關任務,以幫助 Todaygent 並讓我在查看儀表板時保持清醒的頭腦。
耗時較長的多來源資料取得操作( list-all-tasks-today )會將資料寫入本機 JSON 檔案。另一個工具會讀取本機任務列表,並按需向 Todaygent 和儀表板提供更新的任務列表。如果我新增或完成任務,可以再次觸發list-all-tasks-today操作。這樣就不會浪費任何代幣。
會議記錄是最容易出錯的來源,因為行動事項經常以正規表示式無法捕捉到的微妙方式隨意討論。在加入 LLM 增強功能之前,我除錯了大量遺漏的條目和誤報。後端 LLM 會進行第二次掃描,以捕捉對話中隱含的資訊。如果我在自然對話中主動提出(或同意)某項任務,LLM 可以辨識出來,而正規表示式則無法做到。
即使是人工智慧也知道身份驗證才是困難。這 8 個來源,涉及 7 種不同的資源,都需要進行令牌交換。其中包括針對 Google Calendar API、Gmail API、Drive API、Drive Activity API、Linear、GitHub 和 Slack 的權限控制。瀏覽器無法安全地儲存 API 金鑰。為每個提供者建立自訂身份驗證意味著需要 7 個獨立的 OAuth 實作。我在身分和存取管理方面經驗豐富,我知道這是一項繁瑣的工作,而且很容易出錯。

所有操作都透過Keycard OAuth 登入完成,並使用 Google 作為身分辨識提供者。瀏覽器執行 PKCE 流程,客戶端金鑰保存在伺服器端的保密後端。驗證成功後,我會從 Keycard 取得一個 JSON Web Token (JWT)。
我決定採用令牌中介後端(TMB)架構。 React 前端將金鑰卡 JWT 保存在 sessionStorage 中,並在每次向 Express 後端發送請求時,將其作為 bearer token 發送。後端負責所有令牌交換工作:它使用 JWT 請求特定提供者的憑證,呼叫 API,並傳回結果。來源服務的令牌不會經過瀏覽器。
當工具呼叫需要存取第三方 API 時,我的 Keycard JWT 會被交換為特定提供者的存取權杖。我的 Keycard JWT 會與資源 URL 一起發送,該 URL 指明了我想要存取的 API。然後,Keycard 會為我提供一個僅對所需提供者有效的短期存取權杖。
等等……Google的所有服務應該都由同一個 OAuth 提供者管理,對吧?沒錯,但它呼叫了多個 API。 Keycard 會頒發暫存憑證,這些憑證的作用域僅限於特定任務。我不想從谷歌獲得一個權限過大的存取令牌,擁有所有這些服務的權限。我希望 Todaygent 在需要查看日曆時,使用一個只讀的日曆 API 令牌;我希望在需要查看分配給我的評論時,使用一個只讀的雲端硬碟 API 令牌……你應該明白我的意思。這種方式安全可靠,會留下清晰的審計跟踪,並確保 Todaygent 只獲取執行特定任務所需的權限。它不會產生長期存取權限或權限過大的憑證。
注意: Slack 的「OAuth 2.0」實作並不遵循 OAuth 2.0 規範。 Keycard 支援非標準或自訂的「OAuth」協議,同時也預先配置了常用的授權提供者目錄。當授權提供者不符合標準時,Keycard 會自動為您「使其正常運作」。
每次工具呼叫都會從 Keycard 交換一個新令牌,將其用於 API 呼叫,然後丟棄。每個操作使用一個令牌。提供者存取令牌絕不會被儲存。
代理授權應遵循這樣的原則:代理人不應持有憑證超過必要的時間。靜態金鑰和長期有效的代幣會帶來未監控的風險,而這正是 Keycard 旨在解決的問題。
這就是 Keycard 的核心工作原理:策略是在頒發憑證時評估的,而不是在使用憑證時評估的。如果 Keycard 的策略規定 Todaygent 不應該為了這次工具呼叫而存取我的 Gmail,那麼 Gmail API 存取權杖就根本不存在。因為根本沒有頒發任何憑證,所以也沒有什麼可攔截的。
“但是所有這些代幣交易所的速度不都很快嗎?”
其實不然,原因如下。
並行交易可以抵消延遲。列表工具會使用Promise.allSettled()並發執行所有代幣交換。延遲成本是單次交易中最慢的一次(約 150-250 毫秒),而不是所有交易的總和。反正我本來就在等待最慢的 API 回應,而且所有代幣交換都會在所有 API 資料回傳之前完成。
此模式為「一次獲取,多次推理」。代理程式在每次對話中呼叫一次list-all-tasks-today函數,然後無需重新取得資料,即可在多個聊天回合中對結果進行推理。每次聚合呼叫僅需設定一套憑證,之後無需再設定其他憑證。 Todaygent 還擁有針對每個來源的多層配置 (MCP) 工具,並在單獨呼叫這些工具時取得相應範圍的存取權杖。
在初始多提供者工具呼叫中,臨時憑證的效能開銷約為每次儀表板載入 150-250 毫秒。考慮到憑證零重用,這絕對物超所值。
Keycard 最引人注目的功能之一就是它提供的資訊。每一次令牌交換、每一次使用者授權、每一次憑證發放、每一次資源存取都會記錄在 Keycard 稽核日誌中。儀表板載入後,當我打開 Keycard 控制台時,我可以清楚地看到 Todaygent 的所有操作。
Keycard 的稽核日誌顯示了完整的事件時間順序。執行一次list-all-tasks-today呼叫後,會記錄多個令牌交換事件。這些事件由並行執行的Promise.allSettled()獲取操作快速連續觸發。
但最有趣的部分是身份鏈,它顯示了兩個身分:應用程式(「今日計畫」)和使用者(我的郵箱)。這就是完整的追蹤記錄:哪個應用程式代表哪個使用者存取了哪個資源。
授權類型(令牌交換,而非直接的 OAuth 流程)、憑證提供者(Google)、授予的特定權限範圍、頒發時間戳記以及資源都與身分鏈相關聯。我非常清楚 Todaygent 的具體操作。

當我登入並授權 Plan My Today 存取我的行事曆、Gmail 等時,Keycard 會記錄使用者授權事件。授權事件是由使用者本人觸發的,而不是由 Todaygent 觸發的,因為是我授予了存取我自身資源的權限。
區別至關重要:用戶授權即同意(「我允許此應用程式存取我的 Gmail」)。憑證頒發即執行(「Todaygent 剛剛交換了一個令牌來讀取我的 Gmail」)。這是兩個不同的事件,由兩個不同的主體發起,但兩者都完全可追溯。
Keycard 的稽核日誌提供了事件詳情和更高等級的資訊。我還可以查看 Todaygent 在特定工作會話期間的操作:它呼叫了哪些 API、呼叫了多少次以及何時呼叫的。如果發現任何異常,我可以檢查審計日誌以獲取完整的會話事件追蹤。

授權就像一個緊急停止開關。我可以撤銷單一資源的授權,而不會徹底終止整個會話:Todaygent 下次對該資源的代幣交換會失敗,但其他所有功能仍可繼續運作。對 Plan My Today 來說,授權的設計初衷就是臨時性的:它們會在每個提供者代幣的生命週期結束後失效。在生產環境中,授權的有效期更長,而精準的撤銷操作則決定了最終結果是「完全關閉所有功能」還是「切斷 Gmail 存取權限,但日曆和 Linear 仍然可以正常工作」。

傳統的身份驗證方式只提供兩種使用者狀態:使用者已登入或未登入。當系統中存在智慧代理時,這種方式顯然不夠用。您可能在自己的伺服器上保存了存取日誌,但您無法了解哪些令牌被頒發給了哪些代理,用於哪些資源,以及代表哪個使用者。存取日誌會告訴您發生了什麼,而 Keycard 的稽核日誌則會在事件發生之前,告訴您哪些操作已被授權。
我開發 Plan My Today 的目標有兩個:一是規劃我的一天(顯而易見),二是透過使用 Keycard 來避免多工具代理存取的複雜繁瑣。這是我自己的「狗糧計畫」。 (不過在 Keycard 內部,我們喜歡說我們正在喝自己的香檳;這個比喻沒那麼令人反感。)Plan My Today 展示了 Keycard 的核心模型:
任務級憑證:每次 API 呼叫使用一個令牌
複合身分:每次請求中的使用者 + 代理 + 資源
零常駐存取權限:無快取資源令牌,無長期金鑰
授權鏈:每個行動最終都指向我。
Keycard 的稽核日誌提供了完整的流程鏈:使用者 → 應用程式 → 資源,記錄並可查詢每一次代幣交換和授權事件。對於像 Plan My Today 這樣代表我呼叫多個不同 API 的應用程式來說,這至關重要。為了安全地開發和部署代理,我可以用實際證據而非盲目信任來回答「代理如何處理我的資料?」這個問題。
Todaygent是個「計劃者,而非行動者」。它閱讀一切,卻幾乎不採取行動。我希望Todaygent擁有冷幽默,並且能夠自知其局限性,所以當我要求它做超出其能力範圍的事情時,它會說類似這樣的話:“我的創造者沒有授權我去做這件事。”
權限模型(有意限制)
自由讀取(所有讀取工具)-取得任何資料來源
行動前請先詢問- dismiss-task :撤銷會議記錄、文件、Slack 提及和臨時任務(本地存儲,無需 API 憑證); restore-dismissed-task :撤銷撤銷操作; set-task-priority :當我請求重新排序時,提升或降低任何任務的優先級(本地存儲)
故意停用- 線性狀態變更、GitHub 操作、電子郵件標籤、Slack 表情符號移除、電子郵件傳送、行事曆修改
這是一個信任設計決策。一個能夠閱讀我的工作並幫助我思考的規劃代理很有用。而一個可以毫無限制地修改我的工作的代理則很危險。採用最小權限原則意味著我可以放心地讓 Todaygent 執行,而不用擔心它會將我的 Linear 問題標記為“已完成”或自動回复郵件,即使我不小心讓它做了不該做的事情。或者,如果我故意這麼做……有時我這麼做只是為了看看它會如何反應。 (拜託,誰不這麼做呢?)這就是我對我的 Keycard 實現的信心所在。

聊天功能的實作位於一個 React hook 中,該 hook 管理著完整的代理循環:
User sends message
→ Stream Todaygent response (with all tools available)
→ If Todaygent calls tools, execute via MCP
→ Feed results back to Todaygent
→ Loop (max 10 rounds)
Todaygent 有很多地方容易出錯,所以我特意做了一些說明。最大工具呼叫次數限制可以防止無限循環。工具結果截斷機制可以避免單一 API 回應主導整個對話。提示快取機制可以保存每次對話的令牌。基於 Claude Opus 4.6 的自適應思維功能讓 Todaygent 能夠運用擴展思維進行複雜的規劃。最後,上下文管理使用 Anthropic 的 API,而不是手動設定對話視窗。
如果我請 Todaygent 幫我規劃一天的工作,我會收到一份包含時間區塊安排、依賴關係分析和跨來源情境的簡報。我可以向它詢問遇到的障礙、提高效率的建議,甚至可以讓它根據我的任務清單寫出俳句。
https://www.youtube.com/watch?v=DfzISjUqOIE
Todaygent 的系統提示並非「提供幫助」。它非常詳盡,定義了權限模型、行為模式、格式規則、工具呼叫策略以及各種特殊情況。它告訴 Todaygent 何時應該獲取新資料,何時應該從現有上下文推斷,以及在無法執行某些操作時應該如何表現。在早期,Todaygent 非常熱衷於提供幫助,但卻混亂不堪:它會在對話過程中重新獲取資料,忘記加入連結,或者自信地認為自己成功執行了某些它根本沒有相應工具或權限的操作。
我每天都會使用 Todaygent,而且一天用好幾次(因為我早上製定的計劃到了下午就全都變了)。它是我在工作電腦上使用的個人工作工具,完全根據我的工作方式量身定制。沒必要把它部署到公共網路上,也沒必要支援多租戶。我的 SaaS 應用程式已經夠亂了。
但我確實實現了一項生活品質改進:我將 Plan My Today 變成了一個漸進式 Web 應用 (PWA),這樣我就可以將其安裝為桌面應用。

我的「今日計畫」智能體程式設計課程永無止境。我發現,我潛意識裡用來安排一天的思考過程極為複雜。試圖讓一個非我自身的東西可靠地模擬這個過程,是一項艱鉅而永無止境的任務。
這讓我對人工智慧目前的水平有了相當清晰的認識,也讓我意識到我們仍然多麼需要人類的推理參與其中。有時我會想,我這樣做到底能不能節省時間。不過,至少開發這個專案本身就很有成就感。
如果您正在建立需要代表使用者存取多個 API 的原生代理應用,Keycard 可以幫助您省去為每個提供者單獨實現 OAuth 的麻煩。我從事身分認證工作(我非常熱愛這份工作!),即便如此,想到 Keycard 讓我避免了 OAuth 授權和存取管理的種種難題,我仍然會感到由衷的欣慰。只需一次登錄,即可授權所有提供者,並為您的代理所需的每個來源頒發策略感知、臨時且任務限定的令牌。您可以追蹤完整的代理和使用者授權鏈,並在必要時精準撤銷授權。
Keycard 目前處於搶先體驗階段,因此您可以註冊與我們的團隊密切合作,開發您自己的多服務代理應用程式(非常棒)。
我一直在收集關於 Plan My Today 的改進想法,這些想法來自 Linear 中積壓的任務:更多資源、新工具、使用者介面改進、更完善的文件。我每天都在使用 Plan My Today。現在,重點在於擴展 Todaygent 的檢視和(謹慎地)操作範圍,更重要的是,將 Keycard 的新功能整合到我的「內部測試」專案中。
當然,Todaygent 也不斷提醒我還有一些待辦事項需要完成,以便繼續改進它。
原文出處:https://dev.to/kimmaida/i-built-a-secure-planning-agent-with-mcp-and-keycard-324a