execkit-mcp
One line: execkit-mcp lets an AI agent open persistent shell sessions on your machine, remote hosts over SSH, or Docker containers, run commands in them, and take/restore file checkpoints.
Create sessions (
session_create) over three transports:local,ssh(host, user, pluspasswordorkey_path), ordocker(running container name/id).Run commands (
session_exec) and get structured results: split stdout/stderr, exit code, duration, cwd, and truncation flag — state (cwd, env) persists across calls.Shape output with a budget (
grepregex + context,keepinall/tail/head/head_tailmode,max_charscap) per call or as a session default; secrets are redacted before shaping.Fence commands with optional
allow/denyprogram lists and pin SSH host keys viafingerprint.Checkpoint remote workspaces (
session_checkpoint,session_checkpoints) — requiresgiton the remote and an explicitworkspace; files only, not side effects.Restore/undo files (
session_restore) to a given or the most recent checkpoint.Auto-snapshot before changing remote commands, with
pathsandcheckpoint_ignoresto control what's captured.Tear down sessions (
session_destroy) to free resources.
Provides the ability to execute commands inside Docker containers via persistent sessions, with structured results, security controls, and support for checkpoint/restore.
execkit
Persistent, structured shell sessions for AI agents, on your laptop, your servers over SSH, and your Docker containers.

What you get that a built-in agent shell doesn't:
Persistent sessions on local, SSH and Docker.
cdand env carry across calls, and every command returns a structured result: split stdout/stderr, exit code, duration, cwd.Output that protects the agent's context. Secrets are redacted before the model sees them, and output budgets (
tail,head,grep, a char cap) keep a noisy build from flooding the context window.An audit trail, a live viewer, and undo. Every command can go to a JSONL audit log, you can watch sessions live in a terminal or browser (above), and remote sessions can checkpoint and restore the workspace files.
Install
Zero-install, with uv. Add this to your MCP client config:
{ "mcpServers": { "execkit": { "command": "uvx", "args": ["execkit-mcp"] } } }Or install it and let execkit print the config for your client:
pip install execkit-mcp && execkit-mcp setup claude # or: cursor | gemini | codex | vscode | windsurfThen execkit-mcp doctor checks your setup. More options (prebuilt binary,
cargo install, building from source) are in the Quickstart.
Status: early 0.x. The API may change between minor versions. Read
Limitations before pointing it at anything important.
Related MCP server: infrastructure-mcp
Where it fits
execkit complements your agent's built-in shell or sandbox; it does not replace it. Use it when the agent needs to work on a remote host or inside a container, when you want a record of what ran, or when you want to undo file changes on a remote workspace.
The agent is the adversary. The LLM driving execkit can be prompt-injected by anything it reads, so execkit contains its own caller: a command passes the policy fence before it runs, secrets are redacted before output returns, and a changed SSH host key fails loudly instead of reconnecting into a MITM.
flowchart LR
A([AI agent]) -->|command| F{policy fence}
F -->|blocked| X([rejected, never runs])
F -->|allowed| T[transport: local / SSH / Docker]
T --> O[raw output]
O --> R[redact secrets, bound output]
R --> E([structured ExecResult])
E -.-> AUse it from an agent (MCP)
The agent gets session_create (local, ssh, or docker), session_exec,
session_list and session_destroy, plus session_checkpoint /
session_checkpoints / session_restore for remote undo.
State persists across calls, and every result is parsed, not scraped from a terminal:
// session_exec {"command": "cd /app && npm ci"} -> { "exit_code": 0, "cwd": "/app" }
// session_exec {"command": "npm run build"} // cwd is still /app
// -> { "stderr": "Error: Cannot find module 'webpack'",
// "exit_code": 1, "duration_ms": 3420, "cwd": "/app",
// "truncated": false, "timed_out": false }Commands time out after 120 seconds by default (timeout_secs per call, up to
3600). On timeout execkit interrupts the command with Ctrl-C and returns
timed_out: true with exit code 124. The session keeps its cwd and env.
See crates/execkit-mcp/README.md for the operator
security settings (host-key verification, key dir, audit, session limits).
Watch what the agent does
Set EXECKIT_MCP_AUDIT_DIR and every session is recorded. execkit-mcp watch
shows it live in the terminal, and execkit-mcp watch --serve --open opens the
read-only browser viewer shown at the top.
|
|
Search a transcript with | Rename, pin or keep a session, export it, or take a screenshot. Blocked commands show inline. |
Use it as a library
[dependencies]
execkit = "0.9" # local + SSH + Docker
# execkit = { version = "0.9", default-features = false } # local + Docker only (no SSH; no russh/tokio)use std::time::Duration;
use execkit::{Policy, Session};
fn main() -> Result<(), execkit::Error> {
let mut s = Session::local()?
.with_policy(Policy { allow: vec![], deny: vec!["rm".into()] })
.with_timeout(Duration::from_secs(60));
let r = s.exec("echo hi; echo err 1>&2; cd /tmp")?;
// r.stdout == "hi" r.stderr == "err" r.exit_code == 0 r.cwd == "/tmp"
println!("{} (exit {})", r.stdout, r.exit_code);
let r = s.exec_with_timeout("sleep 30", None, Duration::from_secs(1))?;
// r.timed_out == true r.exit_code == 124; the session is still usable
Ok(())
}Runnable examples: cargo run --example local,
EXECKIT_SSH="user:password@host:22" cargo run --example ssh, and
EXECKIT_DOCKER=<container> cargo run --example docker.
Python
The same sessions from Python. pip install execkit (native bindings, no Rust
toolchain needed):
from execkit import Session
with Session.local() as s:
r = s.exec("echo hi; echo err >&2; cd /tmp")
print(r.stdout, r.exit_code, r.cwd, r.stderr) # hi 0 /tmp errSee crates/execkit-py/README.md.
What's in the box
Persistent, stateful sessions over local PTY, SSH, or Docker. SSH accepts host aliases from your
~/.ssh/config.Structured
ExecResult: split stdout/stderr, exit code, duration, cwd,truncated,timed_out.Base64 command framing. Comments, heredocs,
!, trailing&, syntax errors and long commands do not hang the session.Timeouts that keep the session. A timed-out command is interrupted and the session carries on.
Secret redaction of common token shapes (AWS, GitHub, GitLab, Slack, Stripe, Google, Anthropic, OpenAI, JWTs, PEM private keys), URL passwords,
password=/token=-style pairs, and values the session assigned to secret-named variables. The echoed command is redacted too.Output budgets:
tail/head/head+tailby line, agrepfilter with context, and a char cap. Per call or a session default; the result reports what was kept.Undo for agent actions on remote sessions: snapshot the workspace and restore files if a command goes wrong (needs
giton the remote and an explicit workspace; files only, not side effects).Audit log and live viewer, plus live MCP notifications to the client.
Embeddable, never a service:
cargo add, in your process; no daemon, no vendor.
Upgrading to 0.9
Breaking changes from 0.8. The details are in Upgrading to 0.9.
SSH host keys are pinned in
~/.execkit/known_hosts, not~/.ssh/known_hosts. Old pins are not read. The first connection re-pins, or copy them over withmkdir -p ~/.execkit && chmod 700 ~/.execkitthengrep -E '^[^ ]+ SHA256:' ~/.ssh/known_hosts >> ~/.execkit/known_hosts. Old pins were keyed by bare host whatever the port: rewrite a line for a non-22 port as[host]:port, or a later port-22 connection to that host fails as a key mismatch.stdin is
/dev/nullfor every command, and pagers are set tocat.The target needs
base64.A timeout returns exit code 124 with
timed_out: trueand keeps the session, instead of an error that closed it.ExecResulthas a newtimed_outfield.Session ids look like
a3f9-1_localinstead of1_local.SshConfighas a newconnect_timeoutfield (default 15 s). UseSshConfig::new.
Limitations
Not a sandbox. The command policy is advisory string matching. It is easy to bypass:
deny: ["curl"]blockscurlbut notenv curl,sudo curlorsh -c curl. The real control is a least-privilege environment: run the agent and SSH user with minimal rights.No interactive input. stdin is
/dev/null, so prompts, REPLs and editors do not work. Use non-interactive flags (sudo -n,apt-get -y). Pagers default tocat, but runninglessorvimdirectly hangs until the timeout and closes the session. Shell history is off.Timeouts interrupt, they do not kill everything. execkit sends Ctrl-C. A command that ignores Ctrl-C ends the session. For long jobs, run them in the background (
nohup CMD > /tmp/job.log 2>&1 &) and poll the log.The target needs a POSIX shell and
base64. Local sessions usebash. Windows is not supported.Synchronous core. Fine for typical agent use; not tuned for thousands of concurrent sessions.
SSH
AcceptAnyhost-key mode exists for testing, behind an explicit insecure opt-in. Never use it in production.
Found something rough? Open an issue.
Contributing & security
Contributions: see
CONTRIBUTING.md.Found a vulnerability? Follow
SECURITY.md. Please don't open a public issue for security reports.
License
Apache-2.0: embed it freely, including commercially. See LICENSE and
NOTICE.
Available Tools
7 toolssession_checkpointA
Take a workspace checkpoint on a REMOTE session (snapshot of files you can restore). Requires git on the remote host. Undoes FILES only - not side effects (DB, network, installs). Returns { checkpoint_id }.
| Name | Required | Description | Default |
|---|---|---|---|
| label | No | Optional human label for the checkpoint. | |
| session_id | Yes | Session id from session_create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description carries full burden. It discloses dependencies (git), scope (files only), and return format ({checkpoint_id}). Could add detail on persistence or failure modes, but sufficient for safe usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences that front-load the purpose and immediately add requirements and limitations. Every phrase adds value; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
In the absence of an output schema, the description specifies the return value. It explains what the tool does and its constraints. Missing details on checkpoint lifecycle or restoration, but adequate for a simple tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so both parameters have descriptions. The description adds no extra parameter-specific meaning beyond what the schema provides, meeting the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states it takes a workspace checkpoint (snapshot of files) on a remote session. It clarifies it's a file-only operation and distinguishes from sibling tools by emphasizing its scope and requirement for git.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear context: requires git on remote host, undoes files only, no side effects. Implies when to use (file snapshot) but does not explicitly contrast with siblings like session_restore or session_checkpoints.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_checkpointsBRead-only
List checkpoints (newest first) for a remote session.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session id from session_create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so safety is covered. The description adds one genuinely useful behavioral fact beyond the annotations, the newest-first ordering, but says nothing about pagination, result size, or how checkpoints relate to session_restore. Adequate but thin for a read tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence with no waste, with the resource and the ordering constraint front-loaded. It could be a shade more informative without losing brevity, but nothing needs trimming.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read-only list tool with full schema coverage and no output schema, the description covers the essentials. It does omit what a checkpoint represents and how the listing is used downstream (session_restore), which would help an agent place it in the workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the schema already explains that session_id comes from session_create. The description adds no syntax, format, or constraint detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('List') and resource ('checkpoints') scoped to a remote session, and adds ordering ('newest first'). It does not explicitly distinguish itself from the singular sibling session_checkpoint, but any agent can tell a listing operation apart from the others.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use guidance, no mention of the related siblings (session_checkpoint for creating one, session_restore for consuming one), and no prerequisites or exclusion criteria. The intent of a list tool is implied but nothing routes the agent between this and its cluster mates.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_createA
Open a stateful shell session. Prefer this over a built-in/inline shell when you need: cwd/env kept across calls, a remote host over SSH (host may be a hostname/IP or a Host alias from the operator's ssh config, /config, default ~/.ssh/config), a Docker container, secret-redacted output, or undoable remote file changes (checkpoints); local has no checkpoints. transport: "local"|"ssh"|"docker". ssh needs host (alias HostName/User/Port/IdentityFile fill in what you omit) + password or key_path (or an alias/default key). docker needs container. Optional fingerprint (pin host key), allow/deny. Returns session_id. Remote checkpoints need git on the remote AND an explicit workspace (set 'workspace'; otherwise off, never defaults to home); tune via auto_snapshot/paths/checkpoint_ignores. output_budget default-shapes every command's output.
| Name | Required | Description | Default |
|---|---|---|---|
| deny | No | Optional command denylist (program names). | |
| host | No | SSH host (required for ssh). May be a raw hostname/IP, or a Host alias defined in the operator's ssh config (<key_dir>/config, default ~/.ssh/config) - HostName/User/Port/IdentityFile from a matching alias fill in whatever isn't given below. | |
| port | No | SSH port (default 22, or the alias's Port). | |
| user | No | SSH user (required for ssh, unless the operator's ssh config (<key_dir>/config, default ~/.ssh/config) Host alias sets User). | |
| allow | No | Optional command allowlist (program names). If set, only these run. | |
| paths | No | Sub-paths under the root to checkpoint (optional; default: whole root). | |
| key_path | No | SSH private-key path (must live under the operator's key dir). | |
| password | No | SSH password auth. If omitted along with key_path, one key is picked: the first that exists (inside the operator's key dir) of the ssh config (<key_dir>/config, default ~/.ssh/config) alias's IdentityFile entries, then id_ed25519, id_ecdsa, id_rsa in the key dir. If the server rejects that key, no other key is tried. | |
| container | No | Docker container name or id (required for docker). | |
| transport | Yes | Transport: "local" (a local shell), "ssh", or "docker". | |
| workspace | No | Remote workspace root for checkpoints. REQUIRED to enable checkpoints; there is no default (it will not snapshot the cwd/home dir). | |
| fingerprint | No | Optional pinned host-key fingerprint ("SHA256:..."). If set, the server requires the host key to match exactly. Otherwise the operator's known_hosts file is used. | |
| auto_snapshot | No | Auto-snapshot before changing remote commands (default true, but only takes effect once `workspace` is set; remote only). | |
| output_budget | No | Default output budget for every exec in this session (optional). | |
| checkpoint_ignores | No | Extra exclude patterns (gitignore syntax) added to the snapshot, on top of the built-in defaults (.git, node_modules, caches, .ssh, ...). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does well: it discloses statefulness, secret-redacted output, that remote checkpoints require git plus an explicit workspace and never default to home, and the key-selection fallback ("if the server rejects that key, no other key is tried"). It omits session lifecycle (expiry, limits, need to destroy) and overall error behavior, so it falls short of exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action, and every sentence carries information. It is a single very dense run-on paragraph, however, with topics (auth, checkpoints, budgets) packed together rather than grouped, which costs readability for a 15-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex 15-parameter tool with no output schema and no annotations, it covers purpose, transport-specific requirements, checkpoint semantics, and states the return value (session_id). Missing pieces are session lifecycle and concurrency/error expectations, which are not derivable elsewhere.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3; the description adds value by stating cross-parameter relationships the schema does not, e.g. ssh needs host plus password or key_path, docker needs container, and workspace must be set for checkpoints while auto_snapshot/paths/checkpoint_ignores tune them. That is meaningful semantics beyond the per-field text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: "Open a stateful shell session." It immediately scopes the tool (stateful vs. built-in/inline shell) and enumerates the transports it supports, so an agent can tell it apart from session_exec or session_destroy without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit selection criteria: use this "when you need: cwd/env kept across calls, SSH, Docker, secret-redacted output, or undoable remote file changes (checkpoints); local has no checkpoints." It also states the per-transport prerequisites (ssh needs host + password or key_path; docker needs container), which is effectively when-it-applies guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_destroyADestructive
DESTRUCTIVE: destroy a session and free its resources. The session_id becomes invalid immediately; any unsaved shell state (cwd, env, background jobs) is lost.
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session id from session_create. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, so the safety bar is partly covered. The description nonetheless adds real behavioral detail beyond the annotation: the session_id is invalidated immediately and unsaved shell state (cwd, env, background jobs) is lost. It stops short of stating whether the operation is reversible or what happens on an already-invalid id.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the destructive warning front-loaded, followed by the concrete consequences. No filler, every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with an annotation covering the safety profile and no output schema, the description supplies the missing consequence detail (invalidated id, lost shell state). It is nearly complete, lacking only error/idempotency behavior for repeated calls.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter exists and schema coverage is 100%, with the schema itself noting the id comes from session_create. The description adds no format or constraint detail beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('destroy a session and free its resources') and makes the destructive scope explicit. An agent can immediately distinguish it from siblings like session_create, session_restore, and session_checkpoint.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for teardown ('free its resources') but never states when to choose it over alternatives such as session_list or session_restore, nor any prerequisite like completing work first. Usage is inferable from the destructive framing rather than explicitly guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_execADestructive
Run a command in a session; returns ExecResult JSON (stdout, stderr, exit_code, duration_ms, cwd, truncated). Non-interactive: stdin is closed - no prompts, REPLs, or editors; use sudo -n. Default timeout 120s (EXECKIT_MCP_EXEC_TIMEOUT); timeout_secs overrides per call (max 3600). On timeout the command is interrupted (exit_code 124, timed_out:true); the session stays usable. For long jobs, background: nohup CMD > /tmp/x.log 2>&1 & then poll cat /tmp/x.log. exit, or a set -e failure, ends the shell and closes the session. Optional budget shapes output: {grep:{pattern,context?}, keep:{mode:"all"|"tail"|"head"|"head_tail",n?|head?+tail?}, max_chars?} - line-based, after redaction; never changes exit code/side effects; adds a report (mode + lines_total/lines_kept). Truncated unbudgeted output adds a hint. Redacted output is not file-accurate: never write it back to a file.
| Name | Required | Description | Default |
|---|---|---|---|
| budget | No | Shape THIS command's output (overrides the session default). | |
| command | Yes | The shell command to run. | |
| session_id | Yes | Session id from session_create. | |
| timeout_secs | No | Timeout for THIS command in seconds (default 120, or EXECKIT_MCP_EXEC_TIMEOUT; clamped to 1..=3600). On timeout the command is interrupted and the session stays usable. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the openWorldHint/destructiveHint annotations: timeout semantics (exit_code 124, timed_out:true, session remains usable), default and max timeout values, session termination triggers ('exit', or a `set -e` failure), and the guarantee that budget shaping never changes exit code or side effects. The redaction caveat ('never write it back to a file') is a genuinely non-obvious safety detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and return shape, and every clause carries information with no filler. However, the heavy semicolon chaining and nested parentheticals make the constraints harder to scan than they need to be; a few of the later sentences could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, and the description compensates by enumerating the returned fields, documenting timeout and session-lifetime behavior, and covering output shaping and redaction. An agent has everything needed to invoke this correctly and interpret the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description exceeds it by explaining budget semantics that the schema only names - the grep -> line-keep -> char-cap ordering, that it runs after redaction, and that it emits a report (mode + lines_total/lines_kept). It also restates the timeout override/clamp behavior, so most of the gain is on the budget parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ('Run a command in a session') and immediately states the return shape (ExecResult JSON with stdout, stderr, exit_code, duration_ms, cwd, truncated). No sibling does execution, so an agent can route here unambiguously without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-not conditions ('Non-interactive: stdin is closed - no prompts, REPLs, or editors') plus the concrete workaround ('use `sudo -n`'). Also covers the tricky case of long jobs ('nohup CMD > /tmp/x.log 2>&1 &' then poll `cat /tmp/x.log`), which is exactly the guidance an agent needs to avoid a hanging call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_listARead-only
List live sessions: [{session_id, transport, idle_secs}]. Use this to recover a session_id you lost track of, or to check whether a session is still open (it may have been closed by exit, a set -e failure, or idle-timeout reaping) before calling session_exec again.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true. The description adds valuable behavioral context beyond that: sessions may have been closed by `exit`, a `set -e` failure, or idle-timeout reaping, which explains why list results can differ from expectations. It does not cover pagination or ordering, but that is minor for a live-session list.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the purpose and return shape, then the decision criteria. No filler; every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no parameters and no output schema, the description fully carries the burden: it states what is listed, the fields returned, and the reasons a session might be missing. An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so per the rubric the baseline is 4. The description correctly adds no parameter commentary and instead documents the return shape, which is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List live sessions') and enumerates the returned fields (session_id, transport, idle_secs). This clearly distinguishes it from siblings like session_checkpoints, session_create, and session_exec.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names two use cases: recovering a lost session_id and verifying a session is still open before calling session_exec again. It also names the sibling it precedes, giving the agent a clear routing decision.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
session_restoreADestructive
DESTRUCTIVE: restore a remote session's workspace to a checkpoint (omit checkpoint_id to restore the most recent). Reverts tracked files and DELETES untracked files anywhere under the workspace, permanently and without a prompt. Does not undo other side effects (DB writes, network calls, installs).
| Name | Required | Description | Default |
|---|---|---|---|
| session_id | Yes | Session id from session_create. | |
| checkpoint_id | No | Checkpoint id to restore; omit to restore the most recent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well past destructiveHint=true by specifying exactly what is destroyed (untracked files anywhere under the workspace), that it is permanent and unprompted, what is reverted (tracked files), and what it explicitly does NOT cover (DB writes, network calls, installs). This is the rare case where the description meaningfully upgrades the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the DESTRUCTIVE marker, then the action, then the blast radius and limits. No filler, and the most decision-critical fact (permanent deletion without prompt) is placed before the caveats.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter mutation with no output schema, the description covers action, default, destruction scope, and side-effect limits, which is nearly everything an agent needs. It omits any statement of return value or failure conditions (e.g. unknown checkpoint_id, inactive session), which would close the last gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters are already documented, including the 'omit to restore the most recent' default. The description restates that default without adding format, validity, or lookup details, so the schema carries the load and the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — restoring a session's workspace to a checkpoint — with the scope ('remote session's workspace') and default behavior spelled out. The restore-vs-create contrast with sibling session_checkpoint is unambiguous from the verb alone, so an agent can route correctly without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a concrete selection rule for the ambiguous case ('omit checkpoint_id to restore the most recent') and makes the destructive context explicit so the agent knows this is not a routine read. It never names an alternative tool or states a precondition (e.g. session must be active), so it stops short of full when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.10.1- Changed
session_create6 fields changed- added
Input schema / $defs / KeepParams / properties / mode / enumAdded value: +[ + "all", + "tail", + "head", + "head_tail" +] - changed
Input schema / properties / host / descriptionPrevious value: -"SSH host (required for ssh)."New value: +"SSH host (required for ssh). May be a raw hostname/IP, or a Host alias\ndefined in the operator's ssh config (<key_dir>/config, default\n~/.ssh/config) - HostName/User/Port/IdentityFile from a matching\nalias fill in whatever isn't given below." - changed
Input schema / properties / password / descriptionPrevious value: -"SSH password auth."New value: +"SSH password auth. If omitted along with key_path, one key is picked:\nthe first that exists (inside the operator's key dir) of the ssh\nconfig (<key_dir>/config, default ~/.ssh/config) alias's\nIdentityFile entries, then id_ed25519, id_ecdsa, id_rsa in the key\ndir. If the server rejects that key, no other key is tried." - changed
Input schema / properties / port / descriptionPrevious value: -"SSH port (default 22)."New value: +"SSH port (default 22, or the alias's Port)." - added
Input schema / properties / transport / enumAdded value: +[ + "local", + "ssh", + "docker" +] - changed
Input schema / properties / user / descriptionPrevious value: -"SSH user (required for ssh)."New value: +"SSH user (required for ssh, unless the operator's ssh config\n(<key_dir>/config, default ~/.ssh/config) Host alias sets User)."
- Changed
session_exec2 fields changed- added
Input schema / $defs / KeepParams / properties / mode / enumAdded value: +[ + "all", + "tail", + "head", + "head_tail" +] - added
Input schema / properties / timeout_secsAdded value: +{ + "default": null, + "description": "Timeout for THIS command in seconds (default 120, or\nEXECKIT_MCP_EXEC_TIMEOUT; clamped to 1..=3600). On timeout the command\nis interrupted and the session stays usable.", + "format": "uint64", + "minimum": 0, + "type": [ + "integer", + "null" + ] +}
- Added
session_list
6 tool updates
v0.8.0- First observed
session_checkpoint - First observed
session_checkpoints - First observed
session_create - First observed
session_destroy - First observed
session_exec - First observed
session_restore
TDQS
Scored across 7 tools
Most tools have clearly distinct purposes: create, exec, list, destroy, and checkpoint/restore are separate operations. The only mild ambiguity is between session_checkpoint and session_checkpoints, whose names differ only by pluralization, though their descriptions clearly distinguish taking vs listing checkpoints.
All tools use the session_ prefix and snake_case, which is consistent and readable. The minor deviation is that session_checkpoints (list) and session_checkpoint (take) use a singular/plural distinction rather than a clear verb such as list_checkpoints, but the pattern remains largely predictable.
Seven tools is a well-scoped set for managing stateful shell sessions, covering the essential lifecycle without redundancy. Each tool earns its place.
Core session lifecycle is covered: create, exec, list, destroy, plus checkpoint take/list/restore. Minor gaps exist, such as no explicit session info/get tool or checkpoint deletion, but the surface is sufficient for typical agent workflows.
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Real Linux labs your AI agent deploys, routes and runs, with domains, TLS, DBs and an audit log.
Remote shell and detached long-running jobs on your own machines — no SSH, open ports or VPN.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to have persistent, fully interactive SSH sessions into remote hosts, behaving like a local terminal.15 npm1MIT
- AlicenseNot gradedqualityAmaintenanceGive Claude Code, Cursor, and other AI agents safe access to your real infrastructure — without giving them raw SSH access.5MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to securely execute terminal commands with persistent sessions, async jobs, and mission control, while providing a live dashboard for human oversight.4Apache 2.0
- AlicenseAqualityAmaintenanceGive AI agents a persistent, interactive terminal with support for SSH, REPLs, database CLIs, TUI apps, and long-running processes.953 PyPI12MIT

