AltoRank: open-source, self-hosted AI SEO content writer (альтернатива Outrank)
Открытая альтернатива Outrank и Jasper. AltoRank исследует
ключевое слово, пишет статью, оценивает её и проверяет факты: если в тексте
приведена цифра со ссылкой на страницу, AltoRank ищет эту цифру на указанной
странице. Если источник не найден, система отмечает её для проверки
редактором. Любой черновик можно скопировать в формате Markdown (включая
front matter) или HTML либо скачать как файл .md, чтобы затем разместить
там, где вы публикуете материалы.
После одобрения скопируйте и разместите статью, затем нажмите **«Отметить как
опубликованное»** — AltoRank сохранит URL опубликованной страницы и начнёт
отслеживать её индексацию и позиции.
AltoRank никогда не публикует материалы на вашем сайте без зафиксированного
одобрения от конкретного человека. Одобряйте каждый черновик вручную или
настройте правило: оно одобрит черновик по истечении периода ожидания, если
вы не приостановите публикацию. Правило публикует материалы через подключение
к CMS. Эта возможность реализована, но пока не прошла полную сквозную проверку;
подробности — в разделе «Статус».
Агенты могут проводить исследования и создавать черновики через MCP-сервер и
API агента.
Ни один из них не может одобрить материал или опубликовать то, что человек
предварительно не одобрил. Единственный вызов, связанный с публикацией, повторно
запускает неудачную публикацию уже одобренной статьи.
Размещайте AltoRank на собственном сервере бесплатно по лицензии AGPL-3.0
или пользуйтесь размещённым приложением на app.altorank.co.
Весь продукт — с открытым исходным кодом. Нет тарифов с ограничением
возможностей и каталога ee/.
Статус
Размещённое приложение на app.altorank.co — это код из данного репозитория,
развёрнутый из main
(docs/deploy.md). При самостоятельном размещении используется тот же код, но с вашей Supabase и вашими
API keys. Исследования, создание черновиков, оценка, проверка фактов, аудит,
отслеживание позиций и синхронизация с Search Console / Bing уже работают;
подробности приведены в таблице ниже. Пока не завершены следующие задачи:
-
Платящих клиентов и примеров успешного внедрения пока нет. К продукту
не привязаны показатели роста — и это сделано намеренно.
-
**Публикация через CMS реализована, но пока не прошла полную сквозную
проверку.** В
apps/web/lib/cms/находятся тринадцать адаптеров, а формаподключения охватывает их все. Однако публикацию ни одного из них на
работающем сайте ещё не проверяли, поэтому плитки платформ на странице
/connectпредлагают запросить интеграцию, а не подключиться к ней. Ужесейчас любой черновик можно скопировать в формате Markdown или HTML.
Подробности — в разделе «Что уже работает».
-
Отслеживание видимости в AI реализовано, но пока не включено. Проверка,
еженедельная cron-задача и страница
/geoготовы, однако в приложениипока нельзя включить отслеживание для рабочего пространства или добавить
запросы, по которым оно будет выполняться. Поэтому в боковом меню эта
функция помечена как «скоро» (
apps/web/lib/constants.ts). -
CLI можно опубликовать, но в npm его пока нет.
packages/altorank-cliсобирает
apps/web/scripts/cli.tsв исполняемый файлaltorank(послепубликации можно будет выполнить
npx altorank auth whoami). До этогокоманда
npm run cliиз каталогаapps/webзапускает тот же API агентаиз локальной копии репозитория.
skills/altorank/SKILL.md— файл навыка,который читает coding agent; его можно установить с помощью
npx.Подробности приведены ниже.
Здесь можно узнать, как работает продукт, запустить его самостоятельно или
отправить исправление.
Принцип одобрения публикации
Есть один контрольный этап и два способа его пройти. lib/publishing/core.ts
отклоняет любую статью, которая не имеет статуса approved или scheduled
и значения approved_by. Эти столбцы заполняет только сервер: собственный
клиент базы данных пользователя, даже если тот вошёл в систему, не может
перевести статью в статус одобренной, запланированной или опубликованной
(миграция 109). Изменение одобренного текста возвращает статью на проверку.
Одобрить материал можно одним из следующих способов:
-
Человек — через редактор (
approveArticle); имя одобрившего сохраняетсяв
approved_by. Кнопка проверяет, что у пользователя активен план, и непозволяет одобрить материал с неподтверждённой цифрой без источника.
-
Правило, включённое названным участником учётной записи (
auto_approve,миграция 079). Cron-задача публикации выполняет более строгие проверки,
чем кнопка одобрения: активный план, настроенное место для публикации,
отсутствие цифр без источников, отсутствие ожидающего подтверждения
именованного редактора, отсутствие не пройденных пунктов аудита и оценка
SEO не ниже заданного порога. Проверки выполняются по окончании периода
ожидания (по умолчанию — 24 часа); в письме о создании черновика есть ссылка
«Приостановить». В
approved_byуказывается пользователь, включившийправило, а
approval_kindполучает значениеauto.Причина приостановки черновика сохраняется в его записи. См.
lib/publishing/auto-approve.ts.
Статус live устанавливается после публикации одобренной статьи, при нажатии
кнопки «Отметить как опубликованное» для одобренной статьи, а также в одном
случае, не связанном с публикацией: ночная проверка уже размещённых материалов
(lib/found-on-site/detect.ts) отмечает черновик как опубликованный, если его
текст уже есть на собственном сайте клиента. Так фиксируется действие,
выполненное вне AltoRank: система ничего не отправляет в CMS, не регистрирует
одобрение, а отметку можно отменить в редакторе.
Агент не может одобрить материал. **Ни один инструмент MCP или вызов API агента
не одобряет статью и не публикует черновик** — такие функции не отключены, а
вообще отсутствуют. Единственный вызов, связанный с публикацией, —
altorank_retry_publish (POST /articles/{id}/retry-publish): он повторно
запускает неудачную публикацию статьи, уже одобренной человеком, и отклоняет
все остальные запросы. Все инструменты MCP зарегистрированы в
apps/web/lib/mcp/server.ts, а инструкции этого сервера сообщают агенту об
этом ограничении.
Конкурирующие инструменты используют в описаниях фразу «вы сохраняете
контроль». Здесь это можно проверить: каждая запись со статусом live
относится к статье, одобренной нажатием кнопки или правилом, либо к материалу,
который уже был опубликован на собственном сайте клиента.
Что уже работает
| Исследование ключевых слов и анализ SERP | DataForSEO |
| Аудит домена | 9 проверок готовности, сканирование, PageSpeed |
| Создание статей | исследование → черновик → оценка → проверка фактов |
| Голос бренда | профили голоса бренда для каждого рабочего пространства |
| Публикация | экспорт любого черновика в Markdown и HTML; 13 адаптеров (см. ниже), реализованных, но ещё не прошедших полную сквозную проверку |
| Локали | 35 (apps/web/lib/seo/locales.ts) |
| Отслеживание позиций | запланированные проверки SERP |
| Аналитика поиска | Google Search Console; Bing Webmaster Tools (клики и показы по дням) |
| Видимость в AI | пока не включена: инструменты реализованы (lib/geo/, еженедельный /api/cron/geo, страница /geo) для отслеживания того, упоминают ли AI-ответы ваш сайт и какие сайты называют вместо него, но включить отслеживание для рабочего пространства пока нельзя |
Направления публикации (apps/web/lib/cms/adapter.ts) — тринадцать адаптеров
для десяти CMS-платформ. WordPress поддерживается двумя способами, а
git и webhook используются как направления публикации, но не являются
CMS. Поддерживаются Framer, Ghost, git, HubSpot, Magento, Notion, Shopify,
Webflow, webhook, Wix, WooCommerce, WordPress и плагин WordPress — второй,
рекомендуемый способ работы с WordPress. Он устанавливает плагин и использует
токен для конкретного сайта вместо пароля приложения
(apps/web/lib/cms/wordpress-plugin.ts), поэтому WordPress указан дважды.
Пока ни один из тринадцати адаптеров не прошёл полную сквозную проверку на
работающем сайте. Поэтому набор CONNECTABLE_CMS в
apps/web/lib/cms/connectable.ts намеренно оставлен пустым, а на каждой плитке
CMS на странице /connect вместо кнопки «Подключить» предлагается запросить
интеграцию. Если добавить идентификатор в этот набор, для соответствующей
плитки снова появится кнопка подключения. Сама форма подключения не менялась
и по-прежнему охватывает все тринадцать адаптеров. Её можно открыть с помощью
кнопки «Новое подключение» на странице, панели публикации черновика или
параметра /connect?connect=. Если подключение не настроено, любой черновик
можно скопировать из редактора в формате Markdown (включая front matter) или
HTML либо скачать как файл .md.
Установка плагина
Claude Code. Выполните в терминале:
claude plugin marketplace add AltoRank/altorank
claude plugin install altorank@altorank
Или в сеансе Claude Code: /plugin marketplace add AltoRank/altorank,
затем /plugin install altorank@altorank.
В plugins/altorank/ находятся размещённый MCP-сервер
(https://app.altorank.co/api/mcp, OAuth, API key не нужно копировать) и
навык, предназначенный для работы с этими инструментами. В той же папке
находится переносимая конфигурация plugin.json + mcp.json, которую читают
ChatGPT и Codex, а в .agents/plugins/marketplace.json плагин указан для них.
Установка навыка
npx skills add AltoRank/altorank
Команда размещает skills/altorank/SKILL.md там, где его смогут прочитать
Claude Code, Cursor, Codex, Copilot, Windsurf, Gemini CLI, Cline и другие
агенты, поддерживаемые skills CLI.
Навык учит агента работать с API агента (/api/agent/v1): проверять ключ,
оценивать готовность сайта, просматривать список ключевых слов или предлагать
новые, создавать черновик для очереди проверки человеком, редактировать
черновик с помощью поиска и замены, а также менять план публикаций. Агент не
может одобрять, удалять или публиковать черновики: таких вызовов в API нет.
Единственный вызов, связанный с публикацией, повторно запускает неудачную
публикацию статьи, уже одобренной человеком.
Для работы нужен API key. Создайте его в разделе /settings/api-keys панели
управления и задайте в переменной ALTORANK_API_KEY. При самостоятельном
размещении также укажите ALTORANK_BASE_URL. В skills/altorank/commands/
находятся пять простых slash-команд для наиболее частых вызовов. Skills CLI
не регистрирует slash-команды, поэтому, если они нужны, скопируйте их в
.claude/commands/ (Claude Code) или в соответствующий каталог вашего агента.
Запуск
Требуется Node 22+ и проект Supabase — локальный, запущенный через Docker, или размещённый в облаке.
Полное руководство по развёртыванию — в docs/deploy.md, включая облачный и самостоятельный варианты. Оценка Cloudflare приведена в docs/deploy-cloudflare.md.
npm install
cp docker/.env.example apps/web/.env.local # every variable, with what each one enables
npm run dev
Чтобы самостоятельно размещённая установка работала полностью, заранее укажите:
-
URL Supabase, анонимный ключ и
SUPABASE_SERVICE_ROLE_KEY. -
NEXT_PUBLIC_APP_URL— адрес приложения, который открывают пользователи. На его основе формируются все ссылки в письмах: подтверждение регистрации, приглашения и сброс пароля. Этот адрес также встраивается в образ Docker, поэтому задайте его до запускаdocker compose up --build: без него compose откажется собирать образ. -
ANTHROPIC_API_KEY. -
ENCRYPTION_KEYиCRON_SECRET(для каждого можно выполнитьopenssl rand -hex 32).
docker compose откажется запускаться без CRON_SECRET, а без этого ключа не будут выполняться запланированные задачи.
RESEND_API_KEYиRESEND_FROM_EMAIL— адрес отправителя на домене, подтверждённом в вашей учётной записи Resend. Подтверждение регистрации выполняется по электронной почте, поэтому без этих переменных пользователи не смогут создать учётную запись или сбросить пароль.
Для получения данных об объёме поисковых запросов и отслеживания позиций добавьте DATAFORSEO_LOGIN и DATAFORSEO_PASSWORD. Без них соответствующие этапы будут пропущены, а не завершатся ошибкой. Все остальные переменные в примере необязательны; каждая отключает ровно одну функцию. В файле указано, какую именно. Продуктовая аналитика также необязательна и настраивается двумя переменными NEXT_PUBLIC_POSTHOG_* — токеном проекта и хостом. Если их не задать, в консоли браузера появится сообщение об отключённой аналитике, но остальное приложение продолжит работать без изменений.
Другие команды:
npm run test # vitest, unit tier: mocks only, needs no services
npm run test:db # vitest, db tier: *.db.test.ts against the local Supabase only
npm run smoke # research → prompt → model → fact check, against real APIs
Из каталога apps/web:
the agent-readiness checks on their own">
npm run mcp # MCP server over stdio, for driving the engine from an AI assistant
npm run cli -- --help # the agent API from a shell; auth with ALTORANK_API_KEY
npm run readiness -- <domain> # the agent-readiness checks on their own
Размещённая конечная точка MCP
Запущенное приложение предоставляет те же инструменты по адресу /api/mcp через Streamable HTTP. Поэтому MCP-клиенту достаточно добавить один URL в качестве коннектора — запускать сервер stdio не нужно. Для размещённой установки используйте https://app.altorank.co/api/mcp, а при самостоятельном размещении — собственный origin. Для аутентификации нужен bearer-токен: API-ключ из /settings/api-keys или токен, выданный встроенным OAuth-процессом:
- обнаружение по адресам
/.well-known/oauth-authorization-serverи
/.well-known/oauth-protected-resource/api/mcp
-
динамическая регистрация клиентов по адресу
/api/oauth/register(только публичные клиенты и PKCE S256) -
запрос согласия по адресу
/oauth/authorize; доступен только владельцу или администратору, разрешение на запись предоставляется по желанию -
получение токена по адресу
/api/oauth/tokenс использованием grant типа authorization code; refresh token не выдаётся
Токен, который получает коннектор, хранится как запись api_keys (миграция 080). Его можно просматривать, задавать срок действия и отзывать на странице /settings/api-keys, как и любой другой ключ.
Claude Code регистрирует коннектор командой
claude mcp add --transport http altorank https://app.altorank.co/api/mcp;
ChatGPT и Claude.ai принимают тот же URL в качестве пользовательского коннектора.
Ни CLI, ни MCP-сервер не могут одобрить статью или удалить что-либо. Дело не в настройках: в API для агентов нет такого вызова и вообще нет обработчика DELETE. Также ни один из них не может публиковать статьи: единственная конечная точка, обращающаяся к CMS, — POST /articles/{id}/retry-publish. Она повторно запускает публикацию, которую человек уже одобрил, но которая завершилась ошибкой. Статьи в статусе черновика или на проверке отклоняются; в ответе вызывающему предлагается передать их человеку (apps/web/app/api/agent/v1/articles/[id]/retry-publish/route.ts:13-35).
База данных
В apps/web/supabase/ находятся файл config.toml и миграции с номерами, которые применяются по порядку. Чтобы использовать Supabase CLI:
cd apps/web
supabase start # local Postgres + auth; applies the migrations, prints the URL and keys for .env.local
При первом запуске supabase start применяет все миграции к локальной базе данных. Команда supabase db reset применяет их заново с нуля. Не запускайте supabase db push для локального окружения: эта команда предназначена для связанного удалённого проекта.
Для размещённого проекта сначала выполните supabase link --project-ref , затем — supabase db push. Без миграций приложение не сможет нормально работать: все запросы обращаются к созданным ими таблицам.
В docker/ находится конфигурация контейнера — её можно использовать, если вы не хотите запускать Node напрямую.
Структура
apps/web/ the engine and dashboard (Next.js)
app/(dashboard)/ dashboard routes
lib/audit/ domain analysis, readiness checks
lib/seo/ recommendations, scoring, locales, topical profile
lib/content/ generation (one implementation, shared by route + cron)
lib/ai/ fact checking
lib/cms/ 13 publishing adapters
lib/geo/ AI-answer visibility
scripts/mcp.ts MCP server
scripts/cli.ts CLI over /api/agent/v1
plugins/altorank/ Claude / ChatGPT / Codex plugin: hosted MCP server + skill
skills/altorank/ the skill file a coding agent reads (`npx skills add AltoRank/altorank`)
packages/altorank-cli/ npm package `altorank`: bundles scripts/cli.ts into a bin
docker/ container setup for self-hosting
tools/agent-readiness/ standalone agent-readiness scanner
Лицензия
GNU AGPL-3.0-only. Полный текст — в файле LICENSE.
На практике вы можете самостоятельно размещать проект, использовать его для своих клиентов и вести коммерческую деятельность — при этом не нужно ничего раскрывать или публиковать. Обязательство распространяется только на тех, кто распространяет изменённую версию продукта. Если вы измените исходный код и предоставите эту версию другим пользователям через сеть, изменения нужно будет опубликовать на условиях той же лицензии.
Пользоваться учётной записью можно бесплатно и без дополнительных обязательств. Нельзя лишь перезапускать изменённую копию как закрытый конкурирующий сервис.
Участие в разработке
Мы приветствуем сообщения о проблемах и pull request. Однако есть два условия, при нарушении которых исправление будет отклонено независимо от качества кода:
-
Добавление способа публикации, которую нельзя связать с конкретным человеком — например, публикации по клику или по правилу, заданному участником с указанным именем и возможностью отменить действие. Типичный пример — публикация, запускаемая агентом.
-
Добавление утверждения, которое нельзя подтвердить по содержимому репозитория. Если поиск с помощью
grepне находит функцию, README не должен о ней упоминать.
Правила оформления кода, по которым рассматриваются изменения, и сведения о связи этого репозитория с сайтом продукта приведены в CONTRIBUTING.md.