Skip to content

Instantly share code, notes, and snippets.

@z0u
Created October 28, 2025 08:01
Show Gist options
  • Save z0u/46b696ab39e3fdc1ddf6871444f6e5ce to your computer and use it in GitHub Desktop.
Save z0u/46b696ab39e3fdc1ddf6871444f6e5ce to your computer and use it in GitHub Desktop.
Runs npm and Python packages in Docker; additional layer of security for MCP servers
#!/bin/sh
# mcpc - MCP Container wrapper for uvx/npx runtimes
set -e
if [ $# -lt 2 ]; then
printf "Usage: mcpc {uv|uvx|npx} [options] <package> [args...]\n" >&2
printf "\nOptions:\n" >&2
printf " --python-version=X.Y Python version for uvx (default: 3.13)\n" >&2
printf " --node-version=X Node version for npx (default: 22)\n" >&2
exit 1
fi
runtime="$1"
shift
# Default versions
python_version="3.13"
node_version="22"
# Parse version flags
while [ $# -gt 0 ]; do
case "$1" in
--python-version=*)
python_version="${1#--python-version=}"
shift
;;
--python-version)
python_version="$2"
shift 2
;;
--node-version=*)
node_version="${1#--node-version=}"
shift
;;
--node-version)
node_version="$2"
shift 2
;;
*)
# Not a flag, must be the package name
break
;;
esac
done
if [ $# -eq 0 ]; then
printf "Error: No package specified\n" >&2
exit 1
fi
# Detect if stdin is a TTY for proper terminal handling
if [ -t 0 ]; then
tty_flag="-t"
else
tty_flag=""
fi
case "$runtime" in
uv|uvx)
image="ghcr.io/astral-sh/uv:python${python_version}-alpine"
cache_volume="uv-cache"
cache_dir="/mnt/cache"
cache_env="UV_CACHE_DIR=${cache_dir}"
;;
npx)
image="node:${node_version}-alpine"
cache_volume="npm-cache-${node_version}"
cache_dir="/mnt/cache"
cache_env="NPM_CONFIG_CACHE=${cache_dir}"
;;
*)
printf "Error: Unknown runtime '%s'. Supported: uvx, npx\n" "$runtime" >&2
exit 1
;;
esac
exec docker run \
--rm \
-i $tty_flag \
-v "${cache_volume}:${cache_dir}" \
-e "${cache_env}" \
-w "/workspace" \
"${image}" \
"${runtime}" \
"$@"
@z0u
Copy link
Author

z0u commented Oct 28, 2025

Example:

  "mcpServers": {
    "semantic-scholar": {
      "command": "mcpc",
      "args": ["uvx", "semantic-scholar-mcp"]
    }
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment