Last active
February 2, 2026 15:24
-
-
Save bearlike/d17f1c9f7b32d5fa31e5b92360ace16f to your computer and use it in GitHub Desktop.
Workaround for Codex Web Agent. Minimal init script designed for any repo. It bootstraps `remote-mcp-cli` to bypass the agent's lack of native MCP server support.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # codex-init-mcp.sh | |
| # | |
| # Purpose | |
| # ------- | |
| # Minimal, universal bootstrap for the "Remote MCP Client" (remote-mcp-cli via uvx). | |
| # Intended for Codex init scripts and any repo/workdir (repo-agnostic). | |
| # | |
| # What it does | |
| # ------------ | |
| # 1) Determines a target directory: | |
| # - Uses TARGET_DIR if set | |
| # - Else uses git repo root if inside a git repo | |
| # - Else uses current working directory | |
| # | |
| # 2) Ensures uvx exists: | |
| # - If uvx is missing, installs uv (Astral) using curl, which provides uvx | |
| # - Adds common uv install paths to PATH for the current process | |
| # | |
| # 3) Creates/updates Cursor MCP config: | |
| # - Writes TARGET_DIR/.cursor/mcp.json from one of: | |
| # a) MCP_CONFIG_JSON_PATH (file path) | |
| # b) MCP_CONFIG_JSON_STR (raw JSON string) | |
| # c) A hard-coded "valid default" JSON generator (generate_default_mcp_json) | |
| # - Sets restrictive permissions (umask 077 + chmod 600) since MCP configs often include secrets | |
| # - Optionally validates JSON using jq if jq is present (jq is not required) | |
| # | |
| # 4) Optionally adds /.cursor/mcp.json to .gitignore: | |
| # - Only if MCP_GITIGNORE=1 (default) AND target is a git repo | |
| # | |
| # 5) Warms the uvx tool cache: | |
| # - Runs `uvx remote-mcp-cli --help` to download/cache the tool | |
| # - Optional smoke test: | |
| # REMOTE_MCP_SMOKE_TEST=1 uvx remote-mcp-cli list <target> | |
| # | |
| # Environment variables (inputs) | |
| # ------------------------------ | |
| # TARGET_DIR : Directory to place .cursor/mcp.json (defaults: git root or pwd) | |
| # MCP_CONFIG_JSON_PATH : Path to an existing JSON file to copy into .cursor/mcp.json | |
| # MCP_CONFIG_JSON_STR : Raw JSON string to write into .cursor/mcp.json | |
| # MCP_GITIGNORE : 1 (default) add to .gitignore; 0 skip | |
| # REMOTE_MCP_SMOKE_TEST : 1 run smoke test; 0 (default) skip | |
| # REMOTE_MCP_LIST_TARGET : Smoke test target (default: KeywordsAI) | |
| # DEBUG : 1 enables shell tracing (set -x) | |
| # | |
| # Examples | |
| # -------- | |
| # 1) Minimal (generates a valid default config): | |
| # ./remote-mcp-setup.sh | |
| # | |
| # 2) Provide config via JSON string: | |
| # MCP_CONFIG_JSON_STR='{"mcpServers":{}}' ./remote-mcp-setup.sh | |
| # | |
| # 3) Provide config via file: | |
| # MCP_CONFIG_JSON_PATH=/path/to/mcp.json ./remote-mcp-setup.sh | |
| # | |
| # 4) Set explicit target dir and skip gitignore: | |
| # TARGET_DIR=/workspace/project MCP_GITIGNORE=0 ./remote-mcp-setup.sh | |
| # | |
| # 5) Run smoke test: | |
| # REMOTE_MCP_SMOKE_TEST=1 REMOTE_MCP_LIST_TARGET=KeywordsAI ./remote-mcp-setup.sh | |
| # | |
| # Notes | |
| # ----- | |
| # - The generated default config is intentionally minimal and valid JSON: | |
| # { "mcpServers": {} } | |
| # Replace generate_default_mcp_json() if you want a pre-wired server entry. | |
| # - This script does not install system packages (no apt-get); it stays portable and KISS. | |
| # - If your environment blocks network access, uv installation and uvx caching will fail. | |
| # | |
| set -euo pipefail | |
| [[ "${DEBUG:-}" == "1" ]] && set -x | |
| log() { echo "[remote-mcp-setup] $*"; } | |
| die() { log "ERROR: $*"; exit 1; } | |
| have() { command -v "$1" >/dev/null 2>&1; } | |
| # ------------------------------------------------------------ | |
| # Target directory (repo-agnostic) | |
| # Priority: TARGET_DIR -> git root -> pwd | |
| # ------------------------------------------------------------ | |
| resolve_target_dir() { | |
| if [[ -n "${TARGET_DIR:-}" ]]; then | |
| echo "${TARGET_DIR}" | |
| return 0 | |
| fi | |
| if have git && git rev-parse --show-toplevel >/dev/null 2>&1; then | |
| git rev-parse --show-toplevel | |
| return 0 | |
| fi | |
| pwd | |
| } | |
| TARGET_DIR="$(resolve_target_dir)" | |
| [[ -d "${TARGET_DIR}" ]] || die "TARGET_DIR not found: ${TARGET_DIR}" | |
| CURSOR_DIR="${TARGET_DIR}/.cursor" | |
| MCP_FILE="${CURSOR_DIR}/mcp.json" | |
| GITIGNORE_FILE="${TARGET_DIR}/.gitignore" | |
| # ------------------------------------------------------------ | |
| # Ensure uvx (install uv if needed) | |
| # ------------------------------------------------------------ | |
| ensure_uvx() { | |
| if have uvx; then | |
| return 0 | |
| fi | |
| have curl || die "curl is required to install uv (uvx)." | |
| log "uvx not found; installing uv (provides uvx)..." | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| # common uv install paths | |
| export PATH="$HOME/.local/bin:$HOME/.cargo/bin:$PATH" | |
| have uvx || die "uvx still not available after installing uv. Check PATH." | |
| } | |
| # ------------------------------------------------------------ | |
| # Default MCP config generator (hard-coded, valid JSON) | |
| # NOTE: Minimal/portable default. Replace later if you want | |
| # a pre-wired server entry. | |
| # ------------------------------------------------------------ | |
| generate_default_mcp_json() { | |
| cat <<'JSON' | |
| { | |
| "mcpServers": {} | |
| } | |
| JSON | |
| } | |
| # ------------------------------------------------------------ | |
| # Write MCP config (env/file if provided, else generate default) | |
| # ------------------------------------------------------------ | |
| write_mcp_config() { | |
| mkdir -p "${CURSOR_DIR}" | |
| # restrictive permissions (in case secrets exist now or later) | |
| umask 077 | |
| if [[ -n "${MCP_CONFIG_JSON_PATH:-}" ]]; then | |
| [[ -f "${MCP_CONFIG_JSON_PATH}" ]] || die "MCP_CONFIG_JSON_PATH not found: ${MCP_CONFIG_JSON_PATH}" | |
| log "Writing MCP config from file: ${MCP_CONFIG_JSON_PATH}" | |
| cat "${MCP_CONFIG_JSON_PATH}" > "${MCP_FILE}" | |
| elif [[ -n "${MCP_CONFIG_JSON_STR:-}" ]]; then | |
| log "Writing MCP config from MCP_CONFIG_JSON_STR" | |
| printf '%s\n' "${MCP_CONFIG_JSON_STR}" > "${MCP_FILE}" | |
| else | |
| log "No MCP config provided; generating a default ${MCP_FILE}" | |
| generate_default_mcp_json > "${MCP_FILE}" | |
| fi | |
| chmod 600 "${MCP_FILE}" 2>/dev/null || true | |
| # optional validation if jq exists | |
| if have jq; then | |
| jq -e . "${MCP_FILE}" >/dev/null || die "Invalid JSON written to ${MCP_FILE}" | |
| fi | |
| log "MCP config ready: ${MCP_FILE}" | |
| } | |
| # ------------------------------------------------------------ | |
| # Optionally add to .gitignore (only if git repo) | |
| # ------------------------------------------------------------ | |
| ensure_gitignore() { | |
| [[ "${MCP_GITIGNORE:-1}" == "1" ]] || return 0 | |
| have git || { log "git not found; skipping .gitignore update."; return 0; } | |
| git -C "${TARGET_DIR}" rev-parse --is-inside-work-tree >/dev/null 2>&1 || { | |
| log "Not a git repo; skipping .gitignore update." | |
| return 0 | |
| } | |
| touch "${GITIGNORE_FILE}" | |
| grep -qxF "/.cursor/mcp.json" "${GITIGNORE_FILE}" || echo "/.cursor/mcp.json" >> "${GITIGNORE_FILE}" | |
| log "Ensured /.cursor/mcp.json is in .gitignore" | |
| } | |
| # ------------------------------------------------------------ | |
| # Warm cache / optional smoke test | |
| # ------------------------------------------------------------ | |
| warm_remote_mcp_cli() { | |
| ensure_uvx | |
| log "Warming remote-mcp-cli cache via uvx..." | |
| uvx remote-mcp-cli --help >/dev/null | |
| if [[ "${REMOTE_MCP_SMOKE_TEST:-0}" == "1" ]]; then | |
| local target="${REMOTE_MCP_LIST_TARGET:-KeywordsAI}" | |
| log "Smoke test: uvx remote-mcp-cli list ${target}" | |
| uvx remote-mcp-cli list "${target}" | |
| fi | |
| } | |
| main() { | |
| log "Target: ${TARGET_DIR}" | |
| write_mcp_config | |
| ensure_gitignore | |
| warm_remote_mcp_cli | |
| log "Remote MCP Client setup complete." | |
| } | |
| main "$@" |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Append the below to your custom instructions.