fix(mcp): persistent venv cache survives marketplace updates

Problem:
- Venvs in marketplace directory got deleted on every update
- Users had to manually run setup.sh and wait for full pip install
- This caused MCP servers to fail until manually fixed

Solution:
- Store venvs in external cache (~/.cache/claude-mcp-venvs/)
- Auto-repair symlinks via SessionStart hook (instant operation)
- Only run pip install on first use or when requirements change

Architecture:
  Cache (runtime) → Marketplaces → External venv cache

  The chain of symlinks ensures all three locations work:
  1. ~/.claude/plugins/cache/.../mcp-servers/* (runtime)
  2. ~/.claude/plugins/marketplaces/.../mcp-servers/* (install)
  3. ~/.cache/claude-mcp-venvs/* (persistent venvs)

Performance:
- First install: ~2-3 min (unchanged)
- After marketplace update: 0.03 sec (was 2-3 min)

Files:
- scripts/venv-repair.sh: Fast symlink restoration for hooks
- scripts/setup-venvs.sh: Full setup with external cache
- plugins/projman/hooks/startup-check.sh: Auto-repair on session start
- .gitignore: Ignore .venv symlinks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-27 11:48:13 -05:00
parent 1b029d97b8
commit 1abda1ca0f
4 changed files with 474 additions and 5 deletions

View File

@@ -5,13 +5,30 @@
PREFIX="[projman]"
# Check if MCP venv exists
# Calculate paths
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$(dirname "$(realpath "$0")")")}"
VENV_PATH="$PLUGIN_ROOT/mcp-servers/gitea/.venv/bin/python"
# Marketplace root is 2 levels up from plugin root (plugins/projman -> .)
MARKETPLACE_ROOT="$(dirname "$(dirname "$PLUGIN_ROOT")")"
VENV_REPAIR_SCRIPT="$MARKETPLACE_ROOT/scripts/venv-repair.sh"
if [[ ! -f "$VENV_PATH" ]]; then
echo "$PREFIX MCP venvs missing - run setup.sh from installed marketplace"
exit 0
# ============================================================================
# Auto-repair MCP venvs (runs before other checks)
# ============================================================================
if [[ -x "$VENV_REPAIR_SCRIPT" ]]; then
# Run venv repair - this creates symlinks to cached venvs
# Only outputs messages if something needed fixing
"$VENV_REPAIR_SCRIPT" 2>/dev/null || {
echo "$PREFIX MCP venv setup failed - run: cd $MARKETPLACE_ROOT && ./scripts/setup-venvs.sh"
exit 0
}
else
# Fallback: just check if venv exists
VENV_PATH="$PLUGIN_ROOT/mcp-servers/gitea/.venv/bin/python"
if [[ ! -f "$VENV_PATH" ]]; then
echo "$PREFIX MCP venvs missing - run setup.sh from installed marketplace"
exit 0
fi
fi
# Check git remote vs .env config (only if .env exists)