Strapi v5 headless CMS powering colaberry.ai. 6 content types. 2,500+ entries. Zero frontend coupling.
The content backbone for enterprise AI catalog, podcast transcripts, and LLM architecture deep dives.
Frontend Strapi v5 Node.js 20 PostgreSQL 2500+ entries GCP Cloud Run
This is the headless CMS for the Colaberry AI platform. It manages all structured content — agents, skills, MCP servers, tools, podcasts, and LLM architectures — and serves them via REST API to the Next.js frontend.
The CMS handles:
- Content authoring for 6 primary catalog types
- Draft/publish workflow (Strapi v5 draft system)
- Media management for cover images, audio files, and transcripts
- Global navigation configuration consumed by the frontend header/footer
- Distribution channel configuration for automated social posting
- Taxonomy relations (tags, companies, departments, categories)
graph TB
subgraph CMS["Strapi v5 CMS"]
ADMIN["Admin Panel — /admin"]
REST["REST API — /api"]
MEDIA["Media Library — /uploads"]
DRAFT["Draft/Publish — per-entry lifecycle"]
end
subgraph ContentTypes["Content Types"]
AGENTS["Agents — 160+"]
SKILLS["Skills — 500+"]
MCPS["MCP Servers — 1,500+"]
TOOLS["Tools — 200+"]
PODCASTS["Podcasts — 260+ episodes"]
LLM["LLM Architectures — 52 models"]
end
subgraph Relations["Shared Relations"]
TAGS["Tags — cross-type labels"]
COMPANIES["Companies — vendor/provider"]
DEPARTMENTS["Departments — org units"]
CATEGORIES["Categories — taxonomy mapping"]
end
subgraph Consumers
FRONTEND["Next.js Frontend — SSG/ISR"]
SCRIPTS["Deep-Dive Scripts — .mjs authoring"]
DIST["Distribution Cron — social posting"]
PREVIEW["Distribution Preview — dry-run API"]
end
ADMIN --> ContentTypes
REST --> ContentTypes
ContentTypes --> Relations
FRONTEND -->|fetchCMSJson + bearer auth| REST
SCRIPTS -->|PUT /api + ?status=published| REST
DIST -->|source + log| REST
PREVIEW -->|read-only| REST
sequenceDiagram
participant Author as Content Author
participant Admin as Strapi Admin Panel
participant DB as PostgreSQL
participant API as Strapi REST API
participant FE as Next.js Frontend
Author->>Admin: Create/edit content entry
Admin->>DB: Save draft
Author->>Admin: Click "Publish"
Admin->>DB: Set status = published
Note over DB: Entry now visible via API
FE->>API: GET /api/agents?filters[visibility]=public
API->>DB: Query published + public entries
DB-->>API: Results with relations populated
API-->>FE: JSON response
FE->>FE: ISR revalidate (600s) or on-demand
| Content Type | API Endpoint | Key Fields | Entries |
|---|---|---|---|
| Agent | /api/agents |
name, slug, description, longDescription, keyBenefits, useCases, limitations, whatItDoes, outcomes, coreTasks, inputs, outputs, tools, executionModes, orchestration, securityCompliance, industry, status, visibility, rating, source, verified | 160+ |
| Skill | /api/skills |
name, slug, category, skillType, description, provider, prerequisites, linkedMCP, visibility | 500+ |
| MCP Server | /api/mcp-servers |
name, slug, description, serverType, primaryFunction, capabilities, authentication, hostingOptions, visibility | 1,500+ |
| Tool | /api/tools |
name, slug, toolCategory, description, webLink, pricing, visibility | 200+ |
| Podcast Episode | /api/podcast-episodes |
title, slug, publishedDate, transcript, transcriptSegments, audioUrl, buzzsproutId, podcastStatus, tags, companies | 260+ |
| LLM Architecture | /api/llm-architectures |
name, slug, organization, parameters, activeParameters, contextWindow, vocabSize, numLayers, hiddenSize, releaseDate, decoderType, attention, keyFeatures, deepDive (Dynamic Zone) | 52 |
| Content Type | Purpose |
|---|---|
| Tag | Cross-type labels (many-to-many) |
| Company | Vendor/provider references |
| Department | Organizational units with category nesting |
| Category | Taxonomy parent grouping |
| Global Navigation | CMS-driven header/footer link structure |
| Distribution Channel | Social platform config (name, platform, template, credentials ref) |
| Distribution Log | Per-dispatch audit trail (platform, entry ID, status, response) |
LLM Architecture entries include a deepDive Dynamic Zone with these components:
| Component | Fields | Purpose |
|---|---|---|
deep.heading |
level (h2/h3/h4), text, anchor | Section headings |
deep.paragraph |
body (rich text) | Prose content |
deep.callout |
variant (insight/warning/note), title, body | Highlighted blocks |
deep.code-block |
language, code, caption | Code examples |
deep.table |
caption, headers[], rows[][] | Data tables |
deep.list |
style (bullet/numbered), items[] | Lists |
deep.image |
url, alt, caption | Figures |
deep.references |
items[] (title, url, authors, year) | Citations |
- Node.js 20+
- PostgreSQL 16+ (or use Docker)
git clone https://github.com/colaberry/colaberry-ai-cms.git cd colaberry-ai-cms npm install cp .env.example .env # Configure DATABASE_URL and secrets npm run develop
Open http://localhost:1337/admin to access the admin panel.
docker compose up
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
APP_KEYS |
Yes | Strapi app keys (comma-separated) |
API_TOKEN_SALT |
Yes | Salt for API token hashing |
ADMIN_JWT_SECRET |
Yes | JWT secret for admin panel |
JWT_SECRET |
Yes | JWT secret for API auth |
TRANSFER_TOKEN_SALT |
Yes | Salt for transfer tokens |
npm run build # Build admin panel npm run start # Start production server
All API requests from the frontend use a bearer token:
curl -H "Authorization: Bearer <CMS_API_TOKEN>" \ "http://localhost:1337/api/agents?filters[visibility]=public&populate=*"
# List all published agents (public visibility) GET /api/agents?filters[visibility]=public&populate=tags,companies,department,coverImage # Single agent by slug GET /api/agents?filters[slug]=crop-stress-detection&populate=* # Paginated skills with category filter GET /api/skills?filters[visibility]=public&filters[category]=AI&pagination[page]=1&pagination[pageSize]=25 # Podcast episodes with audio GET /api/podcast-episodes?filters[podcastStatus]=published&populate=tags,companies&sort=publishedDate:desc # LLM architecture with deep dive blocks GET /api/llm-architectures?filters[slug]=deepseek-v3&populate[deepDive][populate]=* # Catalog counts (lightweight) GET /api/agents?filters[visibility]=public&pagination[pageSize]=1&pagination[withCount]=true GET /api/skills?filters[visibility]=public&pagination[pageSize]=1&pagination[withCount]=true GET /api/mcp-servers?filters[visibility]=public&pagination[pageSize]=1&pagination[withCount]=true # All tags with usage counts GET /api/tags?populate=agents,skills,mcp_servers&pagination[pageSize]=100
The author-llm-deep-dive.mjs script PUTs dynamic zone blocks directly:
# Publish a deep dive (appends ?status=published for Strapi v5 draft system) node scripts/author-llm-deep-dive.mjs --slug deepseek-v3 # Dry run node scripts/author-llm-deep-dive.mjs --slug deepseek-v3 --dry-run # Publish all 52 flagships node scripts/author-llm-deep-dive.mjs --all
Critical: The ?status=published query param is required. Without it, Strapi v5 defaults PUT requests to draft status and SSR never sees the content.
The CMS stores distribution channel configuration and dispatch logs.
| Field | Type | Description |
|---|---|---|
name |
String | Channel display name (e.g. "X/Twitter Main") |
platform |
Enum | x, moltbook, huggingface, etc. |
template |
Text | Mustache-style post template |
credentialRef |
String | Env var name (CMS never holds secrets) |
active |
Boolean | Enable/disable channel |
| Field | Type | Description |
|---|---|---|
platform |
String | Target platform |
entryId |
String | Source content entry ID |
entryType |
String | Content type (agent, skill, etc.) |
status |
Enum | success, failed, skipped, dry-run |
response |
JSON | Platform API response |
idempotencyKey |
String | ${platform}:${id}:${updatedAt} |
# Idempotent — re-running updates existing rows by name
node scripts/seed-distribution-channels.mjsTemplates live in scripts/distribution-templates/{x,moltbook,huggingface}.md.
| Service | Description |
|---|---|
colaberry-ai-cms-prod |
Production CMS instance |
The CMS runs as a stateless container on Cloud Run with a managed PostgreSQL backend.
- Media storage: Configure a cloud storage provider (GCS, S3) for production media uploads
- API tokens: Generate via Strapi admin panel → Settings → API Tokens
- Draft/Publish: All content types use Strapi v5's built-in draft/publish system. Only published entries are visible via the API with default filters
- ISR sync: The frontend uses ISR with 600s revalidation. Content changes appear on the live site within 10 minutes of publishing
colaberry-ai-cms/
├── config/
│ ├── api.js # API configuration
│ ├── admin.js # Admin panel configuration
│ ├── database.js # Database connection (PostgreSQL)
│ ├── middlewares.js # CORS, security, body parser
│ ├── plugins.js # Plugin configuration
│ └── server.js # Server host/port settings
├── src/
│ ├── api/ # Content type definitions
│ │ ├── agent/ # Schema, controllers, routes, services
│ │ ├── skill/
│ │ ├── mcp-server/
│ │ ├── tool/
│ │ ├── podcast-episode/
│ │ ├── llm-architecture/
│ │ ├── tag/
│ │ ├── company/
│ │ ├── department/
│ │ ├── category/
│ │ ├── global-navigation/
│ │ ├── distribution-channel/
│ │ └── distribution-log/
│ ├── components/ # Reusable Dynamic Zone components
│ │ └── deep/ # Deep dive block types (heading, paragraph, etc.)
│ └── extensions/ # Strapi lifecycle hooks
├── public/ # Static assets
├── database/ # Migrations
└── types/ # Generated TypeScript types
| Repository | Purpose |
|---|---|
| colaberry/colaberry-ai | Next.js frontend (consumer of this CMS) |
| colaberry/WorldOfTaxonomy | Taxonomy classification platform |
Colaberry AI CMS — Structured content for the enterprise AI catalog.