mcp-shell-sudo
The server lets an MCP client execute local shell commands and remote SSH commands as explicit argv arrays, with optional sudo, working-directory confinement, and executable allowlisting.
Run arbitrary local commands such as
["ls", "-la"]or["git", "status"]viashell_execute.Provide stdin, set a working directory, and set a timeout for each command.
Execute commands with local
sudousing a configured password or non-interactivesudo -n.Run commands on remote hosts via
ssh_executeusing OpenSSH aliases, with optional SSH port, TTY, timeout, and remote sudo.Feed stdin to remote commands and request remote elevation with
sudo: true.Use
shell_executewith the simple compatibility form["ssh", "host", "sudo", "command", ...].Restrict available executables with
ALLOW_COMMANDS(e.g.,git,ls,cat), validated for both local and remote commands.Confine local filesystem writes to a
WORK_DIRusing Bubblewrap, which also disables sudo and SSH to preserve isolation.Inspect effective non-secret configuration (allowlist, sudo-password presence, confinement status, SSH availability) through
shell_config.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-shell-sudorun git status in the current directory"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-shell-sudo
Warning: Use this MCP with caution. If sudo credentials are configured, it can execute privileged commands both on the host machine and on SSH-connected remote systems.
MCP server for Linux written in Python that executes local and remote SSH commands using explicit argv arrays, supports non-interactive local and remote sudo, provides an optional executable allowlist through ALLOW_COMMANDS, and can confine local filesystem writes to WORK_DIR using Bubblewrap.
Requirements
Linux.
Python 3.11+.
uvrecommended.MCP Python SDK 2.0.0.
sudoif elevated commands will be executed.OpenSSH client (
ssh) if remote execution will be used.SSH login authentication configured through
~/.ssh/config, a key, or an SSH agent for non-interactive remote access.bubblewrapifWORK_DIRis configured.
On Debian/Ubuntu:
sudo apt update
sudo apt install -y bubblewrapRelated MCP server: MCP Process Server
Environment Variables
PASSWORD_SUDO
Password used for local sudo. It is also the fallback password for remote sudo when PASSWORD_SUDO_SSH is not configured.
Empty or unset: local
sudousessudo -n. Remotesudoalso usessudo -nunlessPASSWORD_SUDO_SSHis configured.Set: local
sudousessudo -S, and the password is provided through stdin, never through argv or logs. Remotesudoreuses this value only whenPASSWORD_SUDO_SSHis absent.
Example:
"PASSWORD_SUDO": "my-password"The supported form is:
["sudo", "id"]Custom sudo flags such as sudo -u postgres ... are not accepted. This prevents the policy layer from having to interpret the full sudo command grammar.
PASSWORD_SUDO_SSH
Optional password override used only for sudo on remote hosts executed through ssh_execute.
"PASSWORD_SUDO_SSH": "remote-sudo-password"Password selection for remote sudo is:
PASSWORD_SUDO_SSHwhen configured.Otherwise
PASSWORD_SUDO.If neither is configured, remote sudo uses
sudo -nand fails instead of waiting for an interactive password prompt.
This variable is not an SSH login password. ssh_execute does not inject SSH login credentials. SSH authentication must already work non-interactively through OpenSSH configuration, a key, or an SSH agent.
WORK_DIR
Optional working directory.
Empty or unset: the MCP server may work from any existing directory specified in the tool call.
Set: the server enters strict mode.
directorymust resolve insideWORK_DIR, and every process runs inside a Bubblewrap mount namespace where/is read-only,WORK_DIRis mounted read-write, and/tmpand/runare temporary.
Using cwd alone would not be sufficient to guarantee this isolation. A process could still write to /etc, /home/..., or follow symlinks outside the project. For this reason, the server fails at startup if WORK_DIR is configured but bwrap is unavailable.
In this mode, local sudo and all SSH execution are rejected. Host-level privilege escalation would break the local write-confinement guarantee, and local Bubblewrap confinement cannot restrict changes made on a remote host.
ALLOW_COMMANDS
Comma-separated list of executable names.
"ALLOW_COMMANDS": "git,ls,cat,grep,python,node,pnpm"Empty or unset: all executables are allowed.
Set: only exact executable names from the list are allowed, and they must be invoked by name rather than through paths such as
/usr/bin/git.If a local command starts with
sudo, the actual executable followingsudois validated.For
ssh_execute, bothsshand the remote target executable must be present in the allowlist.Direct arbitrary
sshcalls throughshell_executeare rejected while an allowlist is active; usessh_executeso the remote executable can also be validated. The simple compatibility form["ssh", "host", "sudo", "command", ...]is recognized and validated.
The allowlist applies to executables, not arguments. Allowing bash, python, node, env, or another tool capable of executing processes significantly expands what the MCP client can do.
Installation
Option 1 — Install directly from GitHub (recommended for users)
If you only want to use the MCP and do not need a local source checkout, install it directly
from the repository with uv:
uv tool install git+https://github.com/eaangrino/mcp-shell-sudo.gitThis installs mcp-shell-sudo in an isolated uv tool environment. You do not need to
clone the repository manually.
Verify that the executable is available:
command -v mcp-shell-sudoIf the uv tool bin directory is not yet in your PATH, run:
uv tool update-shellThe executable is typically available as ~/.local/bin/mcp-shell-sudo.
Option 2 — Clone the repository (development or local changes)
Clone the project when you want to inspect, modify, or contribute to the source code:
git clone https://github.com/eaangrino/mcp-shell-sudo.git
cd mcp-shell-sudo
uv syncInstall development dependencies with:
uv sync --extra devTo expose the executable while keeping the local source editable:
uv tool install --force --editable .Manual Execution
uv run mcp-shell-sudoThe transport is stdio. Logging is never written to stdout in order to avoid corrupting JSON-RPC messages; logs are written to stderr instead.
MCP Configuration
Example with unrestricted commands and sudo enabled:
{
"mcpServers": {
"shell": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/mcp-shell-sudo",
"run",
"mcp-shell-sudo"
],
"env": {
"PASSWORD_SUDO": "YOUR_PASSWORD",
"WORK_DIR": "",
"ALLOW_COMMANDS": ""
}
}
}
}Example using the installed executable with separate local and remote sudo passwords:
{
"mcpServers": {
"mcp-shell-sudo": {
"command": "/home/user/.local/bin/mcp-shell-sudo",
"env": {
"PASSWORD_SUDO": "LOCAL_SUDO_PASSWORD",
"PASSWORD_SUDO_SSH": "REMOTE_SUDO_PASSWORD"
}
}
}
}If local and remote sudo use the same password, omit PASSWORD_SUDO_SSH; PASSWORD_SUDO is reused automatically for remote sudo.
Example confined to a specific project:
{
"mcpServers": {
"shell-project": {
"command": "uv",
"args": [
"--directory",
"/ABSOLUTE/PATH/mcp-shell-sudo",
"run",
"mcp-shell-sudo"
],
"env": {
"PASSWORD_SUDO": "",
"WORK_DIR": "/home/user/projects/app",
"ALLOW_COMMANDS": "git,ls,cat,grep,find,python,node,pnpm"
}
}
}
}shell_execute Tool
Basic input:
{
"command": ["ls", "-la"]
}With a working directory:
{
"command": ["git", "status"],
"directory": "backend"
}With stdin:
{
"command": ["cat"],
"stdin": "hello\n"
}With sudo:
{
"command": ["sudo", "id"]
}Response:
{
"stdout": "uid=0(root) gid=0(root) groups=0(root)\n",
"stderr": "",
"status": 0,
"execution_time": 0.031,
"timed_out": false,
"output_limited": false
}ssh_execute Tool
Use ssh_execute when the command must run on another machine. The command array must contain the remote executable and arguments without sudo; request elevation with sudo: true.
Basic remote execution:
{
"host": "server-alias",
"command": ["id"]
}Remote sudo:
{
"host": "server-alias",
"command": ["systemctl", "status", "docker", "--no-pager"],
"sudo": true
}Optional SSH port and TTY:
{
"host": "my-server",
"command": ["id"],
"sudo": true,
"port": 2222,
"tty": true,
"timeout": 120
}For non-default usernames, identity files, or other SSH options, configure an OpenSSH alias first:
Host my-server
HostName example.com
User user
IdentityFile ~/.ssh/my-server
Port 2222Then pass only the alias in host.
host: an OpenSSH destination or alias. Authentication must already work non-interactively using~/.ssh/config, a default SSH key, or an SSH agent. An alias is recommended when a specific user, non-default identity file, or other SSH options are required.command: remote argv excludingsudo.sudo: when true, runs the remote command assudo -S -p '' -- ...when a remote sudo password is configured, otherwise assudo -n -- ....stdin: optional data delivered to the remote command after the sudo password.port: optional TCP port from 1 to 65535. It controls the SSH connection port; it does not provide authentication credentials.tty: usesssh -tt; enable it only if the remote sudo policy requires a TTY. It does not makessh_executehandle an interactive SSH login password prompt.timeout: 60 seconds by default, capped at 600 seconds.
SSH login authentication is handled entirely by the local OpenSSH client. ssh_execute does not inject an SSH login password and does not currently accept an explicit identity-file parameter equivalent to ssh -i. If a non-default private key is required, configure it with IdentityFile in ~/.ssh/config or load it into an SSH agent.
For compatibility, shell_execute also recognizes the common simple form:
{
"command": ["ssh", "server-alias", "sudo", "id"]
}For explicit remote execution or more complex SSH requirements, prefer ssh_execute.
shell_config Tool
Returns the effective non-secret configuration.
It never returns PASSWORD_SUDO or PASSWORD_SUDO_SSH. It reports only non-secret state such as whether local/remote sudo password injection is configured, whether ssh is available, whether WORK_DIR confinement is active, and the effective allowlist.
Implemented Security Measures
Uses
create_subprocess_exec; it does not useshell=True.commandis passed as an explicit argv array.Local and remote sudo passwords never appear in process argv or the child process environment; configured secrets are also redacted from stdout/stderr before results are returned.
If no applicable sudo password is configured,
sudo -nprevents the process from hanging while waiting for an interactive password prompt.SSH login authentication remains delegated to OpenSSH configuration, keys, and agents; the MCP server does not handle SSH login passwords.
SSH_AUTH_SOCKis forwarded when present so OpenSSH can use the current SSH agent.Remote argv elements are quoted with
shlexsemantics before being passed to OpenSSH.ALLOW_COMMANDSvalidates the local executable after a simplesudoinvocation and, forssh_execute, validates bothsshand the remote target executable.Uses a fixed and reduced
PATHto avoid resolving executables from.or arbitrary inherited paths.Uses a reduced child environment instead of inheriting the entire MCP server environment.
Per-call timeout: 60 seconds by default, with a maximum of 600 seconds.
Output limit: 2 MiB per stream. If the limit is exceeded, the entire process group is terminated.
Processes run in a new session, and the entire process group is terminated on timeout.
WORK_DIRuses Bubblewrap and fails closed if isolation cannot be provided. SSH execution and sudo are disabled whileWORK_DIRis active where confinement cannot be guaranteed.
Important Limitations
ALLOW_COMMANDS=""means arbitrary command execution with the permissions of the user running the MCP server. If a sudo password is also configured, the MCP client can request root actions locally and, throughssh_execute, on SSH hosts for which authentication is already available. Use this configuration only with a client and model you control.An executable allowlist does not semantically validate command arguments.
python,node,bash,sh,perl, and similar tools are effectively equivalent to allowing arbitrary code execution.WORK_DIRis a local filesystem confinement mechanism, not a VM or network sandbox. Because it cannot constrain remote filesystem changes, SSH execution is intentionally disabled wheneverWORK_DIRis configured.Remote execution can modify another machine with the permissions of the SSH account or root when
sudo: truesucceeds. OpenSSH host verification and trust remain governed by the user's SSH configuration andknown_hosts.PASSWORD_SUDOandPASSWORD_SUDO_SSHstored in the MCP client configuration remain secrets stored in that file. Restrict the file permissions withchmod 600and never commit it to version control.
Tests
uv run --extra dev pytest
uv run --extra dev ruff check .Maintenance
Tools
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables AI assistants to securely execute shell commands on local machines through an SSH interface with session management, command execution, and sudo support.1
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to launch and manage system processes with strict security controls through executable allowlists, resource monitoring, and output capture capabilities.761MIT
- AlicenseNot gradedqualityCmaintenanceEnables secure execution of shell commands through a dynamic approval system that prompts for user authorization on first use, with persistent command storage and comprehensive audit logging.Apache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI models to safely execute pre-defined Linux shell commands with a whitelist mechanism, restricting execution to allowed commands only.1
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Remote MCP for Android CLI agent build gate, structured receipts, audit logs, and reviewer-ready evi
Runtime permission, approval, and audit layer for AI agent tool execution.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/eaangrino/mcp-shell-sudo'
If you have feedback or need assistance with the MCP directory API, please join our Discord server