MemPersist について
MemPersistは、AI会話の記憶を永続保存し、指定リビジョンに固定して検索できるリモートMCPサーバーです。正規アーカイブと再構築可能なインデックスを分離し、ChatGPTエクスポートの取り込みと明示的な書き込みに対応します。
主な機能
- 01正規会話アーカイブの永続保存
- 02ChatGPTエクスポートの取り込み
- 03ハイブリッド検索
- 04リビジョン固定の読み取りとコンテキスト
- 05原子的なリビジョン検証付き書き込み
活用シーン
- 01過去の会話から関連情報を検索
- 02ChatGPTの会話履歴を取り込んで検索
- 03選択した会話からコンテキストを構成
- 04リビジョンを検証してキー付きメッセージを保存
MCP 対応
ステートレスなStreamable HTTPを通じて、検索、コンテキスト構成、会話・メッセージの読み取り、インポート、リビジョン検証付き書き込みをMCPクライアントに提供します。OAuth 2.1とPKCEに対応します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://mempersist.codifiedtech.id/mcpclaude mcp add --transport http ravhirizaldi-mempersist https://mempersist.codifiedtech.id/mcp{"mcpServers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}Cursor で開く{"servers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}VS Code で開く{"mcpServers":{"ravhirizaldi-mempersist":{"type":"http","url":"https://mempersist.codifiedtech.id/mcp"}}}{"mcpServers":{"ravhirizaldi-mempersist":{"serverUrl":"https://mempersist.codifiedtech.id/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
MemPersist
Cloudflare 上で完全に動作する、AI との会話のための長期記憶です。ChatGPT のオリジナルのエクスポートと正規化された会話グラフは R2 に保存され、D1 のカタログからクエリできるようになっています。語彙インデックスと意味インデックスは破棄可能な状態で維持され、MCP は簡潔な検索と意図的な書き込みを提供します。
| MCP エンドポイント | https://mempersist.codifiedtech.id/mcp |
| レジストリ | io.github.ravhirizaldi/mempersist — バージョン 1.0.1 |
| ランタイム | Workers、D1、R2、Queues、Workers AI(BGE-M3)、Vectorize、OAuth KV |
| プロトコル | ステートレスな Streamable HTTP 上の MCP v2、PKCE S256 による OAuth 2.1 |
| スコープ | 単一オペレーター向け V1、Worker 1 つ、TypeScript パッケージ 1 つ |
できること。 アップロードされたすべての ChatGPT エクスポートをバイト単位でそのまま保持し、分岐とノードのメタデータをリビジョン固定の正規 JSONL に正規化し、派生した FTS データとベクトルデータをインデックス化して、決定的な ID を使った検索、コンテキスト取得、一括読み取りに応答します。書き込みは明示的に行われ、リビジョンを確認したうえで、インデックス作成をキューに登録する前に永続化されます。
行わないこと。 ChatGPT のトラフィックを傍受したり、代替の「事実」を抽出したり、モデルで要約したり、インデックスを正規データとして扱ったりしません。課金、組織、投機的なマルチテナント機能はありません。また、Durable Objects、Workflows、cron トリガー、コンテナも使用しません。すべてのチャンク、FTS 行、ベクトルを削除しても、記憶は削除されません。「無制限」とは、アプリケーションレベルのメッセージ数の上限がないという意味であり、Cloudflare の制限と課金は引き続き適用されます。
アーキテクチャ
flowchart TD
IMP["ChatGPT data export (conversations.json)"] --> V
WRITE["MCP writes from any client"] --> V
V["Validation and stable IDs"] --> R2[("R2 canonical archive<br/>raw import + immutable revisions")]
R2 --> D1[("D1 catalog<br/>imports, revisions, graph, R2 pointers")]
D1 --> Q["Cloudflare Queues<br/>import and index jobs"]
Q --> FTS[("D1 FTS5<br/>lexical chunks")]
Q --> AI["Workers AI BGE-M3"] --> VEC[("Vectorize<br/>embeddings")]
FTS --> SEARCH["Normalized hybrid search<br/>plus recent-canonical fallback"]
VEC --> SEARCH
SEARCH --> OUT["HTTP API and OAuth-protected MCP"]
R2 --> EXPORT["Lossless export and recovery"]
取り込み経路は 2 つあり、互いに独立しています。ChatGPT データエクスポートパーサーが受け付けるのはネイティブの conversations.json 形式のみです。一方、書き込みは呼び出し元が使用するクライアントから MCP 経由で行われます。どちらも同じ正規リビジョンモデルに集約されるため、ツール呼び出しで作成された記憶も、エクスポートからインポートされた記憶も、同じように読み取り、固定し、復元できます。
R2 が信頼できる唯一のデータソースです。正規データの書き込みが完了してからインデックス作成ジョブがキューに登録されるため、インデックス作成に失敗しても、永続化された記憶が失われたとは報告されません。再構築時には R2 から読み取るため、エクスポートを再アップロードする必要はありません。詳しくは ARCHITECTURE.md と docs/storage-and-indexing.md を参照してください。
クイックスタート
yarn install
cp .dev.vars.example .dev.vars # set a long random MEMORY_API_TOKEN
yarn types:bindings
yarn db:migrate:local
yarn dev
WSL2/Linux、Node.js 22 以降、Yarn 1.22、および yarn wrangler whoami で認証済みの Wrangler 4.x が必要です。Yarn のみを使用してください。ローカルの D1、R2、KV、Queues はシミュレートされます。メイン設定の Workers AI と Vectorize は実際のリモートバインディングを参照しますが、単体テストと統合テストからリモート AI が呼び出されることはありません。
あらゆる MCP クライアントに接続
MemPersist は標準的なリモート MCP サーバーです。ステートレスな Streamable HTTP を
https://mempersist.codifiedtech.id/mcp で提供し、OAuth 2.1 認可コードフローと PKCE S256、スコープ
memory を使用します。エンドポイントにクライアント固有の要素はありません。同じハンドシェイク、ツールの契約、サーバーの指示がすべての呼び出し元に適用されます。クライアントに URL を指定すれば動作します。
| クライアント | 追加方法 |
|---|---|
| Claude Code | claude mcp add --transport http mempersist https://mempersist.codifiedtech.id/mcp を実行し、続いてメールのプロンプトを完了します |
| Codex CLI、ChatGPT desktop、IDE extension | ~/.codex/config.toml(またはプロジェクトの .codex/config.toml)を設定し、続いて codex mcp login mempersist を実行します |
| Cursor、Claude Desktop、VS Code、Zed | クライアントの MCP 設定で URL をリモート(HTTP)MCP サーバーとして追加します。クライアントが OAuth フローを開始します |
| ChatGPT | 開発者モードにしてから、URL をカスタム MCP アプリとして追加します |
| MCP Inspector、カスタム SDK クライアント | npx @modelcontextprotocol/inspector、または公式 SDK クライアントを使用します。URL と OAuth または開発者トークンを指定します |
| stdio 専用クライアント | サーバーはリモートのままにし、OAuth 対応プロキシで stdio を HTTP にブリッジします。MemPersist 自体に npx は不要です |
Codex の設定:
[mcp_servers.mempersist]
type = "remote"
url = "https://mempersist.codifiedtech.id/mcp"
# auth = "oauth" is the default; run `codex mcp login mempersist` to authorize
クライアントは 401 チャレンジから OAuth を検出し、同意ページを開いて、発行されたアクセス・トークンとリフレッシュ・トークンを保存します。同意ページでメールアドレスを入力すると、EMAIL バインディングを通じて1回限りの有効期間15分のマジックリンクが送信されます。そのリンクを開くと接続が完了し、既存のメールアドレスで再接続すると、そのアーカイブに接続します。スコープは memory のみです。送信者アドレスは設定項目(AUTH_EMAIL_FROM、LEGACY_AUTH_EMAIL_FROM)であり、API 契約には含まれません。コネクターに MEMORY_API_TOKEN を貼り付けないでください。
すでに設定済みの接続は、再認証なしでアップグレード後も引き続き機能します。従来のホスト名も引き続きサポートされ、1つのクライアントをプライマリホスト名に移行する際に必要な追加認証は、ちょうど1回です。
開発者トークン
スクリプト、CLI、非対話型の自動化では、OAuth の代わりに
Authorization: Bearer <MEMORY_API_TOKEN> を送信できます。この場合、常に所有者のアーカイブにマッピングされます。各アカウントは複数の名前空間を所有できます。同じ名前空間名でも、アカウントが異なれば別のデータです。指定された namespace が適用されるのは、呼び出し元がその名前空間を所有している場合のみです。
デプロイせずにローカルで実行
MCP のオーディエンスはデプロイ設定なので、開発サーバーが自身を参照するように設定します。
yarn dev --local --port 8787 --local-protocol https \
--var MCP_ORIGIN_OVERRIDE:https://127.0.0.1:8787
検出、同意、トークンのオーディエンスには https://127.0.0.1:8787 が使用され、.dev.vars の開発者トークンと OAuth フロー全体の両方が機能します。ローカルの send_email は各マジックリンクを .wrangler/tmp/email/<id>/email-text/ に書き込みます。
docs/development.md を参照してください。
ツール
24個のツールがあり、それぞれに人が読めるタイトルと、読み取り専用または破壊的操作を示すアノテーションが付いています。まず取得し、選択したものだけを展開してください。
読み取り
| ツール | タイトル | 備考 |
|---|---|---|
memory_search | メモリーを検索 | ハイブリッド検索、1~20件の参照。フィルターと不透明なカーソルによるページネーション |
memory_get_context | メモリーのコンテキストを取得 | 1つの結果チャンクの前後最大10件の正規メッセージ |
memory_get_conversation | 会話を取得 | 1件の会話のアクティブなタイムラインまたは完全なグラフをページ単位で取得 |
memory_get_messages | メッセージを取得 | 正確なソースノードまたはオプションのキー指定による検索。リビジョン固定の順序付き一括取得。不透明なカーソルとバイト予算に対応 |
memory_get_conversations | 会話を取得 | 1~20件の会話をリビジョン固定で一括読み込みし、カーソルでページ分割 |
memory_list_conversations | 会話を一覧表示 | メタデータとタグのみ。本文は含まれません |
memory_list_revisions | リビジョンを一覧表示 | 不変のリビジョン履歴を新しい順に表示 |
memory_resolve_conversations | 会話を解決 | タイトルの完全一致検索。セマンティック検索は行いません |
memory_list_namespaces | 名前空間を一覧表示 | 所有する名前空間と会話数 |
memory_stats | メモリー統計を取得 | 名前空間ごとの件数とインデックス作成の健全性 |
memory_import_status | インポート状況を取得 | インポートの進行状況、重複、または失敗 |
memory_get_capabilities | 機能を取得 | デプロイ済みの仕様:バージョン、上限、ツールごとの制限、および message_keys / atomic_multi_conversation_commit 機能フラグ |
memory_get_messages は、順序付きセレクターを1~100件受け付けます。各セレクターは
conversation_id を指定し、必要に応じて revision_id を固定し、
source_node_id(最大200文字)または前方互換性のある message_key
(小文字の ASCII 英字、数字、.、_、/、- の1~128文字で、英字または数字で始まり、
終わるもの)のいずれか一方を使用します。リビジョンを省略した場合は、
正規の R2 本文を読み込む前に、各会話の現在のヘッドが固定されます。正規本文の読み込みは
固定された一意のリビジョンごとに重複排除されますが、重複するセレクターは順序付きの結果に重複して保持されます。
読み取り専用の検索では FTS や Vectorize は使用しません。存在しない、別の所有者に属する、削除済み、または
不明な会話、リビジョン、ノード、キーには、同じ上限付きの NOT_FOUND 結果が返されます。
正規メッセージキーが重複している場合は、上限付きの正規ストレージエラーが返され、どちらか一方を選んで解決することはありません。
メッセージ全体は、デフォルト32 KiB、最小4 KiB、最大48 KiBの
シリアライズ済み予算内で読み込まれます。サイズ超過のメッセージは切り詰められず、上限付きの識別情報/バイト数の診断情報のみが返されます。続きの取得には、
セレクターの順序とリビジョンの固定を保持する、不透明で HMAC 署名付きのテナント紐付けカーソルを使用します。
省略可能な message_key セレクターは、memory_upsert_messages(およびそれらを含む正規データ)によって書き込まれたキー付きフィールドを読み取ります。memory_upsert_messages は論理レコード用の安定キー書き込みツールです。その仕様については、以下の「書き込み」セクションで説明します。
コンテキストの組み立て
| ツール | タイトル | 備考 |
|---|---|---|
memory_build_context | メモリーコンテキストを構築 | 必須の1~20件の会話と省略可能なハイブリッドエビデンスから作成する、決定的でリビジョン固定のパック。トークン数とバイト数の予算を明示できます |
書き込み
各書き込みは、インデックス作成と検証のステータスを分けた、サイズ上限のある永続的なレシートを返します。また、verify: true を指定すると、コミットされた R2 リビジョンを再読み込みします。memory_commit_batch は、異なる会話に対する1~20件の追加または完全置換操作を、同一アカウント内の単一のアトミックなコミットで適用します。各操作では base_revision_id を明示する必要があります。
memory_upsert_messages は、所有する1つの会話に対して、キー付きテキストメッセージを1~100件受け付けます。すべてのリクエストで base_revision_id とロールが必要です。キーは、[a-z0-9._/-] に一致し、英字または数字で始まり、英字または数字で終わる、長さ1~128文字の小文字 ASCII 文字列である必要があります。既存のキーは、ソース ID、ロール、作成時刻、グラフ、メタデータを維持したままテキストを置き換えます。ロールが一致しない場合は拒否されます。キーが存在しない場合は、サーバー ID とタイムスタンプを付与し、リクエストの順序で追加します。1つのアトミックなリビジョンがコミットされる前に、すべてのエントリーが検証されます。変更のないエントリーのみのリクエストは、リビジョンもインデックスジョブも作成せずに no_change を返します。新規挿入、更新、変更なしのエントリーが混在する場合は、1つのリビジョンが作成されます。verify: true を指定すると、コミットされた正規リビジョンが確認され、永続的なレシートにキーごとの結果が報告されます。インデックス作成は、ヘッドの遷移が成功した後にのみ開始されます。
デプロイ済みの機能レスポンスでは、features.message_keys: true が通知されます。
同じ冪等性キーと内容でバッチを再実行すると、リビジョンやジョブを重複して作成せず、既存の結果が返されます。使用済みのキーで内容を変更すると競合が発生し、古い操作が1つでも含まれていると、バッチ内のすべての操作がコミットされません。所有する名前空間は1つのバッチ内で混在させることができますが、アカウント間は分離されます。
| ツール | タイトル | 備考 |
|---|---|---|
memory_store | メモリーを保存 | 意図的な新規メモリー。最初の書き込みで、指定した名前空間の所有権を取得します |
memory_upsert_messages | キー付きメッセージをアップサート | 正確なキーに基づき、1~100件をアトミックに挿入・更新・変更なしとして処理。ベースリビジョン必須 |
memory_append | メモリーを追加 | base_revision_id を指定して会話を続けます |
memory_replace | メモリーを置換 | ID とタグを維持して、完全なトランスクリプトで置き換えます |
memory_commit_batch | メモリーバッチをコミット | ベースリビジョンを明示して、1~20件の会話をアトミックに追加・置換します |
memory_edit_messages | メモリーメッセージを編集 | 既知のソースノードを1~100件その場で編集します。構造化コンテンツは拒否されます |
memory_restore_revision | メモリーリビジョンを復元 | リビジョンを重複作成せずに、ヘッドを過去のリビジョンに戻します |
memory_copy_conversations | 会話をコピー | 別の所有する名前空間に R2 データを損失なくコピーします。冪等性キーで管理します |
memory_update_tags | メモリータグを更新 | 楽観的同時実行制御のもとでタグを追加または削除します |
管理
| ツール | タイトル | 備考 |
|---|---|---|
memory_delete_conversations | 会話を削除 | 厳密な確認後、正規データと派生データを合わせて最大100件削除します |
memory_empty_namespace | 名前空間を空にする | 厳密な確認後、上限付きで再開可能な一括削除を行います |
再試行、再インデックス、整合性確認のコマンドは、モデルが高コストのメンテナンスを実行できないよう、HTTP/CLI のみで利用できます。ツールの完全な仕様、レシート、一括処理のセマンティクスについては、docs/mcp.md を参照してください。
検索のページネーション
最初の memory_search 呼び出しでは query が必須です。limit(1~20、既定値は8)、任意の namespace、tags、tag_mode(all または any)、および任意の max_serialized_bytes を指定できます。バイト数の上限は既定で32 KiB、4~48 KiBの範囲で指定できます。レスポンスには next_cursor が含まれる場合があります。続けるには、その不透明なカーソル、次の limit、およびバイト数の上限を指定してください。続きのリクエストでは、クエリを再送信したり、フィルターを変更したりしないでください。
ページネーションを要求しない互換性レスポンスでは、ページネーション専用のメタデータが省略される場合があります。
検索カーソルは、短期間有効なテナントに紐づくスナップショットを識別します。スナップショットには最初の呼び出し時の正確なランキング、スコア、順序が保持され、各結果のリビジョンが固定されます。また、元の degraded および unavailable 診断情報も引き継がれます。そのメタデータには、ランキングのバージョン、候補数と上限、作成時刻と有効期限、および上限付きの省略件数と理由が記録されます。期限切れのカーソルは、読み取り時にクリーンアップされます。不正なカーソル、偽造されたカーソル、期限切れのカーソル、互換性のないカーソル、またはアカウントをまたぐカーソルには、上限付きの検証エラーが返されます。カーソルから内部ストレージやアカウントの識別子が漏れることはありません。
検索対象は認証済みアカウントに限定されます。名前空間フィルターには、そのアカウントが所有する名前空間のみ指定できます。フィルターを省略すると、アカウントが所有する名前空間が検索されます。削除済み、古い、または所有権を失ったスナップショット候補は、スナップショットの置き換えや他のアカウントのデータの公開を行わず、安全な上限付き診断情報とともに除外されます。検索カーソルは、MCP/HTTP の検索ページネーション専用です。エクスポートや正規読み取り用のカーソルではありません。
制限
memory_get_capabilities が唯一の仕様です。各トランスポートが適用する定数を報告するため、記載値と実際の適用値に食い違いが生じません。デプロイ済みの値は次のとおりです。
| 制限 | 値 |
|---|---|
| MCP ツール出力ガード | 65,536バイト(64 KiB) |
| 推奨されるツール出力/レシートの上限 | 49,152バイト(48 KiB) |
| 両トランスポートでのインライン JSON 書き込み | 1,048,576バイト(1 MiB) |
| 直接インポートの本文および各マルチパート部分 | 16,777,216バイト(16 MiB) |
| 単一メッセージの内容 | 1,000,000文字 |
| 一括会話読み取りレスポンス | 既定値32 KiB、最大48 KiB |
| 検索レスポンス | 既定値32 KiB、最小4 KiB、最大48 KiB |
| 完全一致メッセージ検索レスポンス | 既定値32 KiB、最小4 KiB、最大48 KiB |
合計上限は、正規処理を行う前に測定した、リクエスト全体をシリアライズした UTF-8 バイト数です。上限を超えるリクエストでは何も書き込まれず、保守的な suggested_max_items の推定値とともに REQUEST_TOO_LARGE(retryable: false)エラーが返されます。黙って切り詰められることはありません。
ChatGPT インポート
ChatGPT からデータをエクスポートし、conversations.json を展開してから、次を実行します。
MEMPERSIST_URL=http://localhost:8787 \
MEMPERSIST_TOKEN='your-token' \
yarn import:chatgpt /path/to/conversations.json
MEMPERSIST_TOKEN='your-token' yarn import:status <import-id>
アップロードされたバイト列は変更されずに保存され、サーバー側でハッシュ化されます。完全に重複するデータには
duplicate のマークが付けられ、再処理されることはありません。キューの1ターンでは、序数チェックポイントから
25件の会話を処理するため、安全に再試行して再開できます。大きなファイルには R2 のマルチパートアップロードを使用します。不明な
フィールド、別のブランチ、グラフの異常は復元可能な状態で保持されます。詳しくは
docs/chatgpt-import.md をご覧ください。
ダッシュボード
/login を開くと、パスワード不要でサーバー描画のダッシュボードにアクセスできます。アーカイブの合計、決定論的なメモリマップ、リビジョン固定の正規版の閲覧、
表示名の編集、ロスレスなストリーミングエクスポートを利用できます。名前空間の消去は非同期で実行されます。アカウントの削除には7日間の
取り消し可能な猶予期間があり、削除が保留中の間は書き込みが読み取り専用になります。フロントエンドフレームワークや追加の
Cloudflare リソースは必要ありません。詳しくはdocs/dashboard.md と
ADR 0028 をご覧ください。
公開サイト、OAuth ページ、マジックリンクメールは英語とインドネシア語で利用できます。 API、MCP、CLI のコントラクトは英語のままです。
開発
yarn verify
フォーマット、バインディング型の最新状態チェック、lint、Worker と
web/mindmap/ ブラウザープロジェクトの厳格な TypeScript チェック、メモリマップのバンドルチェック、ユニットテストと MCP テスト、
Workers ランタイムでの D1/R2 統合テスト、Wrangler のデプロイのドライランを実行します。yarn deploy を実行しない限り、デプロイは行われません。web/mindmap/ 配下のファイルを編集した後は、生成されたバンドルをソースと一致させるため、
yarn build:mindmap を実行してください。
yarn admin search 'api.internal.example' # CLI search against canonical data
yarn retry <job-id> # re-run a failed import or index job
yarn reindex # rebuild derived indexes from R2
yarn verify:integrity # check catalog, R2 pointers, and revision hashes
スキーマの変更は番号付きの SQL マイグレーションとして管理し、Wrangler を通じて適用します。適用後に編集することはありません。 アーキテクチャの変更には、docs/adr/ に ADR が必要です。プルリクエストを作成する前に、 CONTRIBUTING.md と AGENTS.md をご覧ください。
ドキュメント
| ドキュメント | 内容 |
|---|---|
| ARCHITECTURE.md | システム構成、正規データと派生データ、書き込み順序、検索 |
| CONTRIBUTING.md | セットアップ、変更ごとの要件、テスト、認可ゲート |
| SECURITY.md | 脅威モデル、信頼境界、制限、ローテーション、報告 |
| docs/mcp.md | ツールの契約、レシート、バッチ、機能、拒否形式 |
| docs/development.md | ローカル開発サイクル、ローカル MCP クライアント、ブラウザーページ、メモリマップクライアント |
| docs/deployment.md | プロビジョニング、移行、デプロイ、デプロイ後の確認 |
| docs/cloudflare-resources.md | 必要なリソースと手動プロビジョニング手順 |
| docs/chatgpt-import.md | インポートの保証、アップロード経路、パーサーの上限 |
| docs/dashboard.md | ダッシュボード、エクスポート、削除のフロー |
| docs/storage-and-indexing.md | 正規ストレージの構成とインデックスの世代 |
| docs/operations-and-recovery.md | 復旧手順と削除ジョブの再投入 |
| docs/rp-workflow.md | レビュー可能なランタイムルールのワークフロー |
| docs/adr/ | 意思決定ログ、新しい順 |
| docs/adr/0040-atomic-multi-conversation-commit.md | 複数会話のアトミックなコミット、リプレイ、復旧 |
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。