Claude Code にスクリーンリーダーモードが入り、専用のドキュメントページも用意された。罫線やスピナー、その場での再描画といった視覚前提のターミナル表示を、ラベル付きの平文の並びに置き換えるモードだ。有効化の方法は3通りある。
目次
何が変わるのか
ターミナル UI は、同じ場所を何度も描き直して進捗を見せる作りになっている。目で見ている分には自然だが、スクリーンリーダーは書き換わるたびに読み直そうとするので、内容を最後まで追えない。
このモードでは、その前提をやめる。
- 罫線文字を使わない
- 色だけを手がかりにしない
- 変更のない内容を再描画しない(スピナーは静的なテキストになる)
- 表は
Header: valueの文に展開する tuiの設定を上書きして classic レンダラーを強制する- 出力がスクロールバックに蓄積されるので読み返せる
行頭にラベルが付くのも実務的だ。you: / claude: / tool: / tool error: / error: / Permission Required: / Cost: の形で、読み上げの区切りになると同時に検索もできる。
権限プロンプトが番号付きリストになる
変化として一番大きいのはここだと思う。矢印キーで選ぶメニューから、番号付きリストに変わる。
各選択肢が番号の付いた行として読み上げられ、Enter selection が有効な範囲を告げる。範囲外の数字を入力すれば聞き直してくれる。Yes / No は y と n をタイプする(yes / no でも通る)。キャンセルは Escape で、プロンプトの末尾に or Escape to cancel が付く。
矢印キーでの選択は、今どこにカーソルがあるかを目で見る前提の操作だ。それを番号の指定に置き換えたことで、読み上げだけで完結する。
ターミナルベルで状態を知らせる
返答が終わったとき、権限プロンプトが出たとき、5秒を超えたツールが終わったときにベルが鳴る。画面を注視していなくても状態が分かる。
v2.1.211 以降、このモードでは /terminal-setup がベルの設定に触らないようになった。せっかくの通知が設定変更で消える事故を防ぐ変更だ。
有効化の3通り
# そのセッションだけ
claude --ax-screen-reader
# そのシェルだけ
export CLAUDE_AX_SCREEN_READER=1
// マシン全体 ~/.claude/settings.json(VS Code の統合ターミナルを含む)
{ "axScreenReader": true }
優先順位はフラグ、環境変数、設定ファイルの順。CLAUDE_AX_SCREEN_READER=0 にすれば、設定ファイルが true でも強制的にオフになる。SSH で使うときはリモート側に設定する。v2.1.181 未満では error: unknown option '--ax-screen-reader' になる。
起動時に、どの経路で有効になったかを示す行が出る。
[Screen Reader Mode: on via flag]
[Screen Reader Mode: on via env]
[Screen Reader Mode: on via settings]
この表示形式は v2.1.206 以降で、それ以前は [Accessible screen reader mode: on] だった。自己再起動したときは環境変数を継承するので、常に on via env になる。設定した経路と表示が食い違って見えることがあるが、動作としては正しい。
機械処理に流用しようとして、間違えた
正直に書いておく。この機能を知ったとき、筆者が最初に考えたのは「平文になるならログ解析や CI への取り込みに使えるのでは」ということだった。
調べたら、公式が明確に否定していた。
Screen reader mode doesn’t change non-interactive mode with the
-pflag. Non-interactive mode already writes plain text and remains an alternative for scripting.
--ax-screen-reader が変えるのは対話 TUI の描画方式だけで、-p の出力には影響しない。スクリプト用途には -p と --output-format json という別の正解が用意されている。
もう1つ思い込みがあった。「平文になる=ANSI エスケープシーケンスが消える」と考えていたが、ドキュメントに剥がすという記述はない。書かれているのは「色だけを手がかりにしない」であって、色の除去ではない。それどころか、このモードはターン境界をジャンプするための OSC 133 シェル統合マーカーを能動的に出力する。エスケープシーケンスはむしろ増える。
視覚出力や配布物は実測してから「動く」と言うようにしてきたが、今回は自分の期待でドキュメントを読み違えかけた。用途を決めつける前に、公式が何を目的として作ったかを読むほうが早い。
-p の出力が本当に変わらないか、バイトで比べた
公式が否定していると書いたが、読んだだけで済ませたくなかった。2.1.220 で同じ質問を2回投げて、出力を突き合わせた。
claude -p "1から3までの数字を箇条書きで出して" ... | cat -A
claude -p "1から3までの数字を箇条書きで出して" ... --ax-screen-reader | cat -A
cat -A は行末や制御文字も見える形で出す。結果は両方ともこれだった。
- 1$
- 2$
- 3$
行末の $ まで含めて一致した。-p はもともと平文を出しているので、このモードが足すものが無い。記述どおりだ。
環境変数の経路も動いた。CLAUDE_AX_SCREEN_READER=1 を付けて -p を叩いても、エラーにならず通常どおり応答が返る。
スクリプト用の正解として案内されている --output-format json を叩くと、21個のキーが返ってきた。
{"type":"result","subtype":"success","is_error":false,
"result":"OK","num_turns":1,"duration_ms":3528,
"total_cost_usd":0.0605835,
"usage":{"input_tokens":10,"cache_creation_input_tokens":28756,
"cache_read_input_tokens":23415,"output_tokens":144},
"session_id":"...","permission_denials":[],"ttft_ms":...}
total_cost_usd と usage と permission_denials がそのまま入っている。読み上げ用の平文をパースするより、この JSON を読むほうが速いし壊れない。平文が欲しくて --ax-screen-reader を思い出したなら、それは --output-format json の出番になる。
出力モードの使い分け
--ax-screen-reader |
-p |
-p --output-format json |
|
|---|---|---|---|
| 目的 | 支援技術での対話利用 | スクリプト・CI | 構造化した取得 |
| 対話性 | あり(承認できる) | なし | なし |
| 形式 | ラベル付き平文+OSC 133 | プレーンテキスト | JSON |
| 機械処理 用途で選ぶ | 非推奨 | 可 | 推奨 |
JSON なら result、session_id、total_cost_usd、モデル別の内訳が取れる。--json-schema で構造化出力、stream-json で NDJSON も選べる。自動化パイプラインを組むならこちらだ。
CI 向けには --bare もある。フックや MCP、CLAUDE.md の自動探索をスキップするもので、将来 -p の既定になる予定とされている。
ターン間ジャンプの設定は端末による
OSC 133 マーカーを使ったターン間の移動は、端末側の対応が要る。
| 端末 | 操作 |
|---|---|
| iTerm2 | Cmd+Shift+Up |
| VS Code | Ctrl+Up(Windows)/ Cmd+Up(Mac) |
| Windows Terminal | 既定なし。scrollToMark の割り当てが要る |
| macOS Terminal | マーカーを解釈しない |
| WezTerm | マーカーが出力されない |
対応していない端末では you: を検索して移動する形になる。Windows で使うなら、Windows Terminal の設定に scrollToMark を足しておくと体験が変わる。
併用できる関連設定
CLAUDE_CODE_ACCESSIBILITY=1— 画面拡大鏡向け。ネイティブカーソルを維持するprefersReducedMotion— アニメーションを抑えるthemeのdark-daltonized/light-daltonized— 色覚に配慮した配色preferredNotifChannel: "terminal_bell"— このモード外でも同様の通知を鳴らす
スクリーンリーダーを使わない人でも、拡大鏡やアニメーション抑制は効く場面がある。まとめて把握しておくといい。
書かれていないこと
公式が明記しているスクリーンリーダーは VoiceOver と NVDA だけだ。JAWS や Orca への言及はない。Linux 固有の注意点も書かれていない。「対応している」と紹介する前に、この範囲は押さえておきたい。
制限として挙げられているものも実務的だ。スクリーンリーダーの稼働は自動検出されないので手動で有効にする必要がある。Shift+Tab 以外の方法で権限モードを変えても読み上げられない。コストは終了時のサマリのみで、ターンごとには出ない。
claude attach で背景セッションに接続すると代替スクリーンに入り、スクロールバックが無くなる。空のプロンプトで左矢印、ダイアログが出ているときは Ctrl+Z で抜ける。
なぜ再描画が問題になるのか
「再描画しない」という項目が地味に見えるかもしれないので、補足しておきたい。
スクリーンリーダーは画面の内容が変わると、変わった部分を読み上げようとする。ターミナルの進捗表示は同じ行を書き換え続けるので、1秒に何度も「変わった」と判定される。読み上げが始まっては中断され、また最初から始まる。
目で見ていれば、くるくる回るスピナーは「処理中」という1つの情報だ。読み上げに変換すると、終わらない割り込みになる。
権限プロンプトの矢印キー選択も同じ構造で、カーソルが動くたびに画面が変わる。今どれが選ばれているかは、色の反転や記号で示されている。色だけを手がかりにした表現は、読み上げに変換できない。
このモードがやっているのは、状態を「見て分かる形」から「順に読める形」へ翻訳することだ。ラベル付きの平文にして、変わらないものは書き直さない。番号を振って、数字で選ばせる。それぞれの変更が、この方針から素直に導かれている。
Windows で試すなら
NVDA は無償で使えるので、支援技術を普段使っていない人でも動作を確認できる。
手順としては、NVDA を起動した状態で claude --ax-screen-reader を実行し、何か作業を頼んで読み上げを聞く。you: と claude: のラベルがどう読まれるか、ツールの実行がどう伝わるかが分かる。
Windows Terminal を使っているなら、OSC 133 のキー割り当てが既定で無いので scrollToMark を設定しておく。これが無いとターン間を移動できず、長い出力の中で迷子になる。
自分が作ったツールを他の人が使う場面を想像するとき、実際に読み上げさせてみると気づくことが多い。筆者もデスクトップアプリを配布しているが、支援技術での動作までは確認できていない。ここは正直に、未検証だと書いておく。
筆者ならこう試す
自分の環境で確かめるなら、同じプロンプトを通常モードと --ax-screen-reader の両方で実行して script か tee で生のまま採り、cat -v でエスケープシーケンスを可視化するのが早い。ANSI が残るか、OSC 133 が出るかを自分の目で見られる。
そのうえで、権限プロンプトをわざと発生させて番号付きリストの実際の表示を見る。許可していない Bash コマンドを1つ走らせれば出る。範囲外を入力したときの聞き直しまで含めて動かすと、設計の意図が分かる。
3つの有効化経路と優先順位も、順に試せば数分で確認できる。axScreenReader: true を入れた状態で CLAUDE_AX_SCREEN_READER=0 を渡し、オフになることを見ておくと、後で困らない。
この機能を必要としている人が使いやすくなったことが第一で、副次的な流用先を探すのは筋が違った。機械処理には -p --output-format json がある。用途ごとに正解が分かれているだけの話だった。
Claude Code の運用についてはターミナルを使い込むための記事でも扱っている。claude --version で v2.1.181 以降かどうか、まず確認してみてほしい。