Skip to main content

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.

Metadata

Release files for jms-cli 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jms-cli 0.2.0
File Size Uploaded Provenance Actions
jms_cli-0.2.0.tar.gz 193.5 kB Without provenance Details for jms_cli-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for jms-cli 0.2.0
File Interpreter ABI Platform Actions
jms_cli-0.2.0-py3-none-any.whl Python 3 none any Details for jms_cli-0.2.0-py3-none-any.whl

Total release size: 268.4 kB

Release files / jms_cli-0.2.0.tar.gz

Download URL jms_cli-0.2.0.tar.gz
Size 193.5 kB
Tags Source
SHA-256 checksum
How to use checksums
3a5264e8a54368b82f489164aa95e9e74feeac38a1dbe26a7e8413f22364e053
BLAKE2b-256 checksum
How to use checksums
0828ec6f98954cbcf3b32c652009d074ef1e2fe4da2f64dfc4d6d4338de0a148
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.8

Release files / jms_cli-0.2.0-py3-none-any.whl

Download URL jms_cli-0.2.0-py3-none-any.whl
Size 74.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ca899f1c00a8b2f43216ab1a0170617c45bd017886062bacb498d8fa365405b
BLAKE2b-256 checksum
How to use checksums
2b39e7e529c97b47e1f35b1395172559d620f89985614fd424b1ab485fc00ec5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.12.8

Security for jms-cli 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page