-
-
Save edxeth/fffe1aef66c872607f17dff7a2998b7e to your computer and use it in GitHub Desktop.
cdx - Interactive MCP server selector for Codex CLI. Uses fzf for multi-select. Works on Linux/macOS.
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 zsh | |
| # cdx - Codex CLI launcher with interactive MCP server selection | |
| # Works on Linux and macOS | |
| set -euo pipefail | |
| config="${CODEX_CONFIG_PATH:-$HOME/.codex/config.toml}" | |
| if [[ ! -f "$config" ]]; then | |
| echo "Missing config file: $config" >&2 | |
| exit 1 | |
| fi | |
| # Extract MCP server names, strip any quotes | |
| names=$( | |
| grep -E '^\[mcp_servers\.' "$config" \ | |
| | grep -v '\.env\]' \ | |
| | sed 's/\[mcp_servers\.\([^]]*\)\]/\1/' \ | |
| | sed 's/^"//; s/"$//' \ | |
| | sort -u | |
| ) | |
| if [[ -z "$names" ]]; then | |
| echo "No mcp_servers found in $config" >&2 | |
| exit 1 | |
| fi | |
| # Select servers via fzf | |
| if command -v fzf >/dev/null 2>&1; then | |
| selected=$( | |
| print -r -- "$names" | fzf -m \ | |
| --layout=reverse \ | |
| --prompt="Select MCP servers (TAB=toggle, ENTER=confirm): " | |
| ) || { | |
| echo "No MCP servers selected; aborting." >&2 | |
| exit 1 | |
| } | |
| else | |
| echo "fzf not found; enabling all servers" >&2 | |
| selected="$names" | |
| fi | |
| # Build lookup of selected servers | |
| typeset -A selected_map | |
| while IFS= read -r srv; do | |
| [[ -n "$srv" ]] && selected_map[$srv]=1 | |
| done <<< "$selected" | |
| # Backup config | |
| cp "$config" "${config}.bak" | |
| # Rewrite config: | |
| # - Always inject an `enabled = true/false` line immediately after each [mcp_servers.<name>] header | |
| # - Remove any existing enabled= lines within that server block to avoid duplicates | |
| awk -v selected="${(kj:,:)selected_map}" ' | |
| BEGIN { | |
| n = split(selected, arr, ",") | |
| for (i = 1; i <= n; i++) sel[arr[i]] = 1 | |
| in_mcp = 0 | |
| current_server = "" | |
| } | |
| /^\[mcp_servers\.[^.]+\]$/ { | |
| # entering a top-level mcp server block | |
| match($0, /\[mcp_servers\.([^]]+)\]/, m) | |
| current_server = m[1] | |
| gsub(/^"|"$/, "", current_server) | |
| in_mcp = 1 | |
| # ALWAYS write enabled line (even if it didn’t exist before) | |
| if (current_server in sel) print "enabled = true" | |
| else print "enabled = false" | |
| next | |
| } | |
| /^\[/ { | |
| # entering any other table => stop treating as “inside current mcp server” | |
| in_mcp = 0 | |
| current_server = "" | |
| next | |
| } | |
| in_mcp && /^enabled[[:space:]]*=/ { | |
| # drop any existing enabled lines (we already emitted ours) | |
| next | |
| } | |
| { print } | |
| ' "$config" > "${config}.tmp" && mv "${config}.tmp" "$config" | |
| # Build display list | |
| enabled_display="${(j:, :)${(f)selected}}" | |
| # Report and launch | |
| echo "✓ Enabled: ${enabled_display:-none}" | |
| exec codex "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment