Agentic CMS
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| STORAGE_MODE | No | Storage mode for editor (cloud or local) | cloud |
| SUPABASE_URL | Yes | The URL of your Supabase project (e.g., https://your-project.supabase.co) | |
| POSTIZ_API_KEY | No | API key for Postiz | |
| POSTIZ_API_URL | No | URL for Postiz (social publishing) API | |
| RESEND_API_KEY | No | API key for Resend newsletter delivery | |
| TABLE_PROJECTS | No | Table name for video projects (used by editor) | video_projects |
| NEWSLETTER_FROM | No | Newsletter sender formatted as 'Display Name <addr@domain>' | |
| META_TITLE_SUFFIX | No | Suffix appended to blog post meta titles | |
| NEXT_PUBLIC_SITE_URL | No | The customer's website URL | |
| SUPABASE_SERVICE_KEY | No | Alternative name for the service role key | |
| ANALYTICS_OWN_DOMAINS | No | Comma-separated whitelist of self-referrer domains | |
| NEXT_PUBLIC_BRAND_NAME | No | Brand name displayed in newsletter header and meta title suffix | |
| NEXT_PUBLIC_BRAND_EMOJI | No | Brand emoji for carousel watermark/avatar | |
| NEXT_PUBLIC_BRAND_HANDLE | No | Brand handle for carousel watermark/avatar | |
| ANALYTICS_VERCEL_KEYWORDS | No | Keywords to identify Vercel preview domains as owned | |
| NEXT_PUBLIC_CONTACT_EMAIL | No | Contact email for carousel CTA slide | |
| SUPABASE_SERVICE_ROLE_KEY | Yes | The service role key for your Supabase project | |
| GOOGLE_SERVICE_ACCOUNT_KEY | No | Google service account key JSON for GA4/GSC analytics | |
| NEXT_PUBLIC_CONTACT_DOMAIN | No | Contact domain for carousel CTA slide | |
| NEXT_PUBLIC_BRAND_AVATAR_URL | No | URL for brand avatar |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_contentsB | [Pipeline step 3 — Create (master)] List master content items. Agents typically reach this after promote_idea (step 2→3). Use filters to find drafts pending derivation. |
| get_contentA | [Pipeline step 3 — Create (master)] Get a single master content item by id or slug. Use before update_content or create_variant to read the current body/hook/cta. |
| create_contentA | [Pipeline step 3 — Create (master)] Create a new master content item directly (without an Idea). Prefer promote_idea when the content came from an idea (keeps provenance). Status is always "draft". Next step: create_variant (step 4). |
| update_contentA | [Pipeline step 3 — Create (master)] Edit master content fields (hook/body/cta/core_message/tags). Use after promote_idea to fill in the draft body. Cannot set status=published (requires human). Next step: create_variant once body is solid. |
| list_ideasA | [Pipeline step 2 — Discover] List content ideas with optional filters. Use this first to see what ideas already exist before creating new ones. Filter by topic_id to narrow to a single theme, or promoted=false to see ideas not yet turned into Content. Typical next step: create_idea (register new angle) or promote_idea (turn existing idea into draft Content). |
| get_ideaA | [Pipeline step 2 — Discover] Get a single idea by id. Useful when promote_idea or update_idea needs full context first. |
| create_ideaA | [Pipeline step 2 — Discover] Register a new content idea under a Topic. Use this when the agent discovers a new angle from research, competitor scan, user feedback, etc. Link to a Topic (list_topics first) to keep the pipeline organized. Typical next step: promote_idea(id, title, slug) — turns this idea into a draft Content (step 3). |
| update_ideaA | [Pipeline step 2 — Discover] Refine an idea (angle / target_audience / raw_text). Use this when the agent learns more context before promoting the idea to Content. Pass topic_id=null to explicitly un-link from a Topic. |
| promote_ideaA | [Pipeline step 2→3 — Discover → Create] Promote an idea to a draft Content item. Creates a new Content (always status=draft; agents cannot publish directly) and links the original idea via ideas.promoted_to. Typical next step: update_content (edit hook/body/cta) → create_variant (step 4, derive per-platform). |
| list_topicsA | [Pipeline step 1 — Strategy] List all topics (long-lived content themes). Start here: the agent picks which topic an idea belongs to. Typical next step: create_idea (step 2) under the chosen topic. |
| create_topicA | [Pipeline step 1 — Strategy] Create a new topic. Topics are long-lived (3~5 total, rarely changed). Only add when a genuinely new content theme emerges. |
| list_variantsA | [Pipeline step 4 — Adapt] List variants derived from a master Content. Check here before create_variant to avoid duplicates. |
| create_variantA | [Pipeline step 4 — Adapt] Create a platform/format-specific variant of a master Content. Allowed platforms: instagram/linkedin/threads/tiktok/youtube/x (social) + blog/email/self (own channels). Allowed formats: reel/carousel/single_post/article/thread/story/short + blog/video. Use variant.id as the variant_id input for the next step — create_blog_post_from_markdown / create_carousel / send_newsletter / link_video_project_to_variant. |
| update_variantC | Update an existing variant. |
| create_publicationA | [Pipeline step 6 — Publish tracking] Record a publication event (where/when the content went out). Include variant_id so the Content detail view traces which variant was published on which channel. Final pipeline step — after this use get_metrics + get_activity_logs for feedback loop. |
| get_metricsA | [Feedback loop] Get publication metrics for a content item — all publish events across channels. Use to learn which variants performed best before creating the next round of variants. |
| get_activity_logsC | List activity logs with optional filters for collection, action, actor_type, and limit. |
| get_revisionsC | Get revision history for a content item. |
| get_human_feedbackC | Get human-authored revision feedback for a content item. |
| revert_to_revisionA | Revert a content item to a specific revision. Creates a new revision and logs the revert action. |
| list_mediaC | List media items, ordered by most recent first. |
| create_mediaC | Register a media item in the CMS. |
| list_video_projectsC | List video projects from the editor. |
| get_video_projectC | Get details of a specific video project. |
| create_video_projectC | Create or save a video project. |
| extract_beatsB | Extract beats from a music file for syncing video cuts. |
| list_videosB | List available video source files. |
| probe_mediaB | Get metadata (duration, resolution, codec, etc.) for a media file. |
| render_videoC | Start rendering a video project. |
| get_render_statusB | Check the current rendering status. |
| list_blog_categoriesA | List all blog post categories (name, slug, description). Use to find the correct category slug before creating a post. |
| list_blog_postsA | List blog posts with optional filters. Returns summary fields (not full PlateJS content). |
| get_blog_postB | Get a single blog post (including full PlateJS content) by ID or slug. |
| create_blog_post_from_markdownA | Convert a Markdown body to PlateJS JSON and insert as a draft blog post. Status is ALWAYS "draft" — agents cannot publish directly; Studio review is required. Optionally links the post to an existing category by slug. Uses @awc/content-core CLI (convert-plate) for Markdown → PlateJS conversion. |
| update_blog_postA | Update fields on an existing blog post (title, excerpt, meta, thumbnail, or body). If markdown_body is provided, it will be converted to PlateJS and replace content. Status cannot be changed to "published" via this tool — use Studio for publishing. |
| list_carouselsA | List carousels. Returns summary (id, title, caption, slide_count, timestamps). Use get_carousel for full slide data. |
| get_carouselB | Get a single carousel by id (full slide data included). |
| create_carouselA | Create a new carousel with the given slides. Each slide must include templateId, category, label, and content. Slide ids are auto-generated (e.g. "slide-abc123") — do not provide them. Typical structure: 1 cover slide + several body slides + 1 cta slide. |
| update_carouselA | Update an existing carousel. Any of title, caption, or slides can be replaced. If slides are provided, they REPLACE the existing slides entirely (not merged). Each new slide gets a fresh auto-generated id unless one is explicitly passed. |
| send_newsletterA | Send a blog post as a newsletter to subscribers via the dashboard send pipeline. Optionally records which variant (format=blog) this send was derived from, so the Content detail page shows the send count on the Variants & Derivatives card. Prerequisites: the dashboard app must be running (DASHBOARD_API_URL env var, default http://localhost:3000). |
| link_video_project_to_variantA | Link (or unlink) an existing video_project to a variant (1:1). video_projects is currently created via the brxce-editor API which does not accept variant_id, so this tool fills the FK after creation. Pass variant_id=null to explicitly unlink. |
| list_postiz_integrationsA | [Pipeline step 6 — Publish] List connected social integrations in Postiz (returns id + platform + display name per channel). Use this first to get the integration_id before calling send_to_postiz. |
| send_to_postizA | [Pipeline step 6 — Publish] Send a variant to Postiz for immediate or scheduled publication to the connected social channel. Typical flow: create_variant (step 4) → update_variant to fill body_text & hashtags → list_postiz_integrations → send_to_postiz. On success: variant.status becomes "sent_to_postiz", postiz_post_id is stored in platform_settings, and a publications row is automatically created. Use raw_payload to bypass the default DTO builder when a specific Postiz feature (media, thread, poll, etc.) is needed. |
| list_gallery_itemsA | List AWC Gallery items. Filter by status/kinds/featured/visibility. kinds is OR-match (any overlap). Ordered by featured first, featured_rank asc, then published_at desc. |
| create_gallery_itemB | Create a Gallery item with one or more kinds (kinds[0] is the primary). Default status=draft, visibility=public. Use set_gallery_featured afterwards to pin to the landing carousel. |
| set_gallery_featuredA | Pin/unpin a Gallery item to the landing featured carousel. Set is_featured and featured_rank (lower = earlier). |
| update_gallery_itemB | Patch a Gallery item. Any subset of: title, subtitle, summary, kinds, status, visibility, cover_aspect, tags, author, duration_minutes, is_featured, featured_rank, cover_media_id. kinds[0] is treated as primary. published_at/featured_at are auto-set when status flips to published or is_featured flips to true. |
| delete_gallery_itemA | Hard-delete a Gallery item. gallery_item_media rows cascade. Underlying media rows + storage files are NOT deleted (other items may reference them). |
| list_gallery_mediaB | List gallery_item_media rows for an item, ordered by sort_order asc. |
| attach_gallery_mediaC | Attach an existing media row to a gallery item with role + sort_order. role defaults to gallery. |
| detach_gallery_mediaB | Remove a gallery_item_media link. Underlying media row is preserved. |
| set_gallery_coverA | Set gallery_items.cover_media_id. Use attach_gallery_media separately if you also want a gallery_item_media row with role=cover. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 52 tools
Most tools target a distinct resource+action, and pipeline-step labels in descriptions aid selection. However, the 'media' family (list_media, list_gallery_media, list_videos) and gallery cover tools (set_gallery_cover vs attach_gallery_media role=cover) have overlapping boundaries that require careful reading.
Every tool uses snake_case with a consistent verb_noun pattern (list_*, get_*, create_*, update_*, delete_*, send_*). A few longer names like create_blog_post_from_markdown and link_video_project_to_variant remain readable and follow the same convention.
52 tools is well beyond the 25-tool threshold for a heavy server and risks overwhelming an agent's selection space. Although the server spans many subdomains (blog, gallery, video, carousel, social publishing, pipeline), the surface is bloated and could be split or consolidated.
Core pipeline and CRUD flows are well covered: ideas (list/get/create/update/promote), gallery items (full CRUD), carousels, contents, variants, and publishing. Minor gaps exist, notably missing delete/update operations for blog posts, carousels, contents, variants, media, and video projects, though agents can generally work around these.