Skip to main content
Glama

sudo-proxy

tarides/sudo-proxy MCP server

Repository

An MCP server that lets an agent run privileged, mutating commands — locally or over SSH — with a human keypress required on every one and no credential ever stored.

Privileged command execution proxy with an MCP server for AI agent integration. Receives requests over a Unix socket, shows a single-keypress TUI prompt for human approval, then escalates via sudo. Configure sudo-proxy-mcp in Claude Code or any MCP client and the model can run privileged commands — with explicit human approval on every one.

⚠️ Not yet independently audited. The security assurance in this repo is self-produced. Security reviewers: REVIEWING.md is a 15-minute on-ramp — the falsifiable claims, the trust boundary, and where we have no assurance. Reporting: SECURITY.md.

Architecture

AI model ──► sudo-proxy-mcp ──► Unix socket ──► sudo-proxy ──► TUI Y/N ──► sudo
             (MCP server)         │
                                  │
                            local socket, or SSH tunnel
                        (start_server spawns sudo-proxy --host
                         which sets up the tunnel and remote
                         server)

The TUI prompt asks for approval (single keypress), then sudo handles privilege escalation. The password prompt appears in the same terminal. This flow is identical for local and remote hosts. A non-privileged mode runs commands directly as the current user, still behind the same Y/N gate — see docs/usage.md.

Related MCP server: MCP SSH Proxy

Why not just use the Bash tool?

Bash tool

sudo-proxy MCP

Privilege escalation

Not possible

sudo with human approval

Human review

None — executes immediately

TUI Y/N gate on every command (privileged and unprivileged)

Timeout

Up to 10 min, no user prompt

60 s TUI prompt + configurable overall timeout

Remote hosts

Not supported

SSH tunnel with TUI on remote terminal

Environment

Inherits shell env

Sanitized allowlist only

Audit trail

None

Server logs each request (with -v)

sudo-proxy fills the gap when a model needs to install packages, edit system files, manage services, or run any other command — with the human always in the loop, even when Claude Code is run with --dangerously-skip-permissions.

For how this relates to mcp-firewall, sandboxing, polkit, doas, and other neighboring tools, see docs/comparison.md.

Features and non-features

What sudo-proxy does:

  • Per-command human approval — a single-keypress Y/N TUI gate on every command, privileged and unprivileged, with no way to bypass it.

  • Real privilege escalation via sudo — installs packages, edits system files, manages services; not limited to read-only diagnostics.

  • Local and remote over one flow — the same approval TUI whether the command runs on this machine or on a remote host over an SSH tunnel.

  • Stores no secret — the sudo password is typed live into the terminal; nothing is cached, encrypted-at-rest, or written to disk.

  • Explicit argv — commands are passed and displayed exactly as they run, with no shell-string interpolation.

  • Sanitized environment — a fixed allowlist, not the inherited shell environment.

  • Audit trail — each request is logged by the server (-v).

  • Works under --dangerously-skip-permissions — the human gate holds even when the agent's own permission prompts are disabled.

What sudo-proxy deliberately does not do:

  • No stored or managed credentials — it is not a password cache or a secrets manager.

  • No unattended execution — there is no auto-approve mode; a human approves each command or it does not run.

  • Not a sandbox — it grants real privilege rather than isolating or faking it.

  • Not a policy engine or ACL — the human at the keypress is the policy; there are no rules to write or maintain.

  • Not read-only — it is not restricted to a whitelist of safe diagnostic commands.

  • No hosted service — it runs on your own machine; commands never transit a third-party relay.

  • Not a general remote shell — no persistent interactive sessions, SFTP browser, or fleet manager; just gated one-shot commands.

Quickstart

Install the binaries (needs a Rust toolchain; prebuilt static binaries are on Releases):

cargo install sudo-proxy

Or fetch the prebuilt static binaries without compiling, via cargo binstall:

cargo binstall sudo-proxy

cargo binstall downloads the release tarball from GitHub and verifies its minisign signature (public key RWT7gwtBU0v4puI76u0oYwMAT9nmYwGimSOnqJJ+kHExsjTDQj1eZkMW, key ID A6F84B53410B83FB) before installing; a missing or bad signature aborts the install. Prefer cargo install if you'd rather build from source.

Point your MCP client at the server — add to the project's .mcp.json or ~/.claude/claude_desktop_config.json:

{
  "mcpServers": {
    "sudo-proxy": {
      "command": "sudo-proxy-mcp"
    }
  }
}

Then the model starts a server (opening a terminal with the approval TUI) and runs commands through it:

start_server()
execute({"argv": ["apt", "install", "nginx"], "description": "Install nginx"})

Each execute shows the exact command in the TUI; press y to approve, N (default) to deny. For remote hosts, pass host to start_server and execute.

MCP Registry

Listed in the official MCP Registry as mcp-name: io.github.tarides/sudo-proxy.

Documentation

AI-assisted development

sudo-proxy was developed with substantial AI assistance using Claude Code. Commits where AI contributed materially carry a Co-Authored-By trailer naming the specific model. All design decisions, threat modeling, and the final form of every committed change were reviewed and approved by the human maintainer, who takes responsibility for the codebase.

This disclosure is provided in line with emerging industry practice around transparency about generative-AI involvement in software development. It is not a statement that the project is "AI-generated": the human-in-the-loop principle that the tool itself enforces at runtime is also the principle under which it was built.

License

MIT

Available Tools

5 tools
executeA

Execute a command (or multi-stage pipeline) on a sudo-proxy host after a human approves it at that host's terminal. Provide argv for a single command or pipeline for piped stages (e.g. [["ls", "/tmp"], ["wc", "-l"]]); host targets a remote daemon started via start_server (omit for localhost); timeout is in milliseconds (default 120000, clamped to 600000). Blocks until the human answers, then returns the final stage's stdout plus per-stage stderr and exit codes. Errors: 'Request denied by user.' if the human declines, a timeout error if unanswered within 60s, and 'sudo-proxy is not running' if the daemon is down — call start_server first.

ParametersJSON Schema
NameRequiredDescriptionDefault
envNoEnvironment variables
argvNoCommand as argument array
hostNoTarget host (omit for localhost)
timeoutNoTimeout in milliseconds (default: 120000, max: 600000)
pipelineNoPipeline of commands, each as an argument array. Use this for piped commands like [["ls", "/tmp"], ["wc", "-l"]].
privilegedNoPrivilege escalation (default: true)
descriptionNoWhat this command does (shown in TUI prompt)
forward_agentNoForward the local SSH agent to the command (unprivileged only). Requires the proxy session to have been started with `forward_agent: true`. Useful for `git clone` of private repos via SSH on a remote host.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral burden and meets it: it discloses that execution blocks until a human approves, that it returns final-stage stdout plus per-stage stderr and exit codes, and it enumerates specific error strings including user denial, timeout, and daemon-down cases. This is rich, non-obvious behavioral detail that an agent needs to use the tool correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured: it front-loads the core purpose, then covers invocation parameters, blocking behavior, return payload, and error conditions in a compact sequence. Every sentence carries functional information; nothing is redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's high complexity—8 parameters, nested pipeline structure, and no output schema—the description is complete: it covers the two execution modes, target host setup, timeout, return value shape, and failure modes. The mention of per-stage stderr and exit codes compensates for the lack of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, and the description adds real value beyond the schema by clarifying the distinction between argv and pipeline, how host relates to start_server, and the timeout default/clamp. It doesn't add narrative around env, privileged, or forward_agent, but the schema already documents those adequately.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Execute') and resource ('a command or multi-stage pipeline on a sudo-proxy host') and clearly distinguishes this from lifecycle siblings like start_server, stop_server, and status. The inclusion of the human-approval step adds a defining behavioral trait that makes the tool's role unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives practical usage guidance: use argv for a single command, pipeline for piped stages, omit host for localhost, and call start_server first if the daemon is down. It doesn't explicitly contrast with sibling tools, but the operational context and start_server prerequisite are sufficient for an agent to select this tool appropriately.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

start_serverA

Start a sudo-proxy approval daemon: with no host, opens a local terminal window running the approval TUI; with host, opens a terminal running SSH to that host with a Unix-socket tunnel so subsequent execute calls reach it. Idempotent: if the daemon (or tunnel) is already live it returns 'already running' without spawning anything. Blocks while polling for end-to-end socket readiness — up to 5s locally, up to 30s for remote tunnels — and returns as soon as the daemon answers. Set forward_agent: true to enable SSH agent forwarding for unprivileged remote commands (ignored locally); errors if no terminal emulator is found or the socket is not ready within the polling window.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoRemote hostname (omit for localhost)
forward_agentNoEnable SSH agent forwarding on the tunnel so unprivileged commands that opt in (via execute's `forward_agent: true`) can authenticate to GitHub etc. with the user's local key. Ignored for local servers.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full behavioral burden and does so richly: idempotency, polling/blocking behavior, timeout windows, error conditions, and SSH agent forwarding semantics are all disclosed. There is no contradiction with any annotation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured: core purpose comes first, then conditional modes, then idempotency and failure behavior. Each sentence adds needed detail, though the sentence length makes it slightly less scannable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It covers invocation modes, timeouts, error cases, and parameter semantics, which is strong for a tool with no output schema. The only minor gap is the absence of an explicit success-return format, but status/stop siblings mitigate the operational context need.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for both parameters, so the baseline is 3; the description adds real value by explaining the local-versus-host effect, the ignored-locally behavior for `forward_agent`, and the consequences of each setting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the action ('Start') and resource ('sudo-proxy approval daemon'), and explicitly distinguishes local versus host modes. This makes its purpose unambiguous and differentiates it from sibling tools like stop_server and status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage conditions: no `host` means local TUI, `host` means SSH tunnel, and `forward_agent` applies to remote tunnels. It links its role to enabling subsequent `execute` calls, though it does not explicitly name stop_server/status as alternatives for stopping or checking state.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

statusA

Report the status of sudo-proxy daemons without executing any command: with host, checks that one daemon; with no arguments, checks the local daemon plus every host in the registry. For each host it reports whether the socket exists and answers, the live daemon version (learned via a ping that needs no human approval), and registry metadata (description, OS, last connected). Read-only except for refreshing the registry's last-connected/version cache after a successful ping. Hosts that are down are reported as 'not running' — that is a normal result, not an error.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoHost to check (omit to report the local daemon plus every known host)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the operation is read-only except for refreshing the registry cache, that the ping needs no human approval, and that down hosts are reported as 'not running' — a normal result, not an error. This is excellent behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and then efficiently covers invocation variants, output content, side effects, and error interpretation. Every clause earns its place, and the length is appropriate given the lack of annotations and output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one optional parameter, no annotations, and no output schema, the description covers invocation variants, what is reported for each host, the side effect of cache refresh, and how to interpret down hosts. An agent has enough information to call it correctly without further clarification.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description already fully explains the `host` parameter and its omission behavior, so schema coverage is 100%. The tool description reinforces this but does not add meaningful semantic detail beyond what the schema provides, matching the baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Report the status of sudo-proxy daemons' and explicitly notes it does so 'without executing any command', distinguishing it from the execute sibling. The host/no-argument variants further specify the exact resource and scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit usage conditions: with `host` checks one daemon; with no arguments checks the local daemon plus all registry hosts. It also rules out command execution, implicitly steering the agent away from `execute`, though it does not name the sibling alternatives directly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stop_serverA

Stop a running sudo-proxy daemon: sends a stop request over its socket; the daemon prints a shutdown notice on its terminal (no approval prompt is required), exits, and its terminal window — and SSH tunnel, for remote hosts — closes. host selects a remote daemon started via start_server; omit it for the local one. Returns a non-error 'not running' message if no socket exists; on success, confirms after briefly polling for the socket to disappear and removes any stale tunnel socket. If the target runs a sudo-proxy version that predates remote stop, returns an error asking you to press q or Ctrl+C in that daemon's terminal instead.

ParametersJSON Schema
NameRequiredDescriptionDefault
hostNoHost whose daemon to stop (omit for the local daemon)

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure, and it delivers: it states there is no approval prompt, the terminal window and SSH tunnel close, stale tunnel sockets are removed, the tool polls for socket disappearance, and it returns a non-error 'not running' message when no socket exists. This is exceptionally transparent about side effects and return behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence earns its place: the first states the core action and outcome, the second covers parameter semantics and return behavior, and the third handles a compatibility edge case. It is dense but not padded, with the main purpose front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given one optional parameter, no annotations, and no output schema, the description is complete. It covers target selection, side effects, success and failure return behavior, the no-socket case, and the old-version fallback. An agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single `host` parameter, so the baseline is 3. The description adds value beyond the schema by specifying that `host` selects a daemon started via start_server, and it explains the remote-vs-local selection semantics more richly than the schema's 'omit for the local daemon'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Stop a running sudo-proxy daemon') and goes on to explain exactly what happens: a stop request is sent, the daemon exits, and its terminal/tunnel closes. This clearly differentiates stop_server from siblings like start_server and status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete selection guidance: `host` selects a remote daemon started via start_server, and omitting it targets the local daemon. It also explains the fallback for old versions that predate remote stop. However, it does not explicitly contrast with alternatives like status or execute, though the context makes the intended use clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_hostA

Record or update metadata for a host in the sudo-proxy registry (~/.config/sudo-proxy/hosts.json), which is surfaced in this server's instructions and in status output. Partial update: only the description and/or os fields you provide are changed; omitted fields keep their current values. A host not yet in the registry is added automatically. Returns 'Updated host '; errors only if the host name contains characters outside [A-Za-z0-9._@:-].

ParametersJSON Schema
NameRequiredDescriptionDefault
osNoOperating system info (e.g. "Ubuntu 24.04")
hostYesHostname to update
descriptionNoHuman-readable description of the host (e.g. "CI server")

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It transparently discloses the file path, partial-update semantics, automatic addition of new hosts, the exact return message, and the only error condition (invalid host name characters). This is unusually complete.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, each serving a distinct purpose: purpose and location, partial-update mechanics, auto-add behavior, return value and error condition. No redundant or filler text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple three-parameter metadata tool with no output schema need, the description covers all essential aspects: what it does, where it writes, partial updates, creation, return value, and validation. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 adds meaningful behavior beyond the schema by clarifying that omitted description/os fields keep their current values and that host acts as the lookup key, with new hosts auto-added. This elevates the value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb ('Record or update') and resource ('metadata for a host in the sudo-proxy registry'), and explains where the registry lives. This distinguishes it from sibling server-control tools like start_server, stop_server, and status.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context for when to use this tool is clear: it is for adding or updating host metadata entries, not for controlling server execution. It does not explicitly name alternatives or exclusions, but the sibling names and the registry-specific phrasing make the intended usage obvious.

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.

  1. 2 tool updatesv1.1.0
    • Addedstatus
    • Addedstop_server
  2. 3 tool updatesv0.1.0
    • First observedexecute
    • First observedstart_server
    • First observedupdate_host

TDQS

A4.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: execute runs commands, start/stop manage the daemon lifecycle, status queries state, and update_host edits registry metadata. There is no ambiguity between tools, and descriptions reinforce their unique roles.

Naming Consistency4/5

Most tool names follow a verb_noun pattern (update_host, start_server, stop_server), while 'execute' and 'status' are verbs/nouns without an explicit direct object. This is a minor deviation but still predictable and readable, so it warrants a slight deduction.

Tool Count5/5

With only 5 tools, the server is tightly scoped to its purpose: daemon lifecycle (start, stop, status), command execution, and host metadata management. Each tool earns its place, and the count is ideal for a focused utility server.

Completeness4/5

The tool set covers the core lifecycle (start, stop, status) plus the main action (execute) and host registry updates. A missing feature like removing a host is a minor gap that agents can work around, and the surface is otherwise complete for the domain.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A human-in-the-loop SSH bridge for AI agents that requires approval for every command before execution on configured servers.
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides local command execution, remote SSH, interactive terminals, file read/write, and source search for AI CLI through stdio, with large output pagination and safety confirmations.
    6 npm
    1
    Apache 2.0