From e7050e2ad891f18dd5fcf087f2cc92c04b18a9e4 Mon Sep 17 00:00:00 2001 From: lmiranda Date: Tue, 27 Jan 2026 14:36:05 -0500 Subject: [PATCH] fix(mcp): use wrapper scripts instead of venv symlinks Replace direct python path in .mcp.json with run.sh wrapper scripts that automatically locate the venv in cache or local directory. Problem: .venv symlinks are gitignored, causing them to be wiped on every git operation. The SessionStart hook should recreate them but this was unreliable, leading to repeated MCP server failures. Solution: run.sh scripts that: - First check ~/.cache/claude-mcp-venvs/leo-claude-mktplace/{server}/.venv - Fallback to local .venv if exists - Exit with helpful error if neither found This eliminates dependency on symlinks entirely - the scripts are tracked in git and will always be present after clone/pull/update. Co-Authored-By: Claude Opus 4.5 --- mcp-servers/contract-validator/run.sh | 17 +++++++++++++++++ mcp-servers/data-platform/run.sh | 17 +++++++++++++++++ mcp-servers/gitea/run.sh | 17 +++++++++++++++++ mcp-servers/netbox/run.sh | 17 +++++++++++++++++ mcp-servers/viz-platform/run.sh | 17 +++++++++++++++++ plugins/cmdb-assistant/.mcp.json | 8 ++------ plugins/contract-validator/.mcp.json | 5 ++--- plugins/data-platform/.mcp.json | 5 ++--- plugins/pr-review/.mcp.json | 8 ++------ plugins/projman/.mcp.json | 8 ++------ plugins/viz-platform/.mcp.json | 5 ++--- 11 files changed, 97 insertions(+), 27 deletions(-) create mode 100755 mcp-servers/contract-validator/run.sh create mode 100755 mcp-servers/data-platform/run.sh create mode 100755 mcp-servers/gitea/run.sh create mode 100755 mcp-servers/netbox/run.sh create mode 100755 mcp-servers/viz-platform/run.sh diff --git a/mcp-servers/contract-validator/run.sh b/mcp-servers/contract-validator/run.sh new file mode 100755 index 0000000..38e185c --- /dev/null +++ b/mcp-servers/contract-validator/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/contract-validator/.venv" +LOCAL_VENV="$SCRIPT_DIR/.venv" + +if [[ -f "$CACHE_VENV/bin/python" ]]; then + PYTHON="$CACHE_VENV/bin/python" +elif [[ -f "$LOCAL_VENV/bin/python" ]]; then + PYTHON="$LOCAL_VENV/bin/python" +else + echo "ERROR: No venv found. Run: ./scripts/setup-venvs.sh" >&2 + exit 1 +fi + +cd "$SCRIPT_DIR" +export PYTHONPATH="$SCRIPT_DIR" +exec "$PYTHON" -m mcp_server.server "$@" diff --git a/mcp-servers/data-platform/run.sh b/mcp-servers/data-platform/run.sh new file mode 100755 index 0000000..0f60ec1 --- /dev/null +++ b/mcp-servers/data-platform/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/data-platform/.venv" +LOCAL_VENV="$SCRIPT_DIR/.venv" + +if [[ -f "$CACHE_VENV/bin/python" ]]; then + PYTHON="$CACHE_VENV/bin/python" +elif [[ -f "$LOCAL_VENV/bin/python" ]]; then + PYTHON="$LOCAL_VENV/bin/python" +else + echo "ERROR: No venv found. Run: ./scripts/setup-venvs.sh" >&2 + exit 1 +fi + +cd "$SCRIPT_DIR" +export PYTHONPATH="$SCRIPT_DIR" +exec "$PYTHON" -m mcp_server.server "$@" diff --git a/mcp-servers/gitea/run.sh b/mcp-servers/gitea/run.sh new file mode 100755 index 0000000..44195cd --- /dev/null +++ b/mcp-servers/gitea/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/gitea/.venv" +LOCAL_VENV="$SCRIPT_DIR/.venv" + +if [[ -f "$CACHE_VENV/bin/python" ]]; then + PYTHON="$CACHE_VENV/bin/python" +elif [[ -f "$LOCAL_VENV/bin/python" ]]; then + PYTHON="$LOCAL_VENV/bin/python" +else + echo "ERROR: No venv found. Run: ./scripts/setup-venvs.sh" >&2 + exit 1 +fi + +cd "$SCRIPT_DIR" +export PYTHONPATH="$SCRIPT_DIR" +exec "$PYTHON" -m mcp_server.server "$@" diff --git a/mcp-servers/netbox/run.sh b/mcp-servers/netbox/run.sh new file mode 100755 index 0000000..91d10ca --- /dev/null +++ b/mcp-servers/netbox/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/netbox/.venv" +LOCAL_VENV="$SCRIPT_DIR/.venv" + +if [[ -f "$CACHE_VENV/bin/python" ]]; then + PYTHON="$CACHE_VENV/bin/python" +elif [[ -f "$LOCAL_VENV/bin/python" ]]; then + PYTHON="$LOCAL_VENV/bin/python" +else + echo "ERROR: No venv found. Run: ./scripts/setup-venvs.sh" >&2 + exit 1 +fi + +cd "$SCRIPT_DIR" +export PYTHONPATH="$SCRIPT_DIR" +exec "$PYTHON" -m mcp_server.server "$@" diff --git a/mcp-servers/viz-platform/run.sh b/mcp-servers/viz-platform/run.sh new file mode 100755 index 0000000..19b35ea --- /dev/null +++ b/mcp-servers/viz-platform/run.sh @@ -0,0 +1,17 @@ +#!/bin/bash +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_VENV="$HOME/.cache/claude-mcp-venvs/leo-claude-mktplace/viz-platform/.venv" +LOCAL_VENV="$SCRIPT_DIR/.venv" + +if [[ -f "$CACHE_VENV/bin/python" ]]; then + PYTHON="$CACHE_VENV/bin/python" +elif [[ -f "$LOCAL_VENV/bin/python" ]]; then + PYTHON="$LOCAL_VENV/bin/python" +else + echo "ERROR: No venv found. Run: ./scripts/setup-venvs.sh" >&2 + exit 1 +fi + +cd "$SCRIPT_DIR" +export PYTHONPATH="$SCRIPT_DIR" +exec "$PYTHON" -m mcp_server.server "$@" diff --git a/plugins/cmdb-assistant/.mcp.json b/plugins/cmdb-assistant/.mcp.json index b049871..e2d04f5 100644 --- a/plugins/cmdb-assistant/.mcp.json +++ b/plugins/cmdb-assistant/.mcp.json @@ -1,12 +1,8 @@ { "mcpServers": { "netbox": { - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/netbox/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/netbox", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/netbox" - } + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/netbox/run.sh", + "args": [] } } } diff --git a/plugins/contract-validator/.mcp.json b/plugins/contract-validator/.mcp.json index f3aa57b..52301f0 100644 --- a/plugins/contract-validator/.mcp.json +++ b/plugins/contract-validator/.mcp.json @@ -2,9 +2,8 @@ "mcpServers": { "contract-validator": { "type": "stdio", - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/contract-validator/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/contract-validator" + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/contract-validator/run.sh", + "args": [] } } } diff --git a/plugins/data-platform/.mcp.json b/plugins/data-platform/.mcp.json index a31a78c..a36ff8f 100644 --- a/plugins/data-platform/.mcp.json +++ b/plugins/data-platform/.mcp.json @@ -2,9 +2,8 @@ "mcpServers": { "data-platform": { "type": "stdio", - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/data-platform/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/data-platform" + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/data-platform/run.sh", + "args": [] } } } diff --git a/plugins/pr-review/.mcp.json b/plugins/pr-review/.mcp.json index 75191c7..1015f9c 100644 --- a/plugins/pr-review/.mcp.json +++ b/plugins/pr-review/.mcp.json @@ -1,12 +1,8 @@ { "mcpServers": { "gitea": { - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea" - } + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea/run.sh", + "args": [] } } } diff --git a/plugins/projman/.mcp.json b/plugins/projman/.mcp.json index 75191c7..1015f9c 100644 --- a/plugins/projman/.mcp.json +++ b/plugins/projman/.mcp.json @@ -1,12 +1,8 @@ { "mcpServers": { "gitea": { - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea", - "env": { - "PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea" - } + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/gitea/run.sh", + "args": [] } } } diff --git a/plugins/viz-platform/.mcp.json b/plugins/viz-platform/.mcp.json index d4540f8..d05ee28 100644 --- a/plugins/viz-platform/.mcp.json +++ b/plugins/viz-platform/.mcp.json @@ -2,9 +2,8 @@ "mcpServers": { "viz-platform": { "type": "stdio", - "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/viz-platform/.venv/bin/python", - "args": ["-m", "mcp_server.server"], - "cwd": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/viz-platform" + "command": "${CLAUDE_PLUGIN_ROOT}/mcp-servers/viz-platform/run.sh", + "args": [] } } }