Зачем это нужно Link to heading

У меня в opencode накопилось несколько скиллов и MCP-серверов: конвертер в маркдаун, поиск в duckduckgo, deepwiki и т.д Раньше они лежали где попало. Переезжаешь на другую машину или слетает конфиг — и всё, собирай заново.

Захотелось одного: чтобы всё было в git-репозиториях как единственный источник правды, а opencode просто читал оттуда. И чтобы обновление было в одну команду, а не ручной перенос файлов.

Что получилось Link to heading

Два отдельных репозитория:

  • skills — папки с SKILL.md, по одной на каждый скилл
  • mcp — пайтон-скрипты MCP-серверов, opencode.jsonc и requirements.txt

И два скрипта в ~/Documents/scripts/, которые «разворачивают» репозитории в нужные места opencode через symlink’и.

Как это работает Link to heading

Каждый скрипт сначала делает git pull, чтобы подтянуть свежие правки, а потом расставляет symlink’и.

sync_skills.sh Link to heading

Проходит по папкам репозитория, берёт только те, где есть SKILL.md, и симлинкует их в ~/.opencode/skills/. Если там уже лежит настоящая папка — заменяет её на symlink. Флаг --prune подчищает осиротевшие ссылки на удалённые скиллы.

REPO_SKILLS="~/Documents/project/skills"
OPENCODE_SKILLS="$HOME/.opencode/skills"

git -C "$REPO_SKILLS" pull --ff-only
mkdir -p "$OPENCODE_SKILLS"

for dir in "$REPO_SKILLS"/*/; do
  name=$(basename "$dir")
  [[ "$name" == ".git" ]] && continue
  [[ -f "$dir/SKILL.md" ]] || continue
  target="$OPENCODE_SKILLS/$name"
  ln -sfn "$dir" "$target"
done

sync_mcp.sh Link to heading

С symlink’ами тут тоньше: сам конфиг opencode.jsonc и скрипты серверов симлинкуются в ~/.config/opencode/, а вот venv в git не кладём — он тяжёлый и генерится локально из requirements.txt.

MCP_REPO="~/Documents/project/mcp"
MCP_DIR="$HOME/.config/opencode/mcp"

git -C "$MCP_REPO" pull --ff-only
ln -sfn "$MCP_REPO"/*.py "$MCP_DIR/"
ln -sfn "$MCP_REPO/opencode.jsonc" "$HOME/.config/opencode/opencode.jsonc"

python3 -m venv "$MCP_DIR/venv"
"$MCP_DIR/venv/bin/python3" -m pip install -r "$MCP_REPO/requirements.txt"

После этого достаточно перезапустить opencode — и он видит и скиллы, и MCP-серверы.

Правки в репозитории (новый скилл, правка промпта MCP) сразу видны opencode — никакого копирования. Коммитим в git, пушим в gitverse/github, и на другой машине git pull + запуск скрипта возвращают всю настройку.

Как добавить новый скилл Link to heading

Скилл — это папка с обязательным файлом SKILL.md (в нём front matter с полями name и description). Добавляется в три шага:

  1. Создать папку в репо skills:
    mkdir -p ~/Documents/project/skills/my-new-skill
    # положить туда SKILL.md
    
  2. Закоммитить в репо skills (git add/commit, при желании push).
  3. Запустить sync — скрипт сам найдёт папку с SKILL.md и создаст symlink в ~/.opencode/skills/:
    bash ~/Documents/scripts/sync_skills.sh
    

OpenCode подхватит скилл при следующем вызове (перезапуск не обязателен, но надёжнее). Удалить скилл так же просто: убрать папку из репо, закоммитить и вызвать sync_skills.sh --prune — он удалит осиротевший symlink.

Как добавить новый MCP Link to heading

Вся настройка MCP живёт в репо ~/Documents/project/mcp, а opencode читает её через symlink. Поэтому «добавить MCP» = пополнить репо и один раз запустить sync_mcp.sh. Править live-файлы в ~/.config/opencode/ напрямую не нужно — они перезапишутся симлинком.

Локальный python-сервер (как markitdown-mcp) Link to heading

Допустим, новый сервер foobar_server.py:

  1. Положить скрипт в репо: ~/Documents/project/mcp/foobar_server.py.
  2. Дописать его зависимости в ~/Documents/project/mcp/requirements.txt.
  3. Добавить блок в ~/Documents/project/mcp/opencode.jsonc:
    "foobar": {
      "type": "local",
      "command": [
        "/Users/tatarinovms/.config/opencode/mcp/venv/bin/python3",
        "/Users/tatarinovms/.config/opencode/mcp/foobar_server.py"
      ]
    }
    

Пути в commandlive (~/.config/opencode/mcp/...), а не репо-пути. Sync сам симлинкует скрипт именно туда, так что они совпадут.

  1. git add/commit в репо mcp.
  2. bash ~/Documents/scripts/sync_mcp.sh — симлинкует новый .py, обновит symlink opencode.jsonc и выполнит pip install -r requirements.txt, добавив зависимость в локальный venv.
  3. Перезапустить opencode.

Без скрипта и без venv. Только:

  1. Добавить блок в репо-opencode.jsonc (type: "remote" с url либо type: "local" с uvx ...).
  2. git commit + sync_mcp.sh (обновит symlink конфига) + перезапуск opencode.

Для uvx-серверов убедись, что uvx есть в PATH; для remote — что URL доступен.

Нюансы: не редактируй ~/.config/opencode/opencode.jsonc вручную (это symlink на репо, правки «провалятся» в репо, но потеряются при git pull без коммита — правь репо-файл); venv локальный и в git не ходит (новые python-зависимости = правка requirements.txt + перезапуск sync); после любой правки конфига обязателен перезапуск opencode.

Настройка на новой инсталляции OpenCode Link to heading

Переезд на чистую машину сводится к клонированию двух репозиториев и запуску пары скриптов:

  1. Поставить opencode, а также node и python3 (нужны для venv и MCP).
  2. Клонировать репозитории (куда удобно — пути должны совпадать с теми, что прописаны в скриптах, либо поправить пути в самих скриптах
  3. Перенести sync-скрипты в ~/Documents/scripts/ (они у меня синкаются тоже через Я.Диск): sync_skills.sh и sync_mcp.sh.
  4. Запустить синхронизацию — скрипты расставят symlink’и и создадут локальный venv из requirements.txt:
    bash ~/Documents/scripts/sync_skills.sh && bash ~/Documents/scripts/sync_mcp.sh
    
  5. Перезапустить opencode — скиллы и MCP-серверы на месте.

Если MCP-серверы используют внешние бинари (например, yt-dlp/ffmpeg для youtube), не забудь поставить и их.

Итог Link to heading

Пара скриптов и два репозитория — и вся настройка opencode теперь версионируется и переносится одной командой. Новый скилл добавляется как папка с SKILL.md в репо + sync_skills.sh, новый MCP — как скрипт + блок в opencode.jsonc + sync_mcp.sh. Полный перенос на новую машину — это git clone двух репозиториев, копия скриптов и один запуск синхронизации.