@ahmedshaikh/shell-session-mcp
v0.1.0
Published
Persistent stateful shell as an MCP server — env vars, cwd, and shell state survive across tool calls (unlike one-shot bash).
Maintainers
Readme
shell-session
A persistent, stateful shell as an MCP server. Unlike a one-shot bash tool —
where env vars, cd, source, and shell functions vanish after every call — this
keeps a single long-lived shell alive, so state set once is reused across calls.
shell("export PATH=/opt/node/bin:$PATH") # set it once
shell("cd /my/project")
shell("node --version") # PATH + cwd still applyNo more re-exporting the same vars or re-cding on every command.
Tools
shell(command, timeout_ms?)— run a command in the persistent shell; returns the exit code + combined stdout/stderr.shell_reset()— kill the shell and start fresh (clears all state).shell_status()— alive?, pid, current working directory.
How it works
A plain child_process shell (no pty, no native dependencies) reads commands
from its stdin pipe. Completion is detected with a unique end-marker that also
prints the command's exit code. Since a non-interactive shell doesn't echo stdin,
only command output is captured.
Limitations (honest)
- No TTY: interactive programs (vim,
less, prompts) and commands that read stdin won't work — this is for batch commands. - A timed-out command keeps running in the session; call
shell_resetto recover (without a pty there's no way to signal just the foreground command). - One command at a time (calls are serialized).
Setup
npm install
npm test # proves persistence: env/cwd/functions survive across callsRegister with an MCP client, e.g.:
claude mcp add shell-session -- node /abs/path/shell-session/dist/server.jsNode 18+.
