🏗️ ARCHITECTURE

全体アーキテクチャ

Claude.ai → Cloudflare Tunnel → LXC上のMCPサーバー → 任意のSSHホスト。

# リクエストの流れ Claude.ai (ブラウザ / モバイル) │ │ POST /mcp?key=ak_xxx&key=uk_aaa │ HTTPS (Anthropic Cloud → Cloudflare Tunnel) ▼ ┌──────────────────────────────────────┐ │ LXC: ssh-mcp-server (port 3000) │ │ │ │ Express + Streamable HTTP MCP │ │ ?key= → KeyStore → CallerContext │ │ (複数キー → 1つのコンテキスト) │ │ │ │ SSH Session Manager (in-memory) │ │ session_token = SHA-256 capability │ └──────────────────┬───────────────────┘ │ SSH (port 22) ▼ Proxmox / LXC / VM / NAS
🔑 AUTHENTICATION

3層認証モデル

門番(Admin Key) → 接続権(User Key) → 操作権(Session Token)

LAYER 1

Admin Key

環境変数で設定。User Key CRUD、全セッション閲覧。SSH新規接続は不可(権限分離)。

?key=ak_a8f3b2c1...
LAYER 2

User Key

MCP経由で発行。SSH接続の作成権。自分のセッションのみ一覧可能。

?key=uk_84e17ac6...
LAYER 3

Session Token

ssh_connectの戻り値。SHA-256ハッシュ。持っていれば誰でも操作可能

sess_e7b2a4f1c3d8...
🔗 MULTI-KEY

マルチキー対応

?key= を複数指定すると、それぞれの権限が合成されます。

# 最強構成: 管理もSSH接続も1つのコネクターで ?key=ak_xxx&key=uk_hori # 2人のセッションを両方見たい ?key=uk_hori&key=uk_tanaka # 管理者が複数ユーザーを同時管理 ?key=ak_xxx&key=uk_hori&key=uk_tanaka
パターンssh_connectssh_listadmin操作
Admin のみ✗ 拒否全セッション
User ×1✓ primary所有自分のみ
User ×2✓ primary所有両方の和集合
Admin + User ×1✓ user所有全セッション
Admin + User ×2✓ primary所有全セッション
💡 Primary User Key = ?key= パラメータで最初に指定したUser Key。ssh_connectで新しいセッションの所有者になります。
⏱️ SESSION LIFECYCLE

セッションのライフサイクル

$ ssh_connect(host, user, pass) → session_token: sess_a3f8b2c1e7d4... → state: CREATED (TTL: 1日) $ ssh_execute(sess_..., "uptime") → state: USED (TTL: 最終使用から3ヶ月) # 3ヶ月後... → state: EXPIRED (auto-disconnected) # または明示的に: $ ssh_disconnect(sess_...) → state: DISCONNECTED

🆕 未使用 (TTL: 1日)

ssh_connect後、execute/upload/downloadを一度も実行していない。放置防止のため短め。

✅ 使用済 (TTL: 3ヶ月)

execute/upload/downloadを1回以上実行。最終使用時刻から3ヶ月。長期利用を想定。

🔒 SECURITY

セキュリティ設計

🔐 全経路HTTPS

Cloudflare Tunnel経由。Claude.ai → Anthropic → Cloudflare → LXC 全てTLS暗号化。直接ポート公開なし。

🛡️ セルフSSH防御

サーバー自身へのSSH接続をブロック。ADMIN_KEYやWEBHOOK_SECRETの漏洩を防止。BLOCKED_HOSTS環境変数 + localhost系は常時ブロック。

🗑️ 認証情報の非保存

SSHパスワード/秘密鍵はリクエスト処理中のみ使用。保存もログ出力もしない。再起動で全セッション消去。

🔗 SHA-256トークン

session_tokenは256bitハッシュ。SSH接続情報を逆算不可能。ブルートフォース不可能。

⚡ ASYNC COMMANDS

非同期コマンド実行

apt installnpm run build など、数分〜数十分かかるコマンドに対応。MCPタイムアウトを超える長時間コマンドも安全に実行。

# 5秒待って途中結果を取得(デフォルト30秒) $ ssh_execute(command="apt install -y nodejs", wait_ms=5000) → command_id: cmd_0001, running: true → stdout: "Reading package lists..." # 後からポーリング(末尾10行だけ取得) $ ssh_command_status(command_id="cmd_0001", tail_lines=10) → running: false, exit_code: 0, elapsed_ms: 34521 # fire-and-forget(即座に返る) $ ssh_execute(command="nohup ./deploy.sh &", wait_ms=0) → command_id: cmd_0002, running: true(バックグラウンド実行)

wait_ms

コマンドの出力を何ms待つか。0で即座に返す。デフォルト30秒。最大120秒。

tail_lines

大量出力の末尾N行のみ返す。apt installの進捗確認等に有効。

command_id

各コマンドにcmd_0001形式のIDが付与。ssh_command_statusで後からポーリング可能。結果は1時間保持。

🔄 CI/CD

GitHub Webhook自動デプロイ

GitHubにPushするだけで本番サーバーが自動更新。約5秒で新コードが稼働。

git push → GitHub Webhook → POST /webhook/github → HMAC-SHA256署名検証 → git pull → npm install → tsc → process.exit(0) → systemd再起動 → 約5秒で本番更新完了
💡 デプロイ失敗時は旧コードのまま稼働継続します(process.exitしない)。

セットアップは4ステップ

LXCデプロイ → Admin Key生成 → Cloudflare Tunnel → コネクター登録

🚀 始め方へ