Verified Memory について
Verified Memoryは、検証済みメモリパックを読み取り専用で利用するための、ローカルなオフラインMCPサーバーです。チェックサムと任意のピン留め鍵による署名を検証した後、隔離されたメモリスナップショットから正確な引用付きレコードを提供します。
主な機能
- 01オフラインの読み取り専用動作
- 02チェックサムと署名の検証
- 03正確な引用付きメモリレコード
- 04隔離されたメモリスナップショット
- 05メモリパックの構築・署名ツール
活用シーン
- 01署名済みメモリパックから出典付きの事実を取得
- 02支払い情報の気付かれない改ざんを防止
- 03チャットのエクスポートからメモリパックを構築・検証
MCP 対応
stdioのMCPサーバーとして`verified_memory_search`と`verified_memory_get`のみを公開します。リソース、プロンプト、ファイルシステムツール、コマンドツールは提供しません。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
verified-memory-mcp
理由
AI エージェントが請求書の支払いをしたり、買い物をしたりするようになりつつあります。エージェントは、記憶にある支払い先に支払います。記憶された口座番号を誰かが差し替えれば、エージェントは攻撃者に支払ってしまいます。これは、店員をだます手口から AI をだます手口へと移りつつある、取引先への支払い詐欺です。
Verified Memory は、ピン留めした鍵で署名された事実だけを提供し、署名後に変更されたものはすべて拒否します。AI 攻撃者が 12 種類の改ざん攻撃(ファイルの差し替え、署名の破損、偽の時計、5,000 ファイルの大量投入、実行中のフォルダー差し替え)でレッドチームテストを行いましたが、改ざんされたデータが提供されることはありませんでした (完全なログ)。 最新リリース:Verified Memory 0.4.1。
無料の MIT ライセンスのローカル stdio MCP サーバーで、公式の
MCP TypeScript SDK
(@modelcontextprotocol/sdk 1.32.1)を使用して verified_memory_search
と verified_memory_get を公開します。npm では @python1/verified-memory-mcp
として、MCP Registry では io.github.python1/verified-memory として公開されています。
ランタイムは読み取り専用かつオフラインです。ネットワークトランスポート、ソケット、テレメトリー、 埋め込み、アカウント、ファイルシステムへの書き込み、サブプロセス、シェル実行はありません。起動時に設定済みのパックを 1 つ読み込み、分離されたメモリー内スナップショットを提供します。リクエストごとに、ファイルのメタデータのみを使ってパックのフォルダーが検証時と同じものであることを確認し、異なる場合は提供を停止します(監視機能はなく、再読み込みもしません)。標準出力には MCP プロトコルの出力のみが書き込まれます。起動エラーは標準エラー出力に書き込まれ、ゼロ以外の終了コードで終了します。公開するのはこの 2 つのツールのみです。リソース、プロンプト、ファイルシステム用ツール、コマンド用ツールはありません。
npx で実行する
npm パッケージに含まれるのは dist/、パックビルダー、この README、LICENSE のみです。パックは同梱されていないため、--pack が必須です。
npx -y @python1/verified-memory-mcp --pack /absolute/path/to/pack
Claude Code:claude mcp add verified-memory -- npx -y @python1/verified-memory-mcp --pack /absolute/path/to/pack。
npx 経由で実行しても、npx が独自の Node プロセスを起動するため、Node のアクセス許可モードは適用されません。以下で説明する読み取り専用のファイルシステム許可リストを使用するには、パッケージをインストールし、node で dist/index.js を直接実行してください。
独自のパックを作成する
パックは、records.jsonl、MEMORY.md、README.md、SHA256SUMS の 4 ファイルだけで構成されるディレクトリです。これに加えて、任意で PACK.json(作成日と有効期限)と署名 SHA256SUMS.sig
(署名付き・日付付きパックを参照)を含めることができます。最も簡単な作成方法は、同梱のオフラインビルダーを使うことです。メッセージと記憶したいレコードを読み込み、各レコードがメッセージ内にある引用をすべて見つけて、オフセットとハッシュを計算し、パックを書き出した後、サーバー独自の検証機能で読み込みます。引用がメッセージ内に一字一句そのまま存在しない場合は、何も書き込みません。
ChatGPT または Claude のエクスポートから、ブラウザーで作成する
パックメーカー(ベータ版):https://python1.github.io/data-lore-hive/。 データをエクスポートして読み込み、チャットを検索し、記憶する正確な文を選択して、すぐに使えるパックをダウンロードします。すべてブラウザー内で実行され(サーバーはなく、Content-Security-Policy によりネットワークリクエストは禁止されています)、コマンドラインビルダーと同じビルドコードを使い、ダウンロードを提示する前にサーバー独自の検証機能でパックを確認します。パックへの署名や日付の追加は行いません(下記の sign-pack を使用してください)。ただし、署名付きパックを検証パネルでは、署名付きパックと貼り付けた公開鍵に対して、同じ検証機能を実行します。ソースは web/ にあります。チェックアウトから実行するには、代わりにそこで npm install && npm run build を実行し、web/dist/index.html を開いてください。詳細は web/README.md を参照してください。
クイックスタート
-
元のメッセージを
messages.jsonlに、1行につき1つのJSONオブジェクトとして入れます。{"id": 3, "date": "2026-03-02T08:20:00Z", "speaker": "Rowan", "text": "Quick thing first: the shed code changed. Also, the café on the corner sells seedlings on Saturdays."}フィールド ルール id正の整数。一意であること dateZまたは+00:00で終わるUTCのISO 8601形式。例:2026-03-02T08:20:00Zspeaker空でない文字列 text空でない文字列。引用文はこの文字列と完全一致する必要があります -
記憶させたい内容を
records.jsonlに、1行につき1レコードとして入れます。各レコードには、 それらのメッセージからの正確な引用を記載します。{"record_id": "M-garden-3", "role": "user", "topic": "Seedlings", "category": "places", "quotes": [{"message_id": 3, "quote": "the café on the corner sells seedlings on Saturdays."}]}フィールド ルール record_idM-に続く1~127文字の英字、数字、_または-。一意であることrole"user"(本人)または"agent"(アシスタント)topic、category任意の空でない文字列 quotes{"message_id", "quote"}の空でないリスト。引用文はそのメッセージ内に逐語的に含まれている必要があります。同じ引用文が複数回ある場合は"start"を追加します(ビルダーが候補を一覧表示します)statement任意の要約。指定しない場合は、引用文をスペースで結合したものが使われます speaker任意。指定しない場合は、引用したメッセージの話者が使われます。話者が異なる場合は必須です 未知のフィールドは拒否されるため、入力ミスはすぐにわかります。
-
まだ存在しないディレクトリにビルドし、そのディレクトリをサーバーに指定します。
npx -y -p @python1/verified-memory-mcp verified-memory-build-pack \ --messages messages.jsonl --records records.jsonl \ --out /absolute/path/to/my-pack --title "My memory" --description "Optional text for the pack README" npx -y @python1/verified-memory-mcp --pack /absolute/path/to/my-packリポジトリをチェックアウトした状態で、
npm run buildの後にnode tools/build-pack.mjs ...を実行します。 ビルドのルール(逐語的な引用、コードポイント単位のオフセット、ハッシュ、ファイル構成)はtools/pack-core.mjsに記載されています。このファイルにはインポートがないため、ブラウザーでも同じコードを実行できます。 ビルダーはネットワーク呼び出しを行いません。既存の内容を上書きすることはありません。隠し兄弟ディレクトリに ステージングし、検証に合格した後にのみ配置先へ名前を変更します。
examples/input/ には、創作したサンプル入力(実在の人ではなく、架空のコミュニティガーデン)が含まれています。また、examples/pack/ はその入力からビルドされたパックです。テストスイートでは、これをバイト単位で再ビルドします。どちらもnpmパッケージには含まれません。
records.jsonl の形式(サーバーによる検証内容)
1行につき1つのJSONオブジェクトをUTF-8で記述します。レコード数は最大10,000件で、record_id は一意である必要があります。
以下のフィールドは、任意と記載されているものを除き、すべて必須です。
| フィールド | ルール |
|---|---|
record_id | ^M-[A-Za-z0-9_-]{1,127}$ |
role | "user" または "agent" |
speaker、statement、topic、category | 空でない文字列 |
date_first_utc、date_last_utc | UTCのISO 8601形式(Z または +00:00)。最初の日付 ≤ 最後の日付 |
evidence | 空でない引用のリスト(以下を参照) |
| その他すべて | 任意。保持され、verified_memory_get によってメタデータとして返されます(例:supersedes、approval、audits) |
evidence 内の各引用:
| フィールド | ルール |
|---|---|
message_id | 正の整数 |
date_utc | UTCのISO 8601形式。レコードの最初の日付から最後の日付までの範囲内 |
quote | メッセージからの空でない正確なテキスト |
start、end | 整数。start ≥ 0、end − start = Unicodeコードポイントでの引用文の長さ(Pythonの文字列スライスと同様に、オフセットはコードポイント単位でメッセージ本文をインデックスします) |
message_sha256 | 64文字の小文字16進数。UTF-8でエンコードしたメッセージ全文のSHA-256 |
例(ファイル内の1行。ここでは読みやすいように折り返しています):
{"record_id":"M-garden-3","role":"user","speaker":"Rowan","category":"places","topic":"Seedlings",
"statement":"the café on the corner sells seedlings on Saturdays.",
"date_first_utc":"2026-03-02T08:20:00Z","date_last_utc":"2026-03-02T08:20:00Z",
"evidence":[{"message_id":3,"date_utc":"2026-03-02T08:20:00Z",
"quote":"the café on the corner sells seedlings on Saturdays.","start":48,"end":100,
"message_sha256":"e3aebbd25f7b809dd5b0b8d55b9ad7df6566464dc2a5033d02e3c5aa7ed8eeb2"}]}
引用文はパックのビルド時に元のメッセージと照合され、その後は署名によって保護されます。 ビルダー(または agent-memory/)は、メッセージ内に逐語的に含まれていない引用文を拒否し、そのメッセージから message_sha256 を計算します。サーバーは元のメッセージを参照できないため、読み込み時と提供時には、引用の構造、オフセットの計算、ハッシュの形式のみを確認し、引用文と message_sha256 の照合は行いません。パックを封印した後は、SHA256SUMS(署名付きパックの場合は SHA256SUMS.sig)によって、引用文が後から変更されないよう保護されます。レコードのないパックは、読み込み時に拒否されます(0.4.1以降)。
MEMORY.md とパックの README.md
サーバーでは、両方のファイルが存在し、有効な UTF-8 であり、SHA256SUMS と一致している必要があります。サーバーはこれらを解析せず、どちらのツールからも返しません。これらは、パックを直接読む人やエージェント向けのものです。慣例として、またビルダーが書き込む内容として、次のようになっています。
MEMORY.md:# Title見出しの後、各レコードについて ID と話者、発言、各引用についてメッセージ ID と日付を記載し、履歴データとして示します。README.md:パックの内容と由来(入力ファイルの SHA-256、レコード数)に加え、引用は指示ではなくデータであること、チェックサムが証明するのは完全性であり、真実性や承認ではないことを示す注意書き。
SHA256SUMS の形式
他のファイルごとに 1 行(3 行、または PACK.json がある場合は 4 行)とし、各行は <64 lowercase hex>、半角スペース 2 つ、ファイル名の順です。SHA256SUMS と SHA256SUMS.sig のエントリーは含めません。最大 4 KiB です。
f3ed88bca6a7a451a892f49bd6d2970f5671b8c704d0bc6cae7646c46978bc69 MEMORY.md
0685a25133fd3e7f60e70ba1e836a2e8b045ace1e2be2ecbd306a4fc656f558f README.md
34212f199411c8e4ef52cb341b0c68d970b5b30d9b8117c2eae5729b0d71dfa5 records.jsonl
パックを手作業で編集した場合は、パックのディレクトリ内から再生成してください。
shasum -a 256 MEMORY.md README.md records.jsonl > SHA256SUMS # macOS
sha256sum MEMORY.md README.md records.jsonl > SHA256SUMS # Linux
手作業で再封印しても、チェックサムが再び一致するだけで、引用の再確認は行われません。ビルダーを使って再構築することをおすすめします。再封印すると署名も無効になるため、再度署名してください。
署名付き・日付付きパック
パックには、次の 2 つのオプション項目を含めることができます。
SHA256SUMS.sig:正確なSHA256SUMSのバイト列に対する OpenSSH 署名で、他のすべてのファイルを固定します。Ed25519 キー、sha512ハッシュ、名前空間verified-memory-pack-v1のみが受け入れられるため、Git やコードリリースの署名をパックの署名として再利用することはできません。PACK.json(0.3.0 以降):パックの作成日時と、現行ではなくなる日時を記録します。また、0.4.0 以降ではsequence番号を任意で指定できます。他のすべてのファイルと同様にSHA256SUMSに記載されるため、署名は日付とシーケンスも対象にします。
{
"format": "verified-memory-pack",
"version": 2,
"created_utc": "2026-10-12T18:00:00Z",
"expires_utc": "2027-01-10T18:00:00Z",
"sequence": 3
}
キーはこの 4 つと、任意の sequence のみです。日付は UTC の ISO 8601 形式で、created_utc は expires_utc より前でなければなりません。version は形式のバージョンで、2 のままです。sequence は 0 以上の整数で、署名者は公開するパックごとに値を増やします。これにより、ホストは古いパックを拒否できます(ロールバック保護を参照)。
PACK.json の形式が正しくない場合、読み込みは拒否されます。パックメーカーとビルダーは PACK.json を書き込まないため、そのパックは 0.2.0 のホストでも引き続き読み込めます。PACK.json を含むパックには 0.3.0 以降が必要です(古いホストは追加ファイルを拒否します)。また、sequence を含むパックには 0.4.0 以降が必要です(0.3.0 のホストは追加キーを拒否します)。
署名:sign-pack
パスフレーズで保護された鍵を使って、信頼できるマシンで署名します。0.4.1 以降、sign-pack は npm パッケージに verified-memory-sign-pack コマンドとして同梱されています(チェックアウトでは tools/sign-pack.mjs です)。検証済みパックを新しいフォルダーにコピーし、PACK.json を書き込み、SHA256SUMS を再封印して ssh-keygen -Y sign を実行します。秘密鍵自体を開くことはありません。ssh-keygen が鍵を読み込み、パスフレーズを求めます(または ssh-agent を使用します)。結果を配置する前に、ホスト側の検証ツールで厳格モードを使って読み込み、信頼するのは .pub のみです。Node 22+ と OpenSSH 8.1+ が必要です。
ssh-keygen -t ed25519 -f ~/.ssh/verified-memory-pack -C "my packs" # once; set a passphrase
npx -y -p @python1/verified-memory-mcp verified-memory-sign-pack \
--pack /path/to/pack --key ~/.ssh/verified-memory-pack --expires 90d --sequence 1 --out /path/to/pack-signed
リポジトリのチェックアウトから実行する場合は、まず一度 npm ci && npm run build を実行し、その後、同じ引数で node tools/sign-pack.mjs ... を実行します。
--expires は日数(90d、上限は 1825d)または正確な UTC 時刻(2027-01-31T00:00:00Z)です。--sequence(任意、0.4.0 以降)は PACK.json に書き込まれます。新しいパックを公開するたびに値を増やしてください(1、2、3、…)。--out はまだ存在していてはいけません。失敗した場合(パスフレーズが違う、パックを検証できないなど)、何も書き込まれません。署名済みのパックに再度署名すると、日付、シーケンス、署名が置き換えられます。スクリプトは鍵のフィンガープリント、ホスト側で固定するための --trusted-fingerprint の行、および trusted-keys の行を出力します。
秘密鍵はパックやリポジトリに含めず、共有マシンにも置かないでください。共有するのは .pub ファイルだけにしてください。
ssh-keygen -Y sign -f KEY -n verified-memory-pack-v1 pack/SHA256SUMS を実行しても有効な署名は作成できますが、その場合、パックには有効期限(freshness: unknown)もシーケンスもありません。そのため、--strict と --min-sequence では拒否されます。
推奨設定:署名者を固定する
verified-memory-mcp --pack /absolute/path/to/pack \
--trusted-fingerprint SHA256:…the-fingerprint-sign-pack-printed… \
--min-sequence 3 --strict
--trusted-fingerprint は、sign-pack(または ssh-keygen -l -f KEY.pub)が出力するフィンガープリントによって、パックへの署名を許可する鍵を 1 つ指定します。フラグを繰り返すか、フィンガープリントをカンマで区切ると、複数の鍵を許可できます。設定すると、--trusted-keys に含まれている鍵であっても、ほかの鍵による署名はすべて拒否されます。未署名のパックも拒否されます(固定を指定すると --require-signature が適用されます)。この場合、--trusted-keys は固定された鍵の名前を指定するためだけに使われます。指定しない場合、署名者は "pinned" として報告されます。
その理由は次のとおりです。レッドチームの第 4 ラウンドでは、共有マシン上で trusted keys ファイルを書き換えられる攻撃者のボットが、自分の鍵を登録して汚染されたパックに再署名しました。そして、そのファイルを信頼していたホストは、そのパックを verified として提供しました。固定設定はホスト自身の設定(MCP クライアント設定または Claude Desktop の設定)に保存され、パックの隣にあるファイルには保存されません。そのため、この攻撃は拒否されます。拒否時には pack is signed by SHA256:…, which is not a pinned signer fingerprint と表示されます。ホスト設定は自分だけが書き込めるようにしてください。攻撃者がホスト自身の設定を編集できる場合、ここでの対策では保護できません。
鍵の失効:--revoked-keys
--revoked-keys /absolute/path/to/revoked_keys では、信頼しなくなったフィンガープリントを 1 行に 1 つずつ指定します。形式は ssh-keygen -l の出力と同じです。# コメントと、フィンガープリントの後ろに付けるコメントを使用できます。
# laptop lost 2026-10-15
SHA256:…the-old-key-fingerprint… old laptop
失効した鍵で署名されたパックは、鍵が固定または信頼されている場合でも、署名が必須でない場合でも、常に拒否されます。拒否時には pack is signed by SHA256:…, which is revoked と表示されます。失効の指定だけでは署名は必須にならないため、鍵を固定するか署名を必須にしない限り、未署名のパックは引き続き読み込まれます。このファイルは trusted keys ファイルと同様、起動時に一度だけ読み込まれます。自分だけが書き込める場所に置いてください。
ロールバック保護:--min-sequence
--min-sequence N を指定すると、署名済み PACK.json の sequence が欠落している、または N より小さいパックは拒否されます。そのため、正しく署名され、有効期限内であっても、古いパックを現在のパックと差し替えることはできません。拒否時には pack sequence 3 is lower than the minimum 5; refusing a possible rollback to an older pack と表示されます。N は自分で設定し、新しいパックをインストールするたびに引き上げてください。サーバーは状態ファイルを保持せず、何も書き込まないため、これまでに確認した最も大きなシーケンス番号を記憶できません。シーケンス番号が有効と見なされるのは、ピン留めした鍵または信頼した鍵で署名されている場合に限られるため、--min-sequence は --require-signature を暗黙に有効にします。
チェックの順序
拒否時には、最初に失敗したチェックに対応する、具体的なエラーが1つ表示されます。
- パックのファイル、チェックサム、レコード(編集があると、ここで失敗します)。
- 署名が存在する場合は、有効である必要があります。
- 失効済み(ほかの設定にかかわらず拒否されます)、次にピン留め済み(ピンが設定されている場合、ピン留めされた署名者のみが通過します)、次に信頼済み鍵(
verified、untrusted、unsignedのいずれかとなり、--require-signatureを指定するとverified以外はすべて拒否されます)。 --min-sequenceに対するシーケンス番号。--strictによる有効期限(リクエストごとにも再度判定されます)。
変更時の停止
サーバーは起動時に一度だけパックを読み取り、検証します。ツールを呼び出すたびに、パックフォルダー内のファイル一覧と各ファイルのサイズ、更新時刻、変更時刻、識別情報(デバイスと inode)を、検証時の情報と照合します。何かが異なる場合(編集、ファイルの追加や削除、ファイルまたはフォルダー全体の差し替え)、両方のツールは isError を返し、次のメッセージを表示します。verified-memory: pack files changed on disk since startup, so the verified snapshot no longer matches them; restart to verify the pack again サーバーを再起動するまで、レコードデータは返されません。この拒否状態はメモリーに記録されます。追加したファイルを削除したり、フォルダーを元に戻したりしても、配信は再開されません。再度検証するために再起動した場合のみ再開されます。これはメタデータのみを対象とし、バックグラウンド監視、再読み込み、書き込みは行いません。通常のユーザーは変更時刻を元に戻せないため、ファイルの更新時刻を復元しても編集を隠すことはできません。システムクロックまたはファイルシステム自体を変更できる管理者は、この検出の対象外です。
信頼する相手の選択
信頼対象となるのは、自分で列挙した公開鍵だけです。組み込み鍵、ネットワーク、鍵サーバー、レジストリはありません。鍵は allowed_signers 形式のファイルに1行ずつ記述します。形式は name ssh-ed25519 AAAA… [comment] です(空行と # コメントを使用できます)。
alice ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA… alice's laptop
メンテナーのパック署名用公開鍵は keys/ にあります。この鍵で署名されたパックを信頼する場合は、こちらを使用してください。この鍵を列挙しない限り、どのホストも信頼しません。
verified-memory-mcp --pack /absolute/path/to/pack --trusted-keys /absolute/path/to/trusted_keys
verified-memory-mcp --pack /absolute/path/to/pack --trusted-keys /absolute/path/to/trusted_keys --require-signature
verified-memory-mcp --pack /absolute/path/to/pack --trusted-keys /absolute/path/to/trusted_keys --strict
--flag=value、--require-signature=true|false、--strict=true|false の形式も使用できます。空の --trusted-keys=、--trusted-fingerprint=、--revoked-keys=、--min-sequence= は、それぞれの設定がオフであることを意味します。--require-signature の意味は 0.2.0 と同じです。列挙した鍵による署名が必要ですが、新しさは報告されるだけで強制されません。そのため、0.2.0 では通常の ssh-keygen で署名したパックも、引き続き読み込まれます。--strict は、信頼済みの署名と新しい PACK.json の両方を要求します(--require-signature も暗黙に有効にします)。
ホストの動作
すべてのツールの結果には、verification.signature と verification.freshness が含まれます。
鮮度は起動時だけでなく、呼び出しのたびにこのコンピューターの時計を基準に判定されます。
| パック | デフォルト | --require-signature | --strict |
|---|---|---|---|
| 署名なし(すべての 0.1 パック) | 起動します。signature.status: "unsigned" | 起動を拒否します | 起動を拒否します |
| 署名があるが、形式が不正または無効 | 起動を拒否します | 起動を拒否します | 起動を拒否します |
| 有効な署名だが、鍵がファイルに登録されていない | 起動します。鍵のフィンガープリントとともに untrusted | 起動を拒否します | 起動を拒否します |
| 有効な署名で、鍵がファイルに登録されている | 起動します。verified、signer(鍵に付けた名前)、fingerprint | 起動します | 鮮度がある場合(下記)、起動します |
PACK.json がない | 起動します。freshness.status: "unknown" | 起動します。unknown | 起動を拒否します |
PACK.json があり、有効期限前 | 起動します。created_utc、expires_utc とともに fresh | 起動します。fresh | 起動します |
PACK.json の有効期限切れ | 起動します。stale と、stderr への警告 | 起動します。stale と警告 | 起動を拒否します。有効期限が切れると、実行中のサーバーはサービスの提供を停止します(ツールエラー) |
created_utc が 5 分を超えて未来 | 起動します。not_yet_valid と、stderr への警告 | 起動します。not_yet_valid と警告 | 起動を拒否します |
PACK.json またはそのチェックサムが改ざんされている | 起動を拒否します | 起動を拒否します | 起動を拒否します |
| 実行中にパックのフォルダーが変更された | 再起動するまで、ツールは isError を返します | 同じ | 同じ |
0.4.0 のオプションを使用する場合、上記のどのモードでも次のようになります。
| パック | 結果 |
|---|---|
--revoked-keys に指定された鍵で署名されている | ピン留め済みまたは信頼済みであっても、フィンガープリントを示して起動を拒否します |
--trusted-fingerprint が設定されており、ピン留めされた鍵で署名されている | 起動します。verified、pinned: true、--trusted-keys の signer、または "pinned" |
--trusted-fingerprint が設定されており、--trusted-keys にある鍵も含め、それ以外の鍵で署名されている | 起動を拒否します |
--trusted-fingerprint または --min-sequence が設定されており、署名がない | 起動を拒否します |
--min-sequence N が設定されており、署名された sequence が N 以上 | 起動します。freshness.sequence にその値が報告されます |
--min-sequence N が設定されており、sequence が N 未満、または存在しない | 起動を拒否します |
sequence はあるが、--min-sequence がない | 起動します。freshness.sequence は報告されますが、強制される条件はありません |
freshness.authenticated が true になるのは、記載した鍵のいずれかが日付に署名した場合のみです。署名のないパックや信頼されていないパックの日付は、誰でも記入できる可能性があります。ピン留めされたフィンガープリントまたは信頼済みの鍵がない状態で --require-signature または --strict を指定した場合、あるいは信頼済みの鍵の行が単一名の ssh-ed25519 エントリーでない場合は、起動を拒否します。署名者名は常にファイルから取得され、パックから取得されることはありません。また、フィンガープリントは ssh-keygen -l と一致します。このサーバーを使わずにパックを検証することもできます。
ssh-keygen -Y verify -f trusted_keys -I alice -n verified-memory-pack-v1 -s SHA256SUMS.sig < SHA256SUMS
署名で証明されるのは署名者であり、内容の真実性ではありません。 その鍵の所有者が、これらの正確なバイト列に署名したことを示します。引用が正確または完全であることや、その鍵の所有者が想定どおりの人物であることを示すものではありません。「鮮度あり」とは、署名者が設定した有効期限を過ぎていないという意味であり、これが署名者の最新のパックだという意味ではありません。--min-sequence がなければ、同じ鍵による古いパックも、有効期限が切れるまでは読み込まれます。
失効情報と最小シーケンスが最新かどうかは、設定の内容に左右されます。ネットワーク接続がない場合、新たに失効した鍵や新しいシーケンスは、設定を編集するまでホストに反映されません。鮮度の判定は、このコンピューターの時計に依存します。バージョン 0.1.0 は署名済みパックを拒否します(ファイル 5 個)。そこでパックを読み込むには、SHA256SUMS.sig を削除してください。
ビルドと実行
このリポジトリをチェックアウトし、Node 22.0.0 以降(選択した Node の系列の最新パッチリリースを使用)を使って、plugins/verified-memory-mcp で次を実行します。
npm ci --ignore-scripts
npm run build
npm test
node --experimental-permission --allow-fs-read="$PWD" "$PWD/dist/index.js"
最後のコマンドで stdio サーバーが起動し、標準入力で MCP クライアントからの接続を待ちます。
これは対話型のターミナル検索インターフェースではありません。Claude
Desktop などの MCP クライアントを通じて接続し、陶器を検索して
M-sample-2 を取得するようリクエストしてください。Node の権限モードでは、このプロジェクトディレクトリ以下での読み取りのみが許可されます。
ファイルシステムへの書き込み、サブプロセス、ワーカー、ネイティブアドオンは禁止されます。
--experimental-permission の表記は Node 22.0.0 で動作します。Node 22 の初期リリースでは、標準エラー出力に実験的機能についての警告が表示されます。Node 22.13 以降では、代わりに --permission を使用できます。Node 22 ではネットワーク権限は強制されません。このサーバーはネットワーク呼び出しを行いません。Node 25.8.0 では、ソケット拒否プローブも通過します。Node 22.0 の権限に関するドキュメント
およびNode 22.13 の権限に関するドキュメントを参照してください。
実行時は、npm/npx やシェルラッパーではなく、node を直接呼び出してください。
ビルド、依存関係のインストール、テストは開発作業であり、ローカルに出力を書き込みます。依存関係のインストールでは npm レジストリにアクセスします。実行時には、どちらも行われません。 テストハーネスはローカルの Node プロセスを起動し、架空のパックの分離された一時コピーを作成します。サーバー自体が別のプロセスを起動することはありません。
Claude Desktop のワンクリックインストール
最新リリースからverified-memory-<version>.mcpbをダウンロードしてください。
verified-memory-<version>.mcpbは、macOSおよびWindows向けのClaude Desktop用MCPバンドルです。macOSとWindowsで手動テスト済みです。
Claude Desktopに組み込まれたNode.js上で動作するため、NodeのインストールもTerminalも不要です。
.mcpbファイルをダブルクリックします。Windowsでは、どのアプリで開くか尋ねられる場合があります。その場合はClaudeを選択してください。 または、ファイルをClaude Desktop → Settings → Extensionsにドラッグするか、 **Settings → Extensions → Advanced settings → Install Extension…**を使います。- まずパックを解凍します(Windowsの場合:右クリック→すべて展開)。
MEMORY.md、README.md、records.jsonl、SHA256SUMSが入っているフォルダーをアドオンに指定してください。フォルダー選択画面にはフォルダーしか表示されないため、パックフォルダーは空に見えますが、これは正常です。フォルダーのパスを貼り付けることもできます。 - 質問する前に、拡張機能が有効になっていること(Settings → Extensions → Enabled)を確認してください。 質問の例:「verified memoryを使って、…について何を知っていますか?」
設定フォームには、次の項目があります。
| 設定 | 必須 | 渡される値 |
|---|---|---|
| メモリーパックのフォルダー | はい | --pack=<folder> |
| 信頼済みキーのファイル | いいえ(空欄の場合はなし) | --trusted-keys=<file> |
| ピン留めする署名者のフィンガープリント(署名済みパックに推奨) | いいえ(空欄の場合はなし) | --trusted-fingerprint=<SHA256:…[,SHA256:…]> |
| 失効済みキーのファイル | いいえ(空欄の場合はなし) | --revoked-keys=<file> |
| パックの最小シーケンス番号 | いいえ(空欄の場合は無効) | --min-sequence=<N> |
| ピン留め済みまたは信頼済みの署名を必須にする | いいえ(オフ) | --require-signature=true|false |
| 厳格モード:ピン留め済みまたは信頼済みの署名と、期限切れでないパックを必須にする | いいえ(オフ) | --strict=true|false |
署名済みパックの場合は、sign-packが出力したフィンガープリントをピン留めする署名者のフィンガープリントに貼り付けます。信頼済みキーのファイルは不要です。新しいパックをインストールしたら、パックの最小シーケンス番号を引き上げてください。有効期限付きで署名されたパックでは、厳格モードをオンにしてください(sign-packは常に有効期限を追加します)。新しい設定はすべてデフォルトでオフになっているため、0.3.0からアップグレードしたアドオンは、変更時の停止を除き、従来どおりに動作します。
これらの設定は、後からSettings → Extensions → Verified Memoryで変更できます。このバンドルにはnpmパッケージと同じdist/と、本番用の依存関係のみが含まれます。パック、キー、署名、テストは含まれません。秘密鍵が必要になるため、mcpb signによるコード署名はしていません。Claude Desktopがサーバーを起動するため、Nodeの権限モードは使用しません。
npm ci && npm run build:mcpbでローカルビルドできます(出力先:build/verified-memory-<version>.mcpb)。
npm run test:mcpbはバンドルをビルドし、test/mcpb/を実行します。これらのテストでは、@anthropic-ai/mcpbでバンドルを展開し、サンプル設定からgetMcpConfigForManifestが生成する引数を使ってサーバーを起動します。
Claude Desktop の設定例
この例を Claude Desktop の MCP 設定に統合し、ビルド後に Claude Desktop を再起動してください。以下のパスはすべてプレースホルダーであり、実際のユーザーパスではありません。 Node 実行ファイルと、このビルド済みディレクトリへの絶対パスに置き換えてください。 設定が自動的にインストールまたは編集されることはありません。
{
"mcpServers": {
"verified-memory": {
"command": "/absolute/path/to/node",
"args": [
"--experimental-permission",
"--allow-fs-read=/absolute/path/to/hive-public/plugins/verified-memory-mcp",
"/absolute/path/to/hive-public/plugins/verified-memory-mcp/dist/index.js"
]
}
}
}
リポジトリ内でビルドした場合、--pack を省略すると、クライアントの作業ディレクトリにかかわらず、同梱された架空の Juniper Vale/Wren サンプルが使用されます。npm でインストールした場合、サンプルは含まれず、--pack がなければ起動を拒否します。独自の pack を使用するには、args に
"--pack", "/absolute/path/to/pack" を追加し、さらにエントリーポイントの引数より前に
"--allow-fs-read=/absolute/path/to/pack" も追加してください。--trusted-keys を指定する場合は、同じ方法でそのファイルの読み取りも許可してください。
接続するクライアントが読み取りを許可されている pack を選んでください。
相対パスと不明な CLI フラグは拒否されます。ツールがパスを選択することはできません。
ホームディレクトリ、他のエージェント、実際のメモリや設定の検出は行いません。
監視や再読み込みはありません。サーバーの実行中に pack フォルダーが変更されると、変更を元に戻した場合でも、新しい pack を検証するために再起動するまで、ツールはエラーを返すようになります。args に
--trusted-fingerprint、--revoked-keys(およびその --allow-fs-read)、さらに
--min-sequence も同じ方法で追加してください。
ツールの契約
verified_memory_search:
{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":512}},"required":["query"],"additionalProperties":false}
matches、matched、verification、notice を返します。検索では、statement/topic/quotes 全体から、正規化された Unicode の単語をすべて含む必要があります。固有の用語は最大 32 個です。
一致結果は最大 10 件で、用語の出現回数、新しい日付、レコード ID の順に並びます。一致結果では、引用文、ソースメッセージ ID、日付、話者がそのまま保持されます。語幹処理、意味的な推論、ネットワーク検索は行いません。一致しないことは、存在しない証拠にはなりません。
verified_memory_get:
{"type":"object","properties":{"id":{"type":"string","pattern":"^M-[A-Za-z0-9_-]{1,127}$"}},"required":["id"],"additionalProperties":false}
found、完全な record(または null)、verification、notice を返し、引用、来歴、監査、承認、置き換えのメタデータを履歴データとして保持します。MCP の成功結果には、content 内の JSON テキストと、同じオブジェクトが structuredContent 内に含まれます(これは OpenClaw ツールの details に相当します)。無効なツール引数は isError: true を返し、不明なツール名はプロトコルエラーを返します。
両方のツールは、読み取り専用、非破壊的、冪等、閉世界のアノテーションを宣言します。
SDK の低レベル Server API は、additionalProperties: false を含む公開済み JSON スキーマを厳密に維持します。引数は明示的に検査され、共有検証器による検査も行われます。このサーバーのビルドや実行に OpenClaw ランタイムや依存関係は必要ありません。
共有検証器とフェイルクローズ起動
開発時のみ使用する scripts/prepare.mjs は、元の
../verified-memory/src/pack.ts と verify.ts をバイト単位でそのまま無視対象の src/ にコピーし、
公開されている架空のサンプルを無視対象の sample-pack/ にコピーします。TypeScript は
同じ検証器を dist/pack.js(ファイルの読み取り)と dist/verify.js(インポートのない検証処理そのもの)にコンパイルします。保守対象となる別の検証器はなく、このビルドが OpenClaw プラグインを変更することもありません。兄弟ディレクトリのソースとサンプルが存在する状態で、リポジトリのチェックアウトからビルドしてください。生成ファイルはコミットされません。
サーバーの作成または stdio への接続より前に、パック全体を検証する必要があります。
検証に失敗したパックは初期化できず、ツールの一覧表示やレコードの返却もできません。正確な形式は4つの通常ファイル、records.jsonl、MEMORY.md、README.md、SHA256SUMS と、同じ共有検証器でチェックされる任意の PACK.json および SHA256SUMS.sig です。
チェック項目には、ファイル一覧の完全一致、実際に解析されたバイト列に対する SHA-256 ハッシュ、UTF-8、JSON、一意な ID、引用構造とオフセット、日付範囲、マニフェストの構文、シンボリックリンクのルートとエントリ、ファイルサイズと件数の上限が含まれます。上限はデータファイルごとに 16 MiB、マニフェストは 4 KiB、レコードは 10,000 件のままです。寛容なフォールバックはありません。以降にディスク上で編集されても、検証済みのメモリ内スナップショットは変更されません。また、0.4.0 以降は、ディスク上で変更されると提供が停止します(変更時に停止を参照)。取得結果はコピーを返します。
継承されたファイルシステムチェックは、祖先ディレクトリに対する競合操作を行える攻撃者を阻止するサンドボックスではありません。信頼できる安定したローカルディレクトリと、Node の読み取り許可リストを使用してください。
完全性は真正性や真実性を保証するものではありません。 署名者をピン留め(--trusted-fingerprint)するか、攻撃者が書き込めない信頼ファイルに記載された鍵のみを使用しない限り、データとチェックサムの両方を置き換えることで検証に合格するパックを作成できます。実行時に、引用を元のメッセージと照合することはできません。過去の引用はデータであり、指示でも許可でもありません。この注意書きは、成功したすべての結果に付記されます。ホストモデルの動作やツールの自動選択は検証されません。ツールのテキストをそのまま引用し、レコード ID とメッセージ ID を示すようホストに求めてください。
既存の公開された架空のソース
agent-memory/sample/telegram-export.json のみを使用します。非公開のレコード、運用パス、IP アドレス、鍵、他のエージェントのファイルは含まれません。フィクスチャの監査/承認メタデータは、実際のモデル監査や人による承認の証拠ではありません。
ファイルツリー
plugins/verified-memory-mcp/
├── .gitignore
├── LICENSE
├── README.md
├── VALIDATION.md
├── RELEASE-NOTES-0.4.0.md # notes for the 0.4.0 release
├── RELEASE-NOTES-0.4.1.md # draft notes for the 0.4.1 release
├── package.json
├── package-lock.json
├── server.json # MCP Registry metadata
├── tsconfig.json
├── scripts/
│ ├── prepare.mjs
│ ├── build-mcpb.mjs # builds the Claude Desktop bundle into build/
│ └── test-all.mjs # every automated suite, as CI runs it on macOS and Windows
├── mcpb/manifest.json # Claude Desktop bundle manifest (settings form, tools)
├── src/
│ ├── index.ts
│ ├── server.ts
│ ├── pack.ts # generated, ignored; exact shared source
│ └── verify.ts # generated, ignored; exact shared source
├── web/ # repo-only: browser pack maker (see web/README.md)
├── tools/
│ ├── build-pack.mjs # offline pack builder (ships in npm)
│ ├── pack-core.mjs # its import-free building rules (ships in npm)
│ ├── sign-pack.mjs # signs and dates a pack via ssh-keygen (ships in npm)
│ └── export-shape.mjs # repo-only: prints a chat export's structure, never its text
├── examples/
│ ├── input/ # invented messages.jsonl + records.jsonl
│ └── pack/ # pack built from them
├── test/
│ ├── server.test.mjs
│ ├── redteam.test.mjs # red-team rounds R1–R6, revocation, precedence
│ ├── sign-pack.test.mjs
│ ├── build-pack.test.mjs
│ ├── pack-core.test.mjs
│ ├── export-shape.test.mjs
│ └── mcpb/bundle.test.mjs # run by `npm run test:mcpb` against the built bundle
├── validation/
│ ├── tests.txt # Node 25.8.0
│ ├── tests-node22-min.txt # Node 22.0.0
│ └── tests-node22-current.txt # Node 22.23.3
├── sample-pack/ # generated, ignored; four fictional files
├── build/ # generated, ignored; the .mcpb and its staging folder
└── dist/ # generated, ignored; JS and declarations
記録されたテストと制限については、VALIDATION.md を参照してください。
ライセンス
MIT — LICENSE。すべての機能を無料で利用でき、有料プランはありません。
☕ このプロジェクトを支援する:https://buymeacoffee.com/python1
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。