claude-checkpoint-mcp について
claude-checkpoint-mcpは、Claude Codeのセッション向けローカルMCPサーバーです。進捗やファイル状態を保存し、クラッシュ、コンテキスト上限、`/clear`の後に作業を再開できます。Gitによる変更検出にも対応します。
主な機能
- 01セッション状態をJSONで保存
- 02簡潔な再開用ブリーフを読み込み
- 03タスク、判断、次の手順を記録
- 04Gitハッシュで変更ファイルを検出
- 05秘密情報らしき値をマスキング
活用シーン
- 01クラッシュや`/clear`の後に作業を再開
- 02コンテキスト上限到達後にタスクを続行
- 03チェックポイント後に変わったファイルを確認
MCP 対応
MCPクライアントに`save_session_checkpoint`と`load_session_checkpoint`ツールを提供します。ローカルで動作し、プロジェクト内にチェックポイントを保存します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y claude-checkpoint-mcpCHECKPOINT_PROJECT_ROOTAbsolute path of the default project to checkpoint (useful for clients without a current project, e.g. Claude Desktop).ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
2掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| goal | string | はい | セッションの主な目標を 1~2 文で記述します。 |
| mode | enum | いいえ | replace:チェックポイントを上書きします。merge:既存のチェックポイントを更新し、コマンド、決定事項、ファイルを追記します。replace | merge |
| tasks | array | いいえ | ステータス付きのサブ目標。merge モードでは、説明が同じタスクが更新されます。 |
| summary | string | いいえ | 現在の状況:動作しているもの、問題があるもの、作業の途中だった内容。 |
| decisions | array | いいえ | 重要な決定事項、制約事項、繰り返さないようにする行き詰まり。 |
| nextSteps | array | いいえ | 引き継ぐ人が順番に実行する具体的な次のアクション。 |
| projectRoot | string | いいえ | プロジェクトの絶対パス。デフォルトでは、クライアントのワークスペースルートまたはサーバーの作業ディレクトリを使用します。 |
| modifiedFiles | array | いいえ | 変更したファイル。任意でメモを追加できます。未コミットの git 変更は自動検出されます。ファイルをここに列挙すると、注釈を付けたり、コミット済みのファイルを含めたりできます。 |
| recentCommands | array | いいえ | 最近実行した重要なターミナルコマンド(ビルド、テスト、マイグレーション)を古い順に記載し、終了コードと結果の短いメモを添えてください。シークレットは自動的に伏せられます。 |
詳細
claude-checkpoint-mcp
Claude Code のセッション状態をローカルに保存するため、クラッシュ、/clear、コンテキスト上限が発生しても、Claude がコンテキストを一から組み立て直す必要はありません。
claude-checkpoint-mcp は、次の 2 つのツールを備えたローカルの Model Context Protocol サーバーです。
save_session_checkpointは、セッションの作業状態をプロジェクト内の小さな JSON ファイルに書き込みます。load_session_checkpointは、そのファイルをコンパクトな再開用ブリーフに変換します。
すべてお使いのマシン上で動作します。どこにもデータは送信されません。
目次
- 理由:同じコンテキストに二度コストをかけないために
- 仕組み
- インストール
- 設定
- 使い方
- ツールのリファレンスと例
.claude-checkpointファイル- セキュリティとプライバシー
- トラブルシューティング
- 開発
理由:同じコンテキストに二度コストをかけないために
Claude Code の長いセッションでは、多くのコンテキストが蓄積されます。
- 何をしようとしているのか。
- すでに失敗したアプローチはどれか。
- どのファイルが重要なのか。
- まだ失敗しているテストはどれか。
作業の途中で、次のようなことが原因でコンテキストが失われる場合があります。
- ターミナルのクラッシュ、SSH の切断、ノートパソコンのスリープ。
- コンテキストウィンドウの上限に達する。
- 新しいウィンドウを使うために
/clearを実行する。
次のセッションは、何もわからない状態から始まります。元の状態に戻るには、Claude がコンテキストを組み立て直さなければなりません。
- **ファイルの再読み込み。**何が、なぜ変更されたのかを把握するためです。ファイルを読むたびに入力トークンが発生します。
- **探索の再実行。**状態を再発見するためだけに、
grep、git diff、ls、テストの実行などを行います。 - **説明のやり直し。**目標や制約、行き詰まった点を再入力するか、Claude が苦労して行き詰まりを再発見します。
これらのたびに、増え続ける会話が入力として再送信されるため、コストが積み重なります。
claude-checkpoint-mcp を使えば、この再構築の代わりに、構造化された小さな読み込みを 1 回行うだけで済みます。
| チェックポイントなし | load_session_checkpoint を使用 | |
|---|---|---|
| 目標と制約の復元 | 再入力するか、Claude が推測します | ブリーフの 1 セクション |
| 完了済みと保留中の把握 | コードと git から再導出します | 状態付きのタスクリスト |
| 重要なファイルの把握 | 広範囲に読み直します | 変更したファイルの正確な一覧とメモ |
| その後に何が変わったかの把握 | 念のためすべて読み直します | 実際に内容が変わったファイルのみが示されます |
| 失敗した試行の記憶 | 繰り返されることが多いです | 決定事項と注意点に記録されます |
一般的なセッションの再開用ブリーフは、約 1.2 KB の Markdownで、数百トークンほどです。以下の例は、実際に出力されたこのサイズのブリーフです。
最も大きな節約につながるのは、変更の検出です。保存時に、サーバーは未コミットの変更があるすべてのファイルについて、内容のハッシュを記録します。読み込み時には、そのハッシュを作業ツリーと照合し、チェックポイント作成後に変更されたファイルを Claude に正確に伝えます。ブリーフ内のそれ以外の情報はそのまま信頼できるため、Claude は必要なファイルだけを読み直します。
仕組み
Session 1 Session 2 (after crash / /clear)
───────── ────────────────────────────────
Claude ──save_session_checkpoint──┐ ┌──load_session_checkpoint── Claude
goal, tasks, summary, │ │ compact markdown brief
next steps, decisions, ▼ │ + "changed since checkpoint"
files, commands ┌─────────────────────┐
│ <project>/ │
server adds: │ .claude-checkpoint │◀── git: branch, HEAD,
git branch/HEAD, │ .claude-checkpoint │ dirty files + hashes
dirty files + hashes, │ .prev (backup) │
redacts secrets └─────────────────────┘
- Claude が意味を提供します:目標、進捗、決定事項、次のステップ、重要だったコマンドです。
- サーバーが事実を提供します:git ブランチと HEAD、未コミットまたは未追跡のファイルすべてとそのコンテンツハッシュ、タイムスタンプです。
- サーバーの指示により、Claude がいつ処理すべきかがわかります。 セッション開始時に読み込み、マイルストーンの後、リスクのある操作の前、会話が長くなったときに保存するよう Claude に指示されています。毎回プロンプトを入力する必要はありません。
インストール
要件:Node.js 20+ と git です。Git は省略できますが、その場合はドリフト検出ができなくなります。
git clone https://github.com/tenlean/claude-checkpoint-mcp.git
cd claude-checkpoint-mcp
npm install
npm run build
サーバーのエントリポイントは dist/index.js になりました。
設定
Claude Code
プラグインとして(最も簡単)。 このリポジトリは Claude Code プラグインのマーケットプレイスでもあります。クローンやビルドは不要です。
claude plugin marketplace add tenlean/claude-checkpoint-mcp
claude plugin install claude-checkpoint-mcp@tenlean
Claude Code を再起動すると、/mcp に plugin:claude-checkpoint-mcp:claude-checkpoint が接続済みとして表示されます。
手動設定。 リポジトリをクローンした場合は、ユーザーアカウントにサーバーを一度登録すれば、すべてのプロジェクトで利用できます。
# Run from the claude-checkpoint-mcp directory
claude mcp add --scope user checkpoint -- node "$PWD/dist/index.js"
絶対パスを使用してください。 ユーザースコープのサーバーは、Claude Code を開いたプロジェクトから起動されます。
./dist/index.jsのような相対パスは、このリポジトリではなく、そのプロジェクトを基準に解決されます。コマンドの実行時に"$PWD/dist/index.js"は絶対パスに展開され、そのパスが保存されます。
登録されていることを確認します。
claude mcp list
セッション内で /mcp に checkpoint が接続済みとして表示されます。
プロジェクトスコープの代替方法。 バージョン管理を通じてチームとサーバーを共有するには、プロジェクトの .mcp.json に追加します。
{
"mcpServers": {
"checkpoint": {
"command": "node",
"args": ["/absolute/path/to/claude-checkpoint-mcp/dist/index.js"]
}
}
}
どちらの場合も、チェックポイントファイルをプロジェクトの .gitignore またはグローバル gitignore に追加します。
.claude-checkpoint*
Claude Desktop(claude_desktop_config.json)
設定ファイルを開きます。
| OS | パス |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
mcpServers の下に、ローカルビルドへの絶対パスを指定してサーバーを追加します。
{
"mcpServers": {
"checkpoint": {
"command": "node",
"args": ["/absolute/path/to/claude-checkpoint-mcp/dist/index.js"],
"env": {
"CHECKPOINT_PROJECT_ROOT": "/absolute/path/to/your/project"
}
}
}
}
ファイルを保存した後、Claude Desktop を再起動します。
Claude Desktop には「現在のプロジェクト」という概念がありません。
CHECKPOINT_PROJECT_ROOTを使用して既定のプロジェクトを設定するか、各呼び出しで Claude にprojectRootを渡してもらいます(「/home/me/code/my-app のチェックポイントを保存して」)。プロジェクトルートの解決方法を参照してください。
その他の MCP クライアント
stdio トランスポートをサポートする MCP クライアントであれば、サーバーを実行できます。
node /absolute/path/to/claude-checkpoint-mcp/dist/index.js
使用方法
サーバーに組み込まれた指示により、一般的なケースは自動的に処理されます。Claude に直接依頼することもできます。
保存:
- 「作業の進捗をチェックポイントに保存して。」
- 「マイグレーションを実行する前にチェックポイントを保存して。」
- 「チェックポイントを更新して。今やったことを反映して。」
再開(新しいセッションで):
- 「前回の続きから再開して。」
- 「チェックポイントを読み込んで続けて。」
再開時の概要の例
これは load_session_checkpoint の実際の出力です。このシナリオでは、保存後に変更のないまま 1 つのファイルがコミットされ、その後、チームメイトが session.ts を編集しました。
# Resuming: my-app (checkpoint saved 2m ago, 2026-10-08 02:23:55 UTC)
Branch `feat/github-oauth` @ b2ef1b591 (uncommitted changes)
## Goal
Add GitHub OAuth login with persistent sessions
## Tasks
- [x] OAuth callback route
- [~] Session cookie persistence
- [ ] Logout endpoint
## Where things stand
Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.
## Next steps
1. Set sameSite: 'lax' and secure only in production in src/auth/session.ts
2. Re-run npm test -- auth
3. Start the logout endpoint
## Decisions & gotchas
- Use iron-session, not express-session (needs edge runtime support)
- Don't mock the GitHub API in e2e tests; use the recorded fixtures in test/fixtures
## Files touched (3)
- src/auth/session.ts (M) — cookie options
- src/auth/callback.ts (M)
- src/auth/session.spec.ts (??)
## Recent commands (last 2, oldest first)
- ✓ `GITHUB_CLIENT_SECRET=«redacted» npm run dev`
- ✗ exit 1 `npm test -- auth` — 2 failing in session.spec.ts: cookie missing after reload
## Since this checkpoint
- 1 new commit(s) on HEAD
- ⚠ Changed after the checkpoint, re-read before editing: `src/auth/session.ts`
callback.ts は保存後にコミットされましたが、内容は変更されていないため、フラグは付いていません。再読み込みが必要なのは session.ts だけです。
タスクマーカー:[x] 完了 · [~] 進行中 · [ ] 保留中 · [!] ブロック中。
ツールのリファレンスと例
save_session_checkpoint
<projectRoot>/.claude-checkpoint に書き込みます。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
goal | string (≤ 500) | ✅ | セッションの主な目標 |
tasks | { description, status }[] (≤ 30) | status: pending · in_progress · done · blocked | |
summary | string (≤ 4000) | 現状の概要:機能していること、問題があること、作業中だったこと | |
nextSteps | string[] (≤ 20) | 再開する人向けの、順序付きの次のアクション | |
decisions | string[] (≤ 20) | 避けるべき重要な決定事項、制約、行き詰まった方法 | |
modifiedFiles | { path, note? }[] (≤ 100) | 注記を付けるファイル、または含めるコミット済みファイル。未コミットの git の変更は自動的に検出されます。プロジェクト内の絶対パスは相対パスとして保存されます。 | |
recentCommands | { command, exitCode?, note? }[] (≤ 50) | 重要なコマンドを古い順に並べます。シークレットは伏せられます。 | |
mode | "replace" | "merge" | デフォルトは replace です。以下を参照してください。 | |
projectRoot | string (absolute) | ルートの解決方法を上書きします |
完全保存:
{
"goal": "Add GitHub OAuth login with persistent sessions",
"tasks": [
{ "description": "OAuth callback route", "status": "done" },
{ "description": "Session cookie persistence", "status": "in_progress" },
{ "description": "Logout endpoint", "status": "pending" }
],
"summary": "Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.",
"nextSteps": [
"Set sameSite: 'lax' and secure only in production in src/auth/session.ts",
"Re-run npm test -- auth"
],
"decisions": ["Use iron-session, not express-session (needs edge runtime support)"],
"modifiedFiles": [{ "path": "src/auth/session.ts", "note": "cookie options" }],
"recentCommands": [
{ "command": "GITHUB_CLIENT_SECRET=gh_live_8f2a91 npm run dev", "exitCode": 0 },
{ "command": "npm test -- auth", "exitCode": 1, "note": "2 failing in session.spec.ts" }
]
}
応答(モデルに表示されるテキスト):
Checkpoint saved to /home/me/code/my-app/.claude-checkpoint (2202 bytes, replace).
3 task(s), 3 file(s), 2 command(s) on feat/github-oauth@b2ef1b591.
⚠ Redacted 1 secret-looking value(s).
merge による増分更新:
{
"goal": "Add GitHub OAuth login with persistent sessions",
"mode": "merge",
"tasks": [
{ "description": "Session cookie persistence", "status": "done" },
{ "description": "Logout endpoint", "status": "in_progress" }
],
"recentCommands": [{ "command": "npm test -- auth", "exitCode": 0, "note": "all green" }]
}
| フィールド | replace | merge |
|---|---|---|
goal | 設定 | 設定 |
tasks | 設定 | description を照合して更新。新しいタスクは末尾に追加 |
summary, nextSteps | 設定 | 指定されていれば置き換え、指定されていなければ維持 |
decisions | 設定 | 追加(重複を除去) |
recentCommands | 設定 | 追加。50 件を超える場合は古いものを削除 |
modifiedFiles | git の新規スキャン結果+指定分 | git の新規スキャン結果+指定分+以前に記録された分 |
id, createdAt | 新規 | 維持 |
構造化出力(structuredContent):
{
"path": "/home/me/code/my-app/.claude-checkpoint",
"bytes": 2202,
"mode": "replace",
"counts": { "tasks": 3, "modifiedFiles": 3, "recentCommands": 2, "redactions": 1 },
"warnings": ["Redacted 1 secret-looking value(s)."]
}
load_session_checkpoint
読み取り専用です。チェックポイントを読み込み、差分を確認して概要を返します。
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
format | "brief" | "full" | デフォルトは brief(上記のような Markdown 形式)です。full はチェックポイント JSON 全体と差分を返します。 | |
projectRoot | string (absolute) | ルートの解決方法を上書きします |
例:
{}
{ "format": "full", "projectRoot": "/home/me/code/my-app" }
構造化出力(structuredContent):
{
"found": true,
"path": "/home/me/code/my-app/.claude-checkpoint",
"fromBackup": false,
"updatedAt": "2026-10-08T02:23:55.477Z",
"drift": {
"branchChanged": false,
"currentBranch": "feat/github-oauth",
"commitsSince": 1,
"changedSince": ["src/auth/session.ts"]
},
"warnings": []
}
チェックポイントが存在しない場合、ツールは「再開するものがありません」というメッセージとともに found: false を返します。これはエラーとして扱われません。
プロジェクトルートの選択方法
projectRoot引数CHECKPOINT_PROJECT_ROOT環境変数- クライアントが MCP roots をサポートしている場合は、クライアントの最初の
file://ルート - サーバープロセスの作業ディレクトリ
パスは絶対パスで、既存のディレクトリを指している必要があります。シンボリックリンクは解決されます。ファイルは常に <root>/.claude-checkpoint に書き込まれます。
.claude-checkpoint ファイル
これはプレーンなバージョン管理付き JSON で、簡単に読み取り、差分を確認、または手動で編集できます。実際の例:
{
"version": 1,
"id": "ee5507c0-855e-44a5-85c1-d97b767537c9",
"createdAt": "2026-10-08T02:23:55.477Z",
"updatedAt": "2026-10-08T02:23:55.477Z",
"generator": { "name": "claude-checkpoint-mcp", "version": "0.1.0" },
"project": { "name": "my-app" },
"git": {
"branch": "feat/github-oauth",
"head": "b2ef1b5919ee5d456ea146c9362a7abc92b1e556",
"dirty": true
},
"goal": {
"primary": "Add GitHub OAuth login with persistent sessions",
"tasks": [
{ "description": "OAuth callback route", "status": "done" },
{ "description": "Session cookie persistence", "status": "in_progress" },
{ "description": "Logout endpoint", "status": "pending" }
]
},
"summary": "Callback exchanges the code and creates a session, but the cookie is dropped on reload. Suspect SameSite/secure flags in dev.",
"nextSteps": [
"Set sameSite: 'lax' and secure only in production in src/auth/session.ts",
"Re-run npm test -- auth",
"Start the logout endpoint"
],
"decisions": [
"Use iron-session, not express-session (needs edge runtime support)",
"Don't mock the GitHub API in e2e tests; use the recorded fixtures in test/fixtures"
],
"modifiedFiles": [
{ "path": "src/auth/session.ts", "status": "M", "source": "git", "note": "cookie options", "hash": "9ec893ef673dac860e7e2b6fcaad602983eeb0b1" },
{ "path": "src/auth/callback.ts", "status": "M", "source": "git", "hash": "f3ecc849c3875d4f11bb42ae0e5ab6c71931d7f1" },
{ "path": "src/auth/session.spec.ts", "status": "??", "source": "git", "hash": "9daeafb9864cf43055ae93beb0afd6c7d144bfa4" }
],
"recentCommands": [
{ "command": "GITHUB_CLIENT_SECRET=«redacted» npm run dev", "exitCode": 0, "at": "2026-10-08T02:23:55.477Z" },
{ "command": "npm test -- auth", "exitCode": 1, "note": "2 failing in session.spec.ts: cookie missing after reload", "at": "2026-10-08T02:23:55.477Z" }
],
"meta": { "redactions": 1, "truncated": false }
}
| フィールド | 備考 |
|---|---|
version | スキーマのバージョンです。古いバージョンは読み込み時に移行され、未知のバージョンは拒否されます。 |
id / createdAt | merge による保存では維持され、replace では新しく作成されます |
git | git リポジトリ外、またはリポジトリの最初のコミット前は null です |
modifiedFiles[].status | Git porcelain のコード(M、A、D、R、??)、または Claude からのみ報告されたファイルの場合は M |
modifiedFiles[].source | git(検出)または agent(Claude による報告、または以前の merge から引き継がれたもの) |
modifiedFiles[].hash | 保存時点の作業ツリーの内容に対応する Git blob ハッシュです。差分検出に使用されます |
meta.truncated | リストまたはサイズの上限に合わせて何かが削除された場合は true です |
パスは常にプロジェクトルートからの相対パスです。このファイルに絶対パスが保存されることはありません。
セキュリティとプライバシー
-
ローカルのみ。 ネットワークへの呼び出しはありません。サーバーは Git のメタデータと 1 つのファイルを読み取り、1 つのファイルを書き込みます。
-
シークレットのマスキング。 コマンド、メモ、要約、タスク、判断に含まれる以下の情報は、ディスクに書き込まれる前に
«redacted»に置き換えられます。*_KEY=,*_TOKEN=,*_SECRET=,*PASSWORD=の代入。Header: value形式と JSON 形式も含みますAuthorization: Bearer …ヘッダー- URL 内の認証情報(
postgres://user:pass@…) --password/--token/--api-key/--secretフラグ- そのまま記載された
sk-…、ghp_…、github_pat_…、AKIA…、xox?-…トークン
マスキングは安全対策であり、保証ではありません。ファイルをバージョン管理の対象外にしてください。
-
所有者のみがアクセスできる、クラッシュに強い書き込み。 ファイルはモード
0600で書き込まれます。保存時には一時ファイルを書き込み、fsync してから所定の場所にリネームするため、保存途中でクラッシュしてもチェックポイントが不完全な状態で残ることはありません。 -
自動バックアップ。 直前の有効なチェックポイントは
.claude-checkpoint.prevとして保持されます。メインファイルが破損している場合、読み込み時にバックアップへフォールバックし、その旨を通知します。破損したファイルによって正常なバックアップが上書きされることはありません。 -
サイズ制限。 各フィールドには長さの上限があり、ファイルサイズも 64 KB に制限されます(最も古いコマンドから削除されます)。そのため、チェックポイントがトークンを大量に消費することはありません。
-
シェルは使用しません。 Git は 3 秒のタイムアウトと
GIT_OPTIONAL_LOCKS=0を指定してexecFile経由で実行されるため、ユーザー自身の Git コマンドと競合することはありません。 -
設定には手を加えません。 チェックポイントが Git の無視対象になっていない場合、保存時の応答で警告します。
.gitignoreを自動で編集することはありません。 -
並列ツール呼び出しにも安全です。 サーバー内でツール呼び出しを直列化するため、並行して実行される
merge保存によって更新が失われることはありません。
トラブルシューティング
| 症状 | 対処方法 |
|---|---|
/mcp に checkpoint が表示されない | claude mcp list を実行し、パスが絶対パスであることと、dist/index.js が存在することを確認します(npm run build)。 |
| チェックポイントが誤ったディレクトリに書き込まれる | サーバーは作業ディレクトリにフォールバックしています。projectRoot を渡すか、CHECKPOINT_PROJECT_ROOT を設定してください。 |
projectRoot must be an absolute path | ./app ではなく、/home/me/code/app のような絶対パスを使用してください。 |
| 概要に「Saved commit … is no longer reachable」と表示される | 保存後にブランチがリベースまたはリセットされています。履歴を基準に差分を計算できないため、警告されたファイルは再読み込みが必要なものとして扱ってください。 |
| 警告:「not git-ignored」 | .gitignore に .claude-checkpoint* を追加してください。 |
| 「Since this checkpoint」セクションがない | プロジェクトが Git リポジトリではないか、保存時にコミットがありませんでした。 |
サーバーのログは stderr に出力されます。標準出力は MCP プロトコル専用です。
開発
npm run typecheck # strict TypeScript, src + tests
npm test # unit tests + in-memory MCP end-to-end tests (vitest)
npm run build # compile to dist/
npm run inspect # open the MCP Inspector against dist/index.js
src/
├── index.ts # entry point: stdio transport, signals, stderr logging
├── server.ts # McpServer construction + server instructions
├── tools.ts # save/load tool schemas and handlers
├── schema.ts # zod schema for the checkpoint file (v1) + migrations
├── store.ts # project root resolution, atomic I/O, backup/fallback
├── git.ts # branch/HEAD/status snapshot, blob hashing, drift detection
├── redact.ts # secret scrubbing
└── render.ts # checkpoint → markdown resume brief
公式の @modelcontextprotocol/sdk と zod を使用して構築されています。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。