Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rust library

The execkit crate is the core. The MCP server is a thin wrapper over it; you can embed the same sessions directly in your own program.

[dependencies]
execkit = "0.7"                                          # local + SSH + Docker
# execkit = { version = "0.7", default-features = false } # local + Docker only (no SSH; drops russh/tokio)
use execkit::{Session, Policy};

fn main() -> Result<(), execkit::Error> {
    let mut s = Session::local()?
        .with_policy(Policy { allow: vec![], deny: vec!["rm".into()] });

    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);
    Ok(())
}

State persists across exec calls on the same Session, exactly as it does over MCP. Results are the same structured ExecResult (split stdout/stderr, exit code, duration, cwd), ANSI-stripped and secret-redacted.

SSH and Docker sessions are constructed with their configs:

#![allow(unused)]
fn main() {
use execkit::{Session, SshConfig, SshAuth, HostKeyVerification};

let cfg = SshConfig::new("web-01".into(), "deploy".into(),
    SshAuth::Password("...".into()),
    HostKeyVerification::KnownHosts("/home/me/.ssh/known_hosts".into()));
let mut s = Session::ssh(cfg)?;
}

The API surface stays small; the richness lives in the result, not the verbs:

Session::local() / ::ssh(cfg) / ::docker(container)        -> Session
session.exec(command)                                      -> ExecResult
session.exec_budgeted(command, &budget)                    -> ExecResult
session.checkpoint(label?) / restore(id) / restore_last()  -> CheckpointId / restore report

Runnable examples live in the repository:

cargo run --example local
EXECKIT_SSH="user:password@host:22" cargo run --example ssh

Full API docs are on docs.rs/execkit.