Git-Managed MCP Configuration (v2.0.0+ Generic 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
Current deployment snapshot (2026-10-22): The Mac Studio and MacBook Air use the same GitHub-backed
~/.mcp-configrepository. The sharedconfig.jsoncontains 35 MCP server definitions, includingrea-agents@6.7.0. The Mac Studio’s OpenCode adapter compiled all 35 entries into~/.config/opencode/opencode.json; the generated JSON and mode0600were verified.opencode mcp listreports 34 of 35 servers connected; onlymacos-mcpfailed because Accessibility permission is not granted to its server process,/Users/marc/mcp-servers/macos-mcp/.venv/bin/python3. Grant permission to that exact process through the native macOS prompt and restart the MCP server; granting the OpenCode host app does not grant permission to the Python process. Do not add the interpreter manually in System Settings because the uv-managed binary path can change. REA 6.7.0 is connected in OpenCode 2.1.3;binary_session({})succeeded with no analysis target open. Other harnesses and the MacBook Air still need their own connection checks after syncing.
Intel Mac support: The 2014 Intel iMac uses the same shared MCP definitions, but its Homebrew prefix is
/usr/localrather than/opt/homebrew. The portableapply.pycompiler resolves the localopexecutable automatically, so this path difference does not require a separate configuration repository. The compiler still emits the complete shared server list; a server can remain unavailable on a workstation when its local executable, Python environment, credentials, or external service is not present.The active Proxmox MCP endpoints are:
MCP server Proxmox API endpoint proxmox-mmhttps://10.1.1.10:8006proxmox-hp1https://10.1.1.11:8006proxmox-hp2https://10.1.1.12:8006proxmox-hp3https://10.1.1.13:8006proxmox-hp4https://10.1.1.14:8006proxmox-hp5https://10.1.1.15:8006proxmox-hp7(HP7Proxmox)https://10.1.1.17:8006HP node credentials use matching
HPnPROXMOX_TOKEN_IDandHPnPROXMOX_TOKEN_SECRETfields in 1PasswordHomelab-MCP→MCP-Secrets. TheMCP-Accessservice-account token is stored inHomelab→Mac OS .zshrc fileand is configured locally on both Macs. Secret values are never stored in this vault or inconfig.json.
MCP & Client Support Matrix#
| MCP Server | Antigravity-CLI | Antigravity 2.0 | Antigravity-IDE | Codex-CLI | Codex-App | Claude Code | Pi-CLI | Hermes CLI | OpenCode |
|---|---|---|---|---|---|---|---|---|---|
cloudflare |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-100 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-202 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-217 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-230 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-231 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-233 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-10-1-2-4 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
docker-72-11-147-220 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
gdrive |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
git |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
github |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
home-assistant |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
macos-mcp |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
n8n-mcp |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
nut |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
pihole-primary |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
pihole-secondary |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp1 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp2 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp3 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp4 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp5 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-hp7 (HP7Proxmox) |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
proxmox-mm |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
rea |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
shell-exec |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
synology-hp1 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
truenas-hp1 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
truenas-hp2 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
truenas-hp3 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
truenas-hp6 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
truenas-hp7 |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
unifi |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
xcode-tools |
✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
rea is supported by all eight registered client targets. A live binary_session({}) call has been verified in both OpenCode and Codex. OpenCode reports 34 of 35 configured servers connected; macos-mcp awaits Accessibility permission for its Python server process. The matrix records compiler support, not a live connection guarantee. ChatGPT desktop with local execution shares the Codex target; it does not need a separate server definition.
The Hermes column means the compiler emits each server definition in Hermes format. The shared configuration contains 35 entries; local overrides can disable an entry on an individual workstation. Connection tests have verified
gitandhome-assistant. Runtime availability for each remaining server still depends on its local executable, credentials, permissions, and network access.The OpenCode column means the compiler emits each server in OpenCode V2’s local stdio format. It indicates compiler support, not a verified live connection.
Codex-hosted entries#
The following entries are built into Codex rather than defined in the Git-managed ~/.mcp-config/config.json. They may appear in /mcp for Codex CLI and other local Codex clients even when disabled, and are not compiled by apply.py:
| Entry | Observed status outside the ChatGPT desktop app |
|---|---|
codex_app |
disabled (0 tools) |
computer-use |
disabled (0 tools) |
The active computer-use interface is cua_repl; it is separate from the disabled built-in computer-use entry. Do not add or remove these Codex-hosted entries through the external MCP master list.
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.
Prerequisites for a New Mac#
Before beginning the numbered setup, confirm that the workstation has the following foundations:
- GitHub SSH access: Create or register an SSH key for the new Mac with GitHub. Both the
~/Scriptsand~/.mcp-configrepositories use GitHub SSH remotes. Verify access with:ssh -T git@github.com - Homebrew and 1Password: Install Homebrew, 1Password CLI, and the 1Password desktop application. The MCP service-account workflow requires the CLI; the desktop application is used for personal CLI sign-in and optional biometric integration.
- Docker: Install the Docker CLI and a local Docker engine if the local Docker MCP is required. Remote Docker MCPs additionally require network and SSH access to their target hosts and running Docker daemons.
- Node.js and npm: Install a supported Node.js LTS release.
node,npm, andnpxare required by thenpx-launched MCP and by the Pi CLI MCP adapter. - AI clients: Install the AI clients you intend to use and launch each one once so its application directory is created. The compiler can then write the generated MCP configuration files.
- macOS privacy permissions: Grant Accessibility, Screen Recording, and Automation permissions to the AI client or terminal process that will launch the local GUI MCPs. These permissions are only required for local GUI automation; they do not affect Proxmox or Home Assistant MCPs.
On an Intel Mac, Homebrew uses
/usr/localand may build large dependencies from source. Installuvwith the official standalone installer and useuvto provision Python 3.12 for MCP virtual environments when Homebrew installation is impractical. Keep Homebrew-managed Node.js and 1Password CLI separate from this Python bootstrap path.
1.1.0 Restore the Workstation Shell Foundation#
Complete this subsection before setting up ~/.mcp-config. The MCP shortcuts are loaded from ~/Scripts, and the compiler needs the service-account token in the shell when it generates the Codex configuration.
- Restore
~/Scripts: Clone the scripts repository, or pull it if it already exists:git clone git@github.com:marcoue/Scripts.git ~/Scripts # Existing clone: cd ~/Scripts && git pull origin main - Confirm the tracked aliases file exists:
test -f ~/Scripts/MacOS/Aliases/MacOS-Aliases.zsh - Create or update the local
~/.zshrc: Copy the private values from 1PasswordHomelab→Mac OS .zshrc fileinto the local file, and ensure the file sources~/Scripts/MacOS/Aliases/MacOS-Aliases.zsh. Keep credentials local; never put their values in the vault notes or Git repositories. - Reload the shell:
source ~/.zshrc - Verify the shell foundation before continuing:
whence -w mcp pushmcp pullmcp op whoamiop whoamishould reportUser Type: SERVICE_ACCOUNT. Themcp,pushmcp, andpullmcpcommands should be available.
On macOS, personal 1Password CLI sign-in can use the desktop app integration: open 1Password → Settings → Developer → Integrate with 1Password CLI. After it is enabled,
op signinor anotheropcommand may display an authentication prompt from the desktop app. This is separate from theOP_SERVICE_ACCOUNT_TOKENused by the MCP compiler andop runservers.
The aliases restore utility has been removed. Create or update
~/.zshrcmanually using the local 1Password entryHomelab→Mac OS .zshrc file, and keep credential values out of Git repositories and vault notes.
1.1.1 Clone the MCP Master Repository#
git clone git@github.com:marcoue/MCP-Config-MacOS.git ~/.mcp-config1.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-mergeAdd the following content to both files:
#!/bin/bash
/Users/marc/.mcp-config/apply.pyMake them executable:
chmod +x ~/.mcp-config/.git/hooks/post-commit ~/.mcp-config/.git/hooks/post-merge1.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 - Hermes Agent (CLI / Desktop):
~/.hermes/config.yaml(mcp_serverssection) - OpenCode:
~/.config/opencode/opencode.json(mcp.serverssection)
Launch each installed AI client at least once on a new machine so its application data folder (e.g.
~/.gemini,~/.pi/agent,~/.codex,~/.hermes) is created automatically before runningmcp.
1.1.4 Install Python MCP Servers#
Intel runtime bootstrap: When Homebrew’s Python or uv build is excessively slow on Intel, use the standalone uv installer and its managed Python instead:
curl -LsSf https://astral.sh/uv/install.sh | sh ~/.local/bin/uv python install 3.12Use the resulting Python 3.12 interpreter to create the virtual environments below. The 2014 Intel iMac was provisioned this way because
brew install uvattempted a multi-hour source build.
# Proxmox (public repository + Python virtual environment)
mkdir -p ~/mcp-servers
git clone https://github.com/bsahane/mcp-proxmox.git ~/mcp-servers/mcp-proxmox
cd ~/mcp-servers/mcp-proxmox
python3 -m venv .venv
./.venv/bin/python3 -m pip install -r requirements.txt
./.venv/bin/python3 -m pip install -e .
# TrueNAS (custom local server.py — copy source before compiling)
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 local server.py — copy source before compiling)
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
# Synology DSM HP1 (public repository + Python virtual environment)
# The server currently uses the MCP 1.x FastMCP API; install the SDK constraint
# before the editable package so pip does not select MCP 2.x.
mkdir -p ~/mcp-servers
git clone https://github.com/rafalr100/synology-mcp.git ~/mcp-servers/synology-mcp
cd ~/mcp-servers/synology-mcp
python3 -m venv .venv
./.venv/bin/python -m pip install "mcp[cli]>=1.0.0,<2.0.0"
./.venv/bin/python -m pip install -e .Synology HP1 master configuration#
Add this server to ~/.mcp-config/config.json. Do not create a .env file or place credential values in the repository. The op:// references resolve from the Homelab-MCP vault item MCP-Secrets:
"synology-hp1": {
"command": "/opt/homebrew/bin/op",
"args": [
"run",
"--",
"/Users/marc/mcp-servers/synology-mcp/.venv/bin/python",
"-m",
"synology_mcp"
],
"env": {
"SYNOLOGY_URL": "https://10.1.2.221:5001",
"SYNOLOGY_USER": "op://Homelab-MCP/MCP-Secrets/HP1SYNOLOGYDSM_USER_ID",
"SYNOLOGY_PASS": "op://Homelab-MCP/MCP-Secrets/HP1SYNOLOGYDSM_PASSWORD",
"SYNOLOGY_VERIFY_SSL": "false",
"SYNOLOGY_ENABLE_POWER_CONTROL": "false",
"SYNOLOGY_TIMEOUT": "30",
"SYNOLOGY_SESSION_NAME": "HP1SynologyMCP",
"SYNOLOGY_DEVICE_NAME": "HP1-AI-Agent"
}
}The DSM account is restricted to the trusted 10.1.2.0/24 source subnet through DSM Application Privileges. 2FA is not currently enabled. After committing config.json, the post-commit hook runs apply.py and deploys the server to all registered clients. Fully restart each client before checking /mcp.
Read-only smoke test (the op run wrapper resolves the two secret references without printing their values):
cd ~/mcp-servers/synology-mcp
SYNOLOGY_URL='https://10.1.2.221:5001' \
SYNOLOGY_USER='op://Homelab-MCP/MCP-Secrets/HP1SYNOLOGYDSM_USER_ID' \
SYNOLOGY_PASS='op://Homelab-MCP/MCP-Secrets/HP1SYNOLOGYDSM_PASSWORD' \
SYNOLOGY_VERIFY_SSL='false' \
SYNOLOGY_TIMEOUT='30' \
/opt/homebrew/bin/op run -- .venv/bin/python smoke_test.pyExpected results include a successful login, DSM version, temperature, and the shared-folder list. If the client reports an MCP startup failure, confirm the virtual environment has MCP 1.x installed (.venv/bin/python -m pip show mcp) rather than MCP 2.x.
1.1.5 Install Pi CLI and MCP Adapter#
npm install -g --ignore-scripts @earendil-works/pi-coding-agent
pi install npm:pi-mcp-adapter1.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.
Option A: Copy credentials from primary Mac (Recommended)#
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.jsonOption 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 #2. 1Password Service Account Token Management for full instructions.
Quick setup:
Copy your token from 1Password (Vault: Homelab → Item: Mac OS .zshrc file → Field: OP_SERVICE_ACCOUNT_TOKEN), then add it to ~/.zshrc:
nano ~/.zshrc # Add: export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
source ~/.zshrc1.1.8 Compile and Verify#
mcpVerify all 8 client targets report Successfully applied configuration for ... with no Warning: OP_SERVICE_ACCOUNT_TOKEN not found.
Hermes writes the complete server list to ~/.hermes/config.yaml while preserving the other Hermes settings. During compilation, the compiler copies OP_SERVICE_ACCOUNT_TOKEN into the env block of each op run server. This lets Hermes Desktop authenticate when opened from its app icon. The generated local config is mode 0600 and is not part of the MCP Git repository. Load the token before compiling:
source ~/.zshrc
mcp hermesThen verify the registered servers and test a connection:
hermes mcp list
hermes mcp test home-assistantFor OpenCode, restart the client after compilation and check its connection state with:
opencode mcp listTreat entries as connected only when OpenCode reports connected; a generated definition alone is not a live connection test.
Compilation, configuration status, and connection health are separate. The
mcpalias runs the compiler (and may commit/push changed MCP configuration); it does not launch or refresh an AI client, nor does it give an already-running GUI app the shell’s environment.hermes mcp listshows configured/enabled servers, not whether they can connect. Usehermes mcp test <server>or make a real tool call to verify a server.
1.1.9 Launch Clients with the Required Environment#
On this workstation, OP_SERVICE_ACCOUNT_TOKEN is loaded by ~/.zshrc. An MCP launched by a client can use it only if the client process passes the variable through, or the compiler/client explicitly supplies it. Launching an app from Finder or the Dock usually does not load ~/.zshrc; this is why a GUI client can fail while the same MCP works from a terminal.
There are two separate credential steps:
- Client-to-
opauthentication:OP_SERVICE_ACCOUNT_TOKENletsop runauthenticate as the 1Password service account. The client process must pass this variable to the MCP subprocess, unless the client compiler explicitly supplies it. op-to-server credentials:op runreads the individual MCP secrets from the permitted 1Password vault and passes them to that server. MCPs that do not useop runneed their own configured environment, credential file, or sign-in flow.
| Client / harness | How the op run token is supplied |
Required action |
|---|---|---|
| Antigravity CLI | Parent-shell environment when started from Terminal | Run source ~/.zshrc, then start Antigravity CLI from that Terminal. |
| Antigravity 2.0 and Antigravity IDE | The app process environment; a Finder/Dock launch may omit shell variables | For a reliable launch, start the app from Terminal after source ~/.zshrc, or configure its supported environment source. |
| Pi CLI | Parent-shell environment when started from Terminal | Run source ~/.zshrc, then start Pi from that Terminal. |
| Claude Code CLI | Parent-shell environment when started from Terminal | Run source ~/.zshrc, then start Claude Code from that Terminal. |
| Codex CLI / App | The compiler writes the token into each op run server’s local Codex environment block because Codex isolates MCP subprocess environments |
After token rotation, run source ~/.zshrc and recompile the Codex target. The generated local Codex config contains the runtime credential; keep it private and out of Git. |
| Hermes CLI / TUI / Desktop | mcp hermes copies the token into the local generated config’s env blocks for op run servers |
After adding or rotating the token, run source ~/.zshrc && mcp hermes. Then launch or restart Hermes normally, including from its Desktop icon. The config is mode 0600; it contains the token locally and must not be copied to Git. |
| OpenCode | The compiler writes the token into each op run server’s environment block in ~/.config/opencode/opencode.json |
Run source ~/.zshrc before compiling OpenCode. The generated config is mode 0600, contains the runtime credential, and must stay local. Restart OpenCode after recompiling. |
The same rule applies to every other harness and local MCP tool: determine whether the compiler writes credentials into that client’s local MCP config or whether the running client must inherit them. mcp compiles configuration; it does not refresh a running client. Keep tokens out of shared config.json, notes, and Git history. The Codex target also receives an explicit local env entry; other clients that rely on parent-shell inheritance must be launched from a shell where the token is loaded.
1.1.10 REA — Install, Configure, and Run Across Harnesses#
REA (Reverse Engineer Anything) provides local MCP tools for inspecting applications and binaries. Use the same master configuration and compiler as the other MCPs. The shared entry is pinned to rea-agents@6.7.0 and is compiled for all registered harnesses.
Deployment status (2026-10-18): REA 6.7.0 was downloaded and version-checked on the Mac Studio, added to the shared master config, compiled into all seven registered client targets, and pushed to GitHub. A live binary_session({}) call succeeded in Codex. Verify the other harnesses and each additional Mac after syncing.
Step 1 — Prepare each workstation and choose one package version#
REA requires Node.js 22.x at least 22.19, 24.x at least 24.11, or 26+, with npm. Check the runtime on every Mac:
node --version
npm --version
command -v npxThe shared configuration currently pins REA 6.7.0. On a future update, check the published release and deliberately change the single version pin:
npm view rea-agents dist-tags.latestFor the current installation, check the pinned version on each workstation before restarting clients:
npx -y rea-agents@6.7.0 --versionThis uses npm’s local package cache; a global installation is optional. Initial download requires registry access. The persistent MCP entry will remain pinned to the chosen release. REA’s basic local MCP registration does not require an op run wrapper or new 1Password credentials.
Step 2 — Add REA to the master configuration once#
In /Users/marc/.mcp-config/config.json, insert this entry alongside the existing server definitions, preserving the file’s existing outer structure and JSON commas:
"rea": {
"command": "npx",
"args": ["-y", "rea-agents@6.7.0", "mcp"]
}Use the master file for this registration. REA’s general setup wizard can write client configuration files directly, so using it to register these compiler-managed clients would introduce a second configuration owner. A separate REA setup run is not required on each harness.
The existing compiler targets translate this standard command/args entry into their client formats. On the Mac Studio, compilation succeeded for all seven targets and Codex launched REA. Verify that GUI launches on each workstation can resolve both npx and node. If a workstation’s GUI environment cannot find them, resolve the local runtime paths through the compiler or a tracked launcher, as with other portable server commands; avoid separate hard-coded Apple Silicon and Intel master configurations.
The current compiler emits the basic REA command and arguments in the Codex target:
[mcp_servers.rea]
command = "npx"
args = ["-y", "rea-agents@6.7.0", "mcp"]Keep configuration changes in the master/compiler rather than editing generated files manually. The current compiler does not emit REA-specific startup or tool timeout fields. The live Codex tool call succeeded with the current settings; if a long-running provider later times out, add and verify timeout support in the compiler before relying on those settings.
Step 3 — Compile, distribute, and restart the harnesses#
On the Mac Studio, the following command compiled the targets and automatically committed and pushed the changed master config to GitHub:
source ~/.zshrc && python3 $HOME/.mcp-config/apply.pyOn each other Mac, run pullmcp to sync the shared repository, then compile locally if its post-merge hook did not run:
source ~/.zshrc && python3 $HOME/.mcp-config/apply.pyThe compiler still needs its normal environment for the other 1Password-backed servers; follow #1.1.8 Compile and Verify and #1.1.9 Launch Clients with the Required Environment. Compilation does not restart clients. Fully quit and reopen each harness after compiling, then verify REA with a live tool call.
| Harness | Configuration supplied by the existing pipeline | How REA starts |
|---|---|---|
| ChatGPT desktop with local execution, Codex CLI/App, Codex IDE extension | /Users/marc/.codex/config.toml through the codex target |
The local client launches the configured stdio command; view /mcp after restart. |
| Pi CLI | /Users/marc/.pi/agent/mcp.json through pi |
Pi’s configured MCP loader/adapter launches REA; inspect /mcp. |
| Claude Code | /Users/marc/.claude.json through claude-code |
Claude Code launches REA; inspect /mcp. |
| Antigravity CLI / IDE | /Users/marc/.gemini/config/mcp_config.json through the existing targets |
Restart the client and inspect its MCP status. |
| Antigravity 2.0 | /Users/marc/.gemini/antigravity/mcp_config.json |
Restart the client and inspect its MCP status. |
| Hermes CLI / TUI / Desktop | /Users/marc/.hermes/config.yaml through hermes |
Restart Hermes; use hermes mcp list and hermes mcp test rea. |
| OpenCode | /Users/marc/.config/opencode/opencode.json through opencode |
Restart OpenCode, inspect its MCP status, and make a live REA tool call. |
ChatGPT desktop uses the existing Codex configuration on the same host. Local stdio support means this route needs no additional ChatGPT target, hosted REA service, or tunnel. A standalone hosted ChatGPT web chat does not read these local files. See OpenAI’s MCP configuration documentation. A harness not registered in apply.py needs its own supported target adapter before the shared definition can reach it; for example, Claude Desktop is distinct from the existing Claude Code target.
Do not start npx ... mcp manually and leave it running in Terminal. In this configuration, each client starts its own REA process and maintains its own analysis state. For direct terminal use, invoke an ordinary CLI command instead:
npx -y rea-agents@6.7.0 --helpStep 4 — Verify a live connection in each harness#
Check that rea is connected in the harness’s MCP status, then ask the agent:
Use REA’s
binary_sessiontool with an empty object to report the available analysis capabilities. Do not open or run a target application.
This confirms a real tool call without requiring a native analysis engine. Record successful clients per workstation. A configured entry or a passing CLI version check alone does not establish a working MCP connection. Missing optional providers can leave some operations unavailable while the MCP itself works. If tools remain absent after compilation, restart/reconnect the client and check runtime paths, startup errors, timeouts, and project overrides.
Optional — Analysis engines and workflow instructions#
Static JavaScript/Electron and .NET inspection can work without Hopper, Ghidra, or IDA. Deep native analysis requires an installed provider, configured on each workstation that needs it. Other target types have their own dependencies. Follow the REA installation guide for the chosen provider instead of installing every optional engine on every Mac.
REA also supplies a reverse-engineer-anything workflow skill. Its documented skill-only installation is:
npx skills add morluto/rea --skill reverse-engineer-anythingInstall the instructions into the intended harness locations using that installer’s selection flow. This command installs instructions and references, not the MCP registration or analysis engines. Keep the instructions compatible with the pinned server’s actual tool schemas; repository instructions may be newer than the published package. MCP tools can be verified before this optional skill is installed.
Updates across computers#
Choose and check the new package version, update the single version pin in the master rea entry, distribute through pushmcp / pullmcp, download that same version on each workstation, compile, and restart clients. Refresh any installed workflow instructions as needed. This keeps package selection in the shared repository while runtimes and optional providers remain workstation dependencies.
References: REA manual registration and package runners, REA client-specific configuration and timeouts.
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:
-
Update shell token (
~/.zshrc) (only if token changed): Copy the token from 1Password (Vault:Homelab→ Item:Mac OS .zshrc file):nano ~/.zshrc # Update OP_SERVICE_ACCOUNT_TOKEN source ~/.zshrc -
Pull latest config from GitHub and recompile:
cd ~/.mcp-config git pull
(The post-merge hook fires apply.py automatically. The pullmcp convenience alias performs this same pull from either workstation.)
2. 1Password Service Account Token Management#
All MCP servers that use op run require an OP_SERVICE_ACCOUNT_TOKEN. On this workstation the token is stored in local ~/.zshrc. The compiler copies it into the local Hermes and Codex MCP environment blocks; clients that rely on parent-shell inheritance must be launched from a shell where the token is loaded. See §1.1.9 for the per-harness behavior. The mcp alias compiles configuration but does not launch or refresh a client.
The Service Account (
MCP-Access) has read access only to theHomelab-MCPvault. This is intentional — MCP secrets live inHomelab-MCP, notHomelab,Private, or any other vault.
Setting
OP_SERVICE_ACCOUNT_TOKENin.zshrccompletely disables biometric Touch ID authentication for allopcommands 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_TOKENOtherwiseopwill try to authenticate as the deleted service account and fail withauthenticated as a service account.
env -u OP_SERVICE_ACCOUNT_TOKEN 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
mcpRepeat the local ~/.zshrc update, reload, and compilation on both workstations after creating or rotating the token.
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 unsetfirst or token creation fails.
Option A: Routine Rotation (Web UI)#
- Open https://start.1password.com/developer-tools → Service accounts → select
MCP-Access. - Under Tokens, click Rotate Token → set expiration → copy the new
ops_...token. - Save to Vault:
Homelab→ Item:Mac OS .zshrc file. - Update
~/.zshrcand 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 createwill fail:authenticated as a service account. Rununsetin Step 1 first.
- Unset the broken token:
unset OP_SERVICE_ACCOUNT_TOKEN - Create a new Service Account Token:
(Copy the generated
env -u OP_SERVICE_ACCOUNT_TOKEN op service-account create "MCP-Access" --vault "Homelab-MCP:read_items"ops_...token immediately.) - Save to 1Password: Vault:
Homelab→ Item:Mac OS .zshrc file→ Field:OP_SERVICE_ACCOUNT_TOKEN. - Update
~/.zshrcand recompile:nano ~/.zshrc # Replace OP_SERVICE_ACCOUNT_TOKEN source ~/.zshrc mcp - 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.tomlA 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 loadsconfig.json, registers your software clients, filters placeholder servers ([COMMAND_PLACEHOLDER]), resolvesopthrough the localPATH, and writes each client’s configuration. It emits Hermes’mcp_serverssection as YAML while preserving the rest of~/.hermes/config.yaml; forop runservers, it copiesOP_SERVICE_ACCOUNT_TOKENinto local generated configs. Hermes and OpenCode refuse to replace their target config when the token is absent. The Hermes and OpenCode configs are set to mode0600, are local-only, and contain the service-account token; never copy them to Git or shared notes. Codex also receives the token explicitly because it isolates MCP subprocess environments. OpenCode’s adapter merges its managed server definitions intomcp.serverswhile preserving other JSON settings and unrelated servers. It writes standard JSON and refuses to overwrite an existing non-JSON/JSONC file rather than risk losing comments; OpenCode’s first-time setup starts with no config, so compilation creates the file safely. Keep server definitions in the masterconfig.json..git/hooks/post-commit: A Git hook script that automatically triggersapply.pywhenever a commit is executed in the repository..git/hooks/post-merge: A Git hook script that automatically triggersapply.pywhenever agit pullsuccessfully merges updates from GitHub.
4. Target Client Mapping#
The apply.py script registers and compiles the configuration to the following destination files:
antigravity-cli:~/.gemini/config/mcp_config.json(Prerequisite: Section 1.1.3)antigravity-2.0:~/.gemini/antigravity/mcp_config.json(Prerequisite: Section 1.1.3)antigravity-ide:~/.gemini/config/mcp_config.json(Prerequisite: Section 1.1.3)pi:~/.pi/agent/mcp.json(Prerequisite: Section 1.1.3)claude-code:~/.claude.json(Prerequisite: Section 1.1.3)codex:~/.codex/config.toml(Prerequisite: Section 1.1.3). Unlike other clients, Codex sandboxes each MCP process to only its declaredenvblock and does not inherit the parent shell environment.apply.pytherefore injectsOP_SERVICE_ACCOUNT_TOKENdirectly into the env block of everyop runserver at compile time so thatopcan resolve secrets without triggering GUI prompts.hermes:~/.hermes/config.yaml, under the top-levelmcp_serverskey. The compiler owns the marked MCP block and preserves the remaining Hermes settings, including model and provider configuration. After sourcing~/.zshrc,mcp hermeswrites the token into eachop runserver’s local environment block, so CLI, TUI, and Desktop can all use the same generated config. Restart Hermes after recompilation; its Desktop icon can then launch normally.mcp hermescompiles settings but does not launch or restart the app.opencode:~/.config/opencode/opencode.json, undermcp.servers. The adapter translates each genericcommand/argsentry to OpenCode V2’s localcommandarray and mapsenvtoenvironment. Existing JSON settings and unrelated MCP servers are preserved. For eachop runentry, it injectsOP_SERVICE_ACCOUNT_TOKEN; the generated file is mode0600and compilation refuses to replace it if the token is absent. The adapter accepts standard JSON (not JSONC with comments) to avoid stripping user comments. Restart OpenCode after recompilation; the compiler does not refresh a running client.
The compiler needs a format-specific adapter for clients whose configuration format differs from the generic JSON definitions. Hermes’ YAML and OpenCode’s local-server adapters are registered in TARGETS; the master config.json remains the source of truth.
5. Active Compiled MCP Servers#
The pipeline currently compiles the following 35 shared MCP server definitions for all registered clients. Actual availability remains workstation-specific and depends on local runtimes, credentials, permissions, and network reachability:
cloudflare: Cloudflare DNS, Tunnels, Access policies, and edge service management.docker-10-1-2-100: Remote Docker container management for host10.1.2.100.docker-10-1-2-202: Remote Docker container management for host10.1.2.202.docker-10-1-2-217: Remote Docker container management for host10.1.2.217.docker-10-1-2-230: Remote Docker container management for host10.1.2.230.docker-10-1-2-231: Remote Docker container management for host10.1.2.231.docker-10-1-2-233: Remote Docker container management for host10.1.2.233.docker-10-1-2-4: Local Docker daemon container management (unix:///var/run/docker.sock).docker-72-11-147-220: Remote Docker container management for VPS (72.11.147.220).gdrive: Google Drive API file operations and sheet management. (Prerequisite: Section 1.1.6)git: Local repository Git operations (adds, commits, diffs, branches, worktrees).github: GitHub API integration (remote repos, issues, pull requests, workflows).home-assistant: Home automation controls and entities.macos-mcp: macOS desktop UI automation, accessibility controls, and screen interaction. (Prerequisite: Section 1.1.4)n8n-mcp: Workflow automation and node management.nut: Network UPS Tools server monitoring (ups1,ups2,ups3,ups4on10.1.2.230:3493). (Prerequisite: Section 1.1.4)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-hp2: VM, container, cluster, and storage management for Proxmox HP2 cluster. (Prerequisite: Section 1.1.4)proxmox-hp3: VM, container, cluster, and storage management for Proxmox HP3 cluster. (Prerequisite: Section 1.1.4)proxmox-hp4: VM, container, cluster, and storage management for Proxmox HP4 cluster. (Prerequisite: Section 1.1.4)proxmox-hp5: VM, container, cluster, and storage management for Proxmox HP5 cluster. (Prerequisite: Section 1.1.4)proxmox-hp7(HP7Proxmox): VM, container, cluster, and storage management for Proxmox HP7 node. (Prerequisite: Section 1.1.4)proxmox-mm: VM, container, cluster, and storage management for Proxmox MM cluster. (Prerequisite: Section 1.1.4)rea: Reverse engineering and inspection tools for local applications, binaries, and runtimes; packagerea-agents@6.7.0. Optional analysis providers are workstation-specific.shell-exec: Direct terminal command execution, job management, and process control.synology-hp1: Synology DSM HP1 monitoring and administration through the DSM Web API. (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-hp6: TrueNAS storage node HP6 dataset and user management. (Prerequisite: Section 1.1.4)truenas-hp7: TrueNAS storage node HP7 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.
The shared deployment contains 35 MCP definitions, including REA. The deployment steps and current verification scope are recorded in #1.1.10 REA — Install, Configure, and Run Across Harnesses.
5.1 Dependency & Verification Matrix#
The matrix below groups MCPs that share a dependency. It is the checklist for a blank Mac: install or restore the local dependency, provide credentials through 1Password where required, verify the external service, and only then interpret the client’s /mcp status. Homebrew-managed tools are catalogued in Mac OS - Brewfile.
For a specific server, check its command in the master ~/.mcp-config/config.json: if it starts with op run --, it requires both the service-account token to reach the client subprocess and the server-specific secrets referenced by that op run. Other servers use the credential source listed in the matrix (or their own sign-in/configuration flow); they do not automatically need OP_SERVICE_ACCOUNT_TOKEN.
| MCP server(s) | Local dependency / installation | Credentials | External requirement | Verification |
|---|---|---|---|---|
All op run servers |
op resolved through PATH (/opt/homebrew/bin/op on Apple Silicon; /usr/local/bin/op on Intel) and OP_SERVICE_ACCOUNT_TOKEN in local ~/.zshrc |
MCP-Access token in Homelab → Mac OS .zshrc file; service account reads Homelab-MCP |
1Password service account is active | source ~/.zshrc; op whoami reports SERVICE_ACCOUNT |
cloudflare |
Node/npm package @cloudflare/mcp-server-cloudflare; binary mcp-server-cloudflare on PATH |
CLOUDFLARE_API_TOKEN in Homelab-MCP |
Internet and Cloudflare API access | command -v mcp-server-cloudflare; query a read-only account or zone resource |
docker-10-1-2-4, docker-10-1-2-100, docker-10-1-2-202, docker-10-1-2-217, docker-10-1-2-230, docker-10-1-2-231, docker-10-1-2-233, docker-72-11-147-220 |
Node/npm package mcp-server-docker; Docker CLI; local engine for 10.1.2.4; SSH/network access for remote targets |
DOCKER_HOST values in the compiled config |
Local or remote Docker daemon must be running | command -v mcp-server-docker; test each Docker context/host. Offline hosts may remain connected with zero usable tools |
gdrive |
Node/npm via npx; launched as npx -y @modelcontextprotocol/server-gdrive |
~/.gdrive-server-credentials.json |
Google Drive API access and valid OAuth refresh token | Confirm the credential file exists without printing it, then list a Drive resource |
git |
Node/npm package @cyanheads/git-mcp-server; binary git-mcp-server on PATH |
Non-secret MCP logging/transport settings | Local Git repositories | command -v git-mcp-server; query a repository status |
github |
Node/npm package @modelcontextprotocol/server-github; binary mcp-server-github on PATH |
GITHUB_PERSONAL_ACCESS_TOKEN in Homelab-MCP |
Internet and GitHub API access | command -v mcp-server-github; query a repository or issue |
home-assistant |
Homebrew uv; launched as uvx ha-mcp |
HOMEASSISTANT_URL, HOMEASSISTANT_TOKEN, HA_VERIFY_SSL |
Home Assistant API reachable | uvx --help; then verify the server in /mcp |
macos-mcp |
Python package macos-mcp plus ~/.mcp-config/bin/macos-mcp-wrapper; on Intel, use a uv-managed Python 3.12 virtual environment if Homebrew Python is unavailable |
None in MCP config | Accessibility, Screen Recording, and Automation permissions belong to the server process (~/mcp-servers/macos-mcp/.venv/bin/python3), not the MCP host app. Approve the native macOS permission prompt for the running process, then restart the MCP server. Do not manually add a uv-managed interpreter in System Settings; its path can change on update. |
Confirm the wrapper, grant the process permission through the native prompt, restart the MCP server, and check its connection status |
n8n-mcp |
Node/npm package n8n-mcp; binary n8n-mcp on PATH |
N8N_API_URL, N8N_API_KEY, MCP_MODE, LOG_LEVEL |
n8n API reachable | command -v n8n-mcp; then list n8n tools |
nut |
~/mcp-servers/mcp-nut/.venv plus the custom server.py; install mcp[cli] |
NUT_HOSTS, NUT_PORT, PYTHONUNBUFFERED |
UPS services reachable on the configured hosts | Confirm server.py exists, then perform a read-only UPS status query |
pihole-primary, pihole-secondary |
Node/npm package mcp-pihole-server; binary mcp-pihole on PATH |
PIHOLE_URL, PIHOLE_PASSWORD |
Each Pi-hole endpoint reachable | command -v mcp-pihole; then perform a read-only status query |
proxmox-hp1, proxmox-hp2, proxmox-hp3, proxmox-hp4, proxmox-hp5, proxmox-hp7 (HP7Proxmox), proxmox-mm |
~/mcp-servers/mcp-proxmox/.venv from the public mcp-proxmox repository; install requirements and editable package as in §1.1.4 |
Proxmox API URL, token ID, and secret references in Homelab-MCP → MCP-Secrets |
Target Proxmox API reachable; self-signed SSL is handled by PROXMOX_VERIFY=false |
command -v is not sufficient; verify each server in /mcp and expect 118 tools when available, then run a read-only node query |
rea |
Node.js and npm; npx -y rea-agents@6.7.0 mcp pinned in the master config; optional analysis engines per workstation |
None for the basic local MCP registration | npm registry access for initial package download; target-specific providers when needed | Restart each harness, confirm rea is connected, and call binary_session with {}; see §1.1.10 |
shell-exec |
Node/npm package shell-exec-mcp; binary shell-exec-mcp on PATH |
None in MCP config | Local shell access | command -v shell-exec-mcp; run a harmless read-only command |
synology-hp1 |
~/mcp-servers/synology-mcp/.venv from the public rafalr100/synology-mcp repository; install mcp[cli]>=1.0.0,<2.0.0 before pip install -e . |
SYNOLOGY_USER and SYNOLOGY_PASS reference Homelab-MCP → MCP-Secrets; no secret values in config |
HP1 DSM Web API reachable at https://10.1.2.221:5001; account allowed from 10.1.2.0/24 |
Run the read-only smoke test through op run, then restart the client and expect synology-hp1: connected in /mcp |
truenas-hp1, truenas-hp2, truenas-hp3, truenas-hp6, truenas-hp7 |
~/mcp-servers/mcp-truenas/.venv plus the custom server.py and supporting files; install mcp[cli] |
TRUENAS_URL, TRUENAS_API_KEY, TRUENAS_VERIFY_SSL |
Each TrueNAS API endpoint reachable | Confirm server.py exists, then perform a read-only dataset or system query |
unifi |
Node/npm package @thelord/unifi-mcp-server; binary unifi-mcp-server on PATH |
UNIFI_GATEWAY_IP, UNIFI_API_KEY, UNIFI_VERIFY_SSL, LOG_CONSOLE |
UniFi gateway reachable | command -v unifi-mcp-server; then query devices or clients |
xcode-tools |
Node/npm package xcodebuildmcp; Xcode and Xcode Command Line Tools |
None in MCP config | Xcode project/simulator available for build tasks | command -v xcodebuildmcp; then verify the Xcode MCP tools |
The
mcp-truenasandmcp-nutsource directories contain local custom server files and are not cloned byMCP-Config-MacOS. On a new Mac, copy or restore those source files from the working workstation before runningmcp; installing only the Python SDK is not sufficient.
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-commitHook: 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-mergeHook: 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.pyWhenever 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-configMethod A: Standard Pull (Recommended)#
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 needed6.2 Workstation Sync Shortcuts#
The tracked aliases file provides two shortcuts for synchronizing the separate MCP repository:
pushmcp: Enters~/.mcp-config, stagesconfig.json,apply.py, andbin/macos-mcp-wrapper, commits only when those files changed, and pushesmainto GitHub. Thepost-commithook then runsapply.pyto compile all client configurations.pullmcp: Runsgit pull origin mainin~/.mcp-config. Thepost-mergehook then runsapply.pyto compile all client configurations.
These shortcuts are separate from pushscripts and pullscripts, which operate only on the ~/Scripts repository. The exact function and alias definitions are documented in Mac OS - Aliases Management.
7. Proxmox MCP Server Installation (macOS)#
This guide details the manual build process for setting up the Proxmox MCP server environment on macOS. On Intel Macs, use the uv-managed Python 3.12 described in Section 1.1.4 instead of waiting for a Homebrew Python source build.
7.1 Prerequisites#
- Proxmox VE: Access to a Proxmox cluster or node.
- Python 3.12: Required for the MCP server environment. Prefer uv-managed Python 3.12 on Intel Macs.
brew install python@3.12 - API Token: Created in Proxmox (Datacenter > Permissions > API Tokens). Ensure the token has sufficient permissions (e.g.,
PVEAuditororPVEVMAdmin) 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/jsonat 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 runto 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:
Once authenticated,
op run -- echo "1Password warm"op runsecret resolution drops to ~40ms, allowing all 16 servers to load cleanly.
- Fix: Pre-warm 1Password CLI before launching your AI CLI session by running:
8.2. Symptom: Server hangs indefinitely on “Initializing…”#
- Cause: 1Password Session Lock. The 1Password CLI session timed out, and
op runis silently waiting for biometric authentication in the background.- Fix: Run
op signinin your standard terminal, complete authentication, and restart the CLI.
- Fix: Run
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 sendsSIGTERMto stop running servers. Python processes default to exit code143when killed withSIGTERM, which some CLI watchers misidentify as a crash and abort the reload.- Fix: Use the wrapper script at
~/.mcp-config/bin/macos-mcp-wrapperinconfig.json. The wrapper trapsSIGTERM, terminatesmacos-mcpgracefully, and exits with status0.
- Fix: Use the wrapper script at
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 tostderr.
- Fix: Verify you have
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
- Fix: Ensure your keys are loaded into the ssh-agent before running your AI CLI session:
- 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
- Fix: Perform a manual connection to the target IP one time from your terminal to verify and accept the host key into
8.6. Symptom: Codex triggers repeated “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 ofconfig.toml. SinceOP_SERVICE_ACCOUNT_TOKENis only set in~/.zshrc, theop runsubprocesses spawned by Codex never see it and fall back to the 1Password desktop app GUI, producing one popup perop runserver.- Fix: The
apply.pycompiler now readsOP_SERVICE_ACCOUNT_TOKENfrom the shell environment at compile time and injects it into the env block of everyop runserver in the Codex TOML output. The token never entersconfig.jsonor git history. Re-compile after any token rotation:Or simply commit any change — thesource ~/.zshrc cd ~/.mcp-config && ./apply.py codexpost-commithook firesapply.pyfor all clients automatically.
- Fix: The
8.7. Symptom: A Proxmox MCP remains active while its host is offline#
- Cause: The MCP process can start and advertise its tools even when the configured Proxmox API endpoint is temporarily unreachable. This status reflects the MCP process, not the power state of the target host.
- Action: This is expected for an offline server. Do not remove the MCP definition or recreate credentials solely because the host is offline; API calls will work once the target becomes reachable again.
8.8. Symptom: Many MCP servers fail on a newly provisioned workstation#
- Cause: The shared compiler intentionally deploys the complete server definition list to every registered client. A failed entry usually means that workstation is missing its local Node package, Python virtual environment, OAuth file, Docker/Xcode dependency, privacy permission, or access to the target service. It does not imply that the shared configuration or the other Macs are broken.
- Action: Treat each failure according to the dependency matrix in Section 5.1. Confirm the local executable or virtual environment first, then verify credentials and network access. It is valid for optional servers such as Xcode MCP or remote Docker targets to remain offline on a workstation that does not use them.
8.9. Symptom: Hermes Desktop shows an op service-account credential error#
- Cause: The generated Hermes config has a missing or stale
OP_SERVICE_ACCOUNT_TOKENin anop runserver’s environment block. - Fix: Load the current token and recompile the Hermes target:
Then fully quit and reopen Hermes from its Desktop icon. The compiler stores the token in
source ~/.zshrc && mcp hermes~/.hermes/config.yaml, protected by mode0600; it does not write the token toconfig.jsonor Git. If the error persists, verifyop whoamireportsUser Type: SERVICE_ACCOUNT, then test the server withhermes mcp test <server>. - Status interpretation:
hermes mcp listreports configured/enabled entries; it does not test connections. In Desktop,On, unusedmeans enabled but not yet used, not verified healthy. Use a connection test or a real tool call.
8.10. Symptom: macOS shows a “Device Control and Data Access” dialog for osascript#
- Observed cause: Hermes logs identified its configured
macos-mcpserver failing because the Python process lacked Accessibility permission. The Hermes gateway itself is supervised by anosascriptJavaScript wrapper. The prior log review did not prove which script initiated the specific macOS permission request, so the dialog name alone is not enough to attribute it. - Temporary Hermes-only fix: Add
enabled: falseto themacos-mcpentry undermcp_serversin~/.hermes/config.yaml, then runhermes gateway restart. Verify the entry is disabled and no Hermesmacos-mcpprocess starts. This was applied on the Mac Studio and MacBook Air on 2026-10-18. - Persistence:
apply.pyregenerates the compiler-managed Hermes MCP block from the shared~/.mcp-config/config.json. Sincemacos-mcpremains in that master list and the current compiler does not preserve per-serverenabledflags, a later full compile can re-enable it. A persistent policy requires changing the master config/compiler; do not rely on the local Hermes override after recompilation. Other harnesses have separatemacos-mcpprocesses and are not stopped by the Hermes-only fix.