LightCMS
A lightweight, AI-native content management system for building and managing websites. Built with Go and MongoDB Atlas.
Why LightCMS?
Lightweight: A clean, focused codebase (~5K lines of Go) that's easy to understand, modify, and extend. No bloated frameworks or complex abstractions.
AI-Native: Built from the ground up for the AI era:
- MCP Integration: Full Model Context Protocol server with 41 tools for website management. Control your entire site through Claude Code or other agentic workflows.
- Fork-Friendly: Designed to be forked and customized by Claude Code. Ask Claude to add new content types, modify templates, or build custom features—the codebase is structured for AI-assisted development.
- Natural Language Website Management: Skip the admin UI entirely. Create pages, manage assets, customize themes, and publish content through conversation.
Features
- AI-Powered Website Management: MCP server for agentic control of your site
- REST API: Full
/api/v1/JSON API with API key authentication - CLI Tool: Command-line interface for all content management operations
- API Key System: Create and manage API keys from the admin panel
- Template System: Define reusable content structures with custom fields
- Static Page Generation: Fast page loads from pre-rendered HTML
- Content Collections: Group and display content by category
- Custom Pages: Full HTML control for special pages
- Theme Customization: Modern, sleek design with customizable colors, fonts, and styles
- Rich Text Editor: TinyMCE integration for visual content editing
- Admin Panel: Secure content management at
/cm - Content Versioning: Full version history with diff comparison and revert capability
- Soft Delete: Recover deleted content with undelete functionality
Prerequisites
- Go 1.21 or later
- MongoDB Atlas account (free tier works great)
Quick Start
- Clone the repository
- Copy
config.dev.json.exampletoconfig.dev.json - Edit
config.dev.jsonwith your MongoDB connection string - Run
go run cmd/server/main.go - Visit http://localhost:8082/cm and login with
admin123 - Change your password immediately via Security settings
MongoDB Atlas Setup
Step 1: Create an Atlas Account
- Go to MongoDB Atlas
- Sign up for a free account (no credit card required)
Step 2: Create a Cluster
- Click "Build a Database"
- Select "M0 FREE" (Shared) tier
- Choose your preferred cloud provider and region (closest to you)
- Click "Create Deployment"
Step 3: Set Up Database Access
-
Create a database user:
- Username:
lightcms(or your choice) - Password: Generate a secure password (save this!)
- Click "Create User"
- Username:
-
Add your IP address:
- Click "Add My Current IP Address"
- Or add
0.0.0.0/0to allow access from anywhere (less secure, but convenient for development) - Click "Finish and Close"
Step 4: Get Your Connection String
- Click "Connect" on your cluster
- Select "Drivers"
- Copy the connection string, it looks like:
mongodb+srv://lightcms:<password>@cluster0.xxxxx.mongodb.net/?retryWrites=true&w=majority - Replace
<password>with your actual password
Step 5: Create Your Config File
For development, copy the example and fill in your values:
cp config.dev.json.example config.dev.json
Edit config.dev.json:
{
"port": "8082",
"mongo_uri": "mongodb+srv://lightcms:YOUR_PASSWORD@cluster0.xxxxx.mongodb.net/lightcms",
"env": "development",
"session_secret": "any-random-string-for-dev"
}
For production, use config.prod.json:
cp config.prod.json.example config.prod.json
Edit with production values (use openssl rand -hex 32 for session_secret).
Installation
# Clone or navigate to the project
cd lightcms
# Install dependencies
go mod tidy
# Run the server
go run cmd/server/main.go
Or use the run script:
./run.sh
Configuration
LightCMS uses JSON config files. Create either:
config.dev.json- for developmentconfig.prod.json- for production (takes precedence if both exist)
| Field | Description |
|---|---|
port | Server port (e.g., "8082" for dev, "80" for prod) |
mongo_uri | MongoDB Atlas connection string |
env | Environment: "development" or "production" |
session_secret | Random string for session encryption |
Note: Config files contain secrets and are excluded from git via .gitignore.
Usage
Accessing the Site
- Public site: http://localhost:8082
- Admin panel: http://localhost:8082/cm
Default Admin Password
The default password is admin123. On first login, you'll be prompted to change it.
The admin password is stored securely in MongoDB using bcrypt hashing.
Creating Content
- Log in to the admin panel at
/cm - Go to Content → New Content
- Select a template (Blog Post, Press Release, or Explanatory Page)
- Fill in the fields
- Check "Published" and save
Creating Custom Templates
- Go to Templates → New Template
- Define your fields (text, textarea, richtext, date, image, select)
- Create an HTML layout using
{{.field_name}}placeholders - Save the template
Available placeholders:
{{.title}}- Content title{{.slug}}- URL slug{{.published_at}}- Publication date{{.your_field_name}}- Any custom field you define
Creating Collections
Collections display grouped content (like a blog listing page).
- Go to Collections → New Collection
- Set the category filter to match your content's category
- Define item and page templates
- The collection will be available at
/collection-slug
Customizing the Theme
- Go to Theme in the admin panel
- Adjust colors, fonts, and border radius
- Add custom CSS if needed
- Save to apply changes site-wide
Project Structure
lightcms/
├── cmd/
│ ├── server/main.go # HTTP server entry point
│ ├── mcp/main.go # MCP server entry point
│ └── cli/main.go # CLI tool entry point
├── config/
│ └── config.go # Configuration loading
├── internal/
│ ├── apiclient/ # Reusable HTTP client for REST API
│ ├── auth/ # Authentication logic
│ ├── cli/ # CLI subcommands and output formatting
│ ├── database/ # MongoDB connection & operations
│ ├── handlers/ # HTTP handlers (admin UI + REST API)
│ ├── mcp/ # MCP server and tool definitions
│ ├── middleware/ # API auth middleware
│ ├── models/ # Data models & default templates
│ └── services/ # Business logic services
├── static/ # CSS, JS, and uploaded files
├── content/ # Custom pages and generated HTML
└── .goreleaser.yaml # Release configuration
Default Templates
Blog Post
Fields: title, excerpt, featured_image, content, author, tags
Press Release
Fields: headline, subheadline, dateline, release_date, body, boilerplate, contact_info
Explanatory Page
Fields: title, subtitle, hero_image, intro, main_content, sidebar, cta_text, cta_link
API Keys
API keys are required for the REST API, MCP server, and CLI tool. Create them from the admin panel.
- Log in at
/cm - Go to Settings → API Keys
- Click Create New Key, give it a name and description
- Copy the key immediately — it's only shown once
Keys use the format lc_ followed by 32 hex characters. They're stored as SHA-256 hashes.
REST API
LightCMS provides a full REST API at /api/v1/ authenticated with API keys.
Authentication
Include your API key in the Authorization header:
curl -H "Authorization: Bearer lc_your_key_here" http://localhost:8082/api/v1/content
Endpoints
| Resource | Endpoints |
|---|---|
| Content | GET/POST /content, GET/PUT/DELETE /content/{id}, POST .../publish, .../unpublish, .../restore, GET .../versions, POST .../versions/{v}/revert, GET /content/by-path?path=... |
| Templates | GET/POST /templates, GET/PUT/DELETE /templates/{id} |
| Assets | GET/POST /assets, GET/DELETE /assets/{id}, GET /assets/folders, GET /assets/by-path?path=... |
| Theme | GET/PUT /theme, GET /theme/versions, POST /theme/versions/{v}/revert |
| Config | GET/PUT /config |
| Redirects | GET/POST /redirects, GET/PUT/DELETE /redirects/{id} |
| Folders | GET/POST /folders, GET/DELETE /folders/{id} |
| Collections | GET/POST /collections, GET/PUT/DELETE /collections/{id} |
| Search | GET /search?q=..., POST /search-replace/preview, POST /search-replace/execute |
| API Keys | GET/POST /api-keys, DELETE /api-keys/{id} |
| Utility | POST /regenerate |
All endpoints return JSON. PUT endpoints support partial updates (only include fields you want to change).
CLI Tool
The lightcms CLI provides command-line access to all content management operations.
Installation
# Build from source
go build -o bin/lightcms ./cmd/cli
# Or download a release binary from GitHub
Configuration
export LIGHTCMS_URL=http://localhost:8082
export LIGHTCMS_API_KEY=lc_your_key_here
Or use flags: --url and --api-key.
Commands
lightcms content list # List all content
lightcms content get <id> # Get content by ID
lightcms content create --template <id> --title "My Post" --slug my-post --data '{"body":"Hello"}'
lightcms content publish <id> # Publish content
lightcms content versions <id> # Show version history
lightcms template list # List templates
lightcms asset upload --file logo.png --path /images/logo.png
lightcms theme update --primary-color "#1a1a2e"
lightcms search "search terms" # Search content
lightcms api-key create --name "CI/CD" # Create API key
lightcms --json content list # JSON output
Run lightcms --help for full usage.
Using with Claude Code (AI-Powered Content Management)
LightCMS includes an MCP (Model Context Protocol) server that allows you to manage your website content using Claude Code. Instead of navigating the admin UI, you can simply ask Claude to create pages, update content, manage assets, and more.
The MCP server connects to LightCMS via the REST API using an API key — no direct database access needed. This means MCP clients can run remotely.
Quick Setup
- Create an API key in the admin panel at
/cm→ Settings → API Keys - Run the setup script:
export LIGHTCMS_API_KEY=lc_your_key_here
./setup-mcp.sh
This will:
- Build the MCP server and CLI binaries
- Create the wrapper script
- Register the MCP server with Claude Code
Then restart Claude Code and run /mcp to verify the connection.
Manual Setup
-
Build the MCP server:
go build -o bin/lightcms-mcp ./cmd/mcp -
Register with Claude Code:
claude mcp add --transport stdio lightcms-mcp \ -e LIGHTCMS_URL="http://localhost:8082" \ -e LIGHTCMS_API_KEY="lc_your_key_here" \ -- /path/to/lightcms/bin/lightcms-mcp -
Restart Claude Code and verify with
/mcp
Environment Variables
The MCP server uses these environment variables:
LIGHTCMS_URL- Server URL (default:http://localhost:8082)LIGHTCMS_API_KEY- API key (required)
Available Tools
The MCP server provides 41 tools for complete content management:
- Content: Create, read, update, delete, publish, unpublish, versioning
- Templates: Manage content templates and their fields
- Assets: Upload and manage images, documents, and other files
- Settings: Theme customization, redirects, folders, collections
For detailed API documentation, see MCP.md.
MCP Examples
These examples show how the MCP tools work together to manage a website through natural language. Each example lists the user prompt and the exact MCP tool calls that execute behind the scenes.
Example 1: Create and Publish a Blog Post
Prompt: "Create a blog post about AI agents and publish it"
Tool calls:
list_templates— finds the Blog Post template and its IDcreate_content— creates the post with template ID, title, slug, and field data:{ "template_id": "6971098ad0761968133b8e43", "title": "The Rise of AI Agents", "slug": "rise-of-ai-agents", "data": { "excerpt": "How autonomous AI agents are reshaping software development.", "content": "<p>AI agents represent a fundamental shift...</p>", "author": "Editorial Team" } }publish_content— makes it live; a static HTML page is generated at/rise-of-ai-agents
Example 2: Update the Site Theme
Prompt: "Change the site colors to a dark theme with blue accents"
Tool calls:
get_theme— reads current theme settings (colors, fonts, header/footer HTML)update_theme— applies the new palette:
All published pages are automatically regenerated with the new theme.{ "primary_color": "#1a1a2e", "secondary_color": "#16213e", "accent_color": "#0f3460", "background_color": "#0a0a0a", "text_color": "#e0e0e0" }
Example 3: Search and Replace Across the Entire Site
Prompt: "Replace 'Acme Corp' with 'Acme Industries' everywhere on the site"
Tool calls:
search_replace_preview— shows affected pages without making changes:
Returns a list of content items, matched fields, and match counts.{ "search": "Acme Corp", "replace": "Acme Industries" }search_replace_execute— applies the replacement after user confirmation. Each affected content item gets a new version for rollback capability.
Example 4: Create a Custom Template
Prompt: "Create a template for team member profiles with name, role, bio, and photo"
Tool calls:
create_template— defines the structure and HTML layout:
The template is immediately available for creating content.{ "name": "Team Member", "slug": "team-member", "fields": [ { "name": "role", "label": "Role", "type": "text", "required": true }, { "name": "photo", "label": "Photo", "type": "image", "required": false }, { "name": "bio", "label": "Biography", "type": "richtext", "required": true } ], "html_layout": "<div class=\"team-member\"><img src=\"{{.photo}}\" alt=\"{{.title}}\"><h2>{{.title}}</h2><h3>{{.role}}</h3><div>{{.bio}}</div></div>" }
Example 5: Upload an Image and Use It in Content
Prompt: "Upload this logo and add it to the about page"
Tool calls:
upload_asset— uploads the file as base64 with a serve path:
The image is now accessible at{ "filename": "logo.png", "serve_path": "/images/logo.png", "data_base64": "iVBORw0KGgoAAAANSUhEUg..." }/images/logo.png.get_content— retrieves the about page by path to get its current dataupdate_content— adds the image reference to the page's content field
Example 6: Set Up URL Redirects
Prompt: "The old blog moved from /news to /blog — set up redirects for the old URLs"
Tool calls:
create_redirect— creates a permanent redirect:
Visitors to{ "from_path": "/news", "to_path": "/blog", "status_code": 301, "description": "Blog section moved from /news to /blog" }/newsare automatically redirected to/blog. Multiple redirects can be created in sequence for different paths.
Example 7: Content Versioning and Rollback
Prompt: "Show me the version history for the homepage, then revert to version 2"
Tool calls:
get_content— retrieves the homepage by path (/) to get its IDget_content_versions— returns the full version history with timestamps and comments:Version 5 — "Updated hero section" — 2026-02-25 Version 4 — "Added testimonials" — 2026-02-20 Version 3 — "Redesigned layout" — 2026-02-15 Version 2 — "Initial content" — 2026-02-10 Version 1 — "Created page" — 2026-02-08revert_to_version— rolls back to version 2, creating a new version 6 with the old data. The published page is regenerated immediately.
Example 8: Organize Content with Folders
Prompt: "Create a /docs section and move the API reference page into it"
Tool calls:
create_folder— creates the URL path segment:{ "name": "Documentation", "slug": "docs" }get_content— retrieves the API reference page to get its IDupdate_content— moves it into the new folder:
The page is now accessible at{ "id": "...", "folder_path": "/docs" }/docs/api-referenceinstead of/api-reference.
Example 9: Build a Content Collection (Blog Index)
Prompt: "Create a blog listing page that shows all blog posts sorted by newest first"
Tool calls:
create_collection— defines the collection with category filter, sorting, and display templates:
A paginated blog listing is now live at{ "name": "Blog", "slug": "blog", "category": "blog", "sort_field": "created_at", "sort_order": "desc", "items_per_page": 10, "item_template": "<article><h2><a href=\"{{.Path}}\">{{.Title}}</a></h2><p>{{.excerpt}}</p><time>{{.PublishedAt}}</time></article>", "page_template": "<div class=\"blog-index\"><h1>Blog</h1>{{.Items}}{{.Pagination}}</div>" }/blog, automatically including any content with category "blog".
Example 10: Full-Text Search and Content Audit
Prompt: "Find all pages that mention 'pricing' and show me which ones are still in draft"
Tool calls:
search_content— performs a full-text search across all content fields:
Returns matching content items with their publish status, paths, and which fields matched:{ "query": "pricing", "search_type": "fulltext" }
The two draft items can then be reviewed, edited, and published as needed.Found 4 results for 'pricing': - "Pricing Plans" at /pricing — published — matched in: content - "Enterprise FAQ" at /enterprise-faq — published — matched in: content, sidebar - "New Pricing Draft" at /new-pricing — draft — matched in: title, content - "Q1 Press Release" at /press/q1-update — draft — matched in: body
Development
# Run with hot reload (using air)
go install github.com/cosmtrek/air@latest
air
# Build all binaries
go build -o bin/lightcms-server ./cmd/server
go build -o bin/lightcms-mcp ./cmd/mcp
go build -o bin/lightcms ./cmd/cli
# Run the server
./bin/lightcms-server
Security Notes
For production:
- Use a strong
session_secret(generate withopenssl rand -hex 32) - Change the default admin password immediately after first login
- Use HTTPS (put behind a reverse proxy like nginx or caddy)
- Restrict MongoDB Atlas IP whitelist to your server IPs
- Keep API keys secure — they grant full admin-level access to the REST API
- Regularly backup your MongoDB database
Privacy Policy
LightCMS is self-hosted software — you control your database, your hosting, and your data. The MCP server and CLI tool connect to your LightCMS instance via the REST API — no data is transmitted to Metavert LLC or any third party.
For the full privacy policy, see: https://www.metavert.io/lightcms-privacy-policy
License
MIT