Apple Calendar について
Apple Calendar は、EventKit を通じて macOS のカレンダーとリマインダーを管理するローカル MCP サーバーです。CRUD、タグ付け、スケジュール調整、サーバー管理のツールを備え、データはデバイス内に保たれます。
主な機能
- 01カレンダーとリマインダーの CRUD
- 02ハッシュタグ方式のタグ
- 03予定確認とスケジュール調整
- 04空き時間の検索
- 05権限確認とサーバー制御
活用シーン
- 01予定と期限の来たリマインダーの確認
- 02予定の作成や再調整
- 03タグによる項目の整理
- 04勤務時間内の空き時間の検索
MCP 対応
stdio を介して MCP クライアントにカレンダーとリマインダーのツールを提供します。ローカルで動作し、EventKit 経由でデータにアクセスします。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
apple-calendar MCP Server
EventKitをPyObjC経由で使用する、macOSのカレンダーとリマインダー向けの個人用MCPサーバーです。
EventKitを基盤としています。
stdio経由でローカル実行され、ネットワーク通信やクラウドサービスは使用しません。
Claude Desktop(コネクター名:apple-calendar)での使用を想定していますが、
あらゆるMCP stdioクライアントで動作します。
ツールはカレンダー/リマインダーのCRUD全般、ハッシュタグベースのタグシステム(tags_*)、
スケジュール管理用の便利なツール(agenda_*、quick_event、
reschedule_event、find_free_slots)、ホットリスタート用の管理ツール
(server_status、server_restart)を備えています。
要件
- macOS 14以降(最新の
requestFullAccessTo...権限APIを使用し、 古いmacOSでは従来のAPIにフォールバックします) - Python 3.10以降。uvで管理します。
インストール
cd apple-calendar-mcp
uv sync
アクセス権を付与する
EventKitは、最初にアクセスを要求したプロセス(「責任プロセス」)に カレンダー/リマインダーの認証を紐付けます。アクセス権を付与する方法は2つあります。
オプションA - 推奨。ターミナルから一度実行します:
uv run python scripts/setup_permissions.py
これにより、ターミナルの識別情報でカレンダーとリマインダーのシステム権限ダイアログが 表示されます。両方で「許可」をクリックしてください。
オプションB - 手動:
システム設定 > プライバシーとセキュリティ > カレンダー(およびリマインダー)を開き、 ターミナル、Pythonインタープリター、またはClaude Desktopのアクセスを有効にします。 サーバーを少なくとも一度実行すると、いずれかが一覧に表示されます。
ツール呼び出しで"error": "permission_denied"が返された場合は、
現在の状態と手順をeventkit_check_permissionsで確認するか、
セットアップスクリプトを再実行してください。
注:このサーバーをClaude Desktopのサブプロセスとして実行すると、macOSが権限確認の表示先を Claude Desktopに割り当て、ダイアログをまったく表示しない場合があります(バックグラウンドの サブプロセスではUIを表示できないことがよくあります)。Claude Desktopにサーバーを追加しても ダイアログが表示されない場合は、先にターミナルからセットアップスクリプトを実行し、 その後Claude Desktopを再起動してください。
Claude Desktopを設定する
~/Library/Application Support/Claude/claude_desktop_config.jsonに追加します
(このリポジトリのセットアップでは、このマシンですでに設定済みです。下記を参照してください)。
mcpServersキーがClaude Desktopに表示されるコネクター名になります。
{
"mcpServers": {
"apple-calendar": {
"command": "uv",
"args": [
"--directory", "/absolute/path/to/apple-calendar-mcp",
"run", "python", "-m", "apple_calendar_mcp.server"
]
}
}
}
編集後、Claude Desktopを再起動してください(または下記のserver_restartを使用してください)。
ツール
権限
| ツール | 説明 |
|---|---|
eventkit_check_permissions | カレンダー/リマインダーの認証状態と手順 |
カレンダー
| ツール | 説明 |
|---|---|
calendar_list_calendars | すべてのカレンダーを一覧表示 |
calendar_list_events | 指定した日付範囲のイベントを一覧表示 |
calendar_get_event | IDを指定して1件のイベントを取得 |
calendar_search_events | タイトル/場所/メモをテキスト検索。タグでの絞り込みは任意 |
calendar_create_event | イベントを作成(場所、メモ、URL、タグ) |
calendar_edit_event | イベントを編集(calendar_nameでカテゴリーの移動も可能)。繰り返しイベントではspanが必須 |
calendar_delete_event | イベントを削除。繰り返しイベントではspanが必須 |
リマインダー
| ツール | 説明 |
|---|---|
reminders_list_lists | すべてのリマインダーリストを一覧表示 |
reminders_list | リマインダーを一覧表示。リスト/完了状態/期限で絞り込み |
reminders_get | IDを指定して1件のリマインダーを取得 |
reminders_search | タイトル/メモをテキスト検索。タグでの絞り込みは任意 |
reminders_create | リマインダーを作成(期限、優先度、タグ) |
reminders_edit | リマインダーを編集 |
reminders_complete | リマインダーを完了済みにする |
reminders_delete | リマインダーを削除 |
タグ
タグはノート欄に追加される #hashtag として保存されます(EventKit にはネイティブのタグの概念がありません)。正規化では、小文字に変換し、スペースとハイフンをアンダースコアに置き換え、英数字以外を削除します。タグは notes に保存されるため、iCloud 経由で同期され、標準のカレンダー/リマインダーアプリで表示・検索できます。
| ツール | 説明 |
|---|---|
tags_list | 使用中のすべてのタグと、各タグが付いたアイテム数 |
tags_rename(old_tag, new_tag, scope) | タグ名を変更します。scope:events|reminders|all |
tags_merge(from_tag, into_tag, scope) | あるタグを別のタグに統合します |
tags_delete(tag, scope) | タグが付いているすべての箇所からタグを削除します |
この 3 つのツールは一括編集であり、取り消しできないため、タグ名を完全一致で指定する必要があります(あいまい検索や部分一致には対応していません)。notes のハッシュタグ行だけを書き換え、ノート本文の残りの部分はそのまま保持します。
スキャン範囲に関する注意: tags_list/tags_rename/tags_merge/tags_delete は「すべての」イベントを確認する必要がありますが、EventKit の日付範囲述語には、1 回の呼び出しあたり実質約 4 年の制限があります。これらのツールはスキャンを 3 年ごとの期間に分割し、過去 6 年から未来 6 年までを対象とします(合計 12 年、最大 5000 件)。それより先の日付のイベントは確認されません。リマインダーにはこの制限がなく、1 回の呼び出しで取得されます(最大 20000 件)。スキャンが上限に達した場合、レスポンスには "warning" フィールドが含まれます。
繰り返しイベントに関する注意: 一括タグ編集では、calendar_edit_event と同じ calendarItemWithIdentifier_ と EKSpanThisEvent の仕組みを使います。繰り返し予定の場合、すべての表示中の回ではなく、代表となる 1 回分が対象になります。これは、基本の編集ツールにもある制限です。
カスタムスケジューリングツール
| ツール | 説明 |
|---|---|
agenda_today | 今日の予定(イベントと期限を迎えるリマインダー)を読みやすい形式で表示します |
agenda_range(start_date, end_date) | 指定した日付範囲で同様の予定を表示します |
quick_event(text) | 短い自然言語の行からイベントを作成します |
reschedule_event(event_id, new_start) | 所要時間を維持したままイベントを移動します |
find_free_slots(date, working_hours, min_duration_minutes) | 勤務時間内の空き時間を検索します(終日イベントは無視されます) |
quick_event は、小規模なヒューリスティック型パーサーを使用します(設計上、外部 NLP 依存関係はありません。このプロジェクトが依存するのは mcp[cli] と pyobjc のみです)。次の形式を認識します。
- 相対的な日付:
today、tomorrow、mon~sun/曜日のフルネーム - 明示的な日付:
YYYY-MM-DD - 時刻:
3pm、3:30pm、15:00(前にatを付けることもできます) - 所要時間:
for 30 minutes、for 2 hours - 末尾の
#hashtags→ タグ
デフォルトの所要時間は 1 時間です。時刻が見つからない場合は 09:00 になります(残ったタイトルに breakfast/lunch/dinner が含まれている場合は、それぞれ 08:00/12:00/19:00)。これらのパターンに一致しないテキストはすべてタイトルに残ります。あくまで最善の推定なので、時間が重要な用途に利用する前に、返された event を確認してください。
サーバー管理
| ツール | 説明 |
|---|---|
server_status | pid、version、稼働時間、ツール数を表示します |
server_restart | Claude Desktop を終了せずにプロセスをホットリスタートします |
server_stop | プロセスを停止します(再起動しません)。カレンダー/リマインダーへのアクセスを一時停止する場合に使用します |
server_restart の仕組みと検証した内容
server_restart はバックグラウンドスレッドを起動し、しばらく待機した後(デフォルトでは 0.75s、delay_seconds で設定可能)、stdout/stderr をフラッシュしてから os.execv を呼び出し、現在のプロセスイメージを新しい python -m apple_calendar_mcp.server に置き換えます。これにより、ディスク上のコード変更が反映されます。
Claude Desktop の UI 経由ではなく(この環境から UI を操作できないため)、生の MCP Python クライアントを使って直接テストしたところ、次のことが確認できました。
- stdio パイプのファイルディスクリプターは
execvの後も維持されます。クライアントと新しいプロセス間で、引き続きバイトデータが流れます。 - 新しいプロセスの pid は異なり、
uptime_secondsは約 0 にリセットされるため、再起動が行われたことを確認できます。これを確認するための仕組みがserver_statusです。 - MCP/JSON-RPC セッションは維持されません。セッションはメモリ内の状態であり、プロセスイメージが置き換えられるとリセットされます。再起動直後に古いセッションで送信したツール呼び出しは拒否されます(
Invalid request parameters/ "request before initialization was complete")。 - 再起動後、同じ stdio パイプで MCP の
initializeハンドシェイクを再送信すると、セッションが完全に復旧します。pid は新しくなり、稼働時間はリセットされ、すべてのツールを再び呼び出せます。新しいサブプロセスも、Claude Desktop の再起動も必要ありません。
直接確認できなかったのは、呼び出したツールからリクエスト拒否エラーが返された後、Claude Desktop 自身のクライアントが initialize を自動的に再送信するかどうかです(自動的に復旧するのか、それとも再度操作するまでコネクターが「停止」したように見えるのか)。server_restart の呼び出し直後にツールが応答しなくなった場合は、次の手順を試してください。
- いずれかのツールをもう一度、または二度呼び出してみてください。エラー時に一部の MCP クライアントが透過的に再試行や再初期化を行うことがあります。
- 改善しない場合は、Claude Desktop の設定で
apple-calendarコネクターをいったんオフにしてから、もう一度オンにしてください。アプリを終了する必要はなく、新しいサブプロセス上でinitializeが再実行されます。 - 最終手段として、Claude Desktop を終了して再度開けば必ず復旧しますが、このツールの目的に反します。
手動操作なしで Claude Desktop が適切に復旧すること、またはエラーを返さずにハングすることがわかった場合は、このセクションを更新してください。
server_stop
server_stop は再起動を行わない server_restart です。短時間待機してからフラッシュする同じパターンを使いますが、os.execv の代わりに os._exit(0) を呼び出すため、プロセスはそのまま終了します。生の MCP クライアントを使って直接検証したところ、次のことが確認できました。
- プロセスが完全に終了します(
ps -p <pid>の結果が何も返さないことを確認済みです)。 - そのセッションで後続のツール呼び出しを行うと、すぐに
ClosedResourceErrorで失敗します(stdio パイプが閉じられます)。動作したかどうかに曖昧さはありません。
自動的に再起動することはありません。その後、Calendar/Reminders ツールを再び使うには、Claude Desktop で apple-calendar コネクターをいったんオフにしてから、もう一度オンにする(新しいサブプロセスを起動する)か、Claude Desktop を再起動してください。設定ファイルを編集せずにサーバーからデータへのアクセスを一時停止したい場合(たとえば、席を外す場合)に使用してください。
注意事項
- すべてのデータはデバイス上にとどまり、サーバーは stdio 経由で MCP クライアントと通信し、EventKit にアクセスするだけです。
- このサーバーが作成したアイテムのメモには
"Created by Claude Desktop"という行が先頭に追加されるため、手動で作成したアイテムと見分けられます。 - 日時の入出力形式は ISO 8601(
2026-03-15T14:00:00)で、ローカルタイムゾーンとして解釈されます。 - 各ツールは独自に例外を捕捉し、例外を送出する代わりに
{"success": false, "error": ..., "message": ...}という辞書を返します。不正な ID、不正な日付、権限の不足があっても、サーバーがクラッシュすることはありません。
開発
uv run python -m apple_calendar_mcp.server # run standalone (reads/writes stdio)
uv sync # after editing pyproject.toml
公式の MCP Inspector を使ってツールを対話的に調べるには(Node.js が必要です。このプロジェクトのビルド時にはインストールされていません):
npx @modelcontextprotocol/inspector uv run python -m apple_calendar_mcp.server
Node.js を利用できなかったため、代わりに mcp Python SDK 独自のクライアント(ClientSession + stdio_client)を使ってプロトコル層を検証しました。完全な initialize ハンドシェイク、list_tools(28 個のツール)、および代表的なツール呼び出し(無効な日付、無効な期間、未知の ID、無効な優先度/スコープなど、エラーとなるケースを含む)を実行し、いずれもサーバーをクラッシュさせることなく、適切な形式のレスポンスが返ることを確認しました。タグの名前変更/統合/削除が正しく行われること(該当するアイテムのみを更新し、メモの本文を保持し、無関係なタグには触れないこと)は、EventKit の代わりにインメモリの模擬ストアを使って検証しました。このマシンで実際に検証するには、まずカレンダー/リマインダーのアクセス許可を付与する必要があるためです。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。