Codex のターン完了をデスクトップ通知や Slack に送る notify 設定と tui.notifications

Codex 公開:

Codex CLI が応答を終えたときに外部プログラムを起動する config.toml の notify と、ターミナル通知を制御する tui.notifications の書き方を解説します。渡される JSON の中身、通知の種類の絞り込み、macOS と Linux のスクリプト例をまとめます。

検証日 2026年9月10日 仕様変更が早い分野です。最新の公式ドキュメントも併せてご確認ください。
目次
  1. notify:外部プログラムを起動する
    1. macOS の例
    2. Linux の例
    3. Slack に送る
  2. tui.notifications:ターミナル通知を制御する
  3. まとめ

Codex に長めのタスクを任せて別の作業をしていると、終わったことに気づかず放置してしまいます。Codex CLI には、ターン完了時に 外部プログラムを起動する notify と、ターミナル自体の通知を制御する tui.notifications の 2 つの仕組みがあります。

結論として、notify = ["python3", "/path/to/notify.py"] のように argv 配列を書くと、ターン完了ごとに JSON を 1 引数として受け取るプログラムが起動します。デスクトップ通知でも Slack の Webhook でも、そのプログラムで好きな処理ができます。

KEY POINT

この記事で分かること

  • notify の書き方と、プログラムに渡される JSON のフィールド
  • tui.notifications で通知の種類・条件・方式を絞る方法
  • macOS / Linux でデスクトップ通知を出すスクリプト例

notify:外部プログラムを起動する

~/.codex/config.toml に、起動するコマンドを配列で書きます。未設定なら無効です。

notify = ["python3", "/Users/you/.codex/notify.py"]

プログラムは JSON 文字列 1 つを引数として 受け取り、成功時は終了コード 0 を返します。渡される主なフィールドは次のとおりです。

フィールド内容
typeイベント種別。現時点では agent-turn-complete
thread-idセッション(スレッド)の識別子
turn-idターンの識別子
cwd作業ディレクトリ
input-messagesそのターンでユーザーが送ったメッセージ
last-assistant-messageアシスタントの最後の出力テキスト

用語解説

ターン: あなたが 1 回指示を送ってから、Codex が応答を返し終えるまでの単位です。途中でコマンド実行や承認が挟まっても 1 ターンです。notify はこの単位の終わりで発火します。

macOS の例

terminal-notifier を使った例です(Homebrew でインストールできます)。

#!/usr/bin/env python3
import json, subprocess, sys

payload = json.loads(sys.argv[1])
if payload.get("type") != "agent-turn-complete":
    sys.exit(0)
title = "Codex: ターン完了"
body = (payload.get("last-assistant-message") or "")[:120]
subprocess.run(["terminal-notifier", "-title", title, "-message", body, "-group", payload.get("thread-id", "")])

Linux の例

notify-send を使う最小構成なら、スクリプトなしで直接指定もできます。サンプル設定にもこの形が示されています。

notify = ["notify-send", "Codex"]

この場合、JSON 文字列がそのまま通知本文として渡されます。本文を整えたい場合は上のようなスクリプトを挟んでください。

Slack に送る

Slack の Incoming Webhook に POST するなら、スクリプトの中で last-assistant-message を要約して送ります。Webhook URL は環境変数から読むようにし、config.toml に直接書かないでください。

last-assistant-message には作業内容が含まれる

通知本文に last-assistant-message をそのまま載せると、ファイル名やコードの断片が外部サービスに送られます。Slack などに送る場合は、先頭の数十文字に切り詰めるか、「完了」の一言だけにするのが安全です。

tui.notifications:ターミナル通知を制御する

ターミナル自体が出す通知は [tui] セクションで制御します。

[tui]
# true / false、または種類のリスト
notifications = ["agent-turn-complete", "approval-requested"]
# unfocused(既定)| always
notification_condition = "unfocused"
# auto(既定)| osc9 | bel
notification_method = "auto"
キー意味
notificationstrue / false / 種類のリスト既定は有効。agent-turn-completeapproval-requested で絞れる
notification_conditionunfocused / always既定はターミナルが非アクティブのときだけ
notification_methodauto / osc9 / belauto は端末が対応していれば OSC 9、そうでなければ BEL(\x07)

notifytui.notifications は独立しています。外部通知だけにしたいなら notifications = false にし、承認待ちにも気づきたいならリストに approval-requested を残します。

Codex の設定ファイル全体の構造は親記事の config.toml でモデル・推論の深さ・プロファイルを切り替える を参照してください。承認が必要になる条件は approval mode と sandbox 設定の違い で扱っています。

まとめ

  • notify は argv 配列。ターン完了(agent-turn-complete)のたびに JSON 1 引数でプログラムを起動する
  • JSON には typethread-idturn-idcwdinput-messageslast-assistant-message が入る
  • macOS は terminal-notifier、Linux は notify-send を直接指定するだけでも動く
  • 外部サービスに送るときは本文を切り詰め、Webhook URL は環境変数に置く
  • ターミナル通知は [tui]notifications / notification_condition / notification_method で別に制御する

よくある質問

notify にはどんなイベントが渡されますか?
現時点で対応しているのは agent-turn-complete(ターン完了)です。type、thread-id、turn-id、cwd、input-messages、last-assistant-message を含む JSON が 1 つの引数として渡されます。
ターミナルの通知だけ止めて notify は使えますか?
はい。[tui] の notifications = false でターミナル通知を止め、notify は別に設定できます。
IDE 拡張でも notify は使えますか?
公式の通知ページによると、接続先の Codex ホスト側で notify を設定します。

参考にした一次情報

この記事は公式ドキュメントを基に AI が下書きを作成し、運営者が内容を確認して公開しています。誤りを見つけた場合は お問い合わせからお知らせください。