Skip to main content

JumpServer 443-only MCP bridge for coding agents

Project description

mcp-jumpserver-gui-sucks

A JumpServer 443-only MCP bridge for coding agents such as Codex and Claude. The project exposes a CLI-first, MFA-compatible, audit-preserving path into JumpServer assets without depending on port 2222 or any GUI-driven workflow in normal use.

Current Status

The main CLI and MCP chain is working against a real JumpServer instance:

  • CLI-first login with terminal-entered MFA
  • persisted durable access_key auth for REST discovery
  • persisted authenticated web-session cookies for KoKo terminal flows
  • asset, node, connect-method, and asset-access discovery
  • KoKo 443 WebSocket probing
  • one-shot remote command execution through KoKo
  • managed multi-turn terminal sessions for MCP-driven shell interaction
  • process-local terminal idle reaping and session-cap enforcement
  • explicit cookie-session refresh probing before terminal work
  • a line-oriented CLI shell for non-MCP interactive terminal use

The current implementation is usable, but it is not feature-complete yet. The most important known limitation is:

  • terminal access still depends on a valid cookie-backed web session, so a fully expired terminal session still requires a fresh login run with MFA

The project does not currently aim to provide file-manager or SFTP coverage.

Tracked Project Docs

Upstream Reference Repositories

The repository keeps several untracked upstream JumpServer codebases under extern/ for protocol and behavior reference only. They are not runtime dependencies of this package.

  • extern/jumpserver: backend API, authentication, and permission-model reference
  • extern/koko: KoKo terminal gateway and WebSocket behavior reference
  • extern/luna: legacy web-terminal frontend flow reference, especially around browser-driven terminal bootstrap behavior
  • extern/lina: newer web UI and API usage-pattern reference
  • extern/client: official client-side implementation reference for adjacent access workflows

Authentication Model

The runtime intentionally uses two auth layers:

  • access_key for durable REST access
  • authenticated web-session cookies for KoKo terminal access

Do not put live session secrets, cookies, or MFA values into MCP client config files. The intended flow is:

  1. Run the CLI login command once.
  2. Complete MFA in the terminal.
  3. Let the tool persist auth state into the user-scoped application state directory.
  4. Start the MCP server from Codex or Claude.

By default, persisted auth state lives under the platform-specific user application state directory:

  • macOS example: ~/Library/Application Support/mcp-jumpserver-gui-sucks/auth-state.json

Advanced users can override the location with:

  • MCP_JUMPSERVER_GUI_SUCKS_STATE_DIR
  • MCP_JUMPSERVER_GUI_SUCKS_STATE_FILE

Login Before Starting MCP

For local development from this repository:

uv run mcp-jumpserver-gui-sucks login \
  --base-url https://jumpserver.example.com \
  --username alice

For the intended released-package workflow:

uvx mcp-jumpserver-gui-sucks login \
  --base-url https://jumpserver.example.com \
  --username alice

Useful verification commands:

uv run mcp-jumpserver-gui-sucks doctor
uv run mcp-jumpserver-gui-sucks refresh-session --force

The login command persists state outside the repository. MCP client config should only describe how to find that state, not embed the secrets themselves.

MCP Configuration

The MCP server entrypoint is:

uvx mcp-jumpserver-gui-sucks serve

serve defaults to stdio, which is the correct transport for Codex and Claude desktop-style MCP clients.

Codex (~/.codex/config.toml)

This matches the mcp_servers.* structure already used in your local ~/.codex/config.toml:

[mcp_servers.mcp-jumpserver-gui-sucks]
command = "uvx"
args = ["mcp-jumpserver-gui-sucks", "serve"]
startup_timeout_sec = 60.0

[mcp_servers.mcp-jumpserver-gui-sucks.env]
MCP_JUMPSERVER_GUI_SUCKS_BASE_URL = "https://jumpserver.example.com"
MCP_JUMPSERVER_GUI_SUCKS_VERIFY_TLS = "true"
MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_IDLE_TIMEOUT_SECONDS = "900"
MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_REAP_INTERVAL_SECONDS = "30"
MCP_JUMPSERVER_GUI_SUCKS_MAX_TERMINAL_SESSIONS = "8"

# Optional when the default state directory is not desired.
# MCP_JUMPSERVER_GUI_SUCKS_STATE_DIR = "/Users/alice/Library/Application Support/mcp-jumpserver-gui-sucks"
# MCP_JUMPSERVER_GUI_SUCKS_STATE_FILE = "/Users/alice/Library/Application Support/mcp-jumpserver-gui-sucks/auth-state.json"
# MCP_JUMPSERVER_GUI_SUCKS_ORG_ID = "00000000-0000-0000-0000-000000000002"

For local development before the package is published, use a local source checkout through uvx --from:

[mcp_servers.mcp-jumpserver-gui-sucks-dev]
command = "uvx"
args = [
  "--from",
  "/Users/rabyte/github/mcp-jumpserver-gui-sucks",
  "mcp-jumpserver-gui-sucks",
  "serve",
]
startup_timeout_sec = 60.0

[mcp_servers.mcp-jumpserver-gui-sucks-dev.env]
MCP_JUMPSERVER_GUI_SUCKS_BASE_URL = "https://jumpserver.example.com"
MCP_JUMPSERVER_GUI_SUCKS_VERIFY_TLS = "true"

Claude (~/.claude.json)

This matches the mcpServers JSON shape already present in your local ~/.claude.json:

{
  "mcpServers": {
    "mcp-jumpserver-gui-sucks": {
      "command": "uvx",
      "args": ["mcp-jumpserver-gui-sucks", "serve"],
      "env": {
        "MCP_JUMPSERVER_GUI_SUCKS_BASE_URL": "https://jumpserver.example.com",
        "MCP_JUMPSERVER_GUI_SUCKS_VERIFY_TLS": "true",
        "MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_IDLE_TIMEOUT_SECONDS": "900",
        "MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_REAP_INTERVAL_SECONDS": "30",
        "MCP_JUMPSERVER_GUI_SUCKS_MAX_TERMINAL_SESSIONS": "8"
      }
    }
  }
}

For local development before publish:

{
  "mcpServers": {
    "mcp-jumpserver-gui-sucks-dev": {
      "command": "uvx",
      "args": [
        "--from",
        "/Users/rabyte/github/mcp-jumpserver-gui-sucks",
        "mcp-jumpserver-gui-sucks",
        "serve"
      ],
      "env": {
        "MCP_JUMPSERVER_GUI_SUCKS_BASE_URL": "https://jumpserver.example.com",
        "MCP_JUMPSERVER_GUI_SUCKS_VERIFY_TLS": "true"
      }
    }
  }
}

Supported Environment Variables

The current runtime reads these environment variables:

  • MCP_JUMPSERVER_GUI_SUCKS_BASE_URL
  • MCP_JUMPSERVER_GUI_SUCKS_ORG_ID
  • MCP_JUMPSERVER_GUI_SUCKS_STATE_DIR
  • MCP_JUMPSERVER_GUI_SUCKS_STATE_FILE
  • MCP_JUMPSERVER_GUI_SUCKS_VERIFY_TLS
  • MCP_JUMPSERVER_GUI_SUCKS_LOG_LEVEL
  • MCP_JUMPSERVER_GUI_SUCKS_REQUEST_TIMEOUT_SECONDS
  • MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_IDLE_TIMEOUT_SECONDS
  • MCP_JUMPSERVER_GUI_SUCKS_TERMINAL_REAP_INTERVAL_SECONDS
  • MCP_JUMPSERVER_GUI_SUCKS_MAX_TERMINAL_SESSIONS

The recommended minimum MCP config is usually:

  • MCP_JUMPSERVER_GUI_SUCKS_BASE_URL
  • optionally MCP_JUMPSERVER_GUI_SUCKS_STATE_DIR or MCP_JUMPSERVER_GUI_SUCKS_STATE_FILE

PyPI Release Automation

The repository now includes publish-pypi.yml.

Its behavior is intentionally:

  • every push to main inspects pyproject.toml
  • if the package version changed and that version does not already exist on PyPI, GitHub Actions builds and publishes it
  • if the version did not change, the workflow skips publishing
  • if the version already exists on PyPI, the workflow skips publishing
  • workflow_dispatch can be used to publish the current version manually when it is not yet on PyPI

The publish job uses PyPI Trusted Publishing through GitHub OIDC. Configure PyPI to trust this repository and workflow before expecting the publish step to succeed.

Recommended PyPI trusted publisher settings:

  • owner: ArtiPyHeart
  • repository: mcp-jumpserver-gui-sucks
  • workflow file: .github/workflows/publish-pypi.yml
  • environment name: pypi

For the initial 0.1.0 release, the workflow file itself does not change the package version, so the easiest path is:

  1. push this workflow to main
  2. configure the PyPI trusted publisher
  3. run the workflow once through workflow_dispatch

After that, later pushes to main that bump project.version in pyproject.toml will publish automatically.

Current CLI Surface

  • mcp-jumpserver-gui-sucks login
  • mcp-jumpserver-gui-sucks paths
  • mcp-jumpserver-gui-sucks doctor
  • mcp-jumpserver-gui-sucks refresh-session
  • mcp-jumpserver-gui-sucks resolve-target
  • mcp-jumpserver-gui-sucks koko-probe
  • mcp-jumpserver-gui-sucks terminal-exec
  • mcp-jumpserver-gui-sucks terminal-shell
  • mcp-jumpserver-gui-sucks save-state
  • mcp-jumpserver-gui-sucks clear-state
  • mcp-jumpserver-gui-sucks serve

Current MCP Tools

  • jms_paths
  • jms_status
  • jms_profile
  • jms_list_nodes
  • jms_list_assets
  • jms_get_asset
  • jms_list_connect_methods
  • jms_get_asset_access
  • jms_resolve_terminal_target
  • jms_list_connection_tokens
  • jms_create_connection_token
  • jms_expire_connection_token
  • jms_refresh_terminal_auth
  • jms_probe_koko_terminal
  • jms_execute_koko_command
  • jms_list_terminal_sessions
  • jms_open_terminal_session
  • jms_write_terminal_session
  • jms_read_terminal_session
  • jms_resize_terminal_session
  • jms_close_terminal_session

Operational Notes

  • Managed terminal sessions are process-local and intended to live only for the MCP server process lifetime.
  • terminal-shell is line-oriented, not a full raw TTY emulator.
  • Terminal entrypoints preflight the cookie-backed web session before opening KoKo.
  • If the cookie-backed session is already invalid, terminal calls fail early with an explicit re-login requirement instead of a low-level websocket failure.
  • REST discovery can continue to work when the durable access_key remains valid, even if terminal access requires a fresh login.

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

mcp_jumpserver_gui_sucks-0.1.0.tar.gz (52.5 kB view details)

Uploaded Source

Built Distribution

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

mcp_jumpserver_gui_sucks-0.1.0-py3-none-any.whl (45.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mcp_jumpserver_gui_sucks-0.1.0.tar.gz
  • Upload date:
  • Size: 52.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for mcp_jumpserver_gui_sucks-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75a99e0696675661f89941684306052a670159a06ab59d194fa4efd12c3882d6
MD5 473354be531944c4f0a1b76066b7cb75
BLAKE2b-256 b6316a52cc796fbf515cc63b6452900538bbeb0d47d294ee7ca6bc8a861c128b

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_jumpserver_gui_sucks-0.1.0.tar.gz:

Publisher: publish-pypi.yml on ArtiPyHeart/mcp-jumpserver-gui-sucks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

File hashes

Hashes for mcp_jumpserver_gui_sucks-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 89abe09f0a97ad95c7b8ba18a6e16f82957c0cb9884d3880125978be6f903bb9
MD5 6b2ff8e20abccb9111bd6e7ba6834ebc
BLAKE2b-256 1df0904f28d6ed6ffba6d9da9824d1181c78a71200503192955dd8e5c511b330

See more details on using hashes here.

Provenance

The following attestation bundles were made for mcp_jumpserver_gui_sucks-0.1.0-py3-none-any.whl:

Publisher: publish-pypi.yml on ArtiPyHeart/mcp-jumpserver-gui-sucks

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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