Skip to main content
Glama
workerportfolio

MCP Memory System

README.md
# MCP Memory System - チャット跨ぎコンテキスト保持システム

## 概要
Claude DesktopとMCP(Model Context Protocol)を活用し、対話の中から「決定事項・設定・運用ルール」を構造化データとして抽出・蓄積・参照する外部メモリシステムの概念実証(PoC)です。

チャットを跨いだコンテキスト断絶を解消し、長期的な開発における「意思決定の整合性」を保つための「プロジェクト専用の外部脳」の実現可能性を検証しました。

## プロジェクトの目的
- **チャット間のコンテキスト継続性**: ライフサイクル(チャットセッション)終了時に消失する決定事項の永続化
- **情報の正規化(Canonicalization)**: 過去の経緯と現在のルールを整理し、LLMが最新の正解を参照できる状態の維持
- **意思決定の透明性**: どの発言に基づき、いつルールが確定・更新されたかの追跡実現

## 検証した課題

### 1. コンテキスト忘却による意思決定の断絶
**背景:**
開発プロジェクト(RAG検証システム等)の過程で、複数のチャットセッションに跨り同じトピックについて議論すると、以前の決定事項が参照されず、矛盾した判断に繋がるケースが発生。

**例:**
- Session A: 「pgvectorのインデックスはHNSWを採用する」と決定
- Session B: 新しいチャットで「IVFFLATを検討するべきか?」と同じ議論が再発

この状態を解決するためのメモリシステムの構造化が必要と判断。

### 2. 情報の経年劣化と優先順位の曖昧性
複数の記録(チャットログ、手書きメモ、プロジェクトドキュメント)に散在する情報から、「現在の正解」を特定することが困難。古い決定と新しい決定の関係性も不明瞭になりがち。

## 技術スタック
- **LLM UI**: Claude Desktop
- **通信プロトコル**: Model Context Protocol (MCP) over SSH
- **バックエンド**: Python 3.12(venv)
- **永続化**: SQLite3(WAL mode)+ FTS5(全文検索) (※PostgreSQLへの最終的な意向を検討していた)
- **インフラ:**
  - **ホスト**: Windows 11 Pro
  - **ゲストVM**: Ubuntu (Hyper-V)
  - **通信**: Git for Windows 付属 ssh.exe(Stdio安定性確保のため)

## システムアーキテクチャ

```
┌─────────────────────────┐
│   Claude Desktop        │
│  (LLM + UI + MCP Client)│
└────────┬────────────────┘
         │
    SSH (stdio)
         │
┌────────▼────────────────────────────┐
│   Windows 11 Pro                     │
│   Git for Windows ssh.exe            │
│   (MCP Stdio通信の安定化)            │
└────────┬─────────────────────────────┘
         │
    SSH HostKey Auth
         │
┌────────▼─────────────────────────────┐
│   Ubuntu VM (Hyper-V)                 │
│  ┌──────────────────────────────────┐ │
│  │  MCP Memory Server               │ │
│  │  - Python 3.12                   │ │
│  │  - Tool定義(save_draft等)      │ │
│  │  - 状態遷移・トランザクション制御 │ │
│  └──────────────────────────────────┘ │
│  ┌──────────────────────────────────┐ │
│  │  SQLite (memory.db)              │ │
│  │  - WAL mode                      │ │
│  │  - FTS5 全文検索                 │ │
│  └──────────────────────────────────┘ │
└──────────────────────────────────────┘
```

## アーキテクチャ設計原則

### 1. データライフサイクル管理
単なるメモ書きではなく、データ整合性を重視した設計を採用。

**ステータス管理:**
- `draft`: 一時保存状態(ユーザーが確認・修正可能)
- `final`: ユーザー承認による確定状態(参照の正式ルール)

**Supersede(履歴管理):**
古い決定事項を `obsolete` としつつ、新旧の関連性をリンク。いつ、何に基づいて変更されたかを追跡可能にした。

**物理ガード:**
Pythonレイヤーでのトランザクション制御により、並行アクセスやデータ破壊を防止。
(SQLiteによる制約対応のため)

### 2. SSH通信の安定化
SSHクライアントの依存性:
Windows標準の ssh.exe を使用した場合、通信が不安定となり
`Server disconnected` が頻発する現象を確認した。

**解決策:**
Stdio(標準入出力)のハンドリングに定評のある
Git for Windows 付属の ssh.exe に切り替えることで、
通信エラー率を 0% に改善した。

**考察:**
本事象は、プログラム間通信における標準入出力の
バッファリングや改行コード処理の差異が影響している
可能性があると考えられる。

### 3. 暗黙的判断の排除設計
MCPツール呼び出しのトリガーを明示的に設計し、LLMの自律判断による誤発火を防止。

**実装:**
- カスタム指示 で「ユーザーの明示的な命令がない限りツールを呼ばない」と指示
- ただしこれは、コンテキスト量の増大に伴い機能しないことが判明

## 技術的な成果と学習

### 1. Windows環境でのMCP実装基盤の構築
**課題:**
Windows 11からLinux VMへのセキュアなMCP通信構築。MCPはmacOS/Linux環境での資料が主流。

**実装内容:**
- Windows標準ssh ではなく、Git for Windows版sshの採用
- パスフレーズなし秘密鍵による非対話認証運用
- SSH接続設定に明示的なオプション(-T, -o BatchMode=yes等)を指定

**得られた知見:**
Windows-Linux間のプロセス間通信では、OS差異による予期しない出力や挙動が stdio 形式の通信を破損させるため、事前の入出力制御が不可欠であることを確認。

### 2. メモリシステムの状態遷移設計
ステートマシン的なデータ管理パターンを採用し、draft / final / obsolete の状態遷移と、
Supersede による意思決定の変更履歴を追跡可能とした。

**学習:**
- 単純なCRUD操作ではなく、「情報の経年変化を記録する」ことの重要性
- 過去データを削除するのではなく「obsolete マーク + 新旧リンク」による追跡可能性の確保

## 概念実証完了による凍結判断

本PoCの結果、インフラおよび通信プロトコルの確立には成功しましたが、**実運用における信頼性とユーザー体験(UX)**に課題があることが判明したため、開発を一時凍結しました。

### 凍結に至った課題1: 暗黙的トリガーの不安定性
LLMが日常会話から「これは保存すべき重要な決定事項だ」と自律的に判断する境界線が曖昧。

**実装での観察:**
- **過検知**: 意図しないタイミングでツール発火(ノイズ)
- **検知漏れ**: 重要な情報の見落とし
- カスタム指示 による制御も、コンテキスト量増加に伴い無視される傾向

**判断:**
LLMの自律判断に依存する設計は、安定性を欠く。

### 凍結に至った課題2: Project カスタム指示 の限界
「明示的な指示があるまでツールを呼ぶな」というメタ指示が機能せず、LLMが「良かれと思って」ツール呼び出しを行うケースが確認された。

**示唆:**
指示によるLLMの完全制御は困難。システムレベルでの強制が必要。

### 凍結に至った課題3: 投資対効果(ROI)の分析
現実装では、保存時に常にユーザーの明示的な命令とダブルチェックを必要とする。

**比較:**
- **提案システムの手間**: 「これは保存ですか?」「修正点はありますか?」等の確認ループ
- **代替案の手間**: チャットログを検索、以前の決定を手作業で参照

**判断:**
システム導入による効率化が、コスト(実装・運用・学習コスト)を上回らない。

### 判断プロセス
- PoC段階での技術的成功を、そのまま本番運用に延長しない判断
- ROI分析に基づく中止判断(「要件を満たさない」という客観的結論)

## 検証から得られた設計原則

### 課題1: 暗黙的トリガーの不安定性(過検知・検知漏れ)
**設計原則:**
LLMの自律判断は最小化し、状態遷移(draft/final/obsolete)はサーバー側で保証する

---

### 課題2: Project カスタム指示 の限界(指示による制御の破綻)
**設計原則:**
メモリは「ユーザーの指示に従う要約」ではなく、正規化された意思決定として管理する

---

### 課題3: 投資対効果(ROI)の不成立(技術的成功 ≠ 実運用価値)
**設計原則:**
上記原則を技術的に満たしても、UX・運用負荷を含めたROI分析が不十分な場合は、本番導入を見送る判断を優先する

## ファイル構成
```
memory_mcp/
├── server.py             # MCPサーバー本体(ツール定義・Tool実装含む)
├── memory_db.py          # SQLiteデータベース操作・状態遷移管理
├── extractors.py         # 会話ログからの自動提案抽出ロジック
├── config.py             # 定数・キーワードマップ・判定ルール定義
├── requirements.txt      # 依存パッケージ (mcp>=0.9.0)
├── data/
│  ├── memory.db          # SQLiteデータベース (WAL mode)
│  └── logs/              # 会話ログ (JSONL形式)
└── README.md             # このファイル
```

## セットアップ(参考)

### 1. Ubuntu VM上でのMCPサーバー起動
```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python server.py
```

### 2. Claude Desktop 設定
claude_desktop_config.json に MCP接続情報を記述(SSH接続詳細)

### 3. SSH秘密鍵の配置
```bash
ssh-keygen -t ed25519 -f ~/.ssh/mcp_key -N ""
# パスフレーズなし運用(プログラム間通信の安定性確保)
```

## 今後の展開可能性
- **モデル性能の向上**: より精度の高い自動検知が可能になれば、再検討の余地あり
- **サーバー側の厳格化**: LLM判断を排し、ユーザー操作の明示的なUI実装(タグ付け等)
- **他プロジェクトへの応用**: 凍結中も、得られた技術知見は他のMCP統合に活用可能