Skip to main content

jms-cli

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
  • Usable as a Python library (from jms import JMSSession, connect, ...)

Install

uv sync          # or: pip install .

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"))

Roadmap / TODO

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

Development

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

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.1.0.tar.gz (141.4 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.1.0-py3-none-any.whl (57.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: jms_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 141.4 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.1.0.tar.gz
Algorithm Hash digest
SHA256 8a35032a1934d449ebf9af146b5d24dddd1c1277999c783c2db6fb7fe7929e8c
MD5 031e82eefb3a4b2ea7f691de55d3cda4
BLAKE2b-256 4956b9735c874682398606ad26063051e82c69c02b5e2437e65ac510854c949d

See more details on using hashes here.

File details

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

File metadata

  • Download URL: jms_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 57.3 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.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 828e78bd2b397d45a498be7482deb62339e2d52e02923fb7a04a8428103ee071
MD5 fc843891c9b42036eadf8ca31b829b01
BLAKE2b-256 60ee17060dd4473c63250c11641d9496e98d3905130675501c94906463ceef00

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