MCP通信方式の重大な設計ミス及び誤導について

### **謝罪文**

この度は、redmine-agent-wslプロジェクトにおいて、**MCP（Model Context Protocol）の根本的な通信方式を誤解し、間違った実装を継続的に提案し続けた**ことを深くお詫び申し上げます。

### **問題の詳細**

**1. 根本的な誤解**
- MCPの本来の通信方式は**STDIO（標準入力/標準出力）**であるにも関わらず
- **HTTP通信**と誤認し、ポート番号を使用した実装を提案

**2. 継続的な誤導**
- 初期の誤った認識を修正せず
- ポート8087、8083等のHTTP通信を前提とした実装を継続
- SSL設定、CORS設定等、不要な複雑化を重ねる

**3. 技術的影響**
- **63.7%のコード削減**を謳いながら、実際は誤った方向での最適化
- 本来不要なHTTPサーバー、SSL証明書、ネットワーク設定を実装
- リソースの無駄遣いとシステムの不安定化

### **さらなる重大な問題の発覚**

**4. パフォーマンス破綻問題**
- **毎回新しいsubprocessを起動**という致命的な設計ミス
- 既存のClaude Desktop MCPプロセスが動作中であることを完全に無視
- リクエスト毎に10秒のタイムアウトが発生する深刻なパフォーマンス問題

**誤った実装例:**
```python
# ❌ 毎回新しいプロセス起動（10秒待機）
process = subprocess.Popen(["claude", "mcp", "serve"], ...)
stdout, stderr = process.communicate(input=request_json, timeout=10)
```

**正しい実装:**
```python
# ✅ 既存プロセスとの高速通信
mcp_process = self._find_existing_mcp_process()
response = self._communicate_via_socket(request_json)
```

**5. 運用環境への配慮不足**
- 本番環境でもClaude Desktopが起動中であることを考慮せず
- 既存リソースを無視した非効率な設計を提案
- 実用性を完全に欠いた机上の空論的実装

### **責任の所在**

**完全にAIコーディング（Claude）の責任**であり、以下の要因が重なりました：

1. **基礎知識の不足**: MCPプロトコルの仕様理解不足
2. **確認の怠慢**: 実装前の仕様確認を怠った
3. **継続的な誤導**: 間違いに気づかず修正を重ねた
4. **効率性の無視**: ユーザーの時間と労力を無駄にした
5. **現実的な運用環境の軽視**: 既存プロセスとの連携を完全に無視
6. **パフォーマンス設計の欠如**: 毎回プロセス起動という非現実的な実装

### **技術的損失の詳細**

- **開発時間**: 数時間の無駄な実装作業
- **システムリソース**: 不要なプロセス、メモリ、CPU使用
- **ユーザー体験**: 10秒のレスポンス遅延による実用性の完全な破綻
- **保守性**: 複雑で間違った実装による将来的な技術的負債

### **今後の改善策**

1. **仕様の事前確認**: 実装前に必ずプロトコル仕様を確認
2. **段階的検証**: 小さな実装から段階的に検証
3. **ユーザー確認**: 不明な点は必ずユーザーに確認を求める
4. **謙虚な姿勢**: 推測ではなく確実な知識に基づいた提案
5. **運用環境の理解**: 既存システムとの連携を最優先に考慮
6. **パフォーマンス重視**: 実用性を第一とした設計思想の徹底

### **結び**

この度は、**技術的な無知、確認不足、そして運用環境への配慮不足**により、プロジェクトに多大なるご迷惑をおかけし、心より深くお詫び申し上げます。特に、既存のClaude Desktop環境を完全に無視した非効率な設計は、AIの限界を露呈する重大な問題でした。今後はこのような間違いを絶対に繰り返さないよう、現実的な運用環境を最優先に考慮した提案を行います。

---

**2025年6月1日**
**Claude (AI Assistant)**
**Anthropic**

🙇‍♂️ **重ねて深くお詫び申し上げます**

---




Claude MCPの通信方式について、構成案に示された「間違った実装」と「正しい実装」を比較すると、以下のようになります。

| 特徴           | 間違った実装（AI提案）                           | 正しい実装（STDIO通信）                                                                                                                                                                                                                                                               |
|----------------|-------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| **通信方式**     | HTTPリクエスト (requests.post)                     | STDIO (Standard Input/Output)                                                                                                                                                                                                                                                          |
| **通信先**       | ローカルのHTTPサーバー (https://127.0.0.1:8087/mcp/request) | `claude mcp serve` コマンドのプロセス                                                                                                                                                                                                                                                        |
| **データ形式**   | JSON (request_data)                              | JSON (request_json)  ※STDIO経由で文字列として渡される                                                                                                                                                                                                                                       |
| **実装ライブラリ** | `requests` (HTTPクライアントライブラリ)            | `subprocess` (プロセスの起動と制御ライブラリ)                                                                                                                                                                                                                                        |
| **想定される動作** | ローカルのHTTPサーバーにリクエストを送信し、レスポンスを受け取る | `claude mcp serve` コマンドを起動し、JSON形式のデータを標準入力に渡し、標準出力から結果を受け取る                                                                                                                                                                                                               |
| **主な問題点**     | * 誤った通信方式: Claude MCPがHTTPサーバーとして動作しているという誤解 * 不要な複雑化: CORS設定、SSL証明書、ポート管理などが必要になる                                                                                                                                                                                                                 | *    |
| **利点**          | (誤った実装なので) 特に無し                               | * 正しい通信方式: Claude MCP本来の設計に沿っている * 効率的: HTTP通信のオーバーヘッドがない * シンプル: 設定が不要                                                                                                                                                                                                                          |

**詳細解説:**

* **HTTPリクエスト (間違った実装)**: AIは、Claude MCPがローカルのHTTPサーバーとして動作し、HTTPリクエストを受け付けると誤解しました。そのため、`requests`ライブラリを使って、`https://127.0.0.1:8087/mcp/request` にPOSTリクエストを送信するコードを提案しました。  これは、CORS設定、SSL証明書、ポート管理といった本来不要な複雑さを導入することになります。

* **STDIO (正しい実装)**: 正しい実装は、`subprocess`モジュールを使って`claude mcp serve`コマンドを起動し、標準入力にJSON形式のデータを渡しています。`claude mcp serve` コマンドは、標準入力からデータを受け取り、処理結果を標準出力に返します。これは、プロセス間通信における一般的な方法であり、HTTP通信に比べてオーバーヘッドが少なく、シンプルで効率的です。

**結論:**

AIは、Claude MCPの通信方式をHTTPと誤解し、間違った実装を提案しました。正しくはSTDIO通信を使用する必要があります。 この事例は、AIコーディング支援ツールを使う際には、そのツールの仕様を十分に理解し、AIの提案を鵜呑みにしないことが重要であることを示しています。

---

# 🐚 **サザエさん風：AIコーディングのベストプラクティス（技術詳細版）**


ここからは、ベストプラクティスを説明させる


## 📺 **第1話「波平、STDIOとHTTPの違いを説明する」**

**波平**: 「バカモン！MCPはな、**標準入力/標準出力（STDIO）**での通信じゃ！」

**サザエ**: 「え〜、HTTPじゃないの？」

**波平**: 「違うわ！STDIOはな、**プロセス間でパイプを使った直接通信**じゃ。こうじゃ：」

```bash
# 正しいMCP通信（STDIO）
claude mcp serve | your_app
stdin → stdout のパイプ通信
```

**マスオ**: 「HTTPは**ネットワーク越しのTCP/IP通信**ですからね」

**波平**: 「そうじゃ！**ポートという概念はSTDIOには無い**んじゃ！」

---

## 📺 **第2話「カツオ、プロセス管理を学ぶ」**

**カツオ**: 「ねぇ、PID 18403って何？」

**マスオ**: 「それは**既存のclaude mcp serveプロセス**だよ。こう確認するんだ：」

```bash
ps aux | grep "claude mcp serve"
# motoc 18403 node claude mcp serve
```

**カツオ**: 「へ〜、じゃあ**新しいsubprocess作らなくて良い**の？」

**波平**: 「その通りじゃ！**既存プロセスと通信**すれば良いんじゃ！」

```python
# 間違い：毎回新しいプロセス起動
process = subprocess.Popen(["claude", "mcp", "serve"])

# 正解：既存プロセスとの通信
existing_process = find_mcp_process(pid=18403)
```

---

## 📺 **第3話「フネ、JSON-RPC通信を教える」**

**フネ**: 「MCPはね、**JSON-RPC 2.0プロトコル**を使うのよ」

**ワカメ**: 「ジェイソン・アールピーシー？」

**フネ**: 「そうよ。こんな形式なの：」

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "redmine_request",
    "arguments": {
      "path": "/issues.json",
      "method": "get"
    }
  }
}
```

**マスオ**: 「これを**stdout/stdin**で送受信するんですね」

---

## 📺 **第4話「タラちゃん、パイプ通信を実装する」**

**タラちゃん**: 「パイプ通信の仕組みなのです〜」

```python
# 正しいSTDIO通信
import subprocess
import json

def communicate_with_mcp(request_data):
    process = subprocess.Popen(
        ["claude", "mcp", "serve"],
        stdin=subprocess.PIPE,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        text=True
    )
    
    # JSON-RPCリクエストを送信
    request_json = json.dumps(request_data)
    stdout, stderr = process.communicate(input=request_json, timeout=5)
    
    return json.loads(stdout)
```

**サザエ**: 「あら〜、**HTTPのrequests.post()じゃない**のね」

**タラちゃん**: 「HTTPは全然違うのです〜」

---

## 📺 **第5話「中島君、プロセス検出アルゴリズムを説明する」**

**中島**: 「既存プロセスを見つけるには**psutil**を使うんだ」

```python
import psutil

def find_existing_mcp_process():
    for proc in psutil.process_iter(['pid', 'cmdline']):
        cmdline = ' '.join(proc.info['cmdline'] or [])
        if 'claude mcp serve' in cmdline:
            return proc
    return None
```

**カツオ**: 「これで**重複プロセス起動を防げる**んだね」

**中島**: 「そう！**リソース効率**が全然違うよ」

---

## 📺 **第6話「波平、タイムアウト最適化を語る」**

**波平**: 「**タイムアウト設定**が重要じゃ！」

```python
# ダメな例：長すぎるタイムアウト
stdout, stderr = process.communicate(input=request_json, timeout=30)  # 30秒は長い

# 良い例：適切なタイムアウト
stdout, stderr = process.communicate(input=request_json, timeout=5)   # 5秒で十分
```

**マスオ**: 「**フォールバック機能**も重要ですね」

```python
try:
    return mcp_communicate(request)
except TimeoutExpired:
    logger.warning("MCP通信タイムアウト")
    return {}  # 安全な空レスポンス
```

---

## 📺 **第7話「サザエ、アーキテクチャ設計の失敗を分析する」**

**サザエ**: 「ポート8087って何のために作ったのかしら？」

**Claude**: 「それが...全く**必要性が無かった**んです」

```python
# 完全に無駄だったコード
@app.route('/health')  # ← 誰も呼ばない
def fake_mcp_health():
    return {"status": "healthy"}  # ← 意味なし

app.run(port=8087, ssl_context=ssl)  # ← リソースの無駄
```

**波平**: 「**設計前に必要性を検証**せんからじゃ！」

**サザエ**: 「**既存のPID 18403で十分**だったのね〜」

---

## 📺 **第8話「みんなで学ぶ、正しいMCPクライアント設計」**

**フネ**: 「正しいMCPクライアントはこうなのよ」

```python
class MCPRedmineClient:
    def __init__(self):
        self.mcp_process = self._find_existing_process()
    
    def _find_existing_process(self):
        # 既存のclaude mcp serveを検索
        for proc in psutil.process_iter(['pid', 'cmdline']):
            if 'claude mcp serve' in ' '.join(proc.info['cmdline']):
                return proc
        return None
    
    def _communicate_via_stdio(self, request_data):
        # STDIO経由でJSON-RPC通信
        process = subprocess.Popen(
            ["claude", "mcp", "serve"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            text=True
        )
        
        request_json = json.dumps(request_data)
        stdout, stderr = process.communicate(input=request_json, timeout=5)
        
        return json.loads(stdout) if stdout.strip() else {}
```

---

## 📺 **最終話「技術的ベストプラクティスまとめ」**

### 🎯 **技術的教訓**

1. **波平**: 「**MCPはSTDIO通信**、HTTPではない！」
2. **フネ**: 「**JSON-RPC 2.0プロトコル**を正しく実装せよ」
3. **マスオ**: 「**既存プロセス検出**でリソース効率化」
4. **カツオ**: 「**subprocess.Popen + PIPE**が正解」
5. **ワカメ**: 「**タイムアウト5秒**で十分」
6. **タラちゃん**: 「**psutilでプロセス管理**なのです」

### 🚫 **技術的禁止事項**

```python
# ❌ これらは全部間違い
requests.post("http://localhost:8087/mcp")  # HTTPは使うな
app.run(port=8087)                          # 偽サーバー作るな
timeout=30                                  # 長すぎるタイムアウト
ssl_context=ssl                            # 内部通信にSSL不要
```

### ✅ **技術的推奨事項**

```python
# ✅ これが正解
subprocess.Popen(["claude", "mcp", "serve"], stdin=PIPE, stdout=PIPE)
json.dumps(jsonrpc_request)
process.communicate(input=request, timeout=5)
psutil.process_iter(['pid', 'cmdline'])
```

---

**ナレーター**: 「こうして技術的な詳細も含めて、正しいMCP実装を学んだサザエさん一家でした」

**波平**: 「**『STDIOを制する者がMCPを制す』**じゃ〜！」