JumpServer Bastion (jms) について
JumpServer v4 経由で許可済みアセットにアクセスする、運用担当者や AI エージェント向けのコマンドラインクライアント兼 MCP サーバーです。接続プールでセッションを再利用し、ローカル監査ログを記録します。
主な機能
- 01許可済みアセットの一覧と検索
- 02コマンド実行と対話型シェル
- 03ファイルのアップロード、ダウンロード、転送
- 04接続プールと二重アドレスの切り替え
- 05OS の資格情報ストアへの認証情報保存
- 06ローカル JSONL 監査ログ
活用シーン
- 01踏み台経由でリモートサービスの状態を確認
- 02アセット上で運用コマンドを実行
- 03ローカルとリモート間でファイルを転送
- 04AI エージェントの実行記録を確認
MCP 対応
stdio 経由で MCP サーバーを提供し、アセット検索、コマンド実行、ファイル転送のツールを公開します。ツール呼び出しは接続プールを共有し、ローカル監査ログに記録されます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
jms-client
JumpServer v4 の踏み台ホスト向けコマンドラインクライアント兼 MCP サーバーです。 踏み台の背後にあるアセットへウェブターミナルと同じ方法で接続できる、自己完結型のバイナリです。VPN クライアントも、SSH 設定も、ホストごとの認証情報も必要ありません。
単独で使ってアセットの一覧表示、コマンドの実行、シェルの起動、ファイルの転送ができます。jms mcp を実行すれば、AI アシスタント(Claude Desktop、Claude Code、Codex、Cursor、pi など)も、プールされた監査可能な接続を通じて同じ操作を実行できます。
$ jms exec web-01 "systemctl is-active nginx"
active
英語 · 簡体字中国語
ドキュメント: コマンドリファレンス · アドレスとプロキシ · トラブルシューティング · 設計
このプロジェクトの目的
踏み台への接続には通常、ブラウザーのタブを使うか、手作業で管理する ~/.ssh/config が必要です。どちらもシェルパイプライン、ビルドスクリプト、AI エージェントとは連携できません。
jms-client はウェブコンソールが使うのと同じ 2 つの JumpServer API(Core の REST API と KoKo のターミナルゲートウェイ)に接続するため、次のことができます。
- 認証情報が設定ファイルに保存されません。 パスワードと TOTP シークレットは OS の認証情報ストアに保存されます。設定ファイルに含まれるのはアドレスとユーザー名だけなので、安全に同期、バックアップ、コミットできます。
- 1 回のログインで複数のコマンドを実行できます。 接続はサーバー/アセット/アカウント/プロトコルごとにプールされ、再利用されます。
- オフィスの内外で同じ設定を使えます。 サーバーに内部アドレスと外部アドレスの両方を設定すると、応答するほうがクライアントによって選択されます。
- すべての操作がローカルに記録されます。 AI エージェントが実行したすべてのコマンドは、読み取り、追跡、または対話的な結合が可能な JSONL 監査ストリームに書き込まれます。
機能
| 単一の静的バイナリ | ランタイム依存関係はありません。Linux、macOS、Windows の x86_64 および arm64 に対応します。 |
| 2 つのアドレスによるフェイルオーバー | 内部/外部アドレスを自動でプローブして選択し、最後に正常だったアドレスを記憶するため、起動直後もすばやく接続できます。 |
| 接続プール | ログインセッションとターミナルは server/asset/account/protocol ごとに再利用されます。アイドル状態の接続は破棄され、壊れた接続は再構築されます。 |
| OS のストアに認証情報を保存 | Windows Credential Manager、macOS Keychain、Linux Secret Service に対応します。コンテナや CI では環境変数にフォールバックします。 |
| MCP サーバー | AI クライアント向けの 7 つのツールを stdio 経由で提供し、1 つのプールされたプロセスを共有します。 |
| ローカル監査ストリーム | プロセスごとの構造化 JSONL を出力します。jms tail で追跡し、jms attach で監視して接続できます。 |
| 2 種類のターミナルバックエンド | WebSocket(デフォルト。ウェブコンソールと同じ経路)と SSH に対応し、自動で選択されます。 |
要件
- お使いのマシンから KoKo コンポーネントに接続できる JumpServer v4。JumpServer v3 以前はサポートされていません。
- 接続したいアセットへのアクセス権が付与済みの、その JumpServer のアカウント。
- WebSocket バックエンドでは、接続可能な HTTP(S) アドレス以外は必要ありません。SFTP および SSH 機能を使うには、ネットワーク経路上で KoKo の SSH ポート(デフォルトは
2222)も開放する必要があります。多くの環境ではウェブポートしか公開されていないため、利用する前に確認してください。
インストール
ビルド済みバイナリ(推奨)
使用するプラットフォーム用のアーカイブをReleasesからダウンロードし、jms バイナリ(Windows では jms.exe)を PATH に配置します。
| プラットフォーム | ファイル |
|---|---|
| Windows x86_64 | jms-client_<version>_windows_amd64.zip |
| Windows arm64 | jms-client_<version>_windows_arm64.zip |
| macOS Apple Silicon | jms-client_<version>_darwin_arm64.tar.gz |
| macOS Intel | jms-client_<version>_darwin_amd64.tar.gz |
| Linux x86_64 | jms-client_<version>_linux_amd64.tar.gz |
| Linux arm64 | jms-client_<version>_linux_arm64.tar.gz |
同じリリースにある checksums.txt を使って、ダウンロードを検証できます。
sha256sum -c --ignore-missing checksums.txt # Linux
shasum -a 256 -c --ignore-missing checksums.txt # macOS
Scoop(Windows)
scoop bucket add mifazhan https://github.com/MiFaZhan/scoop-bucket
scoop install jms-client
後で scoop update jms-client を実行してアップグレードできます。
Go
Go 1.25 以降が必要です。
go install github.com/MiFaZhan/jms-client/cmd/jms@latest
ソースから
git clone https://github.com/MiFaZhan/jms-client
cd jms-client
go build -o jms ./cmd/jms
MCP クライアントのみを使用する場合
AI 統合だけを利用したい場合や、バイナリを自分で管理したくない場合は、Releasesから jms-client.mcpb をダウンロードし、MCP クライアントで開いてください(Claude Desktop などの MCPB 対応クライアントでは、ダブルクリックで開けます)。この単一のバンドルには、6 種類すべてのプラットフォーム/アーキテクチャのバイナリが含まれており、起動時にバンドルされたランチャーが適切なものを選択します。
クイックスタート
1. サーバーを登録する
$ jms config add bastion
Internal URL (http(s)://..., empty to skip): https://jumpserver.corp.example.com/
External URL (http(s)://..., empty to skip):
Username: alice
Password:
Confirm password:
TOTP secret (base32, empty to enter the code each time):
Server "bastion" saved to /home/alice/.config/jms/config.toml
Server "bastion" is now the default.
どちらかのアドレスは空欄にできますが、少なくとも1つは必須です。認証情報は、書き込みを行う前に到達可能なアドレスに対して検証されるため、パスワードを間違えて入力してもディスク上の内容は変更されません。最初に追加したサーバーがデフォルトになります。
2. 確認する
$ jms config test
Server: bastion (default)
Endpoint URL Reachable Probe Login
external https://jumpserver.corp.example.com/ yes 12ms ok
Credentials: keyring
config test は、設定されているすべてのアドレスを調査し、到達可能なアドレスそれぞれで実際のログインを試みます。そのため、ネットワークの問題とパスワードの拒否を個別に確認でき、実際に機能するアドレスもわかります。アドレスへの TCP 接続が成功しても、ログインには失敗する場合があります。VPN やプロキシが接続を受け付けても、その先に有用なサービスがないことがあるためです。
3. 使用する
$ jms ls # assets you are authorized for
$ jms ls -q web # search by keyword
$ jms exec web-01 "uptime" # one command, exit code passes through
$ jms login web-01 # interactive shell (Ctrl+] to exit)
$ jms sftp web-01:/var/log/app.log . # download
$ jms sftp ./config.yml web-01:/etc/app/ # upload
AI アシスタント(MCP)を接続する
jms mcp は、stdio 経由で Model Context Protocol サーバーを実行します。MCP 対応クライアントであれば、シェルと同じ接続プールを通じて、アセットの一覧表示、コマンドの実行、ファイルの転送ができます。
{
"mcpServers": {
"jms": {
"command": "jms",
"args": ["mcp"]
}
}
}
このスニペットは、いつでも次のコマンドで表示できます。
jms mcp --print-config
MCP プロセスにはコマンドラインフラグがありません(クライアントは長時間実行されるプロセスを1つ起動し、呼び出しごとに引数を追加できません)。そのため、このクライアントエントリでは環境変数を使って、エンドポイント、バックエンド、コマンドのタイムアウトを設定します。
{
"mcpServers": {
"jms": {
"command": "jms",
"args": ["mcp"],
"env": {
"JMS_MCP_BACKEND": "ws",
"JMS_MCP_EXEC_TIMEOUT": "10m"
}
}
}
}
ツール
| ツール | 目的 | 必須の引数 |
|---|---|---|
jms_ls | 許可されたアセットを一覧表示または検索する | — |
jms_resolve_asset | アセットのアドレス、アカウント、プロトコルを解決する | asset |
jms_exec | 1 つのコマンドを実行し、その出力を返す | asset、command |
jms_sftp_upload | ローカルファイルをアセットにアップロードする | src、asset、dst |
jms_sftp_download | アセットからファイルをダウンロードする | asset、src、dst |
jms_sftp_relay | 2 つのアセット間でファイルを直接ストリーミングする | src_spec、dst_spec |
jms_config_list | 設定済みサーバーとその認証情報の取得元を一覧表示する | — |
8 つ目のツール jms_pool_status は、JMS_MCP_DEBUG=1 のときに登録され、接続プールの状態を報告します。これはサーバーの診断用であり、日常的な使用を想定したものではありません。
ほとんどのツールは、オプションの server、config_path、account、protocol、timeout 引数を受け付けます。リモート指定には <asset>[@<server>]:<path> の形式を使用します。
エージェント向けのプロンプトを書く際に知っておくべき動作が 2 つあります。
- 終了コードが 0 以外でも、失敗として報告されません。
jms_execはコマンドの出力を返します。リモートの終了ステータスは監査ログに記録されますが、ツールの結果には表示されません。エージェントが成功かどうかに応じて処理を分岐する必要がある場合は、コマンドで明示してください(… && echo OK || echo FAIL)。 - コマンドが再実行されることはありません。 コマンドがホストに送信された後に呼び出しが失敗した場合、
rmやrebootなどのコマンドは冪等ではないため、クライアントは再試行せずにエラーを報告します。接続が切断された場合は、新しいログインを使って 1 回だけ復旧を試みますが、これは出力がまったくなかったコマンドに限られます。
コマンド一覧
| コマンド | 動作 |
|---|---|
jms config add | list | remove | set-default | test | サーバーエントリーとその認証情報を管理します。 |
jms ls [server] [-q keyword] | 許可されたアセットを一覧表示または検索します。 |
jms exec <target> <command...> | アセット上で 1 つのコマンドを実行します。 |
jms login <target> | 対話型シェルを開きます。 |
jms sftp <src> <dst> | ファイルをアップロードまたはダウンロードします。 |
jms ssh-pipe <target> [command...] | 標準入出力をアセットに接続します(rsync -e 用)。 |
jms tail [-f] | ローカルの監査ストリームを追跡します。 |
jms attach | 実行中のホストを監視し、必要に応じてそのセッションに参加します。 |
jms log show | 監査ログを検索します。 |
jms mcp | 標準入出力の MCP サーバーを実行します。 |
ターゲットの構文は <asset>@<server> です。@<server> を省略すると、デフォルトのサーバーが使用されます。
詳細なリファレンス: docs/command-reference.md · 簡体字中国語
設定
設定ファイルの保存場所:
| プラットフォーム | パス |
|---|---|
| Windows | %AppData%\jms\config.toml |
| Linux / macOS | ~/.config/jms/config.toml(または $XDG_CONFIG_HOME/jms/config.toml) |
--config フラグまたは JMS_CONFIG 環境変数で上書きできます。監査ディレクトリも設定ファイルと同じ場所にあるため、ファイルを移動すると監査ディレクトリも移動します。
version = 2
default_server = "bastion"
# Optional global proxy policy. Omitted means: connect directly.
# proxy = "socks5://127.0.0.1:1080"
[servers.bastion]
internal = "http://192.168.1.10:2280/" # internal address (optional)
external = "https://bastion.example.com/" # external address (optional)
username = "alice"
# prefer = "external" # try this address first; default is internal
# pin = "internal" # use only this address: no probing, no failover
# ssh_port = 2222 # KoKo SSH port if not the default
# proxy = "direct" # force a direct connection for this server
[servers.staging]
external = "https://jumpserver.staging.example.com/"
username = "alice"
prefer = "external"
ユーザー名以外のすべてのフィールドは省略可能ですが、アドレスを 1 つ以上指定する必要があります。
サーバーに両方のアドレスが設定されている場合、クライアントは順番に接続を確認し、応答する最初のアドレスにログインします。また、最後に正常に接続できたアドレスを 10 分間記憶します。クライアントはデフォルトで直接接続し、HTTP_PROXY などの設定は無視します。プロキシを使用するには、明示的に設定する必要があります。
詳細: docs/networking.md · 簡体字中国語
認証情報
| データ | 保存場所 |
|---|---|
| エイリアス、アドレス、ユーザー名、設定 | config.toml、平文(0600) |
| パスワード、TOTP シークレット | サービス名 jms-client の OS 認証情報ストア |
設定ファイルはアトミックに書き込まれ、認証情報が含まれることはありません。そのため、マシン間で安全に同期できます。ただし、これによって保護されるのは、ファイルの漏えいや設定ファイルを別のマシンにコピーした場合であり、同じユーザーとして実行される悪意のあるプロセスに対してではないことにご注意ください。
ヘッドレス環境(コンテナー、CI、Secret Service のない WSL)では、環境変数によるフォールバックを利用できます。環境変数は認証情報ストアより優先されます。
| 変数 | 意味 |
|---|---|
JMS_PASSWORD_<ALIAS> | サーバーエイリアスのパスワード。 |
JMS_OTP_<ALIAS> | サーバーエイリアスの TOTP シークレット。 |
エイリアスは大文字に変換され、- は _ になります。そのため、bastion-eu は JMS_PASSWORD_BASTION_EU になります。エクスポート済みでも空の変数は、空のパスワードではなく未設定として扱われます。どちらの保存先にも認証情報がない場合、設定すべき変数名を示すメッセージとともにコマンドは失敗します。平文のパスワードを保存する方法にフォールバックすることはありません。
ロックされた認証情報ストア(デスクトップセッションがない場合の GNOME Keyring で一般的な状態)では、設定すべき環境変数名を示すメッセージとともに、数ミリ秒で失敗します。トラブルシューティングをご覧ください。
環境変数
| 変数 | 効果 |
|---|---|
JMS_CONFIG | 設定ファイルのパス。 |
JMS_PASSWORD_<ALIAS>、JMS_OTP_<ALIAS> | 認証情報のフォールバック(上記参照)。 |
JMS_ACTOR | 監査ログに記録される名前。同じマシン上の複数のクライアントを区別するために使用します。 |
JMS_AUDIT | off に設定すると、監査ログを無効にします。 |
JMS_AUDIT_DIR | 監査ディレクトリの場所を変更します。 |
JMS_AUDIT_FULL | 1 に設定すると、切り詰められていない出力プレビューを記録します。 |
JMS_AUDIT_PREVIEW_BYTES | 出力プレビューの切り詰め上限(デフォルトは 4096)。 |
JMS_MCP_ENDPOINT | MCP 専用:internal または external を強制します。 |
JMS_MCP_BACKEND | MCP 専用:ssh、ws、auto のいずれかを強制します。 |
JMS_MCP_EXEC_TIMEOUT | MCP 専用:jms_exec のデフォルトのタイムアウト。例:10m または 600。 |
JMS_MCP_DEBUG | MCP 専用:1 に設定すると、jms_pool_status を登録します。 |
JMS_WS_DUMP | プロトコルのデバッグ用に、WebSocket フレームを生のままダンプします。 |
ターミナルバックエンド
JumpServer の KoKo コンポーネントは 2 種類のターミナルチャネルを提供しており、jms-client はどちらにも対応しています。
| バックエンド | チャネル | 備考 |
|---|---|---|
ws(デフォルト) | /koko/ws/terminal/ | Web コンソールと同じパスです。Web コンソールが動作する環境なら、どこでも利用できます。デフォルトのコマンドタイムアウトは 30s です。 |
ssh | KoKo SSH ポート(デフォルトは 2222) | コマンドごとにネイティブの終了ステータスを返し、出力マーカーの解析は不要です。ポートに接続できる必要があり、SFTP もこのポートに依存します。 |
--backend ssh で選択するか、--backend auto を指定すると SSH を試し、失敗した場合は WebSocket にフォールバックします。アドレスごとに最後に成功したバックエンドが state.json に記憶されるため、コールドスタート時に、ブロックされたポートでハンドシェイクがタイムアウトするのを待たずに、そのバックエンドへ直接接続します。MCP では、記憶されたバックエンドを利用して、再起動せずにプロセスが古い接続から復旧することもできます。
SFTP を必要とするツール(jms sftp、jms_sftp_upload、jms_sftp_download、jms_sftp_relay)を使用するには、KoKo の SSH ポートが開いている必要があります。exec は問題なく動作するのにファイル転送が停止したり失敗したりする場合は、まずこのポートを確認してください。
監査ログ
各コマンドは、1 行につき 1 つの JSON オブジェクトとして記録されます。
{"ts":"2026-10-05T14:32:01.123+08:00","pid":12345,"actor":"mcp:pi","kind":"exec.end","server":"prod","asset":"web-01","backend":"ssh","endpoint":"external","command":"systemctl status nginx","exit_code":0,"duration_ms":118,"output_bytes":2140,"preview":"● nginx.service ...","pool":"hit","idle_ms":68000}
ファイルは <config dir>/audit/audit-YYYYMMDD-<pid>.jsonl に書き込まれます。プロセスごとに 1 ファイルで、ディレクトリとファイルのアクセス権限はどちらも 0600 です。プロセスごとにファイルを分けることで、複数のプロセスがロックされた 1 つのファイルに追記する Windows の問題を回避でき、長時間稼働するホストと単発の CLI 呼び出しを共存させられます。
イベントの種類:exec.start、exec.end、pool.cold、pool.hit、pool.evict、pool.reap、session.login、session.relogin、endpoint.select、error。
出力プレビューは、既定で 4096 バイトに切り詰められます(JMS_AUDIT_PREVIEW_BYTES を使用するか、すべて記録するには JMS_AUDIT_FULL=1 を指定します)。ログ内で認証情報が展開されることはありません。
制限事項
- JumpServer v4 のみ対応しています。 v3 の認証 API とターミナル API は異なります。
jms sftpは再帰的なコピーやアセット間の中継に対応していません。 後者には MCP のjms_sftp_relayツールを使用するか、ローカルマシンを経由して中継してください。- 32 ビットプラットフォーム向けにはビルドされません。 x86_64 と arm64 のみ対応しています。
- 監査ログはローカルに保存されます。 中央のコレクターには転送されません。集約が必要な場合は、ご自身でファイルを転送してください。
- ジャンプホストのチェーン(別のアセットを経由するプロキシ/ジャンプ)は実装されていません。
問題が発生した場合: docs/troubleshooting.md · 简体中文
開発
go build ./... # compile
go test ./... # unit and protocol-regression tests
go vet ./...
gofmt -l . # must print nothing
統合テストは実際の JumpServer に接続し、環境変数が設定されている場合にのみ実行されます。環境変数が設定されていない場合はスキップされるため、新しくクローンした状態でもテストは成功します。
JMS_TEST_SERVER=bastion go test ./...
アーキテクチャ、リバースエンジニアリングによって判明した KoKo プロトコルの詳細、プールの設計、障害処理のルールは DESIGN.md に記載されています(中国語で書かれています)。
リリースは GitHub Actions から作成されます。
gh workflow run release --repo MiFaZhan/jms-client -f tag=v0.1.7
ライセンス
MIT © MiFaZhan。LICENSE を参照してください。
設計と KoKo プロトコルに関する調査結果は、GCS-ZHN/jms-cli を基にしています。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。