EmDash — open-source CMS на TypeScript и Astro со структурированным контентом, изолированными плагинами и встроенными инструментами для ИИ-агентов. 28 сентября 2026 года проект выпустил стабильную версию 1.0 и вышел из ветки 0.x. На 3 октября актуален релиз 1.1.0 от 1 октября; ниже — текущая установка, устройство CMS и сохранённый разбор важных изменений 1.0.

📌
Статус на 3 октября 2026: актуальный стабильный релиз — EmDash 1.1.0 от 1 октября 2026 года, лицензия MIT. Ломающие изменения при переходе с 0.x собраны в официальном руководстве по обновлению; устаревшие имена разрешений плагинов продолжают работать весь цикл 1.x.
💡
MCP (Model Context Protocol) — открытый протокол, через который ИИ-агент получает доступ к данным и действиям внешней системы. В EmDash 1.0 MCP-сервер работает с OAuth 2.1 и гранулярными областями доступа, персональными токенами и device flow для CLI.
📌
Установка, API и ограничения сверены с текущей официальной документацией 3 октября. JSON-фрагмент плагина разобран локально; Astro API и команды проверены по документации. Собственный CMS-сайт и облачное размещение не запускались.

CMS — система управления содержанием: редактор меняет записи в админке, а сайт получает их для отображения. Astro отвечает за страницы и компоненты; EmDash — за контент, права и редакционный процесс. Руководство рассчитано на разработчика, знакомого с JavaScript/TypeScript и базовой работой в терминале.


Что нового в EmDash 1.0

НовшествоЧто это даёт
Стабильный релизПроект вышел из ветки 0.x. Код проверен эксплуатацией: официальный блог Cloudflare работает на EmDash с 12 августа 2026 года
Реестр плагиновКаталог plugins.emdashcms.com на децентрализованном протоколе AT Protocol; разработчик публикует релизы из собственного аккаунта и не зависит от владельца каталога
EmDash BuildОткрытая альфа-версия ИИ-конструктора сайтов: описание задачи превращается в Astro-сайт с базой данных и админкой EmDash
MCP с OAuthOAuth 2.1 + PKCE, персональные токены и device flow; агенту выдаются только нужные области доступа
Новая медиабиблиотекаБиблиотека медиа и изображений переписана к релизу 1.0
Навыки для агентовШаблоны по умолчанию содержат agent skills; отдельный репозиторий навыков помогает агенту строить сайт или портировать плагин с WordPress
Переводы интерфейсаСообщество перевело EmDash на 25 языков; контентные инструменты поддерживают локали для многоязычных сайтов
Уведомление об обновленияхАдминка показывает баннер о выходе новой версии со ссылкой на релиз-ноуты

Отдельный эффект дала миграция блога Cloudflare на EmDash. По принципу «customer zero» компания сначала перевела на CMS собственный блог и прогнала его через неделю запусков Agents Week: 28 публикаций за 9 дней, около 3 млн просмотров и пики до 450 RPS на воркере, а 10 августа инфраструктура отразила DDoS-атаку в 28 000 RPS. Созданные для этой миграции возможности теперь доступны всем пользователям: объектный кеш на KV, адаптер Hyperdrive и совместимость с Workers Cache.

В версии 1.1.0 добавлен календарь публикаций: опубликованные и запланированные записи отображаются в часовом поясе сайта, доступны месячная сетка и список. Пользователь с правом публикации может менять расписание; пропущенное время отмечается как Overdue. Это помогает редактору проверить план, но не заменяет проверку фактического выхода записи. Релиз 1.1.0.

Какие задачи решает EmDash

EmDash переносит привычную модель WordPress на современный TypeScript-стек. Темы остаются обычными Astro-проектами, контент хранится в структурированном формате Portable Text, а плагины выполняются в изолированной среде с явно заявленными разрешениями.

Мотивация понятна из статистики, которую команда проекта приводит со ссылкой на Patchstack: 96% уязвимостей WordPress приходятся на плагины. Доля относится к уязвимостям в цитируемой статистике; независимого замера в этом материале нет. Плагины WordPress работают в общем PHP-процессе. В EmDash sandbox-плагин получает только те возможности (capabilities), которые указаны в его манифесте и подтверждены администратором при установке. Изоляция ограничивает прямой доступ плагина заявленными возможностями. Содержимое, доступное по выданному разрешению, остаётся доступным коду плагина.

Основные возможности

ВозможностьЧто это даёт
Темы на AstroОбычные Astro-проекты с компонентами, Tailwind CSS и Islands для React, Vue или Svelte
Кастомные типы контентаКоллекции и поля задаются в seed-файле и админке; из схемы генерируются TypeScript-типы
Portable TextКонтент хранится как структурированный JSON и подходит для повторного использования в разных каналах
Изолированные плагиныSandbox-плагин работает в Dynamic Worker на Cloudflare или в отдельном процессе workerd на Node.js
Реестр плагиновУстановка из админки, проверка подписей и контрольных сумм; каталог может запустить любой оператор
Встроенный MCPИнструменты для контента, схемы, медиа, таксономий, меню и настроек; OAuth 2.1 с областями доступа; защита от конфликтов через _rev
REST API и CLIПолный доступ к сущностям сайта; команда emdash types генерирует типы из схемы
Импорт WordPressОфициальные руководства по миграции контента и портированию плагинов
Портируемое хранениеSQLite, PostgreSQL, D1 или Hyperdrive для данных; S3-совместимое API для файлов
Вход без пароляОсновной способ входа — passkey на базе WebAuthn; дополнительно GitHub, Google, Microsoft и Atmosphere
Публикация по расписаниюОтложенный выход материалов через админку, API и MCP
МногоязычностьРуководство по интернационализации и локали в инструментах контента
МонетизацияПакет @emdash-cms/x402 добавляет оплату доступа к контенту по протоколу x402

Как устроена архитектура

graph TD
    A["Браузер"] --> B["Astro — SSR / SSG"]
    B --> C["EmDash Integration"]
    C --> D["REST API"]
    C --> E["Админ-панель"]
    C --> F["Система плагинов"]
    D --> G["SQLite / PostgreSQL / D1 / Hyperdrive"]
    E --> G
    F --> H["Sandbox: Dynamic Workers или workerd"]
    H -.->|"только разрешённые capabilities"| D
    C --> I["R2 / S3 / локальное хранилище"]
    C --> J["MCP Server + OAuth"]
    J --> K["ИИ-агенты"]
    L["Реестр плагинов на AT Protocol"] --> F

Ключевые решения:

  • темы остаются обычными Astro-проектами;
  • sandbox-плагины не получают прямой доступ ко всей базе и файловой системе;
  • Portable Text хранит содержание как данные, а не как готовый HTML;
  • база, объектное хранилище и кеш подключаются через сменные адаптеры;
  • реестр плагинов отделён от каталога: записи о релизах хранятся в аккаунтах авторов.

Быстрый старт

Для установки нужен Node.js 22.16 или новее и один из пакетных менеджеров: npm, pnpm, yarn или bun. Проверьте версию командой node --version.

npm create emdash@1.1.0

Скаффолдер спросит платформу развёртывания, шаблон и пакетный менеджер. Для описанной ниже локальной проверки выберите имя my-emdash-site, платформу Node.js, шаблон Starter, npm и установку зависимостей Yes. Он запишет сгенерированный EMDASH_ENCRYPTION_KEY в файл .env. Вариант Cloudflare требует своей конфигурации платформы и развёртывания.

Перейдите в созданный проект:

cd my-emdash-site

Если установка зависимостей завершилась ошибкой, файлы проекта сохраняются. Выполните напечатанную генератором проекта команду повтора, затем продолжайте.

⚠️
Внимание: не коммитьте .env и сохраните EMDASH_ENCRYPTION_KEY до первого деплоя. Без этого ключа EmDash не сможет расшифровать сохранённые секреты плагинов.

Сгенерированный проект — обычный Astro-сайт. Конфигурация astro.config.mjs включает серверный рендеринг, адаптер платформы и подключение EmDash с базой SQLite и каталогом для медиа. Файл src/live.config.ts связывает контент с Live Content Collections, а seed/seed.json описывает коллекции и стартовое содержание. Во время разработки EmDash обновляет emdash-env.d.ts, так что редактор кода проверяет имена коллекций и полей.

Запрос коллекции на странице:

---
import { getEmDashCollection } from "emdash";

const { entries: posts, cacheHint } = await getEmDashCollection("posts", {
  orderBy: { published_at: "desc" },
});
---

<ul>
  {posts.map((post) => <li>{post.data.title}</li>)}
</ul>

Генерация TypeScript-типов из текущей схемы:

npx emdash types

Для удалённого сайта используйте emdash types --url <site-url> или переменную EMDASH_URL.

Как проверить установку

  1. Запустите npm run dev и откройте http://localhost:4321/_emdash/admin/.
  2. Setup Wizard предложит название сайта, таглайн и демонстрационный контент, затем запросит email и имя администратора.
  3. Зарегистрируйте ключ доступа (passkey) в диалоге браузера.
  4. После регистрации откроется панель администратора с разделами Posts и Pages.
  5. Откройте пост Welcome, измените заголовок и нажмите Save, затем Publish changes.
  6. Обновите главную страницу http://localhost:4321/: новый заголовок появился в списке. Промежуточное сохранение создаёт черновик, а посетители видят изменение только после публикации.
💡
Email при первоначальной настройке сохраняется без проверки. Для приглашений и входа по magic link позже настройте отправку почты по руководству Email Setup.

Вход и управление доступом

Passkey остаётся основным способом входа. EmDash использует WebAuthn: закрытый ключ не передаётся серверу EmDash, а учётные данные привязаны к домену сайта.

Дополнительно можно подключить GitHub, Google, Microsoft и Atmosphere (AT Protocol). Первые три провайдера включены в EmDash; провайдер Atmosphere устанавливается отдельным пакетом. Эти провайдеры работают вместе с passkey и подходят даже для создания первого администратора. На Cloudflare доступен отдельный режим Cloudflare Access. В production он полностью заменяет стандартный вход: passkey, OAuth, magic link, самостоятельная регистрация и приглашения при этом отключаются.

В EmDash пять ролей: Subscriber, Contributor, Author, Editor и Admin. Права наследуются от младших ролей к старшим. Те же роли учитываются и в MCP: токен с нужной областью доступа не сработает, если роль пользователя ниже требуемой.

Плагины и реестр

АспектWordPressEmDash
ИзоляцияРасширения работают в общем PHP-процессеSandbox-плагин запускается в отдельном Dynamic Worker на Cloudflare или в изолированном процессе workerd на Node.js
ДоступРасширение может обращаться к базе и файлам сайтаДоступ задаётся через capabilities и список разрешённых хостов в манифесте
Последствия компрометацииУязвимость расширения может затронуть весь сайтУщерб ограничен средой и выданными разрешениями
ЭкосистемаБольшой зрелый каталогМолодой реестр, запущенный вместе с 1.0; пока только бесплатные плагины

Фрагмент манифеста sandbox-плагина, который читает контент и отправляет уведомления в Slack. Полные обязательные поля и код hooks создайте по шаблону актуального plugin CLI:

{
  "slug": "slack-notify",
  "publisher": "did:plc:abc123def456",
  "capabilities": ["content:read", "network:request"],
  "allowedHosts": ["hooks.slack.com"]
}

Администратор видит запрошенные разрешения и хосты до установки, а среда исполнения удерживает плагин в этих рамках. Если хук требует незаявленного разрешения, EmDash пропускает его и пишет предупреждение в лог; большинство ошибок манифеста ловит pnpm exec emdash-plugin validate. Старые имена разрешений вроде read:content продолжают работать в течение 1.x, но при старте вызывают предупреждение с подсказкой нового имени.

Публикация в реестр построена на AT Protocol — протоколе, который обслуживает Bluesky. Каждый релиз является подписанной записью в аккаунте Atmosphere самого разработчика:

pnpm dlx @emdash-cms/plugin-cli init my-plugin
cd my-plugin
pnpm install
pnpm exec emdash-plugin validate

Генератор создаёт отдельную папку и добавляет plugin CLI в зависимости проекта. Следуйте README созданного шаблона, напишите код плагина и выполните предусмотренные им тесты. После успешной проверки можно войти в свой аккаунт издателя и опубликовать готовую версию:

pnpm exec emdash-plugin login alice.bsky.social
pnpm exec emdash-plugin publish

Замените alice.bsky.social на handle своего аккаунта Atmosphere. Команда publish создаёт внешний релиз; её выполняют после проверки версии, архива и разрешений плагина.

Перед установкой плагина сайт проверяет доказательство включения записи в подписанный коммит аккаунта, а затем сверяет контрольную сумму архива, имя, версию и запрошенные доступы. Каталог plugins.emdashcms.com модерирует тексты и изображения листингов, но не может подменить код: агрегатор, сервис модерации и загрузчик каталога открыты, поэтому любой оператор может поднять собственную витрину поверх тех же записей. Владелец плагина сохраняет историю релизов независимо от каталога.

⚠️
Ограничения sandbox на Cloudflare: для запуска нужен Worker Loader, доступный только на плане Workers Paid. Сайты с адаптером Hyperdrive sandbox-плагины пока не запускают: плагины получают данные через D1. Оба ограничения повторно подтверждены 3 октября. Кроме LOADER, Worker должен экспортировать PluginBridge; отсутствие binding или entrypoint не включит sandbox автоматически.

Текущая документация ограничивает время одного вызова 30 секундами на обеих платформах. На Cloudflare дополнительно принудительно ограничиваются 50 мс CPU и 10 подзапросов; Node.js эти два ограничения не применяет. Значение памяти 128 МБ не является отдельным принудительным лимитом каждого плагина: на Cloudflare действует общий предел isolate. Размер бандла и состав файлов проверяйте актуальным plugin CLI при подготовке релиза. Плагин, успешно прошедший локальную проверку, ещё нужно проверить на целевой платформе.

Работа через REST API и MCP

REST API доступен по пути /_emdash/api/. Запросы с API-токеном используют заголовок:

Authorization: Bearer <token>

Базовые операции с контентом:

GET    /_emdash/api/content/:collection
GET    /_emdash/api/content/:collection/:id
POST   /_emdash/api/content/:collection
PUT    /_emdash/api/content/:collection/:id
DELETE /_emdash/api/content/:collection/:id

API также охватывает медиа, ревизии, коллекции, поля, плагины, поиск, настройки, меню, таксономии и пользователей. Конкретная операция требует соответствующих прав пользователя и области действия токена.

MCP-сервер принимает JSON-RPC вызовы на POST /_emdash/api/mcp в режиме stateless Streamable HTTP. Поддерживаются три способа аутентификации:

СпособКак работает
OAuth 2.1 + PKCEСтандартный поток для MCP-клиентов; пользователь подтверждает области доступа в браузере
Personal Access TokenДолгоживущие токены ec_pat_*, создаются в админке
Device FlowПоток для CLI с подтверждением кода в браузере; используется командой emdash login

Области доступа делятся по доменам: content:read и content:write для контента, media:read и media:write для медиа, schema:read и schema:write для схемы, taxonomies:manage, menus:manage, settings:read и settings:manage, а также admin для полного доступа к ядру. Инструменты плагинов открываются отдельными областями mcp:tools и mcp:tools:<pluginId> и появляются в списке инструментов только после разрешения администратора; вызовы фиксируются в журнале аудита.

Инструменты сгруппированы в восемь доменов: контент, схема, медиа, поиск, таксономии, меню, ревизии и настройки. Есть операции публикации по расписанию (content_schedule), сравнения черновика с опубликованной версией (content_compare) и восстановления из корзины.

Изменение опубликованной записи через content_update создаёт черновик; посетитель продолжает видеть прежнюю версию. Перед публикацией сравните их через content_compare, затем отдельно вызовите content_publish. Запись и публикация — разные действия.

Для защиты от гонок content_get возвращает непрозрачный токен _rev. Передайте его в content_update вместе с изменениями: если запись успели поменять, сервер ответит CONFLICT. Агент должен перечитать запись, согласовать свою правку с новым содержимым и затем решать, нужно ли повторять операцию с новым токеном.

Обновление с 0.x до 1.0

Сначала сохраните резервную копию базы, медиа и конфигурации и проверьте обновление на отдельной копии сайта. Ниже команда из руководства по переходу на 1.x: --latest выбирает версии на момент запуска, поэтому просмотрите релиз-ноуты и зафиксируйте полученный lock-файл перед рабочим деплоем.

Обновите пакеты и пересоберите проверочную копию сайта:

pnpm up --latest emdash @emdash-cms/cloudflare
pnpm build

Если в деплое выполняется emdash migrate, запускайте его с файлом .emdash/migrations.json, созданным сборкой уже после обновления: манифест от ранней версии будет отклонён.

Что изменилосьЧто делать
Удалён cloudflareCache()Перейдите на cacheCloudflare() из @astrojs/cloudflare/cache: он работает через Workers Cache, а секреты CF_ZONE_ID и CF_CACHE_PURGE_TOKEN больше не нужны
Comments и CommentForm убраны из emdash/uiИмпортируйте их из emdash/ui/comments
Удалены команды emdash dev и emdash auth secretЗапускайте сайт через pnpm dev или astro dev; ключ шифрования секретов создаёт emdash secrets generate
Удалена опция experimental.registryПеренесите значение в верхнеуровневую опцию registry без изменений
Служебные entry points переехалиВсё внутреннее находится под emdash/internal/ и не является публичным API; для тестов плагинов используйте пакет @emdash-cms/plugin-test

После обновления сайт может собраться без правок. Если сборка падает, идите по списку ломающих изменений в официальном руководстве.

Полезные сценарии

CMS для нового сайта на Astro

Исходное условие: команда начинает новый Astro-проект и хочет редактировать контент без отдельной внешней CMS.

Создайте сайт скаффолдером, завершите настройку в админке и получайте записи через getEmDashCollection. Проверяемый результат: после Save и Publish changes изменённый заголовок виден на публичной странице без пересборки проекта; по документации Live Content Collections читают опубликованную версию при запросе страницы. Фактический запуск этого сценария в рамках подготовки материала не выполнялся.

Сценарий хуже подходит команде без опыта TypeScript и Astro или проекту, которому уже нужен большой каталог готовых тем и плагинов.

Управление контентом через ИИ-агента

Исходное условие: контент хранится в коллекциях EmDash, а агент подключён к MCP-серверу с ограниченными правами.

Создайте персональный токен с областями content:read и content:write или подключите клиента по OAuth. Агент читает запись через content_get, получает _rev, готовит изменение и отправляет его вместе с токеном ревизии. Проверяемый результат: запись обновляется только при совпадении версии; при параллельном изменении сервер возвращает CONFLICT, после чего агент перечитывает запись, сравнивает новое содержимое со своей правкой и только затем решает, нужно ли повторять операцию с новым _rev.

Для рабочего контура ограничьте права агента необходимыми операциями и не выдавайте область admin без конкретной задачи: она открывает все операции ядра.

Миграция с WordPress

Исходное условие: есть сайт на WordPress, а команда готова адаптировать тему и расширения под Astro и EmDash.

Действуйте по официальным руководствам: сначала анализ и импорт контента, затем перенос темы и портирование нужных плагинов. Команда EmDash приводит кейс Avulux: миграция микросайта заняла меньше дня благодаря навыкам для агентов из репозитория EmDash Agent Skills. Это оценка участников проекта, а не независимый замер.

Плагины WordPress напрямую не переносятся: их функциональность придётся заменить или переписать. Перед миграцией проверьте формат экспорта и состав данных, которые поддерживает актуальная версия импортёра.

Тарифы Cloudflare

EmDash бесплатен по лицензии MIT. При размещении на Cloudflare оплачивается инфраструктура. Значения ниже проверены 3 октября 2026 года по официальным страницам Cloudflare.

КомпонентБесплатный объёмWorkers Paid и использование сверх включённого
Workers100 000 запросов в сутки; 10 мс CPU на вызовМинимум $5 в месяц; 10 млн запросов и 30 млн CPU-мс включено, затем $0.30 за млн запросов и $0.02 за млн CPU-мс
D15 млн прочитанных и 100 000 записанных строк в сутки; 5 ГБ суммарного хранения25 млрд чтений и 50 млн записей включено в месяц; первые 5 ГБ хранения включены, затем $0.001 за млн чтений, $1 за млн записей и $0.75 за ГБ-месяц
R2 Standard10 ГБ-месяцев хранения, 1 млн операций Class A и 10 млн операций Class B в месяц, исходящий трафик бесплатен$0.015 за ГБ-месяц, $4.50 за млн операций Class A и $0.36 за млн операций Class B; исходящий трафик остаётся бесплатным
⚖️
Для sandbox-плагинов на Cloudflare нужен Worker Loader, а он входит только в Workers Paid: бесплатного плана для них недостаточно. Cloudflare периодически меняет цены и лимиты, поэтому перед расчётом бюджета сверьтесь со страницами Workers и R2.

EmDash также можно разместить на Node.js-сервере с SQLite или PostgreSQL и S3-совместимым хранилищем. В этом случае затраты определяются выбранным хостингом.

Когда EmDash пока не подходит

  • проект зависит от конкретных плагинов WordPress: реестр EmDash запущен вместе с 1.0, каталог молодой, а платных плагинов пока нет;
  • редакторам необходима зрелая библиотека блоков и расширений уровня WordPress;
  • в команде нет разработчика, знакомого с TypeScript и Astro;
  • сайт работает на Cloudflare с базой за Hyperdrive: sandbox-плагины там пока не запускаются;
  • sandbox-плагины нужны на бесплатном плане Cloudflare: Worker Loader требует Workers Paid;
  • вы хотите строить клиентский конвейер на EmDash Build: это экспериментальная альфа без SLA, и перенос контента в production-инстанс ещё в разработке.

EmDash 1.x стоит рассматривать для нового проекта на Astro, мультиканального структурированного контента, контролируемой автоматизации через MCP и архитектуры с изолированными расширениями.

Ссылки


Следующий шаг

Перед выбором платформы разберите разницу между CMS, базой данных и сайтом.

До миграции проверьте импорт контента, нужные плагины и права редакторов на отдельной копии сайта.

Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov