跳轉到

共用基礎設施 & MCP Tool 輸出層

回到 資料流索引

共用基礎設施

safe_encode(data: Any) → str (toon_utils.py)

  • 做了什麼
  • 偵測 Pydantic Model → model_dump()
  • json.dumps(default=str) 序列化 datetime 等特殊型別
  • 呼叫 toon_format.encode() 產出最終 TOON 字串

to_datetime(value) → datetime | None (time_tool.py)

  • 做了什麼:統一處理多種輸入格式(ISO8601、{dateTime:..}{date:..}、UNIX timestamp)→ UTC+8 datetime

format_for_llm(dt) → str (time_tool.py)

  • 做了什麼:將 datetime 格式化為 "YYYY-MM-DD HH:MM"(UTC+8),LLM 可直接理解

MCP Tool 輸出層

每個 MCP 工具最終回傳一個 TOON 字串 (str),由 safe_encode() 從 Python dict 轉換而成。

單一資料源工具

MCP 工具 呼叫的轉換函數 最終回傳格式
get_all_calendar_events to_toon_calendar()safe_encode() TOON 字串
get_event_from_calendar to_toon_calendar()safe_encode() TOON 字串
get_all_tasks to_toon_tasklist()safe_encode() TOON 字串
get_task_from_tasklist to_toon_tasklist()safe_encode() TOON 字串
get_moodle_events to_toon_moodle()safe_encode() TOON 字串
list_calendars _list_writable_calendars()safe_encode() TOON 字串 ({calendars: [{id, summary, primary, accessRole}]})
list_tasklists async_tasklists_list()safe_encode() TOON 字串 ({tasklists: [{id, title}]})
create_calendar_event async_insert_event()safe_encode() TOON 字串 (API 回傳的 event dict)
create_task async_task_insert()safe_encode() TOON 字串 (API 回傳的 task dict)
get_free_busy async_query_free_busy()safe_encode() TOON 字串 (FreeBusy API 回傳原始結構)

[!NOTE] list_calendarslist_tasklists 不使用 TOON 轉換函數(to_toon_*),而是直接在 Tool 層組裝 dict 後呼叫 safe_encode()。 兩者的回傳結構不包含 count 欄位 — TOON 的 key[N] 語法已包含數量資訊。

複合工具

get_time_contextResourceContextText

此工具整合三大資料源(Calendar + Tasks + Moodle),透過 ResourceContextText.from_resource_context() 轉換為統一 TOON 字串。

最終 TOON 字串的 dict 結構

{
    "meta": {
        "time_range": {"start": "2026-01-01T00:00:00Z", "end": "2026-02-01T00:00:00Z"},
        "generated_at": "2026-01-28T12:00:00",
        "sources": ["google_tasks", "google_calendar", "moodle"]
    },
    "google_tasks": {
        "Task List Name": {
            "name": "...", "id": "...",
            "parent_tree": {"父任務": {"子任務": "child"}},
            "month": {
                "2026-01": {
                    "done": [{"Task Title": {id, notes, done, done_at, due, p}}],
                    "pending": [...]
                }
            },
            "undated": [...]
        }
    },
    "google_calendar": {
        "Calendar Name": {
            "name": "...", "id": "...",
            "location_index": {"臺科大 TR-510": "loc_1"},
            "month": {
                "2026-01": [{"Event Summary": {id, t:"10:00~11:00", d, l, r, all_day, recurrence}}]
            }
        }
    },
    "moodle": {
        "course_index": [{"cid": "c1", "course": "[EE1001] 程式設計 張教授"}],
        "semester": {
            "114-1": {
                "2025-11": {
                    "due": [{"title": "...", "cid": "c1", "status": "Closed", ...}]
                }
            }
        }
    }
}

launch_planner_studio

此工具呼叫 get_time_context 取得資料後,透過 build_planner_payload() 生成 Planner Studio 專用 payload,啟動本地網頁伺服器。最終回傳的是狀態摘要:

{
    "ok": True,
    "url": "http://localhost:PORT/sessions/SESSION_ID",
    "opened_browser": True,
    "session_id": "...",
    "calendar_event_count": 42,
    "task_count": 15,
    "variant_count": 3,
    "view_date": "2026-01-28",
    "applied": False
}

錯誤回傳格式

所有工具在驗證失敗時回傳: - 認證失敗"AUTH_REQUIRED: invalid_grant" 純字串 - Moodle 憑證缺失safe_encode({"error": "Moodle credentials missing"}) TOON 字串 - 一般錯誤:由 @mcp_harden 裝飾器捕獲並格式化