feat(mcp): add Serena MCP server with Docker-baked config #70

Closed
opened 2026-08-16 17:27:06 +03:00 by slaid098 · 0 comments
Owner

Контекст

Зачем: у агента нет символьной навигации по коду (кто вызывает функцию, безопасный rename/delete, диагностика LSP без запуска тестов) — grep/read дают только текстовые совпадения. Serena (github.com/oraios/serena, MIT, MCP-сервер на LSP, 40+ языков) закрывает это. Совместимость с opencode заявлена авторами.

Текущее состояние: Dockerfile — node:22-trixie-slim, Python 3.13 (apt), uv в /usr/local/bin (ставится с UV_INSTALL_DIR=/usr/local/bin), PATH-правка только /opt/memory/.venv/bin. docker-compose.yml: bind-mounts /root/.config/opencode, /root/.local/share/opencode, /root/workspace, /root/.ssh; /root/.serena НЕ покрыт mount'ами (не персистентен). .opencode/opencode.json mcp-секция: browser, context7, antidetect-browser, integrations (строки ~440-473); agent.memory-syncer уже имеет tools-map. .dockerignore: app_data/, .git, **/node_modules.

Принятые при планировании решения (не пересматривать): Serena ставится latest (без пина версии); конфиг Serena версионируется в репо и запекается в образ через COPY; собственная память Serena отключается через excluded_tools в её конфиге (конфликт с нашей opencode-memory недопустим); режим --context ide (отключает дубли с встроенными инструментами opencode: create_text_file, read_file, execute_shell_command, find_file, list_dir); memory-syncer не получает serena_*; ALLOWED-список оркестратора в AGENTS.md НЕ расширяется; новых ADR-файлов в docs/decisions не создавать.

Задача

  1. Gate-шаг (записать вывод в PR body секцией ## Watch out): открыть https://opencode.ai/docs/lsp/ и сверить возможности встроенного LSP opencode с символьным ядром Serena (find_referencing_symbols, find_implementations, rename_symbol, safe_delete_symbol, replace_symbol_body, insert_before/after_symbol, get_symbols_overview, get_diagnostics_for_file). Если встроенный lsp-tool уже покрывает references/diagnostics — оставить Serena только для rename/safe_delete/replace_body/insert_* и зафиксировать это в gate-заключении.
  2. Новый файл docker/serena_config.yml (версионируется в репо):
excluded_tools:
  - write_memory
  - read_memory
  - list_memories
  - edit_memory
  - delete_memory
  - rename_memory
gui_log_window: False
web_dashboard_open_on_launch: False
  1. Dockerfile: после строки установки uv добавить RUN UV_TOOL_BIN_DIR=/usr/local/bin uv tool install -p 3.13 serena-agent (latest, без пина) и COPY docker/serena_config.yml /root/.serena/serena_config.yml (выполняется под root, дом = /root). Проверить, что docker/serena_config.yml не попадает под .dockerignore.
  2. .opencode/opencode.json: в mcp добавить сервер serena: {"type": "local", "command": ["serena", "start-mcp-server", "--context", "ide", "--project-from-cwd", "--enable-gui-log-window", "false", "--open-web-dashboard", "false"], "enabled": true, "timeout": 300000}. В agent.memory-syncer.tools добавить "serena_*": false.
  3. AGENTS.md: новая секция ## Символьная навигация (Serena) — жёсткие императивные триггеры в CRITICAL-стиле: (а) ПЕРЕД изменением сигнатуры/контракта публичного символа — ОБЯЗАТЕЛЬНО find_referencing_symbols; (б) переименование/удаление символа — ТОЛЬКО rename_symbol/safe_delete_symbol, НЕ sed/текстовый replace; (в) ПОСЛЕ правок файла — get_diagnostics_for_file. Правка в workspace clone /root/workspace/opencode-config/, sync по процедуре из skill configure-opencode.
  4. .opencode/agents/reviewer.md: дубль той же секции + запись в существующую секцию «Known deterministic links» (строки ~403-421) про триггеры Serena.
  5. .opencode/skills/configure-opencode/SKILL.md: в sync-процедуру добавить упоминание, что правки Dockerfile требуют docker compose up -d --build (а не только restart).
  6. docker-compose.yml и README не меняются.

Контракты

  • MCP-запись: имя сервера serena; type local; команда ровно как в п.4; timeout 300000 (старт LSP медленный).
  • opencode.json остаётся валидным JSON после правки (jq parse).
  • docker/serena_config.yml — ключи ровно как в п.2 (snake_case, boolean YAML).
  • AGENTS.md — секция на русском, императивный тон, ≤15 строк.

Инварианты

  • Serena latest, никаких пинов версии.
  • Память Serena (*_memory точнее write/read/list/edit/delete/rename) недоступна ни одному агенту — глушится Serena-side в одном месте (serena_config.yml), НЕ per-agent.
  • memory-syncer: все serena_* запрещены.
  • Любые правки конфига ТОЛЬКО в workspace clone /root/workspace/opencode-config/, никогда в ~/.config/opencode/ напрямую.
  • Новых файлов в docs/decisions/ не создавать.

Граничные случаи

  • Первый старт pyright через uvx докачивает зависимости в слой контейнера — после recreate первый ответ медленный (минута-две), это норма.
  • --project-from-cwd: если от cwd нет .git/.serena — проект не активируется, сервер предложит activate_project; в --context ide activate_project отключён при стартовом проекте — задокументировать в AGENTS.md-секции одной строкой, если gate подтвердит.
  • Образ не собирается (uv/PyPI недоступен) — падает build, чинить в этом же PR.
  • Gate выявит большое перекрытие со встроенным LSP — зафиксировать в PR body и сузить scope (см. п.1), НЕ убирая MCP-запись целиком.

Влияние на связанные компоненты

  • tests/test_permissions.py (ключи agent.tools поимённые — добавление serena_* не ломает) и tests/test_agent_frontmatter.py (пинят только frontmatter reviewer/memory-syncer): зелёные обязательны.
  • CI .github/workflows/permissions-check.yml триггерится по путям .opencode/opencode.json и .opencode/agents/** — проверок по mcp-сеции нет, нарушений быть не должно.
  • .opencode/skills/configure-opencode/SKILL.md — paired update (п.7).
  • reviewer.md — paired update (п.6).
  • AGENTS.md ALLOWED-список оркестратора — НЕ меняется.
  • README — правок не требует (MCP-серверы не перечислены).

Вне scope

  • Пин версии Serena (отклонено: latest).
  • Bind-mount для /root/.serena (отклонено: конфиг запечён в образ).
  • Доступ к web dashboard с хоста (listen 0.0.0.0) — не делаем.
  • Issue про ADR-указатели — отдельный issue/PR.
  • Переопределение встроенных агентов explore/build/general md-файлами — инвазивно, не делаем (получат секцию через AGENTS.md).

Критерии приемки

  • docker build образа успешен; в образе serena --help отрабатывает из /usr/local/bin.
  • В образе существует /root/.serena/serena_config.yml с 6 записями в excluded_tools.
  • jq empty .opencode/opencode.json проходит; pytest tests/ (test_permissions.py, test_agent_frontmatter.py) зелёные.
  • AGENTS.md содержит секцию «Символьная навигация (Serena)»; reviewer.md содержит дубль + запись в «Known deterministic links».
  • PR body содержит gate-заключение по сравнению со встроенным LSP opencode в секции ## Watch out.
  • CHANGELOG-запись (русская строка) по стандартному release-флоу репо.
## Контекст Зачем: у агента нет символьной навигации по коду (кто вызывает функцию, безопасный rename/delete, диагностика LSP без запуска тестов) — grep/read дают только текстовые совпадения. Serena (github.com/oraios/serena, MIT, MCP-сервер на LSP, 40+ языков) закрывает это. Совместимость с opencode заявлена авторами. Текущее состояние: `Dockerfile` — node:22-trixie-slim, Python 3.13 (apt), uv в /usr/local/bin (ставится с `UV_INSTALL_DIR=/usr/local/bin`), PATH-правка только `/opt/memory/.venv/bin`. `docker-compose.yml`: bind-mounts `/root/.config/opencode`, `/root/.local/share/opencode`, `/root/workspace`, `/root/.ssh`; `/root/.serena` НЕ покрыт mount'ами (не персистентен). `.opencode/opencode.json` mcp-секция: browser, context7, antidetect-browser, integrations (строки ~440-473); `agent.memory-syncer` уже имеет tools-map. `.dockerignore`: `app_data/`, `.git`, `**/node_modules`. Принятые при планировании решения (не пересматривать): Serena ставится latest (без пина версии); конфиг Serena версионируется в репо и запекается в образ через COPY; собственная память Serena отключается через `excluded_tools` в её конфиге (конфликт с нашей opencode-memory недопустим); режим `--context ide` (отключает дубли с встроенными инструментами opencode: create_text_file, read_file, execute_shell_command, find_file, list_dir); memory-syncer не получает serena_*; ALLOWED-список оркестратора в AGENTS.md НЕ расширяется; новых ADR-файлов в docs/decisions не создавать. ## Задача 1. Gate-шаг (записать вывод в PR body секцией ## Watch out): открыть https://opencode.ai/docs/lsp/ и сверить возможности встроенного LSP opencode с символьным ядром Serena (find_referencing_symbols, find_implementations, rename_symbol, safe_delete_symbol, replace_symbol_body, insert_before/after_symbol, get_symbols_overview, get_diagnostics_for_file). Если встроенный lsp-tool уже покрывает references/diagnostics — оставить Serena только для rename/safe_delete/replace_body/insert_* и зафиксировать это в gate-заключении. 2. Новый файл `docker/serena_config.yml` (версионируется в репо): ```yaml excluded_tools: - write_memory - read_memory - list_memories - edit_memory - delete_memory - rename_memory gui_log_window: False web_dashboard_open_on_launch: False ``` 3. `Dockerfile`: после строки установки uv добавить `RUN UV_TOOL_BIN_DIR=/usr/local/bin uv tool install -p 3.13 serena-agent` (latest, без пина) и `COPY docker/serena_config.yml /root/.serena/serena_config.yml` (выполняется под root, дом = /root). Проверить, что `docker/serena_config.yml` не попадает под .dockerignore. 4. `.opencode/opencode.json`: в `mcp` добавить сервер `serena`: `{"type": "local", "command": ["serena", "start-mcp-server", "--context", "ide", "--project-from-cwd", "--enable-gui-log-window", "false", "--open-web-dashboard", "false"], "enabled": true, "timeout": 300000}`. В `agent.memory-syncer.tools` добавить `"serena_*": false`. 5. `AGENTS.md`: новая секция `## Символьная навигация (Serena)` — жёсткие императивные триггеры в CRITICAL-стиле: (а) ПЕРЕД изменением сигнатуры/контракта публичного символа — ОБЯЗАТЕЛЬНО `find_referencing_symbols`; (б) переименование/удаление символа — ТОЛЬКО `rename_symbol`/`safe_delete_symbol`, НЕ sed/текстовый replace; (в) ПОСЛЕ правок файла — `get_diagnostics_for_file`. Правка в workspace clone `/root/workspace/opencode-config/`, sync по процедуре из skill `configure-opencode`. 6. `.opencode/agents/reviewer.md`: дубль той же секции + запись в существующую секцию «Known deterministic links» (строки ~403-421) про триггеры Serena. 7. `.opencode/skills/configure-opencode/SKILL.md`: в sync-процедуру добавить упоминание, что правки `Dockerfile` требуют `docker compose up -d --build` (а не только `restart`). 8. `docker-compose.yml` и README не меняются. ## Контракты - MCP-запись: имя сервера `serena`; type local; команда ровно как в п.4; timeout 300000 (старт LSP медленный). - opencode.json остаётся валидным JSON после правки (jq parse). - `docker/serena_config.yml` — ключи ровно как в п.2 (snake_case, boolean YAML). - AGENTS.md — секция на русском, императивный тон, ≤15 строк. ## Инварианты - Serena latest, никаких пинов версии. - Память Serena (`*_memory` точнее write/read/list/edit/delete/rename) недоступна ни одному агенту — глушится Serena-side в одном месте (serena_config.yml), НЕ per-agent. - `memory-syncer`: все `serena_*` запрещены. - Любые правки конфига ТОЛЬКО в workspace clone `/root/workspace/opencode-config/`, никогда в `~/.config/opencode/` напрямую. - Новых файлов в `docs/decisions/` не создавать. ## Граничные случаи - Первый старт pyright через uvx докачивает зависимости в слой контейнера — после recreate первый ответ медленный (минута-две), это норма. - `--project-from-cwd`: если от cwd нет `.git`/`.serena` — проект не активируется, сервер предложит activate_project; в `--context ide` activate_project отключён при стартовом проекте — задокументировать в AGENTS.md-секции одной строкой, если gate подтвердит. - Образ не собирается (uv/PyPI недоступен) — падает build, чинить в этом же PR. - Gate выявит большое перекрытие со встроенным LSP — зафиксировать в PR body и сузить scope (см. п.1), НЕ убирая MCP-запись целиком. ## Влияние на связанные компоненты - `tests/test_permissions.py` (ключи agent.tools поимённые — добавление `serena_*` не ломает) и `tests/test_agent_frontmatter.py` (пинят только frontmatter reviewer/memory-syncer): зелёные обязательны. - CI `.github/workflows/permissions-check.yml` триггерится по путям `.opencode/opencode.json` и `.opencode/agents/**` — проверок по mcp-сеции нет, нарушений быть не должно. - `.opencode/skills/configure-opencode/SKILL.md` — paired update (п.7). - `reviewer.md` — paired update (п.6). - AGENTS.md ALLOWED-список оркестратора — НЕ меняется. - README — правок не требует (MCP-серверы не перечислены). ## Вне scope - Пин версии Serena (отклонено: latest). - Bind-mount для `/root/.serena` (отклонено: конфиг запечён в образ). - Доступ к web dashboard с хоста (listen 0.0.0.0) — не делаем. - Issue про ADR-указатели — отдельный issue/PR. - Переопределение встроенных агентов explore/build/general md-файлами — инвазивно, не делаем (получат секцию через AGENTS.md). ## Критерии приемки - [ ] `docker build` образа успешен; в образе `serena --help` отрабатывает из /usr/local/bin. - [ ] В образе существует `/root/.serena/serena_config.yml` с 6 записями в excluded_tools. - [ ] `jq empty .opencode/opencode.json` проходит; `pytest tests/` (test_permissions.py, test_agent_frontmatter.py) зелёные. - [ ] AGENTS.md содержит секцию «Символьная навигация (Serena)»; reviewer.md содержит дубль + запись в «Known deterministic links». - [ ] PR body содержит gate-заключение по сравнению со встроенным LSP opencode в секции ## Watch out. - [ ] CHANGELOG-запись (русская строка) по стандартному release-флоу репо.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/opencode-config#70
No description provided.