Skip to main content

JumpServer v4 bastion asset access CLI + lib: exec, login, SFTP transfer, rsync over ssh-pipe

Project description

jms-cli

PyPI version PyPI - Python Version CI

A personal CLI tool and Python library for accessing assets behind a JumpServer v4 bastion host: remote command execution, interactive terminal, parallel SFTP file transfer, and rsync/scp incremental sync via an SSH bridge.

Features

  • jms exec — run commands on assets (SSH or WebSocket backend, auto fallback)
  • jms login — interactive PTY with keepalive (Ctrl+] to exit)
  • jms sftp — parallel SFTP upload/download, chunked large files, cross-server relay
  • jms ssh-pipe-e bridge for rsync / scp
  • Multi-server config, MFA (TOTP) support, AES-256-GCM encrypted credentials
  • Local MCP stdio server (jms mcp) exposing config/asset/exec/SFTP as tools for AI assistants
  • Usable as a Python library (from jms import JMSSession, connect, ...)

Install

pip install jms-cli     # or: uv tool install jms-cli

Requires Python >= 3.10. For development from source:

git clone git@github.com:GCS-ZHN/jms-cli.git
cd jms-cli && uv sync

Quick start

jms config add prod              # add a server (interactive, verifies credentials)
jms ls [-q keyword]              # list/search assets
jms exec web@prod uname -a       # run a command (asset[@server])
jms login web@prod               # interactive terminal
jms sftp ./file.tar.gz web@prod:/tmp/   # direction auto-detected, -j N parallel
rsync -avz -e "jms ssh-pipe" ./dir/ web@prod:/data/

Config lives in the platform config dir (platformdirs, e.g. ~/Library/Application Support/jms/config.yaml on macOS, ~/.config/jms/ on Linux), written with 0600 permissions. Credentials are stored encrypted. Each command also accepts a hidden --config <path> option to point at a different config file.

CLI operations

Target syntax is SSH-style: <asset>[@<server>]. Omit @<server> to use the default server (the first one you added).

Server config

jms config add prod          # interactive; verifies credentials before saving
jms config list              # show servers; default marked with '*'
jms config set-default prod  # change the default server
jms config remove prod       # delete a server (-y to skip confirmation)

List / search assets

jms ls                       # all assets on the default server
jms ls @prod                 # all assets on server 'prod'
jms ls -q mysql              # filter by keyword

Remote command execution

-b ssh|ws|auto selects the backend (auto = SSH first, WebSocket fallback). The remote exit code is propagated to the local shell.

jms exec web@prod uname -a
jms exec web ls -la /var/log
jms exec web@prod 'echo hello world'
jms exec -b ws web whoami          # force WebSocket backend
jms exec -t 60 web 'sleep 30'      # longer timeout (default 30s)

Interactive terminal

jms login web@prod          # Ctrl+] to exit
jms login web               # default server
jms login -b ssh web        # force SSH backend (native PTY)

File transfer (SFTP)

Direction is auto-detected from the arguments; -j N sets parallelism.

jms sftp ./data.tar.gz web@prod:/tmp/        # upload
jms sftp web@prod:/tmp/data.tar.gz ./        # download
jms sftp ./src/ web@prod:~/dst/              # directory tree
jms sftp -j 8 ./big/ web@prod:/data/         # 8 parallel workers
jms sftp --no-verify web@prod:/f ./          # skip md5 verification
jms sftp web@prod:/f other@prod:/g           # cross-server relay (memory-streamed)

rsync / scp bridge

rsync -avz -e "jms ssh-pipe" ./dir/ web@prod:/data/
scp -o ProxyCommand="jms ssh-pipe %h" ./f web@prod:/data/

Known limitation: rsync downloads over the bridge may hang on files larger than ~4KB (see DEVELOP.md §5). Use jms sftp for downloads; rsync uploads work fine.

Library usage

from jms import JMSSession, ServerConfig, resolve_asset, connect, BackendType

server = ServerConfig(name="prod", host="jump.example.com",
                      username="alice", password="...", otp_secret="...")
sess = JMSSession(server)
sess.login()
asset = resolve_asset(sess, "web")
with connect(sess, asset, backend=BackendType.AUTO) as term:
    print(term.execute("uname -a"))

MCP server (AI assistants)

jms mcp starts a local Model Context Protocol stdio server exposing jms-cli as MCP tools for AI assistants / MCP clients. Every tool opens a fresh authenticated session per call (stateless, no shared state). No interactive PTY is used — all tools are headless operations.

Register it in your MCP client config, e.g. opencode (.opencode/opencode.json):

{
  "mcp": {
    "jumpserver": {
      "type": "local",
      "command": ["uv", "run", "jms", "mcp"]
    }
  }
}

Tools

Tool Description
jms_config_list List configured servers (default marked with *)
jms_ls List / keyword-search authorized assets
jms_resolve_asset Resolve an asset to connection info (address/account/protocol)
jms_exec Run a command on an asset, return output (timeout param)
jms_sftp_upload Upload a local file to an asset via SFTP
jms_sftp_download Download a file from an asset to the local machine
jms_sftp_relay Relay a file between two assets (memory-streamed, no local disk)

Each tool accepts an optional server alias (defaults to the configured default) and an optional config_path. The server-wide default config path falls back to the JMS_CONFIG env var, then the platform config dir.

Roadmap / TODO

  • Admin operations (JumpServer management API): asset CRUD, user management, permission/grant management — the REST layer (jms/core/) is designed for these resource modules
  • GitHub Actions CI (pure unit tests always run; real-server tests auto-skip without JMS_TEST_* env vars)
  • PyPI + GitHub release on tag push
  • Dependency audit (pip-audit) in CI

Development

See DEVELOP.md (Chinese) for architecture, dev principles and testing rules.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jms_cli-0.2.0.tar.gz (193.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jms_cli-0.2.0-py3-none-any.whl (74.9 kB view details)

Uploaded Python 3

File details

Details for the file jms_cli-0.2.0.tar.gz.

File metadata

  • Download URL: jms_cli-0.2.0.tar.gz
  • Upload date:
  • Size: 193.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for jms_cli-0.2.0.tar.gz
Algorithm Hash digest
SHA256 3a5264e8a54368b82f489164aa95e9e74feeac38a1dbe26a7e8413f22364e053
MD5 9ee581469bf9df96e3a92691e02b57b9
BLAKE2b-256 0828ec6f98954cbcf3b32c652009d074ef1e2fe4da2f64dfc4d6d4338de0a148

See more details on using hashes here.

File details

Details for the file jms_cli-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: jms_cli-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 74.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.8

File hashes

Hashes for jms_cli-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2ca899f1c00a8b2f43216ab1a0170617c45bd017886062bacb498d8fa365405b
MD5 08c8d155bad4ce6e8d147b35b7d72160
BLAKE2b-256 2b39e7e529c97b47e1f35b1395172559d620f89985614fd424b1ab485fc00ec5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page