Skip to main content

execkit MCP server - stateful, structured, safe shell sessions for AI agents over local shells, SSH, and Docker.

Project description

execkit-mcp

An MCP server (stdio) that exposes execkit shell sessions to any MCP-capable agent - Claude Code, Cursor, Gemini CLI, and others.

Tools

Tool Args Returns
session_create transport ("local"/"ssh"/"docker"); for ssh: host, user, password or key_path, optional port, fingerprint (pin host key); for docker: container (running name/id); optional allow/deny command lists { "session_id": "..." }
session_exec session_id, command, optional budget (shape output: grep/tail/head/head_tail + max_chars) structured ExecResult JSON: stdout, stderr (split!), exit_code, duration_ms, cwd, truncated
session_destroy session_id { "destroyed": true }
session_checkpoint session_id, optional label { "checkpoint_id": "..." }
session_checkpoints session_id [{ id, label, created }]
session_restore session_id, optional checkpoint_id { restored_to, files_changed }

Sessions are stateful - cd/env persist across session_exec calls. Output is ANSI-stripped, secret-redacted, and bounded; commands pass the optional policy fence before running.

Checkpoints (remote only)

On SSH/Docker sessions execkit can snapshot the workspace before changing commands and restore it on demand - a filesystem "undo." It undoes FILES only, never side effects (DB writes, network, installs).

Two requirements: git on the remote host, and an explicit workspace. Without a workspace, checkpoints and auto-snapshot are disabled - execkit will not default to the cwd or home directory (snapshotting $HOME is slow and would capture secrets). Set workspace to the project dir you want undo for (use $HOME explicitly if you really mean it).

Control it via session_create:

  • workspace (root - REQUIRED to enable checkpoints)
  • auto_snapshot (default true; effective only with a workspace)
  • paths (sub-dirs under the root)
  • checkpoint_ignores (extra gitignore-style patterns; added to the built-in defaults: .git, node_modules, build dirs, caches, .ssh, .aws, ...)

If git is absent, auto-snapshot disables itself and checkpoint calls return a clear "install git on the remote" error.

WARNING: session_restore is destructive. It reverts tracked files AND deletes ALL untracked files and directories anywhere under the workspace (via git clean), not only files created since the checkpoint. Do not restore if untracked files in the workspace must be preserved.

Output budgets

Pass budget to session_exec (or output_budget to session_create for a session default) to shape output and protect the agent's context window:

// keep the last 200 lines of a noisy build
{ "session_id": "...", "command": "npm run build",
  "budget": { "keep": { "mode": "tail", "n": 200 } } }

// grep a 50k-line log for errors, with 2 lines of context
{ "session_id": "...", "command": "cat big.log",
  "budget": { "grep": { "pattern": "error|fail", "context": 2 } } }

Shaping is line-based, client-side, and runs AFTER secret redaction; it never changes the exit code or side effects. When applied, the result includes a budget report: per-stream mode, lines_total, lines_kept.

Install

pip install execkit-mcp          # the server binary, shipped as a wheel (no Rust toolchain)
cargo install execkit-mcp        # ...or via cargo (or build from source: cargo build -p execkit-mcp)

Wire it into an agent

execkit-mcp is a stdio MCP server - register the installed binary with your client. (cargo install puts it at ~/.cargo/bin/execkit-mcp; use the full path if it isn't on the client's PATH.)

Claude Code - one command:

claude mcp add execkit -- execkit-mcp        # add `-s user` to enable it everywhere

Cursor (~/.cursor/mcp.json) and Gemini CLI (~/.gemini/settings.json) - add the same block:

{
  "mcpServers": {
    "execkit": { "command": "execkit-mcp" }
  }
}

To turn on auditing or other operator settings, add an env block:

{
  "mcpServers": {
    "execkit": {
      "command": "execkit-mcp",
      "env": { "EXECKIT_MCP_AUDIT": "/var/log/execkit.jsonl" }
    }
  }
}

Then the agent can call session_create -> session_exec -> session_destroy.

Example session (what the agent sees)

// session_create {"transport":"local"}              -> {"session_id":"sess_1"}
// session_exec   {"session_id":"sess_1","command":"npm run build"}
//   -> {"stdout":"...","stderr":"Error: Cannot find module 'webpack'",
//       "exit_code":1,"duration_ms":3420,"cwd":"/home/u/app","truncated":false}

Security model

The agent driving these tools can be prompt-injected, so tool arguments are untrusted. Anything dangerous to the host/filesystem is therefore controlled by the operator at startup (env vars), not by per-call agent arguments:

Env var Purpose Default
EXECKIT_MCP_AUDIT append a JSONL audit log of every command here off
EXECKIT_MCP_KEY_DIR SSH key_path must canonicalize to inside this dir ~/.ssh
EXECKIT_MCP_KNOWN_HOSTS SSH host-key verification file (TOFU; rejects changed keys) ~/.ssh/known_hosts
EXECKIT_MCP_INSECURE_ACCEPT_ANY_HOSTKEY DANGEROUS - disable host-key checks unset
EXECKIT_MCP_MAX_SESSIONS soft cap on concurrent live sessions 64
EXECKIT_MCP_SESSION_TTL reap sessions idle longer than this many seconds (frees the process + cap slot); 0 disables 1800 (30 min)
  • Host keys are verified by default (TOFU against known_hosts; a changed key is rejected as a likely MITM). Pass a fingerprint to require an exact key, or set the insecure env var only for throwaway/test hosts.
  • key_path is sandboxed to EXECKIT_MCP_KEY_DIR; out-of-bounds/traversal paths are rejected with a generic error (no path-existence leak).
  • Audit destination is operator-chosen, never a tool argument (prevents an injected agent from writing to arbitrary files).
  • Docker sessions run docker exec against any container the daemon can see, so the agent reaches whatever your docker context exposes. Grant the server Docker access only when you want that, and scope the daemon/context accordingly.
  • The server speaks MCP on stdout; all diagnostics go to stderr.
  • Use allow/deny for a command fence, and run the agent + SSH user with least privilege. The fence is advisory - defense in depth, not a sandbox.

Watch live activity (read-only)

Point EXECKIT_MCP_AUDIT at a file, then watch it from another terminal:

execkit-mcp watch /var/log/execkit.jsonl   # or just: execkit-mcp watch  (uses $EXECKIT_MCP_AUDIT)

watch is a live, read-only TUI: the agent's sessions on the left, the selected session's shell transcript on the right (prompt, command, stdout, stderr in red, exit status) - rendered like a normal shell, not JSON. Switch sessions with 1-9 or the arrow keys, scroll with PgUp/PgDn, quit with q. It only ever reads the log and never touches a session. Because the data comes from the server (not the client), it works the same under any MCP client (Claude Code, Cursor, Gemini, ...).

Apache-2.0.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

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

execkit_mcp-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

execkit_mcp-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (3.3 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

execkit_mcp-0.7.0-py3-none-macosx_11_0_arm64.whl (3.5 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

execkit_mcp-0.7.0-py3-none-macosx_10_12_x86_64.whl (3.7 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file execkit_mcp-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for execkit_mcp-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 f285659019b66f95186c79b12a7763598eda73b2f050de1d1efdc013b758249e
MD5 4588062dd0de3f22758a507084b0f07f
BLAKE2b-256 c386b3ded9ea74477918fd805c605470d91719c9315a980a9fa81fb04918a372

See more details on using hashes here.

Provenance

The following attestation bundles were made for execkit_mcp-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on blinkingbit-oss/execkit

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

File details

Details for the file execkit_mcp-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for execkit_mcp-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 98865c992c60b2a6f078d3b46ca62e9f7536a7f4e388b13b3cf6e9f0c93748e9
MD5 f8269d8994fe595d09fa40159cf72805
BLAKE2b-256 01fa1456ab24bef5acb058ed62821744f7783a5440467abf72272332ca223f55

See more details on using hashes here.

Provenance

The following attestation bundles were made for execkit_mcp-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: wheels.yml on blinkingbit-oss/execkit

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

File details

Details for the file execkit_mcp-0.7.0-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for execkit_mcp-0.7.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4156093a35e0265fad8a4edd8c2b3f80e865947cf7ce3accee2db8a2718bf5a2
MD5 673aa76ec56eeb385da97c0a7aebd348
BLAKE2b-256 845b18520257c8c2929c12e3aaa1a7e000b962a10b6be4550168d303c451f4b6

See more details on using hashes here.

Provenance

The following attestation bundles were made for execkit_mcp-0.7.0-py3-none-macosx_11_0_arm64.whl:

Publisher: wheels.yml on blinkingbit-oss/execkit

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

File details

Details for the file execkit_mcp-0.7.0-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for execkit_mcp-0.7.0-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 81b43ca55842ede68c6f6037809cd5d4c0b90e8c995284f1ec782900408a0711
MD5 80941aa45af2d665d3903cd02e12100d
BLAKE2b-256 1e292d3c5a2eae0bef3e3c8712f834465f4f3523dfa1c15d02890e3a522baf68

See more details on using hashes here.

Provenance

The following attestation bundles were made for execkit_mcp-0.7.0-py3-none-macosx_10_12_x86_64.whl:

Publisher: wheels.yml on blinkingbit-oss/execkit

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