shellwrap

package
v0.24.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 11, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package shellwrap provides platform-level helpers for wrapping commands in the user's login shell and for resolving tool binaries (e.g. docker) with PATH caching.

It exists so that both the upstream proxy code (internal/upstream/core) and the security scanner (internal/security/scanner) can share a single, well-tested implementation of shell quoting + login-shell wrapping instead of each rolling their own.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoginShellPATH added in v0.24.2

func LoginShellPATH(logger *zap.Logger) string

LoginShellPATH returns the PATH value emitted by the user's login shell. It is captured exactly once per process via `<shell> -l -c 'printf %s "$PATH"'` and cached for the rest of the process lifetime.

Why this exists: when mcpproxy runs as a macOS App Bundle or LaunchAgent, os.Getenv("PATH") is often `/usr/bin:/bin`. That is enough for Go's exec.LookPath to find a docker binary once shellwrap.ResolveDockerPath has cached its absolute path, but it is NOT enough for the docker CLI itself, which re-execs credential helpers like `docker-credential-desktop` via its own $PATH lookup. Those helpers typically live in /usr/local/bin or /opt/homebrew/bin — directories that only exist in the interactive login PATH.

On Windows, this function returns "" (credential-helper PATH drift is not the same problem there, and interactive-shell PATH capture would require cmd.exe or PowerShell gymnastics we explicitly avoid).

Callers should treat an empty return value as "no override available" and fall back to os.Getenv("PATH").

func MinimalEnv

func MinimalEnv() []string

MinimalEnv returns a minimal, allow-listed environment suitable for subprocesses that must NOT inherit the user's ambient credentials (e.g. AWS_ACCESS_KEY_ID, GITHUB_TOKEN, etc). It includes PATH + HOME on Unix and PATH + USERPROFILE on Windows so that `docker` itself still functions.

Callers that need TLS or Docker-specific variables (DOCKER_HOST, DOCKER_CONFIG, …) should append them explicitly.

On Unix, PATH is built by merging the user's login-shell PATH (captured once via LoginShellPATH) with the process's ambient PATH. Login-shell entries come first so that docker's own credential-helper lookups can find binaries installed in /opt/homebrew/bin or /usr/local/bin even when mcpproxy was started from a LaunchAgent with a minimal inherited PATH. See issue #381.

func MinimalEnvWithLogger added in v0.24.2

func MinimalEnvWithLogger(logger *zap.Logger) []string

MinimalEnvWithLogger is MinimalEnv with an optional logger used while capturing the login-shell PATH on the first call. Subsequent calls return the cached value without logging.

func ResolveDockerPath

func ResolveDockerPath(logger *zap.Logger) (string, error)

ResolveDockerPath returns the absolute path to the `docker` binary. The result is cached for the process lifetime so that repeated calls from hot paths (health checks, connection diagnostics) do not re-spawn a login shell on every invocation.

Resolution order:

  1. exec.LookPath("docker") — cheap, works when mcpproxy was started from a terminal or when the LaunchAgent PATH already contains docker.
  2. Fallback: ask the user's login shell `command -v docker` so we pick up Homebrew / Colima / Docker Desktop installs that only exist in the interactive PATH. This fallback is only run once.

func Shellescape

func Shellescape(s string) string

Shellescape escapes a single argument for safe inclusion in a shell command string. On Unix it uses POSIX single-quoting; on Windows it performs a best-effort cmd.exe quoting.

This mirrors the implementation in internal/upstream/core so both code paths can converge on one function.

func WrapWithUserShell

func WrapWithUserShell(logger *zap.Logger, command string, args []string) (shell string, shellArgs []string)

WrapWithUserShell wraps a command and its arguments in the user's login shell so the child process inherits the interactive PATH (important when mcpproxy is launched from a GUI / LaunchAgent on macOS).

It returns the shell to exec and the shell arguments (e.g. ["-l", "-c", "docker run ..."] on Unix, ["/c", "docker run ..."] on Windows cmd).

logger may be nil; when non-nil a debug line is emitted mirroring the existing upstream/core helper.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL