EmDash — open-source CMS на TypeScript и Astro со структурированным контентом, изолированными плагинами и встроенными инструментами для ИИ-агентов. 28 сентября 2026 года проект выпустил стабильную версию 1.0 и вышел из ветки 0.x. На 3 октября актуален релиз 1.1.0 от 1 октября; ниже — текущая установка, устройство CMS и сохранённый разбор важных изменений 1.0.
CMS — система управления содержанием: редактор меняет записи в админке, а сайт получает их для отображения. Astro отвечает за страницы и компоненты; EmDash — за контент, права и редакционный процесс. Руководство рассчитано на разработчика, знакомого с JavaScript/TypeScript и базовой работой в терминале.
Что нового в EmDash 1.0
| Новшество | Что это даёт |
| Стабильный релиз | Проект вышел из ветки 0.x. Код проверен эксплуатацией: официальный блог Cloudflare работает на EmDash с 12 августа 2026 года |
| Реестр плагинов | Каталог plugins.emdashcms.com на децентрализованном протоколе AT Protocol; разработчик публикует релизы из собственного аккаунта и не зависит от владельца каталога |
| EmDash Build | Открытая альфа-версия ИИ-конструктора сайтов: описание задачи превращается в Astro-сайт с базой данных и админкой EmDash |
| MCP с OAuth | OAuth 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.
Как проверить установку
- Запустите
npm run devи откройтеhttp://localhost:4321/_emdash/admin/. - Setup Wizard предложит название сайта, таглайн и демонстрационный контент, затем запросит email и имя администратора.
- Зарегистрируйте ключ доступа (passkey) в диалоге браузера.
- После регистрации откроется панель администратора с разделами Posts и Pages.
- Откройте пост Welcome, измените заголовок и нажмите Save, затем Publish changes.
- Обновите главную страницу
http://localhost:4321/: новый заголовок появился в списке. Промежуточное сохранение создаёт черновик, а посетители видят изменение только после публикации.
Вход и управление доступом
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: токен с нужной областью доступа не сработает, если роль пользователя ниже требуемой.
Плагины и реестр
| Аспект | WordPress | EmDash |
| Изоляция | Расширения работают в общем 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 модерирует тексты и изображения листингов, но не может подменить код: агрегатор, сервис модерации и загрузчик каталога открыты, поэтому любой оператор может поднять собственную витрину поверх тех же записей. Владелец плагина сохраняет историю релизов независимо от каталога.
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/:idAPI также охватывает медиа, ревизии, коллекции, поля, плагины, поиск, настройки, меню, таксономии и пользователей. Конкретная операция требует соответствующих прав пользователя и области действия токена.
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 и использование сверх включённого |
| Workers | 100 000 запросов в сутки; 10 мс CPU на вызов | Минимум $5 в месяц; 10 млн запросов и 30 млн CPU-мс включено, затем $0.30 за млн запросов и $0.02 за млн CPU-мс |
| D1 | 5 млн прочитанных и 100 000 записанных строк в сутки; 5 ГБ суммарного хранения | 25 млрд чтений и 50 млн записей включено в месяц; первые 5 ГБ хранения включены, затем $0.001 за млн чтений, $1 за млн записей и $0.75 за ГБ-месяц |
| R2 Standard | 10 ГБ-месяцев хранения, 1 млн операций Class A и 10 млн операций Class B в месяц, исходящий трафик бесплатен | $0.015 за ГБ-месяц, $4.50 за млн операций Class A и $0.36 за млн операций Class B; исходящий трафик остаётся бесплатным |
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 и архитектуры с изолированными расширениями.
Ссылки
- Официальный сайт
- Документация
- Руководство по обновлению до 1.0
- Справочник MCP-сервера
- Подключение ИИ-инструментов
- Документация по аутентификации
- Справочник REST API
- Настройка sandbox для плагинов
- Индекс документации для ИИ-агентов
- Реестр плагинов
- EmDash Build и исходный код
- GitHub — CMS
- GitHub — релизы
- EmDash Agent Skills
- Пакеты npm организации emdash-cms
- Анонс 1.0 в блоге EmDash
- Анонс 1.0 и реестра в блоге Cloudflare
- Как Cloudflare перевела блог на EmDash
- Playground
- Discord
Следующий шаг
Перед выбором платформы разберите разницу между CMS, базой данных и сайтом.
До миграции проверьте импорт контента, нужные плагины и права редакторов на отдельной копии сайта.
Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov


