Год подряд SEO-плагины к нейросети сводились для меня к одной связке: Claude Code плюс несколько MCP-серверов — Search Console, DataForSEO, выгрузки краулера. Модель тянет цифры сама, а не сочиняет их. Потом DeepSeek представила свой агентный харнесс, DeepSeek Harness — коротко dsh, — и встал очевидный вопрос: можно ли утащить туда весь набор, платить по прайсу DeepSeek и не переучиваться заново ни самому, ни проектам.
Коротко — да, и почти без потерь. А теперь по слоям.
Это запускатель профилей. Профиль — стопка плагинов в заданном порядке плюс ваш слой правок сверху, файл cordis.patch.yml в папке профиля. В поставке уже есть веб-интерфейс, headless для разовых заказов и режимы под автоматизацию. Ставится из npm, пакет @deepseek-ai/dsh.
Сразу оговорюсь: сейчас это версия 0.1.5, релиз-кандидат. Документация подробная, но на боевых задачах я бы держал рядом старый клиент — мало ли что сменится между версиями.
SEO-набор в любом харнессе держится на трех слоях: где брать данные, по каким правилам их обрабатывать и что делать, если модель свернула не туда. Разберу каждый.
За этот слой отвечает плагин dsh-mcp-client. Одна запись в конфиге — один сервер, никаких прослоек. Так выглядит DataForSEO, запущенный локально:
- insert:
- id: mcp-dataforseo
name: '@deepseek-ai/dsh-mcp-client'
config:
serverName: dataforseo
transport: stdio
command: npx
args: ['-y', 'dataforseo-mcp-server']
env:
DATAFORSEO_LOGIN: !!js process.env.DATAFORSEO_LOGIN
DATAFORSEO_PASSWORD: !!js process.env.DATAFORSEO_PASSWORD
Облачные сервисы вроде Ahrefs или Semrush цепляются точно так же, только вместо stdio прописываете transport: streamable-http и адрес. Ключи уходят через переменные окружения, в файл профиля их заносить не стоит.
Теперь то, что разумно проверить до миграции:
toolCallTimeoutMs эту планку поднимает.failOnStartupError: true, чтобы падение было честным.Приятный бонус: имена инструментов совпадают с Claude Code — mcp__dataforseo__.... Все, что завязано на эти названия, — правила разрешений, привычный текст задач — переезжает без правок.

Сервер приносит числа, но не знает ваших внутренних договоренностей: какой длины title, что делать с дублями, по какому признаку разносить фразы по разным посадочным. Раньше все это сидело в длинной подсказке, и каждый писал ее по-своему. В dsh для этого есть навыки — те же skills, что в Claude Code.
Навык — это папка с файлом SKILL.md или просто файл <имя>.md в одном из корней, которые харнесс прочесывает:
.dsh/skills в корне проекта;.agents/skills там же;$DSH_HOME/skills — общие навыки пользователя.В начале файла идет шапка с обязательными полями name и description. Модель по описанию решает, когда навык пригодился, а тело подхватывает только в этот момент. Вот пример:
---
name: semantika-klastery
description: Разбор выгрузки Вордстата на группы под посадочные страницы
---
1. Читай выгрузку целиком, не кусками.
2. Фразы на одну страницу, только если выдача по ним совпадает.
3. В конце сверь число строк на входе и на выходе. Не сошлось — задача не сделана.
Третий пункт я теперь вставляю в каждую пакетную задачу. Модель умеет молча вычистить сто строк из пятисот и доложить, будто справилась целиком. Парный счетчик на входе и выходе ловит такое надежнее, чем перечитывание отчета.
И две мелочи в плюс. Тело навыка читается заново при каждой загрузке, так что правило можно чинить прямо по ходу дела, без рестарта. А папку .claude/skills харнесс по умолчанию не трогает. Если навыки уже сложены туда, укажите ее в customSkillDirs — копировать лишний раз не придется.
Главное, что я запомнил за год возни с плагинами: первые месяц-два не давайте модели права на запись. Пусть смотрит и предлагает, а правит человек. В Claude Code это держится на хуках, и dsh тут радует: есть мост dsh-hooks-claude-code, который гоняет ваш готовый hooks.json без переписывания.
- insert:
- name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: ./.claude/hooks.json
projectDir: .
Основные события работают: PreToolUse блокирует вызов инструмента или требует подтверждения, PostToolUse возвращает модели результат с замечанием, Stop заставляет сделать еще шаг, если проверка не прошла. Хук «не трогай CMS без меня» и хук «не заканчивай, пока счетчики не сошлись» переезжают как есть. Ограничение одно: мост понимает только командные хуки, то есть те, что запускают внешнюю программу.
Для регулярных задач есть профиль headless: одна задача, один ответ, выход.
dsh --profile headless "Сверь страницы из карты сайта с кодами ответа и закрытием в robots. Итог — таблица."
Эту строку удобно вешать в планировщик раз в неделю. Задача стартует в текущей папке — там же лежат навыки проекта, — а сессия сохраняется: утром открываете и видите, что агент делал и где запнулся.
DeepSeek дешевле не только по прайс-листу. У агента, который подолгу сидит в одном проекте, почти весь вход — это чтение кэша: инструкции, описания инструментов, история шагов. Кэш у DeepSeek стоит копейки, особенно вне пиковых часов.
Но у MCP есть и минус: описания всех инструментов подключенного сервера летят в каждый запрос. Сервер на полсотни инструментов — постоянная надбавка к каждому шагу. Пока список не менялся, этот кусок остается одинаковым и оседает в кэше. Стоит серверу обновить список инструментов, как кэш сбивается с этого места и дальше.
Отсюда простое правило: не подключайте все разом. Заведите отдельный профиль под семантику и отдельный под технический аудит, в каждом — только нужные серверы. Для dsh это ложится само собой: профиль и есть такая стопка.
Переезд SEO-набора на DeepSeek Harness — это скорее перекладывание файлов, чем переделка:
SKILL.md, старую папку достаточно указать в настройках;hooks.json работают через мост, если они командные;headless, для разных задач — разные профили.Остается то, что не зависит ни от какого харнесса: модель приносит строки, а не решения. Что продвигать, от чего отказаться и что сказать клиенту — это по-прежнему ваша работа.
Удалось как то налить им, 900~ фтд где-то вышло. До сих пор даже капает. Может чуть позже еще вернусь снова по ревшаре полить, а то в кейсах у коллег уж больно сладкие RD, надо проверить.
Ребята аффы написали вчера говорят вернуться траф дать)) ну отзыв попросили оставить, мне в целом не сложно, но вот как есть)