Skip to main content
Glama

seo-factory-mcp

MCP-сервер + скиллы для Claude Code: SEO контент-фабрика и цикл роста блога — без сервера и крона, агент запускается когда вы просите.

Работает с любым сайтом, реализующим zaytsv-совместимый article-API (см. контракт): переписали клон под другую тематику, оставили эндпоинты — подключается одной командой add_site. Сайтов может быть несколько.

  • 📝 Публикация с валидацией — errors блокируют, warnings предупреждают: FAQ-секция (FAQPage-разметка), обложка первой картинкой (переживает PUT), title ≤60, description ≤160, внутренние ссылки

  • 🔗 Перелинковка — тематический скоринг (тот же, что виджет «Читайте также» на сайте): статьи-сироты без входящих ссылок + доноры, готовые markdown-сниппеты

  • 🔍 Майнинг «второй страницы» — сопоставление запросов Яндекс.Вебмастера со статьями: что дожать, что написать (пара к MCP yandex-marketing)

  • 🧾 Контент-аудит — без FAQ, короткие, без обложки, мало ссылок

  • 📦 Без зависимостей — чистый Node ≥18, ставится и запускается сразу

Установка

Вариант A — плагин Claude Code (рекомендуется: тулы + скиллы-плейбуки):

/plugin marketplace add skiddgoddamn/seo-factory-mcp
/plugin install seo-factory@seo-factory

Вариант B — любой MCP-клиент через npx (только тулы, без скиллов) — см. examples/.mcp.json.

Related MCP server: claude-seo-kit

Подключение сайта

  1. Откройте <ваш-сайт>/articles/api, создайте токен (вид zmcp_…, показывается один раз).

  2. Скажите агенту: «подключи сайт https://ваш-сайт.ru с токеном zmcp_…» — он вызовет add_site (валидирует контракт и токен живыми запросами; невалидное не сохраняется).

  3. Конфиг: ~/.seo-factory-mcp/config.json (несколько сайтов, дефолтный, articlePath для блога не на /articles, yandexHost для цикла роста, hiddenTags для скрытых тем).

Быстрый старт без add_site: env SEO_FACTORY_BASE_URL (+ SEO_FACTORY_TOKEN). Read-only тулы (аудиты, списки, подбор ссылок) работают и вовсе без токена.

Использование

напиши и опубликуй статью про выбор CRM для малого бизнеса

Скилл seo-content-factory проверит дубли, соберёт перелинковку, напишет текст с FAQ и обложкой, провалидирует и опубликует.

что дожать в блоге по данным поиска?

Скилл seo-growth-loop возьмёт запросы позиций 8–30 из Вебмастера (если подключён yandex-marketing MCP), найдёт сирот, соберёт приоритизированный план и исполнит.

Тулы (13)

Тул

Что делает

setup

статус конфига и живой auth-probe по всем сайтам + онбординг

add_site

добавить/обновить сайт (живая валидация; alias, articlePath, yandexHost, hiddenTags)

list_articles

лёгкий список с фильтрами (tag/query), скрытые помечаются

get_article

полная статья по slug (id для update/delete — в ответе)

publish_article

валидация → POST; финальный slug/URL из ответа

update_article

resolve по slug → PUT; ловит затирание обложки; 403-готча

delete_article

⚠️ confirm:true; предупреждает: IndexNow об удалении не узнаёт

upload_image

картинка → URL (вставить ![](url) первой строкой = обложка)

validate_article

офлайн-линтер: errors/warnings/facts

audit_orphans

статьи-сироты + доноры (граф «Читайте также»)

audit_content

аудит полных тел: FAQ/длина/обложка/ссылки

suggest_links

тематически близкие + готовые сниппеты перелинковки

match_queries

запросы Вебмастера → «дожать slug» / «написать новую»

Большие входы/выходы — через файлы (contentFile, queriesFile, saveToFile), чтобы не гнать мегабайты через контекст модели.

Сосуществование с zaytsv-mcp

У zaytsv-mcp есть простые article_* тулы на тот же API. Если установлены оба плагина — для статей предпочитайте seo-factory: здесь валидация, защита обложки от PUT-затирания и перелинковка; article_* в zaytsv-mcp остаются для быстрых правок без SEO-обвязки.

Разработка

npm run check   # синтаксис всех .mjs
npm test        # 18 юнитов (node --test) + smoke по stdio

Тесты уводят конфиг в temp через SEO_FACTORY_CONFIG_DIR — живой ~/.seo-factory-mcp/config.json не трогается.

Публикация: тег vX.Y.Z → GitHub Actions (ассерт синка версий → тесты → npm publish --provenance).

Безопасность

  • Токен zmcp_… даёт полный доступ к аккаунту сайта (не только статьи). Не коммитьте его; в конфигах клиентов храните ссылку ${SEO_FACTORY_TOKEN}, не значение.

  • Файл конфига пишется с mode 0600 (на Windows это no-op — при необходимости ограничьте доступ ACL).

  • add_site не сохраняет токен, не прошедший живую проверку; отзыв — на <сайт>/articles/api.

Лицензия

MIT

Available Tools

13 tools
add_siteA

Добавить/обновить сайт в конфиге (существующий alias перезаписывается — так ротируется токен). Валидирует живьём: GET /api/articles/list (сайт реализует контракт) и, если передан token, GET /api/account/mcp-tokens (токен жив). Невалидное НЕ сохраняется. Первый сайт становится дефолтным. yandexHost принимает и URL, и host_id Вебмастера (https:site.ru:443 — двоеточия не опечатка), нормализуется сам. hiddenTags — темы, скрытые на самом сайте (напр. VPN на zaytsv.ru из-за РКН): исключаются из перелинковки/аудитов.

Inputs: alias (required), baseUrl (required), token, default, +4 more.

audit_contentA

Контент-аудит по ПОЛНЫМ телам (GET /api/articles/all — тяжёлый, на 400+ статьях мегабайты: всегда передавай saveToFile). По каждой статье: есть ли «## FAQ» (≥2 пар), длина < minWords, title>60, нет картинки-обложки в теле (уязвима к PUT-готче), <2 внутренних ссылок. В чат — сводка с приоритетами, полный список — в файл.

Inputs: site, minWords, saveToFile.

audit_orphansA

Статьи-сироты: на кого не ссылается ни одна «Читайте также» (тот же тематический скоринг, что на фронте: теги ×3 + слова заголовка ×1; count = размер блока на сайте, по умолчанию 3). Сирота = поисковик считает страницу неважной. К каждой сироте — до 2 статей-доноров, куда добавить входящую ссылку. Скрытые на сайте статьи (hiddenTags) исключены из графа. На большом сайте — saveToFile.

Inputs: site, count, saveToFile.

delete_articleA

⚠️ Удалить статью (DELETE /api/articles/{id}; resolve по slug). Требует confirm:true. 404 — нет статьи, 403 — чужая (админ-аккаунт может удалять чужие). После удаления IndexNow НЕ уведомляется — URL останется в индексе; при необходимости снять через Вебмастер.

Inputs: id, site, slug, confirm.

get_articleA

Полная статья по slug (публичный GET /api/articles/by-slug/{slug}): title, content (Markdown), excerpt, coverImage, tags, viewCount, id (нужен для update/delete), даты (LocalDateTime без таймзоны). Для больших статей — saveToFile.

Inputs: slug (required), site, saveToFile.

list_articlesA

Лёгкий список статей сайта (GET /api/articles/list — без content; поля: id, slug, title, excerpt, coverImage, tags, viewCount, authorName, createdAt; updatedAt там НЕТ). Фильтры на клиенте: tag (вхождение в теги, без регистра), query (подстрока заголовка). Скрытые на сайте статьи помечаются hidden:true. Пагинации на сервере нет — приходит всё; на большом сайте передай saveToFile.

Inputs: tag, site, query, saveToFile.

match_queriesA

Мост «Вебмастер → контент-план»: сопоставить поисковые запросы со статьями сайта. Вход: queries — массив строк ИЛИ объектов {query, shows?, position?}; queriesFile — JSON-файл того же формата (пиши его сам из ответа yd_webmaster_search_queries_popular: query_text→query, TOTAL_SHOWS→shows, AVG_SHOW_POSITION→position; фильтруй позиции 8–30 ДО вызова). По каждому запросу: score против всех статей → вердикт boost (дожать существующую, best.slug) или new (написать новую). Сортировка по shows desc.

Inputs: site, queries, saveToFile, queriesFile.

publish_articleA

Опубликовать НОВУЮ статью (POST /api/articles). Сначала гоняет validate_article: errors блокируют (обход skipValidation:true), warnings печатаются. content — Markdown; title можно не передавать, если content начинается с «# Заголовок» (сервер возьмёт и вырежет строку). ⚠️ Slug генерирует сервер (транслит + дата + счётчик коллизий) — узнаёшь его ТОЛЬКО из ответа; внутренние ссылки на новую статью ставь после публикации. Обложка = первая картинка в теле (, или голый URL с расширением) — иначе фолбэк-генератор сайта. IndexNow сервер пингует сам (fire-and-forget). Большой текст передавай через contentFile.

Inputs: site, tags, title, content, +2 more.

setupA

Статус конфига и авторизации по всем сайтам (живой лёгкий probe GET /api/account/mcp-tokens на каждый) + инструкция подключения, если пусто. Вызывай первым при ошибках доступа или если пользователь не знает, с чего начать.

Inputs: no named parameters.

update_articleA

Обновить статью (resolve по slug через публичный /by-slug → PUT /api/articles/{id}). Это НЕ upsert: нет статьи → ошибка с подсказкой про publish_article. ⚠️ ГЛАВНАЯ ГОТЧА: PUT стирает excerpt/coverImage/authorName и пере-выводит их из НОВОГО content — если у статьи была обложка, а в новом теле нет первой картинки, обложка пропадёт; тул это ловит и блокирует (обход skipValidation:true). Slug при PUT стабилен. tags: не передал — сохранились старые; передал [] — стёр. 403 = статья не найдена ИЛИ принадлежит другому аккаунту (бэкенд не различает).

Inputs: id, site, slug, tags, +4 more.

upload_imageA

Загрузить картинку статьи (POST /api/media/article-image, multipart): jpg/png/webp/gif/avif/svg, ≤10 МБ. Возвращает {url}. Вставь «» ПЕРВОЙ строкой тела — станет обложкой и переживёт будущие PUT (см. готчу update_article).

Inputs: filePath (required), site.

validate_articleA

Офлайн-линтер статьи БЕЗ сети: errors (пустой content; нет title и нет «# H1»; двойной H1) и warnings (title>60; первый абзац>160 — обрежется excerpt/description; нет «## FAQ» с ≥2 парами «### Вопрос» — не будет FAQPage-разметки; нет картинки-обложки в теле; голый URL без расширения — сервер не увидит обложку; <2 внутренних ссылок; заголовок без букв/цифр → slug no-title; тегов >6/длиннее 40). Возвращает и facts: слова, FAQ-пары, обложка, ссылки. Прогоняется автоматически внутри publish_article/update_article.

Inputs: site, tags, title, content, +1 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.1/5.0

    Scored across 13 tools

    Disambiguation5/5

    Each tool targets a distinct function: site config, article CRUD, audits, linking, validation, image upload, and query matching. No two tools have overlapping purposes; even similar-sounding ones like audit_content and validate_article serve different scopes (full site vs single article).

    Naming Consistency4/5

    Most tools follow a consistent verb_noun pattern (e.g., add_site, get_article, publish_article). The exception is 'setup', which is a single-word verb, breaking the pattern slightly. Overall, naming is clear and predictable.

    Tool Count5/5

    With 13 tools, the server is well-scoped for an SEO/content management domain. Each tool serves a clear purpose without redundancy, and the count falls comfortably within the ideal range of 3-15.

    Completeness4/5

    The tool surface covers the main workflows: site management, full article CRUD, multiple audit types, link suggestions, image upload, and query matching. Minor gaps exist, such as no tool for deleting a site or explicitly listing sites (though setup provides status), but these are non-critical.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers