What works today:
- CRUD: sites, collections, entries
- JWT authentication
- PostgreSQL with GORM
- Echo (Go) backend, React + TypeScript frontend
- Docker and docker-compose
- Public read API at
/api/:siteSlug/data
The basics every CMS needs. Without these, MCP positioning means nothing.
- Entry editing workflow (
feature/content-updates)- Tenant-safe update endpoint with schema validation
- Editor UI reusing typed controls and the media picker
- Complete essential CRUD (
feature/site-collection-updates)- Tenant-safe site renaming with stable public slugs
- Collection name/schema editing with existing-entry compatibility checks
- Minimal edit controls reusing existing modals
-
Tenant authorization implementation (
security/tenant-authorization)- Scope site listings to the authenticated user
- Bind newly created sites to the JWT identity
- Enforce ownership through site, collection, and entry relationships
-
Add cross-tenant authorization regression tests
-
Reject insecure default secrets in production (
security/config-hardening) -
Add authentication rate limiting, request size limits, and security headers
-
Local file and image storage (critical)
- Site-owned upload, serving, listing, and deletion endpoints (
feature/local-media-storage) - Files table tracking size, MIME type, original name, and storage name
- MIME allowlist, opaque filenames, size limits, and traversal protection
- Persistent Docker upload volume
- Image upload and existing-media picker in the collection editor (
feature/media-picker-ui) -
UPLOADS_DIRandMAX_FILE_SIZEenvironment variables
- Site-owned upload, serving, listing, and deletion endpoints (
-
Input validation and structured error responses
- Required, schema, primitive type, URL, and date checks for entries (
feature/entry-validation) - Field-level
422 validation_failedresponse shape - Length and numeric range constraints in collection schemas (
feature/schema-constraints) - Frontend renders accessible field-level errors (
feature/field-validation-ui)
- Required, schema, primitive type, URL, and date checks for entries (
-
API stability
- Lock response shapes for sites, collections, entries
- Bounded pagination and metadata for collection entries (
feature/api-pagination) - Pagination on authenticated site, collection, and media lists (
feature/remaining-list-pagination) - Bounded public collection and single-entry endpoints with cache policy (
feature/public-content-api) - Preserve legacy whole-site endpoint compatibility
-
Database integrity and migrations
- Transactional site, collection, and account deletion (
reliability/database-integrity) - Cascade media metadata cleanup with best-effort disk cleanup
- Rollback regression coverage for failed destructive operations
- Versioned migration ledger, idempotency, and legacy upgrade tests (
reliability/versioned-migrations) - Collection slug uniqueness scoped to its site
- Foreign-key constraints
- Transactional site, collection, and account deletion (
-
UI polish
- Bug-free CRUD for every model
- Loading, empty, and error states
- Confirm dialogs on destructive actions
-
Docker and self-hosting
- Document production environment variables
- Provide a production environment template
- Add liveness
/healthz, database readiness/readyz, and container health check (reliability/health-readiness) - Fail startup when database initialization fails
- Reproducible multi-stage build, static binary, pinned runtime, and non-root container (
reliability/container-hardening) - Production frontend dependency audit enforced in CI
- Document database and media backup/restore verification (
docs/self-hosting-polish)
The differentiator.
- API tokens
- Per-token revocation
- Scoped to a single site
Authorization: Bearer <token>accepted by the existing API and MCP
- MCP server (HTTP transport) exposing
list_sites,list_collections,list_entriesget_entry,create_entry,update_entry,delete_entryquery_entrieswith filters and paginationupload_file
- Schema introspection endpoint
- Lets agents discover collection fields without out-of-band setup
- Connect to Claude Desktop docs
- Copy-paste config snippet
- Same setup for Cursor
- Submit to MCP registries (Smithery, Anthropic directory)
First paying customers.
- Multi-site per user. One user owns multiple projects.
- Path-based multi-tenancy. URLs look like
barecms.dev/u/<slug>. No subdomain routing yet. - Stripe Checkout. Single $15 plan. Manual upgrade for team customers.
- Manual onboarding for the first 30 customers. Instances created by hand.
- Daily DB backup script. Cron plus S3 upload, kept simple.
Only when paid users ask.
- External storage. S3-compatible upload backend.
- Multi-user team tier. Invitations, Admin and Editor roles, gated to the $30/mo plan.
- Subdomain routing and automated SSL. Replaces path-based when it starts feeling limiting.
- One starter template. A polished Astro example, not a marketplace.
- Automated provisioning. Replaces manual onboarding once it becomes painful.
The previous roadmap included these. They are removed.
- Password reset flow (manual recovery for first 100 users)
- Activity tracking and audit log
- Webhooks (replaced by MCP server)
- Granular permissions and custom roles
- Template marketplace with multiple starters
- Container orchestration (Docker Swarm, Kubernetes). Fly.io machines suffice.
- Editor AI buttons. External agents handle this over MCP.
| Tier | Price | Includes |
|---|---|---|
| Self-hosted | Free | Full features, your infra, no support |
| Solo (cloud) | $15/mo | 3 sites, local storage, single user, MCP access |
| Team (cloud) | $30/mo | Multi-user, S3 storage, more sites, MCP access |
- Phase 1. 10+ stars. First self-hoster reports a clean install.
- Phase 2. Listed in MCP registries. First user reports editing via Claude.
- Phase 3. First paying customer at $15 MRR.
- Phase 4. $500+ MRR before adding team-tier features.
Bare minimal, on purpose.
- One sentence describes the project: "MCP-native CMS."
- Deploy with a single binary or Docker image.
- Minimal surface, fast, no bloat.
- Users own their content.
Every feature decision passes through these.