Claude Code の利用枠 3 つ(5 時間・週次・Fable 週次)を、Mac に USB でつないだ 3.5 インチの小さなディスプレイに、メーターで常時表示するようにしました。コードは studioc-co-jp/claude-usage-display(MIT)で公開しています。

写真は文字の色を直す前の画面で、右上の更新時刻と「あと…」の行は、いまは白で表示しています。枠が白いのは、黒を買うつもりで、間違えて白を注文したためです。
きっかけ: 元のツールもメーカーのソフトも Windows 専用
nuits_jp さんの X の記事「AI専用ダッシュボードの作り方」(2026-10-04)で、TURZX(Turing Smart Screen)の USB ディスプレイに AI ツールの利用状況を常時表示する Token Dashboard が紹介されていました。
ただ、Token Dashboard の動作環境は Windows 11 と TURZX 9.2 インチに限られています(同リポジトリの docs/project.md)。メーカーの公式ソフトも Windows 専用でした。
- TURZX の公式サイトの製品一覧では、8 機種すべての対応 OS が Windows です(3.5 インチは Windows 7〜11)
- 3.5 インチ用の配布ページにあるのは、Windows 用のアプリ(英語版・中国語版)だけです
- サイト内検索で「mac」「macos」を引いても、0 件でした
そこで、3.5 インチ(rev A。480×320、USB の ID は 1a86:5722)を Mac から動かす版を、Python で書きました。
macOS ではシリアル経由で送ると画像が崩れる
3.5 インチの定番のライブラリ turing-smart-screen-python は、macOS に「major bug」の注記を付けています。issue #7「Screen displays corrupted images on Mac」は、2022 年 2 月から open のままです。
原因は、issue #7 のコメント(2026-08-21、Mac mini M4 で検証)に書かれていました。
- パネルのファームウェアは USB の転送の単位で動き、転送の先頭をコマンドとして読む
- 画像の表示コマンドの後は、幅×高さ×2 バイトを数え終えるまで、届いたものをすべて画素として扱う
- macOS の CDC ドライバー(シリアルポートの裏側)は、書き込みを任意に分割・結合して転送する
このため、コマンドが画素の中に紛れ込みます。一度ずれると、電源を入れ直すまで崩れ続けます。回避策は、シリアルポートを使わず、libusb でバルク OUT エンドポイント 0x03 に直接書くことです。守ることは 4 つあります。
- コマンドは 1 つずつ、それだけで 1 回の転送にする
- 向きの命令は、ちょうど 11 バイトにする
- 画素は 64 バイトの倍数で区切り、合計をちょうど 幅×高さ×2 バイトにする
- 画素を送っている途中に、ほかのものを書かない
ライブラリも、issue で示された macOS 用の実装(gist)も、GPL-3.0-or-later です。コードは持ち込まず、コマンド番号・バイトの並び・転送の規則という仕様だけを使って、送信部を自前で書きました。要の部分は次のとおりです(claude_usage_display/turing.py から抜粋。入力の検査は省いています)。transport.write() は pyusb の device.write(0x03, data) を 1 回呼ぶだけで、1 回の呼び出しが 1 回のバルク転送になります。
CHUNK = 4096 # 64 の倍数
class TuringRevA:
def _send_pixels(self, frame: bytes) -> None:
for start in range(0, len(frame), CHUNK):
self.transport.write(frame[start:start + CHUNK])
def show_frame(self, frame: bytes) -> None:
self.transport.write(encode_command(Command.DISPLAY_BITMAP, 0, 0, self.width - 1, self.height - 1))
self._send_pixels(frame)
表示コマンドだけで 1 回の転送にし、続く 307,200 バイトの画素は 4,096 バイトずつ、ちょうど 75 回で送り終えます。起動したときに同期が崩れていても戻るよう、接続のたびに全画面分の黒を同じ方法で送ってから描き始めます。
実機では、1 画面(307,200 バイト)の転送に約 1.87 秒かかりました。区切りを 1 KB から 64 KB まで変えても 1,865〜1,873 ミリ秒で変わらないので、速さを決めているのはディスプレイ側の受け取り(約 164 KB/秒)です。利用枠の取得は 2 分ごと、描き直しは 1 分ごとなので、この速さで足ります。
明るさと向きは、パネルへの命令で設定できる
メーカーが用意している設定の手段は、Windows 用の公式ソフトだけです。ただ、明るさや向きの設定も、公式ソフトがパネルへ送っている命令にすぎません。同じ命令を送れば、Mac からでも設定できます。
rev A の命令は 6 バイトです。先頭 5 バイトに 4 つの数(x・y・ex・ey)を 10 ビットずつ詰め、最後の 1 バイトに命令番号を置きます(ライブラリの lcd_comm_rev_a.py の SendCommand)。このツールでは次のように書いています(値の範囲の検査は省いています)。
def encode_command(cmd: Command, x: int = 0, y: int = 0, ex: int = 0, ey: int = 0) -> bytes:
"""座標 4 つ(各 10 ビット)とコマンド番号を 6 バイトに詰める。"""
return bytes((
x >> 2,
((x & 3) << 6) | (y >> 4),
((y & 15) << 4) | (ex >> 6),
((ex & 63) << 2) | (ey >> 8),
ey & 255,
int(cmd),
))
**明るさ(命令番号 110 = 0x6E)**は、値を x に入れて送ります。パネルの値は 0 が最も明るく、255 が最も暗いという逆向きなので、割合からは 255 - 割合 × 255 / 100 で換算します。
| 明るさ | パネルの値 | 送るバイト列 |
|---|---|---|
| 100% | 0 | 00 00 00 00 00 6E |
| 30%(このツールの既定) | 178 | 2C 80 00 00 00 6E |
| 0% | 255 | 3F C0 00 00 00 6E |
30% の 178 は 10 ビットで 0010110010 なので、x >> 2 が 0x2C、(x & 3) << 6 が 0x80 になります。
**向き(命令番号 121 = 0x79)**は、6 バイトの命令の後に、向き(横は 2、上下逆の横は 3 に、それぞれ 100 を足した値)、幅(2 バイト)、高さ(2 バイト)を続けた 11 バイトです。
- 横向き(480×320):
00 00 00 00 00 79 66 01 E0 01 40 - 上下逆の横向き:
00 00 00 00 00 79 67 01 E0 01 40
元のライブラリは、この命令を 16 バイト(後ろ 5 バイトは 0)で送っています。macOS で崩れない送り方では、ちょうど 11 バイトにします。このツールは接続のたびに「黒で同期 → 向き → 明るさ」の順に送るので、--brightness 40 や --flip を付けて起動すれば、公式ソフトを使わずに設定が決まります。
利用枠の取り方と、規約上の位置づけ
利用枠は、Claude Code が macOS の Keychain に保存したログイン情報からアクセストークンを読み、GET https://api.anthropic.com/api/oauth/usage を呼んで取得します。呼び方は tokscale と同じです。tokscale には、トークンを更新してログイン情報に書き戻した結果、Claude Code のログインが切れる不具合がありました(#1001、修正済み)。このツールはログイン情報を読むだけにし、更新は Claude Code に任せています。
この方式は、規約の文言に当てはまります。調べた結果は次のとおりです。
- Consumer Terms of Service(Free・Pro・Max に適用)の §3 は、API キーを使う場合と明示の許可がある場合を除き、ボットやスクリプトなどの自動の手段でサービスにアクセスすることを禁じています。ログイン用のトークンでスクリプトから定期的に呼ぶこのツールは、公開しなくても、自分で使うだけでこれに当たります
- Claude Code の Legal and compliance は、ログイン用の認証(OAuth)を、Claude Code と Anthropic 純正のアプリを普通に使うためのものとしています。そのうえで、第三者の開発者が Free・Pro・Max の資格情報でリクエストを送ることを認めていません
/api/oauth/usageは、公式の文書に載っていません
リスクも書いておきます。Consumer Terms の §12 の Termination は、違反したと Anthropic が判断すれば、予告なく利用停止・解約でき、違反による解約では返金しないと定めています。措置が API 側の遮断になるのか、アカウントの停止になるのかは、文書に書かれていません。
一方で、同じ方式のツールは広く使われています。ADE(Agent Development Environment)の Orca や、VS Code の拡張機能 Claude Usage Meter も、Keychain のトークンで同じ API を呼んでいます。公式に値を受け取れる経路として、Claude Code がステータスラインに渡す rate_limits がありますが、利用枠として入っているのは 5 時間と週次だけです。モデル別の週次(Fable 週次)はこの API でしか取れないので、それを表示するツールはこの方式になります。2026-10-09 に調べた範囲では、利用枠を読むだけのツールが止められたという報告は見つかりませんでした。ただし、広く使われていることは、規約の「明示の許可」には当たりません。
そのため、リポジトリの README の冒頭に、規約上の位置づけと、公式に説明されていない API を使っていることを明記しました。使うかどうかは、これを踏まえて判断してください。
USB-C でつなぐと電源が入らない
付属のケーブルは USB-A⇔USB-C です。USB-C の端子しかない Mac mini(M4)に、USB-C⇔USB-C ケーブルで直接つなぐと、電源すら入りませんでした。
USB-C の電源側は、相手が CC 端子のプルダウン抵抗(Rd)で「受電側」だと示すまで、5V を出しません。USB-A の端子は、つないだだけで 5V を出します(USB Type-C 仕様 Release 2.0 §4.4.2・§4.5.1.3.1)。同じ USB-C⇔USB-C ケーブルで iPhone をつなぐと認識されたので、ケーブルと Mac の端子は正常です。原因は、ディスプレイ側の USB-C 端子が Rd を示していないことでした。USB ハブの USB-A 端子に、付属のケーブルでつなげば使えます。
もう 1 つは、電源は入るのに USB の機器として認識されない件です。原因は、ディスプレイに挟んでいた L 字の USB-C 延長アダプター(オス⇔メス)でした。メス側にケーブルを挿す向きによって、USB 2.0 の信号が通りません。iPhone でも同じで、ケーブルを裏返すと認識されます。USB-C のメス側は、D+/D- を 2 つの位置のどちらでも受けることになっています(同仕様 §3.2.3)が、このアダプターは片方しか通していませんでした。そもそも、USB-C のオス⇔メスの延長アダプターは、仕様で定められていません(同 §3.6)。
3.5 インチは小さかったので、5 インチで作り直す
このパネルは iPhone 3GS と同じ 3.5 インチ・480×320 で、文字の大きさも iOS の既定の文字スタイルに合わせました。それでも、机に置いてみると、画面は思っていたより小さいものでした。
そこで、5 インチを注文することにしました。利用枠の取得や自動起動はそのまま使えますが、画面が 800×480 になるので、画面の配置は作り直しです。Turing の 5 インチは通信方式も 3.5 インチ(rev A)と違う rev C なので、その場合は通信部も新しく書きます。届いたら、改めて記事にします。
まとめ
- Windows 専用のディスプレイでも、通信の仕様が分かれば Mac から動かせる。macOS では、シリアルポートを通さず、USB の転送の単位を自分で決めて送る
- 「公式ソフトでしか変えられない」明るさや向きも、ソフトがパネルへ送っている命令にすぎない
- ログイン用のトークンで非公開の API を呼ぶ方式は、同じことをしているツールが多くても、規約の文言上は認められていない。公開するなら、そのことを README と記事に書く
- USB-C⇔USB-C で電源が入らないときは、同じケーブルで別の機器をつないで、ケーブルと機器のどちらが原因かを切り分ける
着想をいただいた nuits_jp さんと、macOS で崩れる原因を突き止めて共有してくださった issue #7 の報告者の方に感謝します。

