Antigravity CLI: Git-Managed MCP Configuration (v2.0.0+ Generic Hook-Based Compiler Pipeline)#

In this configuration workflow, all Model Context Protocol (MCP) server definitions are managed via a centralized, version-controlled repository. Directly modifying target configuration files or using basic symlinks from your Obsidian vault has been deprecated.

Instead, a single generic flat list of servers is defined in a master configuration file. This is automatically compiled, adapted, and deployed to all your software clients via an automated Git post-commit pipeline.

Antigravity chat: agy –conversation=2b91f028-6933-4a8f-b76a-7b35290e35b8


MCP & Client Support Matrix#

MCP Server Antigravity-CLI Antigravity 2.0 Antigravity-IDE Codex-CLI Codex-App Claude Code Pi-CLI
home-assistant
n8n-mcp
pihole-primary
pihole-secondary
proxmox-hp1
proxmox-mm
truenas-hp1
truenas-hp2
truenas-hp3
truenas-hp7
truenas-hp8
unifi
xcode-tools
shell-exec
macos-mcp
git
github
docker-10-1-2-4
docker-10-1-2-100
docker-10-1-2-217
docker-10-1-2-202
docker-10-1-2-230
docker-10-1-2-231
docker-10-1-2-233
docker-72-11-147-220
nut
cloudflare
computer-use
gdrive

1. Workstation Setup & Replication#

1.1 New Machine Setup (From Scratch)#

Follow these steps in order when setting up MCP on a new computer for the first time.

1.1.1 Clone the Master Repository#

git clone git@github.com:marcoue/MCP-Config-MacOS.git ~/.mcp-config

1.1.2 Set Up Git Hooks#

The .git/hooks/ directory is never tracked by GitHub (Git intentionally excludes it for security). You must create these hook scripts manually on every new machine.

Create and populate both hook files:

nano ~/.mcp-config/.git/hooks/post-commit
nano ~/.mcp-config/.git/hooks/post-merge

Add the following content to both files:

#!/bin/bash
/Users/marc/.mcp-config/apply.py

Make them executable:

chmod +x ~/.mcp-config/.git/hooks/post-commit ~/.mcp-config/.git/hooks/post-merge

1.1.3 Verify Target Software Clients & Folders#

Before running the compiler, ensure your AI software clients are installed. The compiler (apply.py) will deploy settings to the following expected folders and files:

  • Antigravity CLI: ~/.gemini/config/mcp_config.json
  • Antigravity 2.0: ~/.gemini/antigravity/mcp_config.json
  • Antigravity IDE: ~/.gemini/config/mcp_config.json
  • Pi-CLI: ~/.pi/agent/mcp.json
  • Claude Code: ~/.claude.json (lives directly in user home folder)
  • Codex (CLI / App): ~/.codex/config.toml

Launch each installed AI client at least once on a new machine so its application data folder (e.g. ~/.gemini, ~/.pi/agent, ~/.codex) is created automatically before running mcp.

1.1.4 Install Python MCP Servers#

# Proxmox (pip package)
python3 -m venv ~/mcp-servers/mcp-proxmox/.venv
~/mcp-servers/mcp-proxmox/.venv/bin/pip install proxmox-mcp

# TrueNAS (custom server.py in repo — install MCP SDK)
mkdir -p ~/mcp-servers/mcp-truenas
python3 -m venv ~/mcp-servers/mcp-truenas/.venv
~/mcp-servers/mcp-truenas/.venv/bin/pip install "mcp[cli]"

# NUT UPS Monitor (custom server.py in repo — install MCP SDK)
mkdir -p ~/mcp-servers/mcp-nut
python3 -m venv ~/mcp-servers/mcp-nut/.venv
~/mcp-servers/mcp-nut/.venv/bin/pip install "mcp[cli]"

# macOS MCP (pip package)
mkdir -p ~/mcp-servers/macos-mcp
python3 -m venv ~/mcp-servers/macos-mcp/.venv
~/mcp-servers/macos-mcp/.venv/bin/pip install macos-mcp

1.1.5 Install Pi CLI and MCP Adapter#

npm install -g --ignore-scripts @earendil-works/pi-coding-agent
pi install npm:pi-mcp-adapter

1.1.6 Google Drive Credentials#

Why do we copy this file? The Google Drive MCP server (gdrive) authenticates using a local OAuth token file (~/.gdrive-server-credentials.json). Copying this file from your primary Mac avoids having to re-authenticate through Google Cloud in a web browser on every new machine.

Run this command from your primary Mac to copy the existing credentials to your new machine:

scp ~/.gdrive-server-credentials.json marc@<new-machine-ip>:~/.gdrive-server-credentials.json
Option B: Create manually (If primary Mac is unavailable)#

If copying via SSH is not possible, create the file ~/.gdrive-server-credentials.json on the new machine using this format:

{
  "access_token": "[ACCESS_TOKEN]",
  "refresh_token": "[REFRESH_TOKEN]",
  "scope": "https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/spreadsheets",
  "token_type": "Bearer",
  "expiry_date": [EXPIRY_TIMESTAMP]
}

1.1.7 Configure the 1Password Service Account Token#

See #7. 1Password Service Account Token Management for full instructions.

Quick setup: Copy your token from 1Password (Vault: HomelabItem: Mac OS .zshrc fileField: OP_SERVICE_ACCOUNT_TOKEN), then add it to ~/.zshrc:

nano ~/.zshrc   # Add: export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
source ~/.zshrc

1.1.8 Compile and Verify#

mcp

Verify all 6 client targets report Successfully applied configuration for ... with no Warning: OP_SERVICE_ACCOUNT_TOKEN not found.


1.2 Existing Machine Sync (Token Rotation or Config Update)#

When a 1Password token is rotated or MCP master configuration changes are pushed from your primary machine:

  1. Update shell token (~/.zshrc) (only if token changed): Copy the token from 1Password (Vault: HomelabItem: Mac OS .zshrc file):

    nano ~/.zshrc   # Update OP_SERVICE_ACCOUNT_TOKEN
    source ~/.zshrc
  2. Pull latest config from GitHub and recompile:

    cd ~/.mcp-config
    git pull

    (The post-merge hook fires apply.py automatically.)


2. 1Password Service Account Token Management#

All MCP servers that use op run require an OP_SERVICE_ACCOUNT_TOKEN set in ~/.zshrc. This allows all 29 MCP servers to authenticate silently without GUI popups.

The Service Account (MCP-Access) has read access only to the Homelab-MCP vault. This is intentional — MCP secrets live in Homelab-MCP, not Homelab, Private, or any other vault.

Setting OP_SERVICE_ACCOUNT_TOKEN in .zshrc completely disables biometric Touch ID authentication for all op commands in that shell. The two modes are mutually exclusive.

The generated token is displayed only once. Save it to 1Password immediately before doing anything else.

2.1 Initial Token Creation#

If re-creating after revoking an old token, first run: unset OP_SERVICE_ACCOUNT_TOKEN Otherwise op will try to authenticate as the deleted service account and fail with authenticated as a service account.

op service-account create "MCP-Access" --vault "Homelab-MCP:read_items"

Save the generated token to:

  • Vault: Homelab
  • Item: Mac OS .zshrc file
  • Field: OP_SERVICE_ACCOUNT_TOKEN

Then update ~/.zshrc and recompile:

export OP_SERVICE_ACCOUNT_TOKEN="ops_your_generated_token_here"
source ~/.zshrc
mcp

2.2 Token Rotation vs. Re-creation#

Which method should you use?

Scenario Method Why
Standard hygiene / renewal Option A: Web UI Rotation Keeps the same Service Account. Old token expires gracefully.
Token leaked / exposed / deleted Option B: CLI Re-create Immediately kills access. Must unset first or token creation fails.

Option A: Routine Rotation (Web UI)#

  1. Open https://start.1password.com/developer-toolsService accounts → select MCP-Access.
  2. Under Tokens, click Rotate Token → set expiration → copy the new ops_... token.
  3. Save to Vault: HomelabItem: Mac OS .zshrc file.
  4. Update ~/.zshrc and recompile:
    nano ~/.zshrc   # Replace OP_SERVICE_ACCOUNT_TOKEN
    source ~/.zshrc
    mcp

Option B: Re-create after Deletion / Exposure (CLI)#

If the old/deleted token is still in your terminal environment, op service-account create will fail: authenticated as a service account. Run unset in Step 1 first.

  1. Unset the broken token:
    unset OP_SERVICE_ACCOUNT_TOKEN
  2. Create a new Service Account Token:
    op service-account create "MCP-Access" --vault "Homelab-MCP:read_items"
    (Copy the generated ops_... token immediately.)
  3. Save to 1Password: Vault: Homelab → Item: Mac OS .zshrc file → Field: OP_SERVICE_ACCOUNT_TOKEN.
  4. Update ~/.zshrc and recompile:
    nano ~/.zshrc   # Replace OP_SERVICE_ACCOUNT_TOKEN
    source ~/.zshrc
    mcp
  5. Verify:
    op whoami
    # Expected: User Type: SERVICE_ACCOUNT

To verify the token was injected into Codex without exposing its value:

grep -c "OP_SERVICE_ACCOUNT_TOKEN" ~/.codex/config.toml

A non-zero result confirms injection without printing the token itself.


3. The Centralized Configuration Repo (.mcp-config)#

All master settings live inside a dedicated, local Git repository located at: /Users/marc/.mcp-config

3.1. Repository Structure#

  • config.json: The single source of truth configuration file. It contains a standard, flat list of all MCP servers (completely generic and client-agnostic).
  • apply.py: A Python compiler script that loads config.json, registers your software clients, filters out any placeholder servers (which use [COMMAND_PLACEHOLDER]), and automatically deploys the output to all active client paths. For the Codex target specifically, it also reads OP_SERVICE_ACCOUNT_TOKEN from the shell environment at compile time and injects it into the env block of every op run MCP server — see #4. Target Client Mapping and #6.6. Symptom: Codex triggers ~29 “1Password Access Requested” GUI popups on every launch for why this is necessary.
  • .git/hooks/post-commit: A Git hook script that automatically triggers apply.py whenever a commit is executed in the repository.
  • .git/hooks/post-merge: A Git hook script that automatically triggers apply.py whenever a git pull successfully merges updates from GitHub.

4. Target Client Mapping#

The apply.py script registers and compiles the configuration to the following destination files:

If you need to add a new software client, you simply update the TARGETS registry inside apply.py. You never need to touch the master config.json file.

5. Active Compiled MCP Servers#

The pipeline currently compiles and activates the following 29 MCP servers for all registered clients:

  • home-assistant: Home automation controls and entities.
  • n8n-mcp: Workflow automation and node management.
  • pihole-primary: DNS sinkhole and ad-blocking controls for primary server.
  • pihole-secondary: DNS sinkhole and ad-blocking controls for secondary server.
  • proxmox-hp1: VM, container, cluster, and storage management for Proxmox HP1 cluster. (Prerequisite: Section 1.1.4)
  • proxmox-mm: VM, container, cluster, and storage management for Proxmox MM cluster. (Prerequisite: Section 1.1.4)
  • truenas-hp1: TrueNAS storage node HP1 dataset and user management. (Prerequisite: Section 1.1.4)
  • truenas-hp2: TrueNAS storage node HP2 dataset and user management. (Prerequisite: Section 1.1.4)
  • truenas-hp3: TrueNAS storage node HP3 dataset and user management. (Prerequisite: Section 1.1.4)
  • truenas-hp7: TrueNAS storage node HP7 dataset and user management. (Prerequisite: Section 1.1.4)
  • truenas-hp8: TrueNAS storage node HP8 dataset and user management. (Prerequisite: Section 1.1.4)
  • unifi: Network clients, devices, and firewall management.
  • xcode-tools: Xcode simulator controls, builds, and iOS test utilities.
  • shell-exec: Direct terminal command execution, job management, and process control.
  • macos-mcp: macOS desktop UI automation, accessibility controls, and screen interaction. (Prerequisite: Section 1.1.4)
  • git: Local repository Git operations (adds, commits, diffs, branches, worktrees).
  • github: GitHub API integration (remote repos, issues, pull requests, workflows).
  • docker-10-1-2-4: Local Docker daemon container management (unix:///var/run/docker.sock).
  • docker-10-1-2-100: Remote Docker container management for host 10.1.2.100.
  • docker-10-1-2-217: Remote Docker container management for host 10.1.2.217.
  • docker-10-1-2-202: Remote Docker container management for host 10.1.2.202.
  • docker-10-1-2-230: Remote Docker container management for host 10.1.2.230.
  • docker-10-1-2-231: Remote Docker container management for host 10.1.2.231.
  • docker-10-1-2-233: Remote Docker container management for host 10.1.2.233.
  • docker-72-11-147-220: Remote Docker container management for VPS (72.11.147.220).
  • nut: Network UPS Tools server monitoring (ups1, ups2, ups3, ups4 on 10.1.2.230:3493). (Prerequisite: Section 1.1.4)
  • cloudflare: Cloudflare DNS, Tunnels, Access policies, and edge service management.
  • computer-use: Native macOS agent GUI automation client.
  • gdrive: Google Drive API file operations and sheet management. (Prerequisite: Section 1.1.6)

6. Automated Compilation Pipeline (Git Hooks)#

For instructions on creating and activating these Git hooks on a new machine, see #1.1.2 Set Up Git Hooks.

To make updates effortless, Git hooks are set up to trigger compilation automatically:

  • post-commit Hook: Located at /Users/marc/.mcp-config/.git/hooks/post-commit. Fires automatically when you execute a local commit:
    git add config.json
    git commit -m "update: configuration description"
  • post-merge Hook: Located at /Users/marc/.mcp-config/.git/hooks/post-merge. Fires automatically when you pull updates (git pull) from the remote GitHub repository:
    git pull

Both hooks execute the compiler script:

#!/bin/bash
/Users/marc/.mcp-config/apply.py

Whenever you commit changes locally or pull updates from GitHub, the compiler is automatically invoked, compiling fresh adapted target mcp_config.json files to all target paths in a single execution.

6.1 Updating Master Configurations (~/.mcp-config)#

All git commands below must be executed inside your master configuration directory:

cd ~/.mcp-config

Use this whenever you pushed configuration changes from another Mac and want to update your current machine:

cd ~/.mcp-config
git pull origin main

(Git automatically fetches updates and fires the post-merge hook to compile all AI client configs).

Method B: Forced Reset (If local files are broken or out of sync)#

Use this if git pull fails due to local file conflict errors and you want to discard local changes to align 100% with GitHub:

cd ~/.mcp-config
git fetch origin
git reset --hard origin/main
git clean -fd
./apply.py   # Required: Hard reset bypasses git hooks, so manual compile is needed

7. Proxmox MCP Server Installation (Silicon Mac)#

This guide details the manual build process for setting up the Proxmox MCP server environment on macOS.

7.1 Prerequisites#

  • Proxmox VE: Access to a Proxmox cluster or node.
  • Python 3.12: Required for the MCP server environment.
    brew install python@3.12
  • API Token: Created in Proxmox (Datacenter > Permissions > API Tokens). Ensure the token has sufficient permissions (e.g., PVEAuditor or PVEVMAdmin) and ‘Privilege Separation’ is unchecked.

7.2 Server Installation#

Run the following commands to clone the repository and set up the Python environment in a dedicated directory:

# Create and enter a dedicated directory for MCP servers
mkdir -p ~/mcp-servers
cd ~/mcp-servers

# Clone the Proxmox MCP repository
git clone https://github.com/bsahane/mcp-proxmox.git
cd mcp-proxmox

# Create a virtual environment
python3 -m venv .venv

# Activate the virtual environment
source .venv/bin/activate

# Install requirements
pip install -r requirements.txt

# Install the package in editable mode to resolve module paths
pip install -e .

7.3 Configuration Notes#

  • PROXMOX_API_URL: Do not include /api2/json at the end of the URL; the server library appends this automatically.
  • PROXMOX_TOKEN_ID: Format is typically user@realm!tokenname (e.g., root@pam!gemini).
  • PROXMOX_VERIFY: Set to "false" to allow connections to nodes using self-signed SSL certificates.

8. Troubleshooting Common Issues#

8.1. Symptom: Half of the MCP servers are missing or missing checkmarks at CLI launch#

  • Cause: 1Password Session Lock / Startup Timeout. Most servers use /opt/homebrew/bin/op run to inject secrets. When 1Password CLI is locked or cold, the initial biometric authentication call takes 10–15 seconds. Because AI clients enforce a 5-second per-server startup timeout, any server waiting for 1Password authentication times out and is skipped.
    • Fix: Pre-warm 1Password CLI before launching your AI CLI session by running:
      op run -- echo "1Password warm"
      Once authenticated, op run secret resolution drops to ~40ms, allowing all 16 servers to load cleanly.

8.2. Symptom: Server hangs indefinitely on “Initializing…”#

  • Cause: 1Password Session Lock. The 1Password CLI session timed out, and op run is silently waiting for biometric authentication in the background.
    • Fix: Run op signin in your standard terminal, complete authentication, and restart the CLI.

8.3. Symptom: Failed to reload MCP config: failed to stop mcp instance: macos-mcp: exit status 143 during /mcp hot-reload#

  • Cause: Unix SIGTERM Exit Code. When performing an in-session hot reload (/mcp), the CLI sends SIGTERM to stop running servers. Python processes default to exit code 143 when killed with SIGTERM, which some CLI watchers misidentify as a crash and abort the reload.
    • Fix: Use the wrapper script at ~/.mcp-config/bin/macos-mcp-wrapper in config.json. The wrapper traps SIGTERM, terminates macos-mcp gracefully, and exits with status 0.

8.4. Symptom: Error: invalid trailing data at the end of stream#

  • Cause: Stdout Pollution. The MCP server wrote plain-text logs or status messages to standard output instead of valid JSON-RPC format.
    • Fix: Verify you have "LOG_CONSOLE": "false" configured (for Node.js) or that the server is logging only to stderr.

8.5. Symptom: SSH-based MCP servers (e.g. Remote Docker hosts) fail to start or time out#

  • Cause: Missing SSH Keys / Empty SSH Agent. If your private SSH keys are encrypted with a passphrase and your local SSH agent has no unlocked identities, non-interactive SSH connections launched by the MCP process will silently block waiting for passphrase input until the 5-second startup timeout hits.
    • Fix: Ensure your keys are loaded into the ssh-agent before running your AI CLI session:
      ssh-add --apple-use-keychain ~/.ssh/id_ed25519
  • Cause: Untrusted SSH Host Key (known_hosts prompt). If you have never manually connected to a target remote host from the command line, SSH will attempt to prompt Are you sure you want to continue connecting (yes/no/[fingerprint])?. Because the server is launched in a headless background sub-process, it hangs indefinitely on this prompt.
    • Fix: Perform a manual connection to the target IP one time from your terminal to verify and accept the host key into ~/.ssh/known_hosts:
      ssh root@10.1.2.100 exit

8.6. Symptom: Codex triggers ~29 “1Password Access Requested” GUI popups on every launch#

  • Cause: Codex MCP Environment Sandboxing. Unlike Antigravity, Claude Code, and Pi-CLI — which pass the full parent shell environment (including OP_SERVICE_ACCOUNT_TOKEN) to MCP child processes — Codex explicitly constructs an isolated environment per server using only what is declared in the [mcp_servers."name".env] block of config.toml. Since OP_SERVICE_ACCOUNT_TOKEN is only set in ~/.zshrc, the op run subprocesses spawned by Codex never see it and fall back to the 1Password desktop app GUI, producing one popup per op run server (~16 servers = ~16–29 prompts).
    • Fix: The apply.py compiler now reads OP_SERVICE_ACCOUNT_TOKEN from the shell environment at compile time and injects it into the env block of every op run server in the Codex TOML output. The token never enters config.json or git history. Re-compile after any token rotation:
      source ~/.zshrc
      cd ~/.mcp-config && ./apply.py codex
      Or simply commit any change — the post-commit hook fires apply.py for all clients automatically.