🤖

Claude Code の実質料金や使用コンテキスト量を可視化する

に公開

はじめに

Claude Code v1.0.71 のアップデートで、ターミナル下部のステータスラインを自由にカスタマイズできるようになりました。
この機能を活用すると、作業中の重要な情報を常に把握しながら開発を進められます。

特に長時間の作業では、コンテキストウィンドウがいつ満杯になるか分からず、突然の auto-compact(自動圧縮)に驚くことがあります。
また、有料プランを使っている方は「今日は実質いくら使ったか」も気になるポイントです。

今回は、ステータスラインをカスタムして、利用料金のリアルタイム追跡コンテキスト使用状況の可視化を実現する方法をご紹介します。

この記事で得られること

  • 🎯 メモリ管理の見える化 - auto-compact のタイミングを事前に予測
  • 💸 コスト意識の向上 - リアルタイムで利用料金を確認
  • 📊 作業効率の改善 - コンテキストの無駄遣いを防止
  • 🎮 ゲーミフィケーション - 日々の利用状況を楽しく管理

こんな人におすすめ

  • Claude Code をよく使う人
  • 利用料金を把握しながら使いたい人
  • コンテキストウィンドウの管理を意識したい人
  • 「今日は元取れた!」という達成感を味わいたい人

完成イメージ

🤖 Opus 4.1 | 💰 $83.68 | 🪙 58.3K | 📊 36.4%

各要素の意味

  • 🤖 Opus 4.1 - 使用中のモデル
  • 💰 $83.68 - 今日の Claude Code 利用料金(従量課金換算)
  • 🪙 58.3K - 現在のセッションで使用したトークン数
  • 📊 36.4% - コンテキストウィンドウ使用率(色付き)

使用率の色分け

コンテキストウィンドウの使用率に応じて、📊の色が変わります

  • 🟢 70%未満:安全(緑) - 快適に作業可能
  • 🟡 70-89%:警告(黄) - そろそろ整理を検討
  • 🔴 90%以上:危険(赤) - auto-compact 間近!

これにより、作業を中断することなくメモリ状況を把握できます。

動作の仕組み

このカスタマイズは、Claude Code が内部で管理している以下の情報を取得・集計します。

  1. セッション情報 - 現在のモデルとセッション ID
  2. トランスクリプトファイル - ~/.claude/projects/ 内の使用量ログ
  3. ccusage API - 日次の利用料金データ
  4. リアルタイム計算 - コンテキスト使用率と色分け

これらの情報を bash スクリプトで処理し、見やすい形式で表示します。

必要なもの

  1. Claude Code v1.0.71 以降
  2. ccusage(コスト計算ツール)
  3. jq(JSON パーサー)
  4. bc(計算ツール)

セットアップ手順

1. ccusage のインストール

まず、Claude Code の使用量を追跡する ccusage をインストールします:

# npm を使用する場合
npm install -g ccusage

# または Homebrew を使用する場合(macOS)
brew install ccusage

2. statusline.sh スクリプトの作成

以下のスクリプトを ~/.claude/scripts/statusline.sh として保存します

#!/bin/bash

# Constants
readonly MAX_CONTEXT=160000  # 200K * 0.8
readonly CACHE_FILE="/tmp/claude_statusline_cost_cache"
readonly CACHE_TTL=60  # seconds

# Format token count (e.g., 15.2K, 1.3M)
format_token_count() {
  local tokens="$1"
  
  if [ "$tokens" -ge 1000000 ]; then
    echo "$(echo "scale=1; $tokens / 1000000" | bc)M"
  elif [ "$tokens" -ge 1000 ]; then
    echo "$(echo "scale=1; $tokens / 1000" | bc)K"
  else
    echo "$tokens"
  fi
}

# Calculate daily cost using ccusage
calculate_daily_cost() {
  if ! command -v ccusage >/dev/null 2>&1; then
    echo "0"
    return
  fi

  local today
  today=$(date +%Y%m%d)  # No hyphens - this format works
  
  local ccusage_output
  ccusage_output=$(ccusage daily --json --since "$today" --until "$today" 2>/dev/null)
  
  if [ -z "$ccusage_output" ]; then
    echo "0"
    return
  fi
  
  local cost
  cost=$(echo "$ccusage_output" | jq -r ".daily | to_entries | .[0].value.totalCost // 0" 2>/dev/null)
  
  if [ -n "$cost" ] && [ "$cost" != "0" ]; then
    echo "$cost"
  else
    echo "0"
  fi
}

# Get cached cost or recalculate
get_cached_cost() {
  local today
  today=$(date +%Y-%m-%d)
  
  # Check if cache exists and is recent
  if [ -f "$CACHE_FILE" ]; then
    local cache_date cache_cost cache_age
    cache_date=$(head -1 "$CACHE_FILE" 2>/dev/null)
    cache_cost=$(tail -1 "$CACHE_FILE" 2>/dev/null)
    cache_age=$(($(date +%s) - $(stat -f %m "$CACHE_FILE" 2>/dev/null || echo 0)))
    
    # Use cache if it's from today and fresh
    if [ "$cache_date" = "$today" ] && [ "$cache_age" -le "$CACHE_TTL" ]; then
      echo "${cache_cost:-0.00}"
      return
    fi
  fi
  
  # Calculate and cache new cost
  local cost
  cost=$(calculate_daily_cost)
  cost="${cost:-0.00}"
  
  # Update cache
  echo "$today" >"$CACHE_FILE"
  echo "$cost" >>"$CACHE_FILE"
  
  echo "$cost"
}

# Calculate token usage percentage with color coding
calculate_usage_percentage() {
  local total_tokens="$1"
  
  if [ "$MAX_CONTEXT" -eq 0 ]; then
    echo "0.0"
    return
  fi
  
  local usage_percent
  usage_percent=$(echo "scale=1; $total_tokens * 100 / $MAX_CONTEXT" | bc -l 2>/dev/null || echo "0")
  
  # Cap at 100%
  if (($(echo "$usage_percent > 100" | bc -l 2>/dev/null))); then
    echo "100.0"
  else
    echo "$usage_percent"
  fi
}

# Get color code based on percentage
get_percentage_color() {
  local percentage="$1"
  local percent_int=$(echo "$percentage" | cut -d. -f1)
  
  if [ "$percent_int" -ge 90 ]; then
    echo "\033[31m"  # Red
  elif [ "$percent_int" -ge 70 ]; then
    echo "\033[33m"  # Yellow
  else
    echo "\033[32m"  # Green
  fi
}

# Get token usage from transcript
get_token_usage() {
  local session_id="$1"
  local transcript_dir="$2"
  local transcript_file="$transcript_dir/$session_id.jsonl"
  
  if [ ! -f "$transcript_file" ]; then
    echo "0"
    return
  fi
  
  # Get last usage entry (cumulative)
  local last_usage
  last_usage=$(grep '"usage"' "$transcript_file" 2>/dev/null | tail -1 | jq '.message.usage' 2>/dev/null)
  
  if [ -z "$last_usage" ] || [ "$last_usage" = "null" ]; then
    echo "0"
    return
  fi
  
  # Sum all token types
  local input output cache_creation cache_read
  input=$(echo "$last_usage" | jq -r '.input_tokens // 0')
  output=$(echo "$last_usage" | jq -r '.output_tokens // 0')
  cache_creation=$(echo "$last_usage" | jq -r '.cache_creation_input_tokens // 0')
  cache_read=$(echo "$last_usage" | jq -r '.cache_read_input_tokens // 0')
  
  echo $((input + output + cache_creation + cache_read))
}

# Main
main() {
  # Read JSON from stdin
  local json_input
  json_input=$(cat)
  
  local model session_id current_dir
  model=$(echo "$json_input" | jq -r '.model.display_name // .model // "unknown"' 2>/dev/null)
  session_id=$(echo "$json_input" | jq -r '.session_id // ""' 2>/dev/null)
  current_dir=$(echo "$json_input" | jq -r '.workspace.current_dir // .cwd // "~"' 2>/dev/null)
  
  local total_tokens=0
  if [ -n "$session_id" ]; then
    # Try to find the transcript file in any project directory
    local projects_dir="$HOME/.claude/projects"
    if [ -d "$projects_dir" ]; then
      # Search for the session transcript in all project directories
      for project_dir in "$projects_dir"/*; do
        if [ -d "$project_dir" ]; then
          local transcript_file="$project_dir/$session_id.jsonl"
          if [ -f "$transcript_file" ]; then
            total_tokens=$(get_token_usage "$session_id" "$project_dir")
            break
          fi
        fi
      done
    fi
  fi
  
  # Format token count
  local token_display
  token_display=$(format_token_count "$total_tokens")
  
  # Calculate usage percentage
  local usage_percent
  usage_percent=$(calculate_usage_percentage "$total_tokens")
  
  # Get color for percentage
  local color_code reset_color
  color_code=$(get_percentage_color "$usage_percent")
  reset_color="\033[0m"
  
  # Get today's cost
  local today_cost
  today_cost=$(get_cached_cost)
  today_cost=$(printf "%.2f" "$today_cost")
  
  # Output status line with colored percentage
  printf "🤖 %s | 💰 \$%s | 🪙 %s | ${color_code}📊 %s%%${reset_color}\n" \
    "$model" "$today_cost" "$token_display" "$usage_percent"
}

main "$@"

3. 実行権限の付与

スクリプトに実行権限を付与します。

chmod +x ~/.claude/scripts/statusline.sh

4. Claude Code の設定ファイルを編集

~/.claude/settings.json に以下を追加します。

{
  // ... 既存の設定 ...
  
  "statusLine": {
    "type": "command",
    "command": "~/.claude/scripts/statusline.sh"
  }
}

5. Claude Code を再起動

設定を反映させるため、Claude Code を再起動します。

動作確認

正しく設定されていれば、Claude Code の下部ステータスバーに以下のような表示が現れます。

🤖 Opus 4.1 | 💰 $83.68 | 🪙 58.3K | 📊 36.4%

トラブルシューティング

コストが $0.00 のまま変わらない

ccusage が正しくインストールされているか確認してみてください。

which ccusage
ccusage --version

トークン数が 0 のまま

セッションのトランスクリプトファイルが生成されているか確認してみてください。

ls ~/.claude/projects/

ステータスラインが表示されない

  1. settings.json の JSON 構文が正しいか確認
  2. スクリプトの実行権限があるか確認
  3. Claude Code のログを確認

カスタマイズのヒント

コンテキストウィンドウの閾値を変更

MAX_CONTEXT の値を調整することで、使用率の計算基準を変更できます。

readonly MAX_CONTEXT=160000  # デフォルト: 200K * 0.8

キャッシュ時間の調整

API 呼び出しを減らすため、コスト情報は 60 秒間キャッシュされます。
以下のように変更できるのでお試しください。

readonly CACHE_TTL=60  # 秒単位
# readonly CACHE_TTL=300  # 5分間キャッシュする場合

色の閾値を変更

警告色の基準を変更したい場合は、get_percentage_color 関数を編集。

if [ "$percent_int" -ge 80 ]; then  # 80%以上を赤に
  echo "\033[31m"  # Red
elif [ "$percent_int" -ge 60 ]; then  # 60%以上を黄色に
  echo "\033[33m"  # Yellow

実際に使ってみて

私はこのステータスラインを導入してから、以下のような変化がありました。

  1. 無駄な会話の削減 - コンテキスト使用率が見えることで、以前よりは必要最小限の質問を心がけるように
  2. 適切なタイミングでの新規セッション - 80%を超えたら、タイミングを見て新規セッションに移る判断が前より早まりました
  3. モチベーション向上 - 料金が可視化されることで、「今日も頑張った」という充実感を得られます

まとめ

Claude Code v1.0.71 で追加されたステータスラインのカスタム機能は、単なる情報表示以上の価値があります。
作業の効率化、コスト管理、そして何より「見える化」による安心感が得られます。

特に長時間の開発作業では、突然の auto-compact によるコンテキストロスを防げるため、生産性の向上にも貢献するかと思います。
「今日は1日で$100超えた!元取れた!」という達成感も、日々のモチベーションアップにつながるでしょう。

参考リンク


質問や改善案があれば、ぜひコメントでお知らせください!
最後までお読みいただきありがとうございました。

Discussion