ShieldFive について
@shieldfive/mcpは、ShieldFiveのボールトと許可されたローカルフォルダーを整理するMCPサーバーです。ボールトのデータは端末上で復号し、アップロードを検証してから元ファイルをゴミ箱へ移動するため、変更を取り消せます。
主な機能
- 01ボールト内のファイル閲覧と検索
- 02容量の確認と重複ファイルの検出
- 03項目の名前変更・移動・ゴミ箱への移動
- 04アップロード検証後の元ファイル移動
- 05許可されたローカルフォルダーのオフライン整理
- 06変更のプレビューと取り消し
活用シーン
- 01検証済みファイルをShieldFiveのボールトへ移動
- 02重複ファイルや大きなファイルを探す
- 03許可されたフォルダー内のファイルを整理
- 04選択したテキストファイルをアシスタントに読ませる
MCP 対応
このサーバーはMCPツールとして、ボールトとローカルファイルの操作を対応アシスタントに公開します。破壊的な操作はプレビューと確認を経て実行し、クライアントが対応する場合はMCP elicitationで承認を求めます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @shieldfive/mcpSHIELDFIVE_GRANTシークレットConnection string from ShieldFive → Settings → AI assistants. Optional: `npx @shieldfive/mcp login` stores it in the OS keychain instead.SHIELDFIVE_MCP_ROOTSLocal directories the local tools may use, separated by the platform path separator. Optional.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
10掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| path | string | いいえ | スキャンするディレクトリ。省略すると、設定済みのすべてのルートをスキャンします。 |
| limit | integer | いいえ | 返す行数の上限。最大 10,000。 |
| sort_by | enum | いいえ | path | size | modified |
| max_files | integer | いいえ | この数のファイルに達すると停止します。最大 1,000,000。上限に達した場合は結果に表示されます。 |
| include_hidden | boolean | いいえ | ドットファイルとドットディレクトリを含めます。 |
詳細
@shieldfive/mcp
Model Context Protocol サーバーです。Claude、ChatGPT、Cursor、またはローカルモデルで、次の 2 つを操作できます。
- エンドツーエンドで暗号化された ShieldFive の vault:ファイルをコンピューターから vault に移動します。ファイルはそれぞれこのサーバー上で暗号化され、アップロードされ、読み戻されてバイト単位で一致することを確認してから、元のファイルがローカルのゴミ箱フォルダーに移動されます。削除されることはありません。重複を探したり、容量を多く使っているファイルを確認したり、名前の変更、移動、ゴミ箱への移動もできます。許可したフォルダーのみが対象で、復号はコンピューター上で行われ、すべての変更を元に戻せます。
- ご自身のディスク上のフォルダー:ネットワークに一切アクセスせず、同じ整理作業を行えます。
ShieldFive のサーバーが、ファイル名やコンテンツのバイト列を平文で見ることはありません。このサーバーの実行中も同様です。復号は、コンピューター上のこのプロセス内で行われます。その後、アシスタントが読み取った内容をどう扱うかは別の問題であり、セキュリティモデルで説明しています。
60 秒で vault に接続する
Node 20 以降が必要です。
-
アシスタントにサーバーを追加します。Claude Desktop の場合は、
claude_desktop_config.jsonに次の内容を追加します(Cursor では同じブロックを~/.cursor/mcp.jsonに追加します)。{ "mcpServers": { "shieldfive": { "command": "npx", "args": ["-y", "@shieldfive/[email protected]"] } } }Claude Code の場合:
claude mcp add shieldfive -- npx -y @shieldfive/[email protected]バージョンを固定しているのは意図的です。このサーバーは接続情報を読み取れるため、確認したリリースのバージョンを固定し、アップグレードする際に番号を変更してください。公開された最新のものを無条件に実行するのは避けてください。
-
アシスタントを再起動し、ShieldFive の vault を整理してと頼みます。アシスタントは
vault_connectを呼び出し、ブラウザーで ShieldFive を開きます。 -
そのタブでフォルダーを選び、読み取り専用または読み取りと整理を選択し、有効期限(1 時間から 90 日)を設定して、認証するをクリックします。
これで設定は完了です。接続情報は、コンピューター上で実行されているサーバーに直接送られます。127.0.0.1 経由であり、ShieldFive を経由することはありません。接続情報はシステムのキーチェーンに保存されます。手動でコピーする必要はありません。
会話を始める前に接続するには、npx -y @shieldfive/[email protected] login を実行します。ブラウザーで同じページが開き、同じ結果が得られます。login --paste を使うと、代わりに「設定」→「AI アシスタント」からコピーした接続文字列を指定できます。ブラウザーを使えないマシン向けです。
npx @shieldfive/[email protected] status を実行すると、設定されている接続と、ShieldFive が引き続きその接続を受け入れているかどうかを確認できます。npx @shieldfive/[email protected] logout を実行すると、キーチェーンと以下のフォールバックファイルから接続情報が削除されます。どこからのアクセスも遮断するには、ShieldFive で接続を取り消してください。
システムのキーチェーンを使用できない場合(たとえば、Secret Service のない Linux マシン)、接続情報はユーザーアカウントのみが読み取れるファイルに保存されます。macOS では ~/Library/Application Support/shieldfive-mcp/connection、Windows では %APPDATA%\shieldfive-mcp\connection、Linux では $XDG_CONFIG_HOME/shieldfive-mcp/connection(デフォルトは ~/.config)、または $SHIELDFIVE_MCP_CONFIG_DIR/connection に保存されます。この方法で保存した場合、サーバーが通知します。このファイルは暗号化されません。暗号鍵を使う場合、その鍵も同じディスクに保存されるためです。SSH キーと同様に、ファイルのアクセス権(0600)で保護されます。このファイルがないと、再起動のたびに新しい接続が必要になります。また、ShieldFive では同時に有効にできる接続数に上限があります。後でキーチェーンへの保存に成功すると、このファイルは削除されます。
CI では、代わりに SHIELDFIVE_GRANT に接続文字列を設定します。サーバーの環境変数を読み取れるものは接続情報も読み取れるため、キーチェーンが利用できる場合はそちらを優先してください。SHIELDFIVE_GRANT=none を設定すると、キーチェーンに別の接続情報が保存されているマシンでも、1 つのクライアントをローカル専用にできます。
ブラウザへの引き渡しを安全に保つ仕組み
- ページが受け取るのはポート番号だけで、コールバック URL は受け取りません。ページ自体が
http://127.0.0.1:<port>/callbackを構築します。細工されたリンクを使っても、接続先を自分のマシン以外にすることはできません。 - リスナーが受け付けるのは、
/callbackへの POST を使った一度きりの送信です。Hostはループバックアドレスと完全に一致している必要があり(そのため、別の DNS 名に再バインドされている場合は拒否されます)、Originは ShieldFive のもの以外認められず、256 ビットの state は時間差のない方法で比較されます。その後、リスナーは終了します。 - 接続文字列は URL ではなくフォームの本文で送信されるため、ブラウザーの履歴には残りません。
- リスナーが動作するのは接続の認可中のみで、最長でも 10 分間です。
セキュリティモデル
簡単に説明すると、次のとおりです。
- 接続文字列には 2 つの情報が含まれます。 サーバーがすべてのリクエストで確認する トークン と、マシンの外に出ることのない シークレット です。ShieldFive が保存するのはトークンのハッシュのみで、シークレットを目にすることはありません。
- シークレットで開けるのは、選択したフォルダーだけです。 接続を作成するとき、ブラウザーはシークレットから導出したキーを使って、それらのフォルダーのキーをラップします。ラップするのはそれだけです。ボルトのルートキーも、パスワードも、ポスト量子シークレットキーもラップしません。サブフォルダーは、ボルトの通常のフォルダーキーの連鎖を通じて開かれます。選択していないフォルダーは、このサーバーが保持する情報では開けません。
- ShieldFive はすべてのリクエストでスコープ、有効期限、失効を適用します。 このプロセス内のチェックはエラーをわかりやすくするだけで、境界となるのはサーバーです。接続を失効させると、その接続の次のリクエストは失敗します。失効後も残るキャッシュはありません。
- 復号はこの場でメモリー上で行われます。 平文、キー、暗号文がディスクに書き込まれることはありません。ボルトのモジュールはファイルシステムをインポートしません。テストでそのことを検証しています。
- 削除は行われません。
vault_trashは項目を、接続専用のゴミ箱フォルダーに移動します。完全削除ツールはなく、接続からアクセスできる API にも削除用のルートはありません。名前変更、移動、ゴミ箱への移動はすべて Settings → AI assistants → Activity に表示され、元に戻すボタンも利用できます。 - 変更内容はすべて事前にプレビューされます。 変更を行うツールは実行計画を返します。確定の呼び出しにはその計画のトークンを含める必要があり、その間に項目が変更されている場合は拒否されます。
- 破壊的な変更は、クライアントから確認できる場合、必ずユーザー自身が承認します。 破壊的とマークされたツール(
vault_trash、vault_move_in、move_local、trash_local)では、確定の呼び出し時にまず MCP のエリシテーションを通じて、クライアント自身のプロンプト内で承認済みの計画が表示されます。承認された場合に限り実行されます。拒否しても何も変更されません。エリシテーションに対応していないクライアントでは、前述のプレビューとトークンを使うフローが維持されます。 - 一覧表示と内容の読み取りは別々です。
vault_list_files、vault_search_files、vault_storage_statsが返すのは名前とメタデータのみです。ファイルの内容を返すツールはvault_read_fileだけで、内容を復号するもう 1 つのツールvault_find_duplicatesはハッシュを返します。サーバーを--no-contents(またはSHIELDFIVE_MCP_CONTENTS=off)を指定して起動すると、これら 2 つのツールは登録されません。また、「read」権限のない接続からの呼び出しも拒否されます。
この仕組みで保護されないもの:
- AI プロバイダーには、アシスタントが読み取る内容が渡ります。 ファイル名と、アシスタントが開くファイルの内容はアシスタントに渡されます。クラウド型アシスタントの場合、会話のほかの内容と同様に、そのプロバイダーにも渡されます。これを避ける唯一の方法は、ローカルモデルを使うことです。
- アクセスを取り消しても、既読の内容は消せません。 アシスタントがすでに読み取った内容は、そのまま読み取られた状態です。それ以外の情報は残りません。ファイルの内容はリクエストごとに ShieldFive 経由でストリーミングされるため、アクセス取り消し後も有効なダウンロードリンクはありません。
- 接続は、作成時にサーバーがブラウザーに表示する情報をもとに構築されます。 その後の拡張はすべて、お客様自身のキーを使って確認されるため、サーバーが侵害されても、後から接続範囲を広げることはできません。ただし、作成時には、侵害されたサーバーが選択したフォルダーを偽って表示する可能性があります。
- コピーされた接続文字列は、それが対象とするフォルダーへの有効なキーです。 有効期限が切れるか、アクセスを取り消すまで有効です。キーチェーンに保管してください(キーチェーンがない場合は、サーバーが書き込む 0600 の代替ファイルに保管してください)。
- ファイルには、アシスタントに向けた指示が含まれている場合があります。 このサーバーは、すべての名前とファイル内容をデータとして扱い、ファイル内容をファイル自体では閉じられないブロック内に囲み、1 回の呼び出しにつき
vault_trashの項目数を 50 件までに制限し、すべての変更にプレビューを必須とし、すべての変更を取り消し可能な状態に保ちます。それでも、許可したフォルダー内で、モデルが取り消し可能な誤操作をするよう誘導される可能性はあります。
脅威モデルや各判断の根拠を含む設計の全容については、
docs/mcp-grants-design.md
をご覧ください。
Vault ツール
vault_connect は常に利用できます。それ以外のツールは接続が確立されると登録されます。会話の途中で接続すると、notifications/tools/list_changed によって通知されます。以下では項目をすべて ID で示しています。パスは人間向けです。
| ツール | 必要な権限 | 機能 |
|---|---|---|
vault_connect | — | ブラウザーで ShieldFive を開いて接続を認可し、キーリングに保存します |
vault_list_files | 読み取り | スコープ内のファイルとフォルダーを、復号された名前、パス、サイズ、日付とともに一覧表示します |
vault_search_files | 読み取り | 復号された名前をローカルで検索し、名前、パス、拡張子、サイズ、日付で絞り込みます |
vault_storage_stats | 読み取り | 合計、最も大きなフォルダーとファイル、種類別の内訳を表示します |
vault_find_duplicates | 読み取り(内容) | 同じサイズのファイルをメモリ内で復号し、SHA-256 で比較します。処理量には上限があり、結果が下限値の場合はその旨を示します |
vault_read_file | 読み取り(内容) | 内容を返す唯一のツールです。テキストファイルは信頼されていないコンテンツとしてフェンス付きで返します(最大 100 万文字)。それ以外の種類は詳細のみを返します |
vault_rename | 整理 | ファイルまたはフォルダーの名前を変更します |
vault_move | 整理 | スコープ内の別のフォルダーに移動します |
vault_create_folder | 整理 | スコープ内にフォルダーを作成します |
vault_upload | 書き込み | ローカルファイルを暗号化してここにアップロードし、読み戻して照合します。元のファイルを安全に削除できると通知するのは、その後です |
vault_trash | 整理 | 接続に対応する Bin 内のフォルダーに、最大 50 項目を移動します |
vault_move_in | 書き込み | 空き容量を確保します。ローカルファイルを最大 50 個、1 つずつアップロードして検証し、コピーを読み戻して同一であることを確認した後にのみ各元ファイルをローカルのゴミ箱に移動します。承認は 1 回だけで、何も削除されません |
ユーザーが遭遇する可能性のある制限事項:
- スマートフォンまたは CLI からアップロードしたポスト量子ファイルは、次に Web で ShieldFive を開いて接続に必要なキーが追加されるまで、
readable: falseと表示されます。Web アプリでアップロードしたファイルはすぐに利用できます。 - 大規模な Vault の最初の一覧表示には時間がかかります。 各名前の処理には約 70 ms の Argon2id が必要で、CPU コア全体に分散されます(8 コアで 2,000 件の名前に約 20 秒)。名前はセッション中、メモリにキャッシュされます。
- Vault 全体への接続で最上位にある項目は読み取ってフォルダーに移動できますが、その場で名前を変更することはできず、最上位への移動もできません。項目の名前は Vault のルートキーで封印されており、接続がそのキーを保持することはありません。
- アップロードには、ファイルを追加できる接続(認可時に「読み取り、整理、ファイルの追加」)と、認可時に選択するアップロード許容量が必要です。各ファイルの上限は 512 MB です。アップロードと移動ではローカルファイルを読み取るため、サーバーには接続に加えてルートも必要です。
- ファイルを移動しても、それだけでは空き容量は増えません。
vault_move_inは検証済みの各元ファイルを.shieldfive-mcp-trashに移動し、Vault 内のコピー名を記載したマニフェストを保存します。そのディレクトリを空にすると、空き容量が戻ります。
ローカルファイル
パッケージ名の後に指定するパスはすべてルートです。ローカルツールはこれらのディレクトリ内だけで読み書きでき、それ以外の場所にはアクセスできません。また、ネットワークリクエストは行いません。
npx @shieldfive/[email protected] ~/Documents ~/Downloads
claude_desktop_config.json では:
{
"mcpServers": {
"shieldfive": {
"command": "npx",
"args": ["-y", "@shieldfive/[email protected]", "/Users/you/Documents", "/Volumes/Archive"]
}
}
}
接続を設定していてルートがない場合は、Vault ツールのみが登録されます。ルートがあり接続がない場合は、ローカルツールのみが登録され、サーバーは 0.2.0 とまったく同じように動作します。両方がある場合は、両方を利用できます。
SHIELDFIVE_MCP_ROOTS でもルートを追加できます。両方の設定が結合され、どちらか一方が優先されるわけではありません。リストはプラットフォームのパス区切り文字(macOS と Linux では :、Windows では ;)で区切ります。
SHIELDFIVE_MCP_ROOTS="/Users/you/Documents:/Volumes/Archive" npx @shieldfive/[email protected]
ルートの前後にある空白は無視されます。一方、ツールに渡すパスでは無視されません。パスでは、すべての文字がそのままパスの一部になります。
まず動作を確認する
npm run demo
demo/run-demo.mjs は、一時ディレクトリに5つのファイルを作成します。名前は異なるものの内容が同一のファイル2つ、同じサイズの偽ファイル、12 MB のアーカイブ、2年前の PDF です。これらに対して読み取りツールを実行し、ゴミ箱への操作をプレビューした後、実行を確認してマニフェストを表示します。そのディレクトリ以外には一切触れず、最後にディレクトリを削除します(--keep を指定すると残します)。
ローカルツールでできないこと
ローカルファイルがすでに保管庫にあるかどうかは判断できません。 ローカルの名前とサイズを保管庫の一覧と照合する方法では、ツールが唯一のコピーを削除してしまうことがあります。このサーバーは推測で判断しません。
結果が AI プロバイダーに届くのを防ぐことはできません。 ローカルツールはネットワークリクエストを行いません。それが意味することは、その言葉どおりであり、それ以上ではありません。 ツールが返すものはすべて――パス、ファイル名、サイズ、日付、報告するダイジェスト――呼び出した AI クライアントに戻されます。そのクライアントがクラウドアシスタントの場合、会話のほかの内容と同様に、これらの名前もアシスタントのプロバイダーに送られます。その点を踏まえてルートを選んでください。
名前とサイズから、2 つのファイルが同じだと推測することはありません。 重複検出では両方のファイルを読み込み、内容の SHA-256 全体を比較します。名前だけで照合する方法では、重複排除ツールが唯一のコピーを削除してしまうことがあります。正確に判定するために必要なのは、数秒のディスク I/O です。
ただし、ハッシュ計算には上限があり、その上限によって結果が不完全になることがあります。候補はサイズごとに分類され、64 KiB より大きいファイルは先頭 64 KiB のハッシュで絞り込んだ後、完全なダイジェストで確認されます。どちらの種類の読み取りも max_files_hashed の上限にカウントされます。デフォルトは 20,000 です。上限に達すると、残りはハッシュ計算されません。上限に達したグループは一部のみが計算され、古いコピーが優先されます。結果には、未確認のファイル数と容量が示されます。グループは大きい順に処理されるため、厳しい上限の中でも、残るのは最も価値の高いものです。
回収可能な容量は、ディスク上のファイルごとに数えます。ハードリンクされた名前は 1 つのファイルを指すため、1 つのコピーとして扱われます。削除しても容量は空きません。APFS クローン――APFS ボリューム上で Finder の「複製」を使って作成されるもの――もストレージを共有します。しかし、このサーバーが読み取れる情報では、クローンと実際のコピーを区別できません。そのため、クローンをゴミ箱に移しても容量がほとんど、あるいはまったく空かない場合でも、回収可能として報告されます。残すコピーとして指定されるのは、最も早く変更されたものです。同じ場合はパスが短い方、さらに同じ場合はコード単位順のパスが選ばれます。そのため、同じツリーであれば常に同じコピーが指定されます。
例外を除き、ファイルを削除することはありません。 trash_local はファイルを削除するのではなく、同じボリューム上の .shieldfive-mcp-trash ディレクトリに移動し、それぞれの元の場所を記録した manifest.json を書き込みます。自分でファイルマネージャーを使い、自分で取り消せる状態でこのディレクトリを削除するまで、ディスク容量は空きません。 アシスタントが容量を回収済みと報告できないよう、ツール自身の出力にもその旨が記載されます。例外はボリューム間の move_local です。この場合はコピーが必要です。コピーが検証された後にのみ、元のファイルが削除されます。詳しくはボリューム間の移動をご覧ください。
上書きの場合も同様です。overwrite: true を指定した move_local は、移動先にすでにある項目をゴミ箱に移してから、その場所に項目を移動します。既存の項目は削除されません。プレビューには、移動するファイルの数だけでなく、置き換えられるファイルの数とバイト数も表示されます。その後、移動に失敗した場合は、置き換えられる項目が元に戻されます。
変更を加えるすべてのツールは、デフォルトでは何もしません。 confirm: true を指定せずに呼び出すと、パスを解決して包含関係を確認し、実行予定の内容を正確に報告して停止します。プレビューでも操作時と同じチェックが実行されるため、拒否を報告するプランは、そのまま拒否となります。
また、確認済みの呼び出しは、表示されたプランどおりでなければなりません。 プレビューは plan_token を返します。これを指定せずに confirm: true を指定すると、呼び出しは拒否されます。確認済みの呼び出しでは、現在のファイルシステムに基づいてプランを再作成し、トークンで承認されたプランと比較します。比較対象は、パス、各項目の種類、サイズ、変更日時、およびその配下のファイル数とバイト数です。違いがあれば、何が変わったかを示して拒否されます。トークンで実行できる変更は 1 つだけで、有効期限は 10 分です。そのため、ディレクトリの拡大、移動先の出現、あるいは別のファイルを指すようになったパスがあると、呼び出しは対象を黙って拡大せずに停止します。
ローカルツール
| ツール | 読み取る情報 | 書き込む内容 |
|---|---|---|
list_local | ファイル、サイズ、日付 | — |
find_duplicates | ファイルの内容(SHA-256) | — |
find_large_files | サイズ | — |
find_old_files | 更新日時 | — |
storage_summary | サイズ(拡張子別、ディレクトリ別) | — |
move_local | 移動元と、移動先で置き換える対象のサイズ | ファイル、フォルダー、またはシンボリックリンクを移動します。置き換えられた移動先はゴミ箱に移動します。ボリュームをまたぐ場合は、コピーして検証してから移動元を削除します |
rename_local | — | 既存の名前を上書きせず、その場で名前を変更します |
create_local_folder | — | ディレクトリを作成します |
trash_local | ゴミ箱に移動するサブツリーのサイズ | アイテム自身のボリューム上にあるゴミ箱ディレクトリに移動し、マニフェストを書き込みます |
デフォルト値はすべて呼び出しごとに上書きできます。list_local は 200 行を返し、それ以外の一覧表示ツールは 100 行を返します。find_large_files は min_bytes 100,000,000(100 MB)から開始します。find_old_files は older_than_days 365 から開始します。find_duplicates は空のファイルをスキップし(min_bytes 1)、最大 max_files_hashed 20,000 個をハッシュ化して、100 個のグループを返します。各グループに含まれる複製は最大 50 個です。storage_summary は拡張子の上位 15 件とディレクトリの上位 15 件を報告します。すべてのスキャンは、すべてのルートを合わせて max_files 200,000 個のファイルに達すると停止し、ルートとその下のサブディレクトリを 64 階層までたどります。
すべての上書き値には上限があり、MCP スキーマとツール自体の両方で適用されます。limit は 10,000 行、max_files は 1,000,000、max_files_hashed は 1,000,000、trash_local の呼び出しごとの paths は 1,000 件、パスは 4,096 文字、new_name は 255 バイトまでです。拒否メッセージには、長すぎる値の先頭部分のみが引用されます。
find_old_files が報告するのは更新日時であり、これは信頼性の低い指標です。一部のコピー操作では更新日時がコピーした日付にリセットされます。また、変更されていないファイルが不要なファイルとは限りません。アシスタントが候補一覧を確定事項のように提示しないよう、ツール自身の結果にこの注意が含まれます。
スキャンは網羅的ではありません
すべての読み取りツールは同じ方法でスキャンし、デフォルトでは次の項目をスキップします。
- 隠し項目。
include_hidden: trueを渡すと対象に含めます。 - 名前で判定される 19 個のビルドおよびキャッシュディレクトリ。場所を問わず、次のものをスキップします。
node_modules、.git、.svn、.hg、.cache、.venv、venv、__pycache__、.next、.turbo、dist、build、target、Pods、.gradle、.tox、.mypy_cache、.pytest_cache、およびこのサーバー独自の ゴミ箱。コードツリーの外ではbuild、dist、targetは一般的なフォルダー名なので、実際のデータが除外されることがあります。現時点ではこのリストを上書きする方法はありません。 - シンボリックリンク。常にスキップされ、上書きする方法はありません。
これら 3 種類の件数は結果の警告に記載されるため、合計が少なすぎる場合はその理由が分かります。ただし、これをもって storage_summary がディスク使用量を調べるツールになるわけではありません。開発者のホームディレクトリを指定するとその旨は伝えますが、容量を消費している場所までは分かりません。
すべてのルートをスキャンする前に max_files の上限に達した場合、結果ではスキャンしたルートが scanned に、スキャンしていないルートが not_scanned に一覧表示され、警告にもそのルートが記載されます。
ゴミ箱を空にする
このサーバーはゴミ箱を空にしませんし、空にすることもできません。trash_local は各アイテムを、アイテムとそのルートの間にある、アイテム自身のボリューム上の最も上位のディレクトリにある .shieldfive-mcp-trash/<batch>/ に移動します。通常はルート自体ですが、アイテムがルート内にマウントされたドライブ上にある場合は、そのドライブの最上位ディレクトリです。<batch> はタイムスタンプ、プロセス ID、カウンターで構成されるため、呼び出しごとに別の値になります。アイテムを移動する前に、アイテムの元の場所を一覧にした manifest.json を同じ場所に書き込みます。trashed_to の場所が存在しないエントリは、移動予定だったものの、移動されなかったことを示します。実際に削除するには、そこにある内容を確認したうえで、自分で rm -rf を実行してください。このツールがディスク領域を解放することはありません。
マウントポイントはゴミ箱に移動できません。ルート内に、同じボリューム上でそのマウントポイントを格納できるディレクトリがないためです。.shieldfive-mcp-trash がシンボリックリンクまたはファイルの場合、trash_local と、既存のものを上書きする move_local は、それをたどらずに処理を拒否します。
ボリューム間の移動
rename(2) はボリュームをまたげないため、ボリューム間の移動はコピーしてから元のファイルを削除する処理になります。これは、このサーバーが作成したものを削除する唯一のケースです。どの段階で失敗しても何も失われないよう、次のように処理します。
- コピーは、移動先の隣にある新しい隠し名(
.shieldfive-mcp-incoming-<pid>-<n>)で作成されます。排他的に作成し、既存のものを置き換えずに配置します。すでにそこにあったものには触れません。 - シンボリックリンク、FIFO、ソケット、デバイスファイルを含むフォルダーは、コピーではそれらを忠実に保持できないため、何も削除する前に拒否されます。
- すべてのファイルをディスクにフラッシュし、コピー元と比較します(サイズと SHA-256 が同一であること)。また、コピー中にコピー元が変更されていないことも確認します。どちらかの確認に失敗した場合、コピーは破棄され、コピー元はそのまま残ります。
- コピーされたファイルと同一のファイルである場合に限り、コピー元をファイル単位で削除します。フォルダーは空になった場合にのみ削除します。移動中に変更または追加されたものはその場所に残し、
source_left_in_placeに記載します。
途中でクラッシュすると、その隠し名の下に不完全なコピーが残ることがあります。コピーが配置されるまでは、コピー元はそのまま残ります。
キャンセル
キャンセルされたリクエストでは、変更は開始されません。trash_local は項目ごとに処理を停止し、項目の途中では停止しません。そのため、各項目は移動されて記録されるか、変更されずに残り、エラーにはどの項目かが示されます。move_local がコピー元の削除開始前にキャンセルされた場合、置き換えられたものも含めて元の状態に戻します。その時点を過ぎてからキャンセルされた場合は処理を完了します。停止すると、両側にツリーの一部ずつが残ってしまうためです。MCP SDK はキャンセルされたリクエストに応答を返さないため、キャンセルされた呼び出しが何を実行したかは、サーバーの stderr ログに記録され、ゴミ箱への移動の場合はマニフェストにも記録されます。
封じ込めの仕組み
アシスタントから指定されたすべてのパスは、指定どおりに使用されます。そのため、"report "が"report"として扱われることはありません。また、読み取りや書き込みを行う前に、すべてのシンボリックリンクをたどってrealpathで解決されます。解決後のパスは、設定されたルート内になければなりません。区切り文字を考慮した境界チェックにより、/data/roots-evilがルートの/data/rootに一致することはありません。
この順序が重要です。指定されたパス文字列をチェックするだけでは、..によって回避されます。path.resolveの後にチェックしても、シンボリックリンクによって回避されます。たとえば、/allowed/link -> /etcは、/etcを読み取るにもかかわらず、/allowed配下の文字列に解決されます。先にリンクを解決すれば、この両方を防げます。そのため、ディレクトリの走査にはlstatを使用し、リンクをたどらないようにしています。走査中にリンクをたどってしまうと、パスの封じ込めチェックがそのパスを検出できなくなるためです。
移動先など、まだ存在しない宛先は、最も近い既存の祖先パスを解決してから、残りのパスを付け足してチェックします。これにより、シンボリックリンクを含む親ディレクトリを通じた書き込みを、書き込み後ではなく前に検出できます。リンク先が存在しないシンボリックリンクは、書き込みがそこを通る場合は拒否されます。realpathはこのリンクを存在しないパスと同様に報告するため、その結果をそのまま受け入れると、コピー先がリンクの指す場所になってしまうおそれがあります。
たどらないものは、変更ツールが操作対象にする項目だけです。move_local、rename_local、またはtrash_localにシンボリックリンクを渡すと、mvの動作と同様に、リンク自体が移動、名前変更、またはゴミ箱への移動の対象となり、リンク先には触れません。ルート内になければならないのは、リンク自体の場所だけです。移動先についても同様です。そこにあるシンボリックリンクは、リンク先が存在するかどうかにかかわらず、移動先のフォルダーではなく、overwrite: trueの場合にゴミ箱へ移される既存の項目です。フォルダーの実際のパスを指定してください。
rename_localとmove_localは、移動先のチェック後にそこへ現れた項目を置き換えません。ファイルは新しい名前にハードリンクを作成してから、古い名前を解除します。シンボリックリンクは再作成されます。フォルダーは、直前に作成した空のプレースホルダーの上に名前を変更します。その間に何かが現れた場合、上書きするのではなく操作が失敗します。こうした操作ができない場合、つまりFIFO、ソケット、デバイスファイル、FATやexFATのようにハードリンクに対応していないファイルシステム、Windows上のフォルダーでは、ツールはチェック後に名前を変更します。その瞬間に作成されたファイルは置き換えられます。
テストで検証していること
npm test では256件のテストが実行されます。特に知っておく価値があるものは次のとおりです。
- サーバーがあるファイルの暗号文と鍵を別のファイルのものと入れ替えた場合、そのファイルは拒否されます(ポスト量子方式とAES-GCM v1)。ヘッダーのファイルIDは、その行のファイルIDと一致している必要があります。UUIDv7 IDで作成された行にv4の名前をコピーしても表示されず、アップロードではファイル名とヘッダーの両方が、新たに作成される行のIDにひも付けられます。
- ルートの外を指すシンボリックリンクは、読み取り側でも書き込み側でも拒否されます。書き込み先にあるリンク先が存在しないシンボリックリンクも同様です。
- ルートの外を指すシンボリックリンクである
.shieldfive-mcp-trashは拒否され、そのリンクを経由した書き込みは行われません。 - 同じ名前とサイズでも内容が異なる2つのファイルは重複として報告されず、1つのファイルに対する2つの名前が、回収可能な容量として二重に数えられることもありません。
trash_localは、同じボリューム上の新しい場所でもバイト列を読み取れる状態に保ち、space_freed_bytes: 0を報告します。- ルート内にマウントされたRAMディスクを使う場合、ボリュームをまたぐ移動では、コピーが破損して届いた場合や、コピー中に変更された場合も元ファイルが残されます。既存ファイルは元のステージング名のまま保たれ、FIFOを含むフォルダーは拒否され、リンク先が存在しないシンボリックリンクを経由した書き込みは行われません。これらのテストはmacOSで実行され、それ以外の環境ではスキップされます。
- チェックと名前変更の間に新しい名前でファイルが作成された場合、そのファイルは置き換えられません。
- リクエストがキャンセルされると何も移動されず、途中でキャンセルされたゴミ箱への一括操作では、実際に移動したものだけが正確に報告されます。
fetchを呼び出すのはsrc/vault/api.mjsのみで、接続先はhttpsのShieldFiveオリジンに限られます。ローカルツールのモジュールがVault側から何かをインポートすることはなく、読み取られる環境変数はSHIELDFIVE_MCP_ROOTS、SHIELDFIVE_MCP_CONTENTS、SHIELDFIVE_GRANT、SHIELDFIVE_API_URLのみです。- アップロードでは、まずファイルを開き(
O_NOFOLLOWを指定)、開いたファイル記述子をfstatで確認します。シンボリックリンクや、プラン作成後に差し替え・書き換えられたファイルは拒否されるため、暗号化される内容は確認済みの内容と完全に一致します。 - 破壊的な操作の確認済み呼び出しでは、クライアントが対応している場合、ユーザーに確認を求めます。拒否しても何も変更されません。
--no-contentsを指定するとコンテンツツールは無効になり、一覧表示のみの接続ではコンテンツツールの利用が拒否されます。- ブラウザーへの引き継ぎは、このパッケージにおける唯一の受信ソケットと唯一のサブプロセスです。
src/vault/connect.mjsは127.0.0.1でランダムなポートにバインドし、自ら接続を開くことはなく、固定のコマンドを使い、シェルを介さずにブラウザーを起動します。別のオリジンから、異なるstateで、別のHost宛てに、別のメソッドで、または最初の配信後に届いた配信は拒否されます。 - Vaultのモジュールはファイルシステムモジュールをインポートしないため、復号されたデータがディスクに書き込まれることはありません。独自に暗号、HMAC、KDFを使用するモジュールもありません。暗号処理はすべて
@shieldfive/cryptoから提供されます。 - 3種類すべてのVault形式で実際の暗号文を提供するインメモリのShieldFiveに対し、実際のMCPクライアントを使って次のことを検証します。
- ファイルはgrantの鍵のみで復号され、スコープ外のものが一覧表示、読み取り、リクエストされることはありません。
- 接続が取り消されるか期限切れになると、次の呼び出しが失敗します。
- 名前変更と移動では、名前と鍵が再封印されるため、所有者自身の鍵で引き続き開けます。
- grantのシークレットとトークンが、リクエスト本文やパスに現れることはありません。
- アシスタントにすべてをゴミ箱に移すよう指示する内容を含むファイルは、閉じることのできないフェンス内に返されます。そのファイルの読み取りで発行されるのは読み取りだけであり、51項目のゴミ箱への移動呼び出しは拒否されます。
- 実際のstdioトランスポートを使う実際のMCPクライアントには、接続が設定されていない場合、ローカルツールが9つだけ表示されます。npmによるインストール時のように、サーバーがシンボリックリンク経由で起動された場合も同様です。
ネットワークに関する検証の限界についても明記しておく価値があります。この検証で証明されるのはsrc/の動作であり、依存関係ツリーが行い得ることではありません。@modelcontextprotocol/sdkには、他者のサーバー向けHTTPトランスポートが含まれています。この隔たりを埋めるのは、server.mjsがstdioトランスポートのみをインポートし、HTTPトランスポートをインポートしないことです。これも検証されています。
制限事項
- プランの確認により、プレビューと実行の間の差は縮まりますが、なくなるわけではありません。 比較は確定した呼び出しの中で行われるため、その確認から実際の書き込みまでの間に変更が加わる可能性は残ります。各ツールは書き込みの直前にそれぞれの書き込み先を再確認するため、この時間差はなくなるのではなく小さくなります。また、パスを基準とするツールでこれ以上の対策はできません。
- プランで固定されるのは、プラン内で指定した内容です。 ディレクトリの場合、対象となるのはディレクトリ自体と、その配下のファイル数およびバイト数です。これにより、内容の追加、削除、サイズ変更は検出できますが、同じ秒のうちに同じ長さのままファイルの内容が編集された場合は検出できません。
- サイズはファイル内容のサイズです。 ディレクトリの管理領域は含まず、ファイルシステムの圧縮、スパースファイル、ハードリンク、APFS クローンも考慮しないため、合計サイズはディスクユーティリティの値と正確には一致しません。
storage_summaryは、ハードリンクされたファイルの各名前をすべて数えます。 - APFS クローンはコピーのように見えます。
find_duplicatesはこれらを回収可能として報告しますが、ゴミ箱に移動しても、解放される領域はほとんどないか、まったくありません。 - スキャンには上限があります。 デフォルトではファイル数が 200,000 件までで、ルートと、その下のサブディレクトリ 64 階層までです。上限に達した場合、結果にはフィールドだけでなく概要行にもその旨が記載されます。上限で停止したスキャンは、そうでなければ完了したスキャンとまったく同じように見えるため、アシスタントが部分的な一覧を全件として報告してしまいます。
- ボリューム間の動作は macOS でのみテストしています。 テストでは、一時ディレクトリ内に RAM ディスクをマウントしています。
- Windows ではテストしていません。 POSIX 専用の API は使用しておらず、パスの処理には
node:pathを使っていますが、Windows での実行実績はありません。
その他の内容については SECURITY.md をご覧ください。そこでは、チェックと使用の間の時間差、名前の変更によって置き換えが起こり得るタイミング、ハードリンク、環境変数を引き継ぐ場合に当てはまることと当てはまらないこと、ネットワーク通信を行わないという保証の範囲について説明しています。
プライバシーポリシー
ShieldFive への接続が設定されていない限り、このサーバーはどこにもデータを送信しません。設定されている場合も、送信先は ShieldFive の API(https://shieldfive.com、または SHIELDFIVE_API_URL で指定したオリジン)のみです。
- 送信する情報: ボールトツールが必要とするリクエストです。具体的には、一覧、読み取り、ID による変更、アップロードの場合はこのマシン上で生成した暗号文とラップ済みキーです。ファイル名と内容は外部に送信される前に暗号化されます。ストレージへのアップロードは署名付きストレージ URL に直接送信され、接続認証情報が含まれることはありません。
- 送信しない情報: 暗号化されていない名前や内容、ローカルパス、ローカルフォルダーに関する情報、テレメトリ、分析データです。ローカルツールはネットワークリクエストを一切行いません。
- ShieldFive が保持する情報: 接続記録と、実行した各リクエストの記録(ID、アクション、結果、時刻。名前、内容、IP アドレス、ユーザーエージェントは含まれません)です。アカウントの存続中は保持され、アカウントとともに削除されます。これらの記録、その保持期間、および記録に関するお客様の権利については、ShieldFive プライバシーポリシーのセクション 3.9 をご覧ください。
- アシスタントが受け取る情報: このサーバーを通じて読み取られ、ここで復号された情報は、そのアシスタントの運営者に送られます。これは、その会話内のその他の情報と同様に、運営者の規約に従います。
- 認証情報: OS のキーチェーン(または
SHIELDFIVE_GRANT)に保存され、ログに記録されたり、返されたりすることはありません。キーチェーンを利用できない場合に限り、ファイルに書き込まれ、そのファイルはお使いのユーザーアカウントのみが読み取れます(ボールトを接続するをご覧ください)。
お問い合わせ先:[email protected]。脆弱性については [email protected] までご連絡ください。
セキュリティ
脆弱性は [email protected] までご報告ください。SECURITY.md をご覧ください。
ライセンス
MIT。0.6.3 以前のバージョンは Apache-2.0 のもとで公開されていました。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。