mcpField
F
fs-mcp-rs

fs-mcp-rs

ローカル
github.com/nihmadevファイル・ストレージ813 週間前に更新

fs-mcp-rs について

fs-mcp-rsは、AIクライアントに選択したディレクトリへの制限付きアクセスを提供するRust製のファイルシステムMCPサーバーです。読み書きツールや検索に加え、任意でターミナルセッションを利用でき、パス範囲と安全制限を設定できます。

主な機能

  1. 01許可リストによるルート制限
  2. 02読み取り専用または書き込みツール
  3. 03文字列・正規表現検索
  4. 04Git ignoreと隠しファイル制御
  5. 05任意の制限付きターミナルセッション

活用シーン

  1. 01選択したプロジェクトディレクトリをMCPクライアントに公開
  2. 02読み取り専用のファイルアクセスを提供
  3. 03テキストやパターンでプロジェクトファイルを検索

MCP 対応

STDIO JSON-RPCまたはHTTP経由で、MCPクライアントにファイルシステムツールを公開します。アクセス可能な範囲は設定済みのルートに限定され、ターミナル実行は任意です。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"nihmadev-fs-mcp-rs": {
"command": "npx",
"args": [
"-y",
"fs-mcp-rs"
]
}
}
}
起動コマンドnpx -y fs-mcp-rs

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
npmfs-mcp-rs1.2.4

ツール

ツール一覧はまだ取得されていません

ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。

詳細

fs-mcp-rs Crates.io docs.rs License Rust 1.85+ MCP

English Русский

Rust で書かれた、Model Context Protocol(MCP)用の高速で設定可能なファイルシステムサーバーです。

fs-mcp-rs は、オペレーターが選択したディレクトリ内にアクセスを制限しながら、MCP クライアントに少数のファイルシステムツールを提供します。暗黙のファイルシステムルートや、組み込みの個人用パス、書き込み可能なデフォルト設定はありません。サーバーは設定ファイルを指定した場合にのみ起動します。

なぜ単一のクレートなのか?

公開配布物は、どちらも fs-mcp-rs という名前の単一クレートと単一実行ファイルです。プロトコル、ポリシー、ファイルシステム、検索、設定の各コンポーネントは、そのクレート内で独立した Rust モジュールとして構成されています。これにより、インストールが簡単になります。

cargo install fs-mcp-rs

ユーザーは内部クレートの依存関係グラフをインストールしたり、理解したりする必要はありません。ベンチマークランナーは開発専用のワークスペースメンバーとして残され、crates.io パッケージには含まれません。

機能

  • JSON-RPC HTTP POST および行区切り STDIO(stdin/stdout)での MCP。
  • npx fs-mcp-rs によるインストール不要の実行。
  • 1 つ以上のファイルシステムルートを明示的に許可リストで指定(CLI の位置引数または TOML 設定ファイル)。
  • 安全なデプロイ向けの読み取り専用モード。
  • 書き込み、移動、編集、ディレクトリ作成、削除の各操作を任意で有効化。
  • 読み取り、書き込み、検索結果、同時実行数の上限設定。
  • リテラル検索と正規表現によるコンテンツ検索。
  • .gitignore のサポートと、隠しファイルの取り扱い設定。
  • シンボリックリンクのたどり処理はデフォルトで無効。
  • アトミックなファイル置換と BLAKE3 ハッシュ。
  • 時間と出力に上限を設けた、任意の端末コマンド実行。
  • 出力カーソルによる差分取得、ロングポーリング、stdin、プロセスツリーの終了、保持期間、上限付きバッファーに対応した永続的な端末セッション。
  • 簡潔なツール実行ログ([OK] / [WARN])。
  • テレメトリーおよび自動ネットワーク検出なし。

要件

  • npx で実行する場合は Node.js(v18 以上)、ソースからビルドする場合は Rust 1.85 以上。
  • STDIO JSON-RPC または Streamable HTTP/JSON-RPC エンドポイントで接続できる MCP クライアント。
  • 設定ファイル、またはサーバーに渡す明示的なルートパス。

インストール

npx を利用(インストール不要)

Claude Desktop や Cursor などの任意の MCP クライアントで fs-mcp-rs を実行する最も簡単な方法は、npx を使うことです。

npx fs-mcp-rs /path/to/project

npm パッケージが、お使いのオペレーティングシステムとアーキテクチャに適した事前ビルド済みバイナリを自動的にダウンロードします(Windows x64、Linux x64、macOS x64/arm64)。

crates.io から
cargo install fs-mcp-rs
fs-mcp-rs --version
ソースから
git clone https://github.com/nihmadev/fs-mcp-rs.git
cd fs-mcp-rs
cargo build --release

実行ファイルは、Unix 系システムでは target/release/fs-mcp-rs、Windows では target\release\fs-mcp-rs.exe に生成されます。

設定ファイルを作成する

configs/example.toml を適切な場所にコピーして編集します。サーバーには意図的にデフォルトの設定ファイルパスがありません。

cp configs/example.toml fs-mcp-rs.toml

Windows PowerShell の場合:

Copy-Item configs\example.toml fs-mcp-rs.toml

最小限の読み取り専用設定:

[server]
host = "127.0.0.1"
port = 8000
max_concurrency = 32
max_io_concurrency = 16

[filesystem]
roots = ["/home/alice/projects"]
read_only = true
max_read_bytes = 8388608
max_write_bytes = 8388608
follow_links = false

[search]
max_results = 1000
max_concurrency = 4
worker_threads = 4
regex_cache_capacity = 64
include_hidden = false
respect_gitignore = true

# WARNING: enables arbitrary commands with the server process permissions.
[terminal]
enabled = true
max_concurrency = 2
default_timeout_ms = 30000
max_timeout_ms = 300000
max_output_bytes = 4194304

Windows のルートは、エスケープしたバックスラッシュまたはスラッシュを使います。

roots = ["C:\\Users\\Alice\\Projects", "D:/Shared/Documentation"]

相対ルートは、任意のプロセス作業ディレクトリではなく、設定ファイルが置かれているディレクトリを基準に解決されます。

設定リファレンス
[server]
  • host:バインドする IP アドレスです。リモートクライアントからのアクセスが本当に必要な場合を除き、127.0.0.1 のままにしてください。
  • port:/health および /mcp 用の TCP ポートです。
  • max_concurrency:同時に処理する MCP リクエストの最大数です。
  • max_io_concurrency:同時に実行する検索以外のファイルシステムジョブの最大数です。
  • log_tools:簡潔なツール実行ログ([OK] / [WARN])を出力するかどうかです(デフォルト:true)。
[filesystem]
  • roots:許可するディレクトリの空でないリストです。リクエストされたすべてのパスは、そのいずれかのディレクトリ内に解決される必要があります。
  • read_only:true の場合、すべての変更を伴うツールが拒否されます。
  • max_write_bytes:許可される write_file の最大サイズ、または edit_text の結果の最大サイズです。
  • follow_links:シンボリックリンクを含むパスをたどるかどうかです。影響を確認していない場合は、false のままにしてください。
[search]
  • max_results:1 回の検索で返される一致結果の最大数です。
  • max_concurrency:同時検索ジョブの最大数です。
  • worker_threads:各検索で使用するファイルシステム走査スレッド数です。
  • regex_cache_capacity:メモリにキャッシュするコンパイル済み検索パターンの数です。0 にするとキャッシュが無効になります。
  • include_hidden:隠しファイルと隠しディレクトリを含めます。
  • respect_gitignore:ディレクトリの走査時に Git の ignore ファイルを適用します。
[terminal]
  • enabled:コマンド実行を公開するかどうかです。無効の場合、run_command はツールエラーを返します。
  • max_concurrency:同時に実行できるターミナルコマンドの最大数です。
  • default_timeout_ms:呼び出しでタイムアウトが指定されていない場合に使用するタイムアウトです。
  • max_timeout_ms:呼び出しで指定できるタイムアウトの最大値です。
  • max_output_bytes:ターミナルセッションごとに保持する stdout/stderr の合計バイト数の上限です。古い出力は削除され、削除または切り詰められたことが報告されます。
  • max_read_bytes:1 回の terminal_read 呼び出しで返される出力バイト数の上限です。
  • max_wait_ms:1 回の terminal_read 呼び出しにおけるロングポーリング時間の上限です。
  • session_retention_ms:完了したセッションとその出力を、自動クリーンアップまで読み取り可能な状態で保持する時間です。

run_command は、Windows では cmd.exe を通じて、GNU/Linux および macOS では /bin/sh を通じて任意のコマンドを実行します。破壊的操作およびオープンワールドを示す MCP アノテーション付きで公開されるため、互換性のあるプロバイダーでは警告を表示できます。有効にすると、コマンドはサーバーを実行しているオペレーティングシステムアカウントのすべての権限を持ちます。ファイルシステムのルートや読み取り専用モードによって、ターミナルコマンドがサンドボックス化されることはありません。

不明なフィールドと値が 0 の安全制限は拒否されます。これにより、設定の誤記が無視されずに検出されます。

サーバーを起動する

位置指定のルートパス(クイックスタート)

コマンドラインで許可するファイルシステムのディレクトリを指定して、直接起動します。

fs-mcp-rs /home/alice/project1 /home/alice/project2

設定ファイルも位置指定のルートパスも渡されない場合、fs-mcp-rs は現在の作業ディレクトリに限定したデフォルト設定を使用します。

設定ファイルを使用する場合

設定を明示的に渡します。

fs-mcp-rs --config /absolute/path/to/fs-mcp-rs.toml

または、環境変数を使用します。

FS_MCP_CONFIG=/absolute/path/to/fs-mcp-rs.toml fs-mcp-rs

PowerShell:

$env:FS_MCP_CONFIG = "C:\config\fs-mcp-rs.toml"
fs-mcp-rs
トランスポートモード(STDIO と HTTP)
  • STDIO モード:stdout/stdin が非対話型のパイプである場合(MCP サブプロセスとして起動された場合など)、または --stdio を渡した場合に自動的に有効になります。行区切りの JSON-RPC メッセージ用に stdout をクリーンに保つため、構造化ログは stderr に書き込まれます。
  • HTTP モード:対話型の実行中はデフォルトで有効になります。設定されたホストとポートで /health および /mcp エンドポイントをリッスンします。

HTTP のヘルス状態を確認します。

curl http://127.0.0.1:8000/health

期待されるレスポンス:

ok

MCP エンドポイント:

http://127.0.0.1:8000/mcp
サーバーとトンネルを同時に起動する

run サブコマンドは常に HTTP モードで MCP サーバーを起動し、同じプロセスのライフサイクル内で ngrok、Cloudflare Quick Tunnel、または zrok のパブリック共有を管理できます。

fs-mcp-rs run --ngrok /path/to/allowed/directory
fs-mcp-rs run --ngrok --config ./fs-mcp-rs.toml
fs-mcp-rs run --cloudflared /path/to/allowed/directory
fs-mcp-rs run --zrok /path/to/allowed/directory

プロバイダーは同時に使用できません。Windows では、デフォルトでトンネルが新しいコンソールで開きます。別のコンソールを表示せず、生成された URL を現在のターミナルに表示するには --tunnel-window hidden を使用します。通常どおりアタッチするには --tunnel-window inherit を使用します。Linux と macOS では、新しいターミナルウィンドウの作成はデスクトップ環境に依存するため、new は現在のターミナルを継承します。各プロバイダーでは、繰り返し指定可能な追加引数と、実行ファイルの明示的なパスを指定できます。

fs-mcp-rs run --ngrok --tunnel-window hidden --ngrok-arg=--region=eu
fs-mcp-rs run --ngrok --ngrok-bin /opt/ngrok/ngrok
fs-mcp-rs run --cloudflared --cloudflared-arg=--no-autoupdate
fs-mcp-rs run --zrok --zrok-bin /opt/zrok/zrok

MCP サーバーを停止すると、トンネルプロセスも停止します。fs-mcp-rs [PATHS]、fs-mcp-rs --config FILE、fs-mcp-rs serve などの既存の呼び出し方法は変更されません。以前の --ngrok-window という表記も、--tunnel-window のエイリアスとして引き続き使用できます。

セキュアなトンネルを通じてサーバーを公開する

リモート MCP クライアントでテストする場合は、fs-mcp-rs をループバックにバインドしたまま、トンネル経由で公開します。まずサーバーを起動します。

fs-mcp-rs --config ./fs-mcp-rs.toml

トンネルを作成する前に、ローカルエンドポイントを確認します。

curl http://127.0.0.1:8000/health

注意

パブリックトンネルの URL を使うと、リモートクライアントが設定で許可されたツールやファイルシステムのルートにアクセスできるようになります。まず read_only = true に設定し、範囲を狭く限定したルートのみを許可してください。シークレットを公開せず、不要になったらトンネルを停止してください。Quick Tunnel は開発用であり、恒久的な本番環境でのホスティングを目的としたものではありません。

Cloudflare Tunnel

cloudflared をインストールし、一時的な Quick Tunnel を作成します。

cloudflared tunnel --url http://127.0.0.1:8000

cloudflared は https://random-name.trycloudflare.com のような一時的な URL を出力します。末尾に /mcp を追加した MCP エンドポイントを使用します。

https://random-name.trycloudflare.com/mcp

固定ホスト名を使用するには、名前付き Cloudflare Tunnel を作成し、DNS ホスト名を割り当てて、そのホスト名を http://127.0.0.1:8000 にルーティングします。長期稼働するデプロイは、Cloudflare Access などの認証レイヤーで保護してください。

ngrok

ngrok をインストールし、アカウントで必要な場合は CLI を認証してから、HTTP トンネルを起動します。

ngrok http 8000

ngrok に表示される HTTPS 転送 URL を使用し、末尾に /mcp を追加します。

https://example.ngrok-free.app/mcp

ローカルのインスペクション UI は通常 http://127.0.0.1:4040 で利用できます。リクエストの詳細が公開される可能性があるため、ローカルに留め、公開しないでください。

リモート MCP クライアントに接続する

パブリック HTTPS URL を、HTTP/Streamable HTTP MCP サーバーとして使用します。

{
  "mcpServers": {
    "filesystem": {
      "transport": "http",
      "url": "https://your-public-host.example/mcp"
    }
  }
}

トンネルの起動後、両方のエンドポイントをテストします。

curl https://your-public-host.example/health
curl -i https://your-public-host.example/mcp

単純な GET /mcp に対する 200 以外の応答は、MCP 通信がプロトコルリクエストを使用するため、想定される場合があります。重要な確認事項は、/health に到達できることと、MCP クライアントがセッションを初期化できることです。

本番環境でのホスティング

継続的に稼働するデプロイでは、プライベートネットワーク/VPN、または認証付きの名前付きトンネルを優先してください。fs-mcp-rs は権限を最小限にした専用アカウントとサービスマネージャーの下で実行し、ループバックにバインドしたままにしてください。トンネルまたはリバースプロキシで TLS を終端し、クライアントアクセスを制限し、設定ファイルのパスを固定して、ログを監視してください。保護されていないパブリック URL だけをセキュリティ境界として頼らないでください。

MCP クライアントを設定する

fs-mcp-rs は、Claude Desktop、Cursor、VS Code、Windsurf などの MCP クライアントで、ローカルの STDIO サブプロセス、またはリモート/ローカルの HTTP サービスとして設定できます。

オプション A:npx を使った STDIO トランスポート(Claude/Cursor に推奨)

事前インストールは不要です。

{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "fs-mcp-rs", "/path/to/allowed/directory"]
    }
  }
}

または、インストール済みのバイナリで --stdio を明示して使用します。

{
  "mcpServers": {
    "filesystem": {
      "command": "fs-mcp-rs",
      "args": ["--stdio", "/path/to/allowed/directory"]
    }
  }
}
オプション B:HTTP トランスポート

fs-mcp-rs を長時間稼働するサービスとして起動し、クライアントを /mcp HTTP エンドポイントに接続します。

{
  "mcpServers": {
    "filesystem": {
      "transport": "http",
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}

認証または TLS を使用せずに、信頼できないネットワークへ HTTP エンドポイントを公開しないでください。

利用可能なツール

  • list_directory:ディレクトリの直下にある項目を一覧表示します。
  • read_file:オフセットと長さを明示して、UTF-8 のバイト範囲を読み取ります。
  • write_file:UTF-8 ファイルをアトミックに作成または置換します。新しい階層パスを作成する場合は createParents: true を設定してください。サーバーは、許可されたルートを検証した後、安全に不足している親ディレクトリを作成します。デフォルトは false です。
  • search_files:ファイル名に文字列が含まれるパスを検索します。
  • search_content:テキストファイル内を、大文字と小文字を区別しないリテラルまたは正規表現で検索します。
  • get_capabilities:サニタイズされた有効な制限、ルート、プロトコルバージョン、および公開されているツールを報告します。
  • list_tree:制限付きで、決定的かつページ分割されたフラットなディレクトリツリーを返します。
  • apply_patch:検証済みの単一ファイル向け統合テキスト差分をアトミックに適用します。dryRun では変更を行いません。
  • file_info:詳細なメタデータと、任意で制限付きストリーミング BLAKE3 ダイジェストを返します。
  • create_directory:ディレクトリを 1 つ作成します。親ディレクトリはあらかじめ存在している必要があります。
  • remove:ファイルまたは空のディレクトリを 1 つ削除します。
  • hash_file:BLAKE3 ファイルハッシュを計算します。
  • move:既存の宛先を上書きせずに移動します。
  • edit_text:期待されるテキスト一致数を正確に指定して、アトミックに置換します。
  • terminal_start:永続コマンドを開始し、セッション ID をすぐに返します。
  • terminal_read:バイトカーソルを使って stdout/stderr イベントを段階的に読み取ります。新しい出力を任意でロングポーリングできます。
  • terminal_write:実行中セッションの stdin に UTF-8 データを書き込みます。
  • terminal_close_stdin:実行中セッションに EOF を送信します。
  • terminal_kill:セッションのプロセスツリー全体を終了します。
  • terminal_close:完了したセッションと保持されている出力を明示的に削除します。
  • run_command:任意のシェルコマンドを実行します。作業ディレクトリとタイムアウトを指定でき、後方互換性のため完了まで待機します。

変更を伴うツールは読み取り専用モードでも表示されますが、明確なツールエラーを返します。これにより、読み取り専用と書き込み可能の両方のデプロイで、1 つのクライアント設定を使用できます。

セキュリティモデル

  1. 読み取り可能なパスはすべて正規化され、設定されたルートに含まれるか検証されます。
  2. 書き込み先はすべて、既存の親ディレクトリを通じて検証されます。
  3. デフォルトでは、シンボリックリンクをたどる操作は拒否されます。
  4. 読み取り、書き込み、結果数、ワーカーの同時実行数には上限があります。
  5. 書き込みでは、保存前に宛先ディレクトリ内の一時ファイルを使用します。
  6. edit_text では置換件数の指定が必須であり、意図しない広範囲の編集を防ぎます。

推奨される本番環境での設定:

  • まず read_only = true に設定します。
  • 可能な限り最小のルートのみを許可します。具体的な理由がない限り、ホームディレクトリやドライブ全体を許可しないでください。
  • ループバックにバインドします。
  • 権限を制限した専用のオペレーティングシステムアカウントで実行します。
  • 必要な場合を除き、隠しファイルは除外します。
  • リモートアクセスが必要な場合は、サーバーの前段に認証と TLS を配置します。
  • 書き込み可能なルートをバックアップし、復元手順をテストします。

操作中に別のプロセスがパスの構成要素を置き換えられる場合、ファイルシステムのチェックはオペレーティングシステム上の競合状態の影響を受けることがあります。信頼できないローカルユーザーと書き込み可能なルートを共有しないでください。

新しいツールの例

パスを試しに調べることなく、有効な制約を確認します:

{"name":"get_capabilities","arguments":{}}

決定的なツリーページを一覧表示し、返されたカーソルを使って続きを取得します:

{"name":"list_tree","arguments":{"path":".","depth":2,"include":["**/*.rs"],"exclude":["target/**"],"maxEntries":100,"cursor":null}}

対象を変更せずに、単一ファイルのパッチを検証します:

{"name":"apply_patch","arguments":{"path":"README.md","patch":"--- a/README.md\n+++ b/README.md\n@@ -1 +1 @@\n-old\n+new\n","expectedBlake3":null,"dryRun":true}}

詳細なメタデータと、サイズ制限付きのストリーミングハッシュを取得します:

{"name":"file_info","arguments":{"path":"README.md","includeHash":true}}

apply_patch は、バイナリ、複数ファイル、新規作成/削除、リネームのパッチを拒否します。すべてのハンクがアトミックに適用されるか、まったく適用されないかのいずれかです。対象の既存の LF または CRLF の規則と、末尾の改行状態を保持します。dryRun は完全な検証を行いますが、読み取り専用モードを含め、ファイルへの書き込みは行いません。

ツリーとパッチの上限に関する設定リファレンス

以下の省略可能な [filesystem] フィールドには検証済みのデフォルト値が設定されているため、既存の設定ファイルも引き続き読み込めます。

フィールドデフォルト値制約
tree_max_depth8再帰の最大深度。正の値
tree_max_entries1000ページごとに返すエントリーの最大数。正の値
tree_max_warnings32スキップされたエントリーに関する警告の最大数。正の値
patch_max_bytes1048576unified-diff 入力の最大バイト数。正の値
patch_preview_bytes16384patch_max_bytes 以下の正の値

list_tree は、検索時の隠しファイルおよび Git の無視設定を使用します。カーソルは不透明で、正規化されたルート、深度、フィルターに紐づいています。要求された各パスは引き続き Policy を通過します。これらのツールによって、ルートの分離、読み取り専用の適用、シンボリックリンクの制限が緩和されることはありません。

stat からの移行

file_info は、以前公開されていた stat ツールに代わるものです。stat は公開もディスパッチもされなくなりました。クライアントは file_info に移行してください。BLAKE3 ダイジェストが必要な場合にのみ、includeHash を設定してください。

ロギング

構造化トレーシングログ

STDIO モードの実行時に stdout を JSON-RPC 2.0 フレーム専用に保つため、構造化トレーシングログはすべて stderr に出力されます。詳細度を制御するには RUST_LOG を設定してください。

RUST_LOG=info fs-mcp-rs --config ./fs-mcp-rs.toml

診断出力にパスが表示されることがあるため、トラブルシューティング時にのみ debug を使用してください。

ツール呼び出しの実行ログ

log_tools = true(デフォルト)の場合、fs-mcp-rs は各ツール呼び出しの概要を1行でログに記録します。

  • 成功:[OK] read_file src/main.rs (3 ms)
  • 警告/エラー:[WARN] read_file outside/allowed/path - OUTSIDE_ALLOWED_ROOT: path outside allowed roots (0 ms)

ツールのログ記録は、TOML 設定の [server] の下に log_tools = false を設定すると無効にできます。

開発とリリースの検証

リリースを開始する前に、ローカルで一連のチェックをすべて実行してください。

cargo fmt --all -- --check
cargo check --workspace --all-targets
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo publish --dry-run -p fs-mcp-rs

Windows では、scripts\build.cmd が同じチェックを実行します。継続的インテグレーション(.github/workflows/ci.yml)では、Ubuntu、macOS、Windows のランナー上でフォーマット、リント、テストが実行されます。GitHub Actions のリリースワークフロー(.github/workflows/release.yml)では、主要なすべてのプラットフォーム向けにコンパイル済みバイナリーのアーカイブがビルドされ、npm パッケージとともにリリースされます。

ベンチマークの方法は BENCHMARKS.md に記載されています。パフォーマンスに関する主張には、生の結果、マシンの詳細、設定、コミットハッシュを添えてください。

ライセンス

Copyright (C) 2026 nihmadev ([email protected]).

GNU GPL version 3 or any later version(GPL-3.0-or-later)のもとでライセンスされています。LICENSE および https://www.gnu.org/licenses/gpl-3.0.html にある公式のライセンステキストを参照してください。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。