Docs

データの扱い

kichijitsu は予定の複製を手元に置いて動く。予定そのものの正本は Google にあり、サーバーが持つのは同期に必要な最小限だけ。 どこに何が保存され、消すと何が起きるかをまとめた。

正本は Google にある

kichijitsu は Google カレンダーと Google ToDo リストのクライアントであって、予定の保管庫ではない。 予定の正本 (オリジナル) は常に Google 側にあり、kichijitsu が扱うのはその複製 (レプリカ) にすぎない。

複製が置かれるのは、あなたが使っている端末のブラウザの中 (IndexedDB) だけ。画面はこの手元の複製から組み立てるので、表示や移動の操作は Google への往復を待たずに済む。予定を編集すると kichijitsu は Google へ書き戻し、更新された正本が次の同期で手元へ還ってくる。

その間に立つサーバー (Cloudflare Worker) は、Google と端末をつなぐ中継役で、予定の中身を保存しない。エージェント向けの MCP サーバーも同じ read-through 原則 で、ツールが呼ばれるたびに Google から取り直すか、その場で書き戻すだけになっている。

この前提があるので、以降の「どこに何が保存されるか」は 手元 (ブラウザ)・サーバー・Google の3つに分けて読むとよい。プライバシーポリシー上の位置づけは プライバシーポリシーにまとめてある。

ブラウザに入るもの

予定の複製と、この端末だけの設定が入る。保存先は3種類あり、性質がそれぞれ違う。

IndexedDB — 予定の複製

kichijitsu という名前のデータベースに入る。中身はストアごとに分かれている。

ストア 入るもの
occurrences 時刻のある予定の1回分。週グリッドに並ぶのはこれ
allDayOccurrences 終日予定
tasks Google タスク
series 繰り返し予定の定義 (何回分に展開するかの元)
overrides 繰り返しのうち、その回だけ変更された予定
githubItems GitHub の issue・PR・milestone。取得のたびに丸ごと置き換える (GitHub 連携と実績記録)
plannedBlocks 作業の予定ブロック。Google に正本が無い kichijitsu だけのデータで、この端末にしか存在しない
timeEntries 旧・手動タイマーの実績。現在は読み書きしておらず、既存ユーザーとの互換のために残してある
meta この端末の識別子、表示するカレンダーの選択、非表示にしたタスクリスト、不参加予定の表示設定など

localStorage — 画面の設定と、通知済みの記録

この端末での見た目・操作の好みと、リマインダー通知の設定が入る。 予定の中身 (タイトル・説明・参加者) は入らないが、 通知済みの記録だけは予定を指す値を持つ (最後の項目を参照)。キーはすべて kichijitsu: で始まる。

  • kichijitsu:theme — テーマ (自動/ライト/ダーク)
  • kichijitsu:view — 最後に選んでいた表示 (日/週/月など)
  • kichijitsu:hourHeight — 週グリッドの縦ズーム
  • kichijitsu:paneMode / kichijitsu:leftPaneOpen — ペインの配置と開閉
  • kichijitsu:calendarPaneCollapsedAccounts / kichijitsu:calendarPaneCollapsedGroups — カレンダー一覧の折りたたみ状態
  • kichijitsu:oooAllDayPlacement — 終日の不在 (OOO)を、その日のタイムラインに載せるか終日レーンに出すか
  • kichijitsu:ghPathgh コマンドのパス (デスクトップ版のみ)
  • kichijitsu:reminderLead予定のリマインダー通知を「何分前に出すか」の決め方 (デスクトップ版のみ)。 キー名は lead (何分前) だが、入るのは分数とは限らず 「Google の設定に従う」「通知しない」「一律◯分前の分数」の3種。 初版が分数だけを書いていた名残で、名前を変えると既存の設定が消えるためそのままにしてある
  • kichijitsu:reminderNotified — 同じ通知を二度出さないための通知済みの記録 (デスクトップ版のみ)。 1件ごとに「何分前の通知か・どの予定か・その予定の開始時刻」を持ち、 予定を指す部分にはカレンダー ID (多くはメールアドレス) と予定の ID が含まれる。予定のタイトル・説明・参加者は入らない。 24時間より古い記録は自動で捨てられる

Cache Storage — 画面を組み立てるファイル

kichijitsu- で始まるキャッシュ (kichijitsu-shell-v1kichijitsu-assets-v1) に、JavaScript や CSS といった画面を組み立てるファイルが入る。予定は一切入らない。

これら3つは端末ごと・ブラウザプロファイルごとに独立している。同じ Google アカウントで使っていても、PC とスマートフォンでは別々の複製を持つ (どちらも同じ正本を見ているので、内容は同期で揃う)。

サーバーに入るもの

サーバー側の保存先は Cloudflare の D1 (データベース) と Durable Object の2つ。どちらにも予定のタイトル・参加者・本文は保存されない。 MCP 連携も同じで、エージェントに返す予定の要約はその場の応答として返すだけで、 サーバー側には残らない。

D1 — 連携の情報

テーブル 入るもの
accounts 連携した Google アカウントの識別子とメールアドレス、暗号化した refresh token、どれがログイン用のアカウントか
account_visible_calendars
account_calendar_prefs
どのカレンダーを表示するかの選択。端末をまたいで揃えるためにサーバーが持つ
watches Google からの更新通知を受け取るための登録状態 (チャネル ID・対象カレンダー・期限)
block_rules
block_rule_sources
block_mirrors
カレンダーブロックの設定と、「元の予定の ID → 生成したブロックの ID」の対応。予定の内容は写さない
github_connections GitHub のログイン名と、暗号化したアクセストークン
mcp_tokens MCP トークンのハッシュ値・ラベル・最終使用日時。生のトークンは保存されない
work_logs 作業実績 (リポジトリ・issue・ブランチ・エージェント名・開始と終了の時刻)。Google に正本が無い kichijitsu 固有のデータなので、ここだけはサーバーが保管する

Durable Object — 同期の状態

  • アカウントごとの同期状態 — Google から差分を受け取るための同期カーソル (syncToken) を、カレンダーと端末の組ごとに持つ。あわせて access token のキャッシュ (寿命は1時間ほど) と、更新通知が届かないときのポーリング状態を持つ
  • 更新の配信 — 開いているタブへ「変わった」と知らせる接続を束ねる。接続は保持するが保存はしない
  • MCP の接続 — エージェントとの接続1つにつき1つ。read-through 原則どおり、予定を溜め込むことはない

認可情報の守りかた

サーバーが預かるもののうち、いちばん重いのが Google の refresh token ―― これがあると、あなたのカレンダーに kichijitsu としてアクセスできてしまう。

  • refresh token は AES-256-GCM で暗号化してから D1 に保存する。暗号化のたびに新しい初期化ベクトルを使い、保存されるのは暗号文だけ
  • 復号の鍵はデータベースの中には無く、Worker の秘密情報 (secret) として別に持つ。D1 の中身だけを取り出しても復号できない
  • GitHub のアクセストークンも同じ方式で暗号化する
  • MCP トークンはハッシュ値しか保存しない。生の値は発行直後に一度だけ表示され、以降どこにも残らない (MCP 接続ガイド)
  • 寿命の短い access token (1時間ほど) は Durable Object にそのままキャッシュする。毎回 refresh token から取り直す負荷を避けるための割り切りで、期限切れとともに無効になる
  • Google・GitHub・ブラウザとの通信はすべて TLS で暗号化される

Google タスクで扱えないもの

タスクの正本も Google 側にあるが、Google Tasks API はカレンダーの API ほど多くを返さない。kichijitsu が受け取れるのは、タスクの ID・タイトル・完了状態・期限・メモ・親タスクだけで、ここから外れる情報は そもそも届かない

  • 繰り返し (定期) タスク — API は繰り返しの設定を返さない。kichijitsu から見えるのは個々のタスクだけで、それらが繰り返しの一部であることを知る手立てが無い
  • 期限の時刻 — API が時刻を捨てるため、期限は日付までしか扱えない。タスクが日付のレーンに並び、週グリッドの時間帯に置かれないのはこのため
  • 即時の更新通知 — タスクにはカレンダーのような push 通知が無い。反映はカレンダーより遅れる

繰り返しタスクが期待どおりに扱えないのは Google Tasks API 側の制約であって、kichijitsu の不具合ではない。 kichijitsu 側で直せる種類の問題ではないので、繰り返しの設定・変更は Google ToDo リスト側で行うこと。

消しかた

消す操作は3段階ある。どれを実行しても Google 側の予定そのものは消えない (正本は Google にあるため)。例外はカレンダーブロックのルールを削除するときだけで、確認の「作成済みのブロック予定も削除する」を選んだ場合に限り、コピー先に作られた「予定あり」を Google カレンダーから消す。

  1. キャッシュ削除 — 表示が古いとき

    設定 (歯車アイコン) のいちばん下、「キャッシュを削除して再読み込み」。消えるのは kichijitsu- で始まる Cache Storage ―― つまり画面を組み立てるファイルだけで、 予定データ・連携アカウント・設定はどれも消えない。 更新したはずの画面が古いままのときの脱出口で、詳しくはデスクトップ版と PWAにある。予定の中身のほうが合わないときは、すぐ下の「予定を再同期」を使う (この一覧のあとの注記を参照)。

  2. 連携解除 — そのアカウントとの縁を切る

    設定のアカウント一覧にある「連携解除」。次の順で処理される。

    • Google 側の更新通知 (push 通知) の購読を止める ―― トークンを失効させると 停止を頼めなくなるので、必ずこれが先
    • Google 側のトークンを失効させる
    • サーバーからそのアカウントの行 (認可情報・カレンダー選択・購読の記録) と、 Durable Object の同期状態を消す
    • そのアカウントが関わるカレンダーブロックの設定を片付ける ―― 書き込み先だったならルールごと、参照元が複数あるうちの1つだったなら その参照だけを外す (残りの参照でルールは生き続ける)
    • ブラウザの IndexedDB から、そのアカウント由来の予定・終日予定・タスクを消す

    ただし、ブロック機能が Google カレンダーに作った「予定あり」のブロックは 解除後もそのカレンダーに残る (対応表が消えるのでアプリからは もう触れない)。解除の場面では消すかどうかを選べないため、 あらかじめ消しておきたいなら先にルールを削除して 「作成済みのブロック予定も削除する」を選ぶ。残ってしまったものは Google カレンダー側で消す。

    最後の1アカウントを外すと、そのプロファイルにぶら下がっていた GitHub 連携・MCP トークン・作業実績もまとめて消え、ログイン状態も破棄される。 Google アカウントの設定から kichijitsu のアクセス権を取り消してもよい。

  3. ログアウト — この端末の写しだけ消す

    設定の「ログアウト」は、ログイン状態を終えると同時にこの端末に置かれた 予定・タスク・GitHub の一覧を消す。正本は Google にあるので、次にログインすれば同期で戻ってくる。

    タイムブロックと作業タイマーの記録は消さずに残す。これらは サーバーに置き場が無く、この端末にしか存在しないため ―― 消すと二度と戻らない。 逆に言えば、端末を人に渡すときはこれらが残る点に注意する (その場合は下のサイトデータ削除を使う)。

  4. ブラウザのサイトデータ削除 — 手元を空にする

    ブラウザの設定から kichijitsu のサイトデータを消すと、IndexedDB・localStorage・Cache Storage がすべて消える。予定・タスクは正本が Google にあるので、次にログインすれば同期で戻ってくる。ただし 作業の予定ブロックのようにこの端末にしか無いデータは戻らない

「予定を再同期」は消す操作ではない。 設定のキャッシュ削除の隣にある 「予定を再同期」は、表示中のカレンダーの予定と取得済みのタスクリストを Google から全件取り直してブラウザ側の複製を作り直すだけの操作で、上の3段階とは性質が違う。

サーバーに入っているもの (認可情報・カレンダー選択・購読の記録・作業実績・カレンダーブロックの設定・MCP トークン) には一切触らず、Google 側の予定も当然そのまま。書き換わるのは IndexedDB の occurrences / allDayOccurrences / tasks だけで、手元の複製が Google と食い違ってしまったときに使う。手順はデスクトップ版と PWAの「更新されないとき」にある。

公式インスタンスとセルフホスト

予定の中身がサーバーに保存されないのは、どちらで使っても変わらない。違うのは 暗号化された認可情報を誰の Cloudflare アカウントに預けるか ―― つまり、誰を信頼することになるかだ。

公式インスタンス セルフホスト
D1 と Durable Object 運営者の Cloudflare アカウント あなたの Cloudflare アカウント
OAuth クライアント 運営者のもの あなたが Google Cloud で作ったもの
信頼する相手 運営者 (と Cloudflare・Google) あなた自身 (と Cloudflare・Google)
利用条件 招待制 制限なし (Cloudflare の無料プランで動く)

自分のデータの置き場所を自分で管理したいならセルフホスト手順へ。セルフホストしたインスタンスの規約・プライバシーポリシーには、運営者であるあなた自身の情報を出す必要がある (運営者情報と規約の差し替え)。