Skip to main content
Glama
densuke
by densuke
README.md
# fuga-memory

Claude Code(および他の LLM)向け長期記憶 MCP サーバー。

会話内容を SQLite に保存し、FTS5(全文検索)+ ベクトル検索(ruri-v3-310m)のハイブリッド検索で関連する記憶を呼び出します。

## 特徴

- **外部依存なし**: 全データを SQLite 単一ファイルに格納
- **ハイブリッド検索**: FTS5 キーワード検索 + ベクトル検索を RRF で統合
- **時間減衰**: 古い記憶のスコアを半減期 30 日で段階的に低下
- **軽量推論**: ONNX バックエンドで ruri-v3-310m を CPU で動作
- **MCP 対応**: Claude Code / Gemini / Copilot など複数 LLM で共有可能
- **自動保存**: Claude Code の Stop フックでセッション終了時に自動保存

## セットアップガイド

- [Claude Code での設定 (CLAUDE.md)](CLAUDE.md)
- [Gemini CLI での設定 (docs/gemini-guide.md)](docs/gemini-guide.md)

---

## クイックスタート

### 1. インストール

```bash
git clone https://github.com/densuke/fuga-memory
cd fuga-memory
uv sync
```

> **初回起動時**: ruri-v3-310m モデルを自動ダウンロードし ONNX 形式に変換します(約 600MB・数十秒)。変換済みモデルは `~/.local/share/fuga-memory/onnx_cache/` にキャッシュされるため、2回目以降は高速に起動します。

### 2. 設定ファイルを配置(任意)

デフォルト設定のまま使う場合はスキップできます。カスタマイズしたい場合はテンプレートをコピーします。

```bash
# macOS
mkdir -p ~/Library/Application\ Support/fuga-memory
cp config.toml.example ~/Library/Application\ Support/fuga-memory/config.toml

# Linux
mkdir -p ~/.config/fuga-memory
cp config.toml.example ~/.config/fuga-memory/config.toml
```

### 3. Claude Code に登録

`~/.claude/settings.json` を開き、以下を追加します(`/path/to/fuga-memory` は実際のパスに変更してください)。

Stop フックによる自動保存も使う場合は `hooks` セクションをそのまま含めてください。使わない場合は `hooks` セクションを削除してください。

```json
{
  "mcpServers": {
    "fuga-memory": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/fuga-memory", "fuga-memory", "serve"]
      //                            ^^^^^^^^^^^^^^^^^^^^ クローン先の絶対パスに変更
    }
  },
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "uv run --project /path/to/fuga-memory fuga-memory save --stdin --session-id \"${CLAUDE_SESSION_ID:-unknown}\" --source claude_code",
            //                            ^^^^^^^^^^^^^^^^^^^^ 同上
            "timeout": 60
          }
        ]
      }
    ]
  }
}
```

### 4. 動作確認

Claude Code を再起動すると MCP ツールが有効になります。Claude に話しかけてみてください。

```
あなたはfuga-memoryの search_memory ツールを使えます。
「Python の asyncio について」と検索してみてください。
```

---

## MCP サーバーの仕組み

`fuga-memory serve` は **stdio transport** で動作します。

```
Claude Code ←─ stdin/stdout ─→ fuga-memory serve (子プロセス)
```

**ポイント:**

- Claude Code が `mcpServers` の設定を読み、**必要に応じて自動でプロセスを起動・停止**します
- 常駐サーバーを手動で立ち上げておく必要はありません
- HTTP ポートも使用しません

### Stop フックでの自動保存の仕組み

```
セッション終了
    ↓
Claude Code が Stop フックを実行
    ↓
fuga-memory save --stdin --session-id <id>  (短命な1回限りのプロセス)
    ↓
SQLite に保存完了
```

Stop フックは MCP サーバーとは独立して動作します。フックが走るときに MCP サーバーが起動している必要はありません。

---

## Claude Code での使い方

MCP ツールが有効になると、以下の 3 つのツールが使えるようになります。

### save_memory — 記憶を保存

```
save_memory(content="今日Pythonのasyncioを勉強した", session_id="my-session")
```

| 引数 | 型 | 説明 |
|------|----|------|
| `content` | str | 保存するテキスト(必須) |
| `session_id` | str | セッション識別子(必須) |
| `source` | str | ソース識別子(デフォルト: `"manual"`) |

### search_memory — 記憶を検索

```
search_memory(query="Pythonの非同期処理", top_k=5)
```

| 引数 | 型 | 説明 |
|------|----|------|
| `query` | str | 検索クエリ(必須) |
| `top_k` | int | 返す最大件数(デフォルト: 5) |

返り値: `[{"id", "score", "content", "session_id", "source", "created_at"}, ...]`(score 降順)

### list_sessions — セッション一覧

```
list_sessions(limit=20)
```

返り値: `[{"session_id", "memory_count", "last_updated"}, ...]`

---

## CLI リファレンス

MCP 経由ではなく、コマンドラインから直接操作できます。

### serve — MCP サーバーを起動

```bash
uv run fuga-memory serve
uv run fuga-memory --debug serve   # ライブラリ警告を抑制しないデバッグモード
```

通常は手動で起動する必要はありません。Claude Code が自動で管理します。
他の MCP クライアント(Gemini CLI 等)と接続する場合や動作確認時に使用します。

### search — 記憶を検索

```bash
uv run fuga-memory search "Rustのlifetimeについて"
uv run fuga-memory search "Python" --top-k 10
```

### save — 記憶を保存

3 種類の入力方式があります。

```bash
# 引数として直接渡す
uv run fuga-memory save "今日学んだこと" --session-id my-session

# ファイルから読み込む
uv run fuga-memory save --file notes.txt --session-id my-session

# 標準入力から読み込む(パイプ)
echo "パイプで渡す内容" | uv run fuga-memory save --stdin --session-id my-session
cat transcript.txt | uv run fuga-memory save --stdin --session-id my-session
```

---

## 設定

### 設定ファイル(推奨)

以下の順で探索し、最初に見つかったものを使用します。

| 優先度 | OS | パス |
|--------|-----|------|
| 1 | macOS | `~/Library/Application Support/fuga-memory/config.toml` |
| 2 | Linux / 共通 | `$XDG_CONFIG_HOME/fuga-memory/config.toml`(未設定時: `~/.config/fuga-memory/config.toml`) |
| 3 | 共通 | `~/.fuga-memory.toml` |

**テンプレートから作成:**

```bash
cp config.toml.example ~/.config/fuga-memory/config.toml  # Linux
cp config.toml.example ~/Library/Application\ Support/fuga-memory/config.toml  # macOS
```

**設定例:**

```toml
[fuga-memory]
db_path = "~/.local/share/fuga-memory/memories.db"
decay_halflife_days = 14   # 記憶の半減期を2週間に変更
default_top_k = 10
```

### 環境変数

設定ファイルより優先されます。Docker / CI など、ファイル配置が難しい環境向けです。

| 変数 | デフォルト | 説明 |
|------|-----------|------|
| `FUGA_MEMORY_DB_PATH` | `~/.local/share/fuga-memory/memories.db` | DB ファイルパス |
| `FUGA_MEMORY_MODEL_NAME` | `cl-nagoya/ruri-v3-310m` | 埋め込みモデル |
| `FUGA_MEMORY_THREAD_WORKERS` | CPU 数 ÷ 2 | 推論スレッド数 |
| `FUGA_MEMORY_RRF_K` | `60` | RRF の k パラメータ |
| `FUGA_MEMORY_DECAY_HALFLIFE_DAYS` | `30` | 時間減衰の半減期(日) |
| `FUGA_MEMORY_DEFAULT_TOP_K` | `5` | デフォルト検索件数 |
| `FUGA_MEMORY_DAEMON_PORT` | `18520` | デーモンの待ち受けポート |
| `FUGA_MEMORY_DAEMON_IDLE_TIMEOUT` | `600` | デーモンのアイドル自動終了(秒) |
| `FUGA_MEMORY_ONNX_CACHE_DIR` | `~/.local/share/fuga-memory/onnx_cache` | ONNX キャッシュディレクトリ |
| `FUGA_MEMORY_DEBUG` | `false` | デバッグモード(警告を抑制しない) |

詳細は `.env.example` を参照してください。

### 優先順位

```
デフォルト値  <  設定ファイル  <  環境変数
```

---

## データの場所

| 項目 | デフォルトパス |
|------|--------------|
| DB ファイル | `~/.local/share/fuga-memory/memories.db` |
| ONNX キャッシュ | `~/.local/share/fuga-memory/onnx_cache/` |
| モデルキャッシュ | `~/.cache/huggingface/` |

DB ファイルは SQLite 単一ファイルです。バックアップは `cp memories.db memories.db.bak` で行えます。

---

## 技術スタック

- Python 3.13, uv, fastmcp
- SQLite + FTS5(trigram トークナイザ)+ sqlite-vec
- sentence-transformers + cl-nagoya/ruri-v3-310m(ONNX バックエンド)
- ThreadPoolExecutor + asyncio

## インスピレーション

このプロジェクトは、noprogllama 氏による Zenn 記事

**[Claude Codeに長期記憶を持たせたら、壁打ちの質が変わった](https://zenn.dev/noprogllama/articles/7c24b2c2410213)**

にインスパイアされて開発しました。

同記事では、SQLite 単一ファイルへの格納、FTS5 + ベクトル検索のハイブリッド化、RRF による統合、時間減衰スコアリングといった設計思想が紹介されています。fuga-memory はこれらのアイデアを出発点として、Python + fastmcp による実装、セキュリティ強化、設定の柔軟化などを加えた独自の実装です。

優れた設計思想を公開してくださった noprogllama 氏に感謝します。

---

## ライセンス

MIT

TDQS

A4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: save, search, list sessions, and delete. No overlap or ambiguity in their functionalities.

Naming Consistency5/5

All tool names follow the consistent verb_noun pattern (save_memory, search_memory, list_sessions, delete_memory), enhancing predictability.

Tool Count4/5

With 4 tools, the set is slightly minimal but covers core memory operations. A few more tools like update or get-by-id could be added, but the current count is reasonable for the domain.

Completeness3/5

Missing update and direct retrieval by ID are notable gaps; however, search serves as a retrieval mechanism. The surface covers create, read (via search), and delete, with list_sessions providing session management.

Maintenance

ActivityInactive
ResponsivenessNo issues