Skip to content

原文(日本語に翻訳)

stdio MCPサーバーが非プロトコルデータをstdoutに書き込む際に発生する、メモリが無制限に増大する問題(RSS 10GB以上)を修正しました。

原文(英語)

Fixed unbounded memory growth (10GB+ RSS) when a stdio MCP server writes non-protocol data to stdout

概要

stdio(標準入出力)を使用するMCPサーバーが、MCPプロトコル以外のデータ(ログ出力やデバッグ情報など)をstdoutに書き込んだ場合、Claude CodeのメモリがRSSで10GB以上に達する可能性がありました。この問題はプロセスのクラッシュやシステムの不安定化を引き起こす深刻なバグでした。修正により、非プロトコルデータが適切に無視またはフィルタリングされ、メモリ使用量が安定するようになります。

基本的な使い方

この修正はユーザーが特別な操作をする必要はなく、自動的に適用されます。ただし、MCPサーバーを開発している場合は、stdoutへの不必要な出力を避けることをお勧めします。

bash
# MCPサーバーの設定例(~/.claude/claude_desktop_config.json)
{
  "mcpServers": {
    "my-server": {
      "command": "node",
      "args": ["./my-mcp-server.js"],
      "type": "stdio"
    }
  }
}

実践例

MCPサーバー開発時のベストプラクティス

stdio MCPサーバーを開発する際は、stdoutをMCPプロトコル専用に保つことが重要です。

javascript
// 悪い例: stdoutにログを出力してしまう(修正前はメモリ問題を引き起こした)
console.log("サーバーが起動しました");  // これがstdoutに書き込まれる
console.log("リクエストを受信:", request);

// 良い例: stderrにログを出力する(MCPプロトコルに影響しない)
console.error("サーバーが起動しました");  // stderrに書き込む
process.stderr.write("リクエストを受信: " + JSON.stringify(request) + "\n");
python
# Pythonのstdio MCPサーバーでのログ出力
import sys
import logging

# ログをstderrに向ける(重要)
logging.basicConfig(
    stream=sys.stderr,  # stderrを使用
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# 悪い例
print("デバッグ情報")  # stdoutに書き込まれてしまう

# 良い例
logging.debug("デバッグ情報")  # stderrに書き込まれる
sys.stderr.write("デバッグ情報\n")  # 明示的にstderr

メモリ使用量の監視

修正が適用されているか確認するために、メモリ使用量を監視できます。

bash
# Claude Codeのプロセスのメモリ使用量を確認(Linux/macOS)
ps aux | grep claude
# または
top -p $(pgrep -f "claude")

# 修正前: MCPサーバーから非プロトコルデータが来ると急激にメモリが増加
# 修正後: メモリ使用量が安定した範囲に保たれる

MCPサーバーのデバッグ

bash
# MCPサーバーのstdoutのみを確認(デバッグ用)
node my-mcp-server.js 2>/dev/null

# MCPサーバーのstderrのみを確認(ログ確認用)
node my-mcp-server.js 2>&1 1>/dev/null

# Claude Codeのログでエラーを確認
cat ~/.claude/logs/claude-code.log | grep -i "mcp"

注意点

  • この問題はstdio型のMCPサーバーのみに影響します。HTTP/SSE型のMCPサーバーには影響しません。
  • 既存のMCPサーバーが非プロトコルデータをstdoutに出力している場合でも、修正後は安全に動作しますが、MCPサーバー側でstderrを使用するよう修正することを推奨します。
  • 修正前に長時間実行していたセッションでメモリ不足が発生した場合は、Claude Codeを再起動することで解消されます。
  • システムのスワップ領域が大量に消費されていた場合、OS再起動が必要になる場合もあります。

関連情報