まだ毎回 /context を打っていますか?Claude Code のステータスラインにコンテキストと利用枠の残りを常時表示する
Claude Code でコンテキストの残量を見るために、毎回 /context を打つ必要はありません。ステータスラインに、コンテキストの使用率と 5 時間・週の利用枠の残りを常時表示する方法を、Windows と Node.js だけで動く 40 行足らずのスクリプトつきで紹介します。
こんにちは!
Claude Code で長い作業を続けていると、コンテキストがあとどれくらい残っているかが気になってきます。そのたびに /context と打つ。すると、使用量の内訳の表に続いて、MCP ツールの表、カスタムエージェント、メモリファイル、スキルの一覧まで、数十行が画面を流れていきます。
知りたいのは「残り何 % か」の 1 行だけです。
結論から言うと、毎回 /context を打つ必要はありません。Claude Code には、画面の下に好きな 1 行を出しておける「ステータスライン」があり、そこにコンテキストの使用率を常時表示できます。

5 時間と週の利用枠の残りも、同じ 1 行に並べられます。
先にことわっておくと、これは新しい技ではありません。公式ドキュメントのステータスラインのページでは、最初に出てくる例からコンテキストの使用率が入っています。
でも、 /context コマンドを定期的に打ってる人をみかけます
この記事では、Windows と Node.js だけで動く 40 行足らずのスクリプトで、
ctx 25% (250k/1M) 残り 75% | 週 残り 82% (11/20 16:00 リセット)
という 1 行を出すまでを、手元で動かしたコードつきで書きます。あわせて、Windows でつまずきやすい点と、/context の数字と合わないときの理由、モデルごとの週の枠がステータスラインに出せない点も整理します。
動かした環境は Windows 11、Claude Code 2.1.325、Node.js v24.12.0 です。
/context は内訳を見る道具で、残量を眺める道具ではない

- 開発者「残りのコンテキストを見たくて、毎回 /context を打っています。」
- 先輩「/context は内訳を調べる道具。残量を見るだけなら長すぎるね。」
- 先輩「残量はステータスラインに、1行で出しておけるよ。」
- 開発者「残量は下の1行で見て、内訳だけ /context で調べます。」
/context が返すのは、コンテキストの中身の内訳です。システムプロンプト、ツールの定義、MCP ツール、メモリファイル、スキル、メッセージがそれぞれ何トークンを占めているかが表で出ます。当社の環境では、そのあとにサーバーごとの MCP ツールの表、カスタムエージェント、メモリファイル、スキルの表が続きました。
「何がコンテキストを食っているのか」を調べたいときには、これがそのまま役に立ちます。
ただ、作業の途中でちらっと残量を見たいだけのときには多すぎます。打つたびに会話の画面が数十行ぶん流れ、直前まで読んでいた出力が上へ消えます。
残量は常に見えていて、内訳は必要なときだけ /context で見る。この分担にするのがステータスラインです。
ステータスラインは、JSON を受け取って 1 行を返すだけの仕組み
仕組みは単純です。settings.json の statusLine にコマンドを 1 つ書いておくと、Claude Code がそのコマンドを実行し、セッションの情報を JSON にして標準入力へ流し込みます。コマンドが標準出力に書いた文字が、そのまま画面の下に出ます。
公式ドキュメントによると、ステータスラインは手元のマシンで動くだけで、API のトークンは使いません。新しい応答が届いたときなどに実行され、短い間隔で続けて変化があったときは 300 ミリ秒ぶんをまとめて 1 回だけ実行されます。
渡される JSON のうち、この記事で使う項目は次のとおりです(公式ドキュメントの表からの抜粋)。
| 項目 | 中身 |
|---|---|
context_window.used_percentage | コンテキストの使用率(計算済み) |
context_window.remaining_percentage | 残りの割合(計算済み) |
context_window.context_window_size | コンテキストの上限のトークン数。既定は 200000、拡張コンテキストのモデルでは 1000000 |
context_window.total_input_tokens | いまコンテキストに入っている入力側のトークン数(直近の応答の時点) |
context_window.current_usage | 直近の API 呼び出しのトークン数の内訳 |
rate_limits.five_hour.used_percentage、rate_limits.seven_day.used_percentage | 5 時間の枠と 7 日の枠の使用率(0 から 100) |
rate_limits.five_hour.resets_at、rate_limits.seven_day.resets_at | それぞれの枠がリセットされる時刻(Unix 秒) |
使用率が計算済みで届くので、スクリプトの側で割り算をする必要がありません。拾って 1 行に並べるだけです。
40 行足らずのスクリプトで、コンテキストと利用枠の残りを出す
公式ドキュメントの例は Bash と jq で書かれています。Windows では jq を別に入れることになるので、Claude Code を使っている環境ならまず入っている Node.js で書きました。
statusline-context.mjs(全文)
// Claude Code のステータスラインに、コンテキストの残りと利用枠(5 時間・週)の残りを 1 行で出す
let s = "";
process.stdin.on("data", (d) => (s += d));
process.stdin.on("end", () => {
try {
const data = JSON.parse(s);
const parts = [];
// コンテキスト: 使用率が数値で届いているときだけ出す
const cw = data.context_window || {};
if (typeof cw.used_percentage === "number") {
const used = cw.used_percentage;
const size = cw.context_window_size;
const k = (n) => (n >= 1e6 ? (n / 1e6).toFixed(n % 1e6 ? 1 : 0) + "M" : Math.round(n / 1e3) + "k");
const tokens = typeof size === "number" ? ` (${k((size * used) / 100)}/${k(size)})` : "";
parts.push(`ctx ${Math.round(used)}%${tokens} 残り ${Math.round(100 - used)}%`);
}
// 利用枠: 届いた枠だけを足す。リセットが今日なら時刻だけ、別の日なら月/日も出す
const pad = (n) => String(n).padStart(2, "0");
const windowPart = (label, w) => {
if (!w || typeof w.used_percentage !== "number") return;
let reset = "";
if (typeof w.resets_at === "number") {
const d = new Date(w.resets_at * 1000);
const hm = `${pad(d.getHours())}:${pad(d.getMinutes())}`;
const today = d.toDateString() === new Date().toDateString();
reset = ` (${today ? hm : `${d.getMonth() + 1}/${d.getDate()} ${hm}`} リセット)`;
}
parts.push(`${label} 残り ${Math.max(0, Math.round(100 - w.used_percentage))}%${reset}`);
};
const rl = data.rate_limits || {};
windowPart("5h", rl.five_hour);
windowPart("週", rl.seven_day);
process.stdout.write(parts.join(" | "));
} catch {}
});やっていることは 4 つです。標準入力を最後まで読み、context_window.used_percentage を取り出し、rate_limits に届いている枠を足し、区切りの | でつないで 1 行に書き出します。
コンテキストの使用率が数値でないときは、その表示を省きます。利用枠が届いていれば、そちらだけを出します。公式ドキュメントに、used_percentage と remaining_percentage はセッションの最初のうちは null になりうると書かれているためです。ここで 0% と出してしまうと、まだ分からないだけなのか本当に空なのか、見分けがつかなくなります。
かっこの中のトークン数は、上限に使用率を掛けて出した目安です。「22%」だけよりも「224k/1M」と並んでいたほうが、あとどれくらい書けるかの感覚をつかみやすいので添えました。
利用枠は、届いた枠だけを足します。公式ドキュメントによると、rate_limits が届くのは claude.ai の Pro や Max などのサブスクリプションで使っているときで、それもセッションの最初の応答が返ったあとです。5 時間の枠と 7 日の枠はそれぞれ単独で欠けることがあり、リセットの時刻を過ぎた枠は届かなくなります。
当社の環境でも、届いた JSON の rate_limits に入っていたのは seven_day だけで、five_hour はありませんでした。無い枠は出さないと決めておけば、どの組み合わせで届いても表示が崩れません。
リセットの時刻は Unix 秒で届くので、手元の時計の時刻に直して添えました。今日のうちにリセットされる枠は時刻だけ、別の日なら月日も出します。
try と catch で全体を包んでいるのは、ステータスラインのスクリプトがエラーで落ちても、作業の邪魔をしないようにするためです。
入れる前に、サンプルの JSON で動かして確かめる
ステータスラインのスクリプトは、ただの「標準入力を読んで 1 行返すプログラム」です。Claude Code につなぐ前に、サンプルの JSON を流して単体で確かめられます。公式ドキュメントもこの確かめ方をすすめています。
Git Bash で次のように流します。
echo '{"context_window":{"used_percentage":22.4,"context_window_size":1000000}}' | node statusline-context.mjs手元の結果です。
ctx 22% (224k/1M) 残り 78%上限が 200000 のモデルを想定した入力でも試しました。
echo '{"context_window":{"used_percentage":8,"context_window_size":200000}}' | node statusline-context.mjsctx 8% (16k/200k) 残り 92%使用率が null の入力と、空の JSON({})では、どちらも何も出力されず、エラーにもなりませんでした。
利用枠が入った入力も流しました。まず、5 時間の枠と 7 日の枠の両方がある場合です。
echo '{"context_window":{"used_percentage":25,"context_window_size":1000000},"rate_limits":{"five_hour":{"used_percentage":23.5,"resets_at":1794735000},"seven_day":{"used_percentage":18,"resets_at":1795158000}}}' | node statusline-context.mjsctx 25% (250k/1M) 残り 75% | 5h 残り 77% (18:30 リセット) | 週 残り 82% (11/20 16:00 リセット)リセットの時刻は、実行した日とタイムゾーンで表示が変わります。上は日本時間の 2026 年 11 月 15 日に実行した結果です。
7 日の枠だけがある入力では、次のようになりました。当社の環境で実際に届いたのと同じ形です。
echo '{"context_window":{"used_percentage":25,"context_window_size":1000000},"rate_limits":{"seven_day":{"used_percentage":18,"resets_at":1795158000}}}' | node statusline-context.mjsctx 25% (250k/1M) 残り 75% | 週 残り 82% (11/20 16:00 リセット)settings.json に 1 項目を足す
スクリプトを C:\Users\<あなた>\.claude\ に置き、同じフォルダの settings.json に次の 1 項目を足します。
settings.json(足す部分だけ)
"statusLine": {
"type": "command",
"command": "node \"C:/Users/<あなた>/.claude/statusline-context.mjs\""
}ここで 2 つ、Windows ならではの注意があります。
コマンドの中のパスは、バックスラッシュではなくスラッシュで区切ります。
公式ドキュメントによると、Windows の Claude Code は、Git Bash が入っていればステータスラインのコマンドを Git Bash 経由で実行します。Git Bash はバックスラッシュをエスケープ文字として扱うので、C:\Users\... と書くと区切りが消えた状態でスクリプトに届き、エラーも表示されないまま何も出なくなります。設定したのに表示が出ないときは、まずここを見てください。
もう 1 つは、パスを引用符で囲むことです。ユーザー名に空白が入っているフォルダでは、囲まないとパスが空白の位置で 2 つの引数に分かれ、スクリプトが見つからなくなります。空白を含む名前の仮のホームフォルダを作って確かめたところ、引用符を付けたコマンドは表示が出て、外したコマンドは Cannot find module のエラーで止まりました。
手で足すのが面倒なら、Claude Code に /statusline と打って、出したい内容を文章で頼む方法もあります。公式ドキュメントによると、Claude Code がスクリプトを ~/.claude/ に作り、設定も書き換えてくれます。今回この方法は使っていません。当社では、AI エージェントが ~/.claude/ の配下へ書き込むことをフックで止めているためです。そこで、人が 1 回実行すれば入る小さなスクリプトを用意しました。
install-statusline-context.mjs(全文)
// コンテキストと利用枠の残りを出すステータスラインを入れる: スクリプトを ~/.claude に置き、settings.json に statusLine を足す
import fs from "fs";
import os from "os";
import path from "path";
import {fileURLToPath} from "url";
const here = path.dirname(fileURLToPath(import.meta.url));
const claudeDir = path.join(os.homedir(), ".claude");
const target = path.join(claudeDir, "statusline-context.mjs");
const settingsPath = path.join(claudeDir, "settings.json");
const raw = fs.existsSync(settingsPath) ? fs.readFileSync(settingsPath, "utf-8") : "{}";
const settings = JSON.parse(raw.replace(/^/, ""));
// 既にあるものは上書きしない。何も書き込む前に確かめて止まる
if (settings.statusLine) {
console.log("既に statusLine があります。何も変えません:", JSON.stringify(settings.statusLine));
process.exit(1);
}
if (fs.existsSync(target)) {
console.log("既に " + target + " があります。何も変えません");
process.exit(1);
}
fs.mkdirSync(claudeDir, {recursive: true});
fs.copyFileSync(path.join(here, "statusline-context.mjs"), target);
if (fs.existsSync(settingsPath)) fs.writeFileSync(settingsPath + ".bak-before-statusline", raw);
// パスはスラッシュで区切り、空白を含むフォルダ名でも 1 つの引数として届くように引用符で囲む
settings.statusLine = {type: "command", command: `node "${target.replace(/\\/g, "/")}"`};
const indent = (raw.match(/\n([ \t]+)"/) || [null, " "])[1];
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, indent) + "\n");
console.log("OK: " + target + " を置き、" + settingsPath + " に statusLine を足しました");2 つのファイルを同じフォルダに置いて、node install-statusline-context.mjs を 1 回実行します。すでに statusLine が設定されているとき、または同じ名前のスクリプトがすでに置かれているときは、何も書き込まずに止まります。.claude フォルダが無ければ作り、元の settings.json があれば settings.json.bak-before-statusline として残します。パスの区切りをスラッシュに直して引用符で囲むところも、このスクリプトの中でやっています。
空白を含む名前の仮のホームフォルダに向けて実行し、settings.json に上に書いたとおりの statusLine の項目が入ること、設定済みの状態でもう一度実行しても何も変わらないこと、ほかの設定がある settings.json にも項目が足されることを確かめました。
【公開前にここへ、実際の Claude Code の画面でステータスラインが出ているスクリーンショットを入れる】
長いコマンドは、短いパスに置いてから実行する
入れる作業で、もう 1 つ気をつけたことがあります。
インストール用のスクリプトを、最初は一時フォルダの深い場所に置いていました。実行するコマンドは、全体で 140 文字ほどありました。当社の環境では、別の作業で長いコマンドを貼り付けたときに途中で改行が入力され、1 行目だけが実行されたことがありました。
同じことを避けるため、スクリプトを短いパスのフォルダへ写し、実行するコマンドを 60 文字台に収めました。
パスの区切りにも、同じ種類の注意が要ります。Claude Code の入力欄で先頭に ! を付けて実行したコマンドは、当社の環境では Git Bash で実行されました。スクリプトのパスをバックスラッシュで区切って書いたところ、区切りが消えたパスを探しに行き、Cannot find module のエラーで止まりました。同じパスをスラッシュで区切って書き直すと、そのまま通りました。
人に「このコマンドを実行してください」と渡すときは、コマンドの中身より先に、長さを見ています。長くなるなら、ファイルを短いパスへ動かしてから渡します。
モデルごとの週の枠は、ステータスラインには届かない
claude.ai の使用状況の画面には、週の全体の枠とは別に、特定のモデルだけの枠が出ることがあります。当社の画面では、Fable の枠が全体の枠の下に並んでいます。これもステータスラインに並べたくなります。
ただ、公式ドキュメントに載っている rate_limits の中身は、five_hour、seven_day、ゲートウェイ経由で使うときの spend_limit の 3 つです。モデルごとの枠は記載がありません。
当社の環境で、ステータスラインのコマンドに実際に届いた JSON をファイルに保存して中を見ました。Claude Code 2.1.325 で、rate_limits に入っていたのは seven_day だけでした。モデルごとの枠にあたる項目はありませんでした。
外部の道具には、公開されていない窓口から値を取って表示するものもあります。今回は使っていません。モデルごとの残りは、これまでどおり /usage で見ています。公式の JSON に項目が足されたら、スクリプトに 1 行足せば同じ行に並べられます。
/context の数字と合わないのは、数えている時点が違うから
ステータスラインを出したあとで /context を打つと、数字が少し違うことがあります。
これは不具合ではありません。公式ドキュメントによると、ステータスラインが受け取るのは直近の API の応答の時点の数で、/context はそこに、その応答のあとで増えたメッセージの見積もりを足します。そのため、次の応答が届くまでは /context のほうが大きく出ることがあります。
もう 1 つ、used_percentage は入力側のトークンだけで計算されます。入力トークン、キャッシュへの書き込み、キャッシュからの読み出しの合計で、出力トークンは含みません。
ステータスラインの数字は「ちらっと見る目安」、/context は「内訳まで含めた詳しい表」と考えておくと、ずれに迷いません。
なお、公式ドキュメントには、ステータスラインを自分で設定すると、画面下のキーボード操作のヒント(esc to interrupt など)の多くが表示されなくなる、とも書かれています。ヒントを頼りにしている場合は、入れる前に知っておいてください。
作り込みたいなら、既製の道具もある
コンテキストの使用率と利用枠のほかに、モデル名、git のブランチ、かかった費用なども、同じ JSON で届きます。いろいろ並べたい場合は、自分で書く以外の方法もあります。
| 方法 | 要るもの | 向いている場面 |
|---|---|---|
/statusline に文章で頼む(公式の機能) | Claude Code だけ | まず試してみたいとき |
| ccstatusline、starship-claude(公式ドキュメントが紹介しているコミュニティ製の道具) | それぞれの導入 | テーマや複数の項目を作り込みたいとき |
| 自分で数十行を書く(この記事の方法) | Node.js | 出したいものが少なく、中身を全部把握しておきたいとき |
今回は、既製の道具は使っていません。出したいのがコンテキストと利用枠の残りだけだったので、40 行足らずで足りました。
まとめ
/context は内訳を調べる道具として残し、残量はステータスラインに出しておく。利用枠の残りも同じ行に並べておけば、/usage を開く回数も減ります。入れてしまえば、コマンドを打つ手間も、画面が流れることもなくなります。
つまずきやすい点を表にしておきます。
| 起きること | 理由と対処 |
|---|---|
| 設定したのに何も出ない | Windows ではコマンドのパスをスラッシュで区切り、引用符で囲む。バックスラッシュだとエラーも出ずに失敗する |
| セッションの最初だけ何も出ない | 最初の応答が届くまで使用率が null になりうる。この記事のスクリプトは、その間は何も出さない |
/context と数字が違う | 数えている時点が違う。次の応答が届くと近づく |
| 貼り付けたコマンドが途中で切れる | 長いコマンドを貼り付けたときに、途中で改行が入力されたことがあった。ファイルを短いパスへ動かし、コマンドを短くしてから実行する |
| 利用枠の残りが出ない | rate_limits は、サブスクリプションで使っているときに、最初の応答のあとから届く。枠ごとに欠けることもある。この記事のスクリプトは、届いた枠だけを出す |
! で実行したコマンドがファイルを見つけられない | Git Bash で実行されると、バックスラッシュの区切りが消える。パスはスラッシュで区切る |
| モデルごとの週の枠が出せない | ステータスラインに届く JSON に項目が無い。/usage で見る |
それでは、また次回、お会いしましょう!