https://github.com/mx-space/core
AI-powered CMS core for personal blogs and creator websites, with AI summaries, translation, moderation, and writing workflows.
https://github.com/mx-space/core
ai ai-cms ai-summary ai-translation blog-cms content-workflow creator-tools headless-cms llm mongodb nestjs personal-blog redis self-hosted typescript
Last synced: 21 days ago
JSON representation
AI-powered CMS core for personal blogs and creator websites, with AI summaries, translation, moderation, and writing workflows.
- Host: GitHub
- URL: https://github.com/mx-space/core
- Owner: mx-space
- License: other
- Created: 2021-07-14T14:47:50.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2026-04-15T14:32:42.000Z (about 2 months ago)
- Last Synced: 2026-04-15T16:33:59.836Z (about 2 months ago)
- Topics: ai, ai-cms, ai-summary, ai-translation, blog-cms, content-workflow, creator-tools, headless-cms, llm, mongodb, nestjs, personal-blog, redis, self-hosted, typescript
- Language: TypeScript
- Homepage:
- Size: 18.3 MB
- Stars: 517
- Watchers: 1
- Forks: 139
- Open Issues: 16
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
MX Space Core
AI-powered CMS Core for personal blogs, creator homepages & content websites.
---
## Overview
MX Space Core is a headless CMS server built with **NestJS**, **PostgreSQL**, and **Redis**. Beyond standard blog features (posts, pages, notes, comments, categories, feeds, search), it ships with a full AI content workflow — summary generation, multi-language translation, comment moderation, and writing assistance — powered by pluggable LLM providers.
### Key Features
| Category | Capabilities |
|----------|-------------|
| **Content Management** | Posts, notes, pages, drafts, categories, topics, comments, snippets, projects, friend links, subscriptions |
| **AI Workflow** | Summary generation, multi-language translation, comment moderation, writing assistance, streaming responses |
| **LLM Providers** | OpenAI, OpenAI-compatible, Anthropic, OpenRouter |
| **Real-time** | WebSocket via Socket.IO with Redis adapter for multi-instance broadcast |
| **Distribution** | RSS/Atom feeds, sitemap, local search, aggregate API |
| **Auth** | JWT sessions, passkeys, OAuth, API keys (via better-auth) |
| **Deployment** | Docker (multi-arch), PM2, standalone binary |
## Tech Stack
- **Runtime**: Node.js >= 22 + TypeScript 5.9
- **Framework**: NestJS 11 + Fastify
- **Database**: PostgreSQL 16 (Drizzle ORM)
- **Cache**: Redis (ioredis)
- **Validation**: Zod 4
- **WebSocket**: Socket.IO + Redis Emitter
- **AI**: OpenAI SDK, Anthropic SDK
- **Editor**: Lexical (via @haklex/rich-headless)
- **Auth**: better-auth (session, passkey, API key)
- **Testing**: Vitest + PostgreSQL testcontainers / Redis memory server
## Monorepo Structure
```
mx-core/
├── apps/
│ └── core/ # Main server application (NestJS)
├── packages/
│ ├── api-client/ # @mx-space/api-client — typed SDK for frontend & third-party clients
│ ├── cli/ # @mx-space/cli (mxs) — owner-side CLI for content + config
│ ├── db-schema/ # @mx-space/db-schema — shared Drizzle schema + Snowflake utilities (private)
│ ├── mongo-pg-cli/ # @mx-space/mongo-pg-cli — one-shot v11→v12 (MongoDB→PostgreSQL) data migration
│ └── webhook/ # @mx-space/webhook — signature-verified webhook handler SDK
├── docker-compose.yml # Development stack (PostgreSQL + Redis + mx-migrate)
├── dockerfile # Multi-stage production build
└── docker-compose.server.yml # Production deployment template
```
### Core Architecture (`apps/core/src/`)
```
src/
├── modules/ # 45 business modules
│ ├── ai/ # AI summary, translation, insights, writer, agent, task queue
│ ├── auth/ # Better Auth: session, OAuth, passkey, API key
│ ├── post/ # Blog posts
│ ├── note/ # Short notes with topic support
│ ├── comment/ # Nested comments + AI moderation + reader image upload
│ ├── configs/ # Runtime configuration
│ ├── enrichment/ # URL extraction, screenshot pipeline
│ ├── reader/ # Reader identity / image quotas
│ ├── webhook/ # Event dispatch to external services
│ ├── serverless/ # User-defined serverless functions
│ └── ... # page, draft, category, topic, feed, search, owner, etc.
├── processors/ # Infrastructure services
│ ├── database/ # PostgreSQL connection + repository registry + BaseRepository
│ ├── redis/ # Cache, pub/sub, emitter
│ ├── gateway/ # WebSocket (admin, web, shared namespaces)
│ ├── task-queue/ # Distributed job queue (Redis + Lua)
│ └── helper/ # Email, image, JWT, Lexical, URL builder, etc.
├── database/ # Drizzle ORM
│ ├── schema/ # Table definitions
│ └── migrations/ # SQL migration files (release-phase, never run on boot)
├── common/ # Guards, interceptors, decorators, filters, pipes
├── constants/ # Business events, cache keys, error codes
├── transformers/ # Response transformation (snake_case, pagination)
└── utils/ # Utility modules
```
> Historical MongoDB → PostgreSQL data migration lives in [`packages/mongo-pg-cli`](./packages/mongo-pg-cli). Forward schema migrations live in `apps/core/src/database/migrations/` and run as a one-shot release-phase step (see the [release-phase migration design](./docs/superpowers/specs/2026-05-05-database-migration-release-phase-design.md)).
## Quick Start
### Prerequisites
| Dependency | Version |
|-----------|---------|
| Node.js | >= 22 |
| pnpm | Latest (via Corepack) |
| PostgreSQL | 16+ |
| Redis | 7.x |
### Local Development
```bash
# Enable Corepack for pnpm
corepack enable
# Install dependencies
pnpm install
# Start PostgreSQL + Redis (via Docker)
docker compose up -d postgres redis
# Start dev server (port 2333)
pnpm dev
```
The API is available at `http://localhost:2333`. In development mode, routes have no `/api/v2` prefix.
### Docker Deployment
The fastest way to get a production instance running:
```bash
# Clone and enter the project
git clone https://github.com/mx-space/core.git && cd core
# Edit environment variables
cp docker-compose.server.yml docker-compose.prod.yml
# Edit docker-compose.prod.yml — set JWT_SECRET, ALLOWED_ORIGINS, etc.
# Start all services
docker compose -f docker-compose.prod.yml up -d
```
Or use the prebuilt image directly:
```bash
docker pull innei/mx-server:latest
```
The image supports `linux/amd64` and `linux/arm64`.
## Available Commands
Run from the repository root:
| Command | Description |
|---------|-------------|
| `pnpm dev` | Start development server (watch mode) |
| `pnpm build` | Build the core application |
| `pnpm bundle` | Create production bundle (tsdown) |
| `pnpm test` | Run test suite (Vitest) |
| `pnpm lint` | Run ESLint with auto-fix |
| `pnpm typecheck` | TypeScript type checking |
| `pnpm format` | Format code with Prettier |
### Running Tests
```bash
# Run all tests
pnpm test
# Run a specific test file
pnpm test -- test/src/modules/user/user.service.spec.ts
# Run tests matching a pattern
pnpm test -- --testNamePattern="should create user"
# Watch mode
pnpm -C apps/core run test:watch
```
## Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `JWT_SECRET` | Secret for JWT signing | Required |
| `ALLOWED_ORIGINS` | CORS allowed origins (comma-separated) | — |
| `PG_URL` | Full PostgreSQL connection string | — |
| `PG_HOST` | PostgreSQL host | `127.0.0.1` |
| `PG_PORT` | PostgreSQL port | `5432` |
| `PG_USER` | PostgreSQL user | `mx` |
| `PG_PASSWORD` | PostgreSQL password | `mx` |
| `PG_DATABASE` | PostgreSQL database name | `mx_core` |
| `PG_MAX_POOL_SIZE` | PostgreSQL connection pool size | `20` |
| `PG_SSL` | Enable PostgreSQL SSL | `false` |
| `REDIS_HOST` | Redis host | `localhost` |
| `REDIS_PORT` | Redis port | `6379` |
| `REDIS_PASSWORD` | Redis password | — |
| `SNOWFLAKE_WORKER_ID` | Snowflake ID worker ID (0–1023) | Required |
| `ENCRYPT_ENABLE` | Enable field encryption | `false` |
| `ENCRYPT_KEY` | 64-char hex encryption key | — |
| `THROTTLE_TTL` | Rate limit window (seconds) | `10` |
| `THROTTLE_LIMIT` | Max requests per window | `100` |
| `PORT` | Server port | `2333` |
| `TZ` | Timezone | `Asia/Shanghai` |
| `DISABLE_CACHE` | Disable Redis caching | `false` |
Configuration can also be provided via CLI arguments or YAML files. See `apps/core/src/app.config.ts` for the full config schema.
## API Response Format
All responses are automatically transformed by interceptors:
- **Array** → `{ data: [...] }`
- **Object** → returned as-is
- **Paginated** (via `@Paginator`) → `{ data: [...], pagination: {...} }`
- **Bypass** (via `@Bypass`) → raw response
All response keys are converted to **snake_case** (e.g., `createdAt` → `created_at`).
## Upgrading
### v11 → v12
v12 migrates the database from MongoDB to PostgreSQL. This is a hard cutover: all data must be migrated through the provided CLI before starting the new version. See [Upgrading to v12](./docs/migrations/v12.md).
### v10 → v11
v11 refactors the Aggregate API: `categories` and `pageMeta` are removed from `GET /aggregate`; a new `GET /aggregate/site` endpoint is added for lightweight site metadata. See [Upgrading to v11](./docs/migrations/v11.md).
### v9 → v10
v10 includes a breaking auth system refactor. See [Upgrading to v10](./docs/migrations/v10.md).
## Related Projects
| Project | Description |
|---------|-------------|
| [Yohaku](https://github.com/Innei/Yohaku) | Next.js frontend |
| [mx-admin](https://github.com/mx-space/mx-admin) | Vue 3 admin dashboard |
| [@mx-space/api-client](./packages/api-client) | TypeScript API client SDK |
| [@mx-space/cli](./packages/cli) | `mxs` CLI for posts/notes/pages/config (OIDC device auth) |
| [@mx-space/mongo-pg-cli](./packages/mongo-pg-cli) | One-shot MongoDB → PostgreSQL migration for v11 → v12 |
| [@mx-space/webhook](./packages/webhook) | Webhook handler SDK (signature-verified) |
| [@haklex/rich-headless](https://github.com/innei/haklex) | Lexical editor (server-side) |
## License
- **`apps/`** — [AGPLv3 with Additional Terms](./ADDITIONAL_TERMS.md)
- **Everything else** — [MIT](./LICENSE)
See [LICENSE](./LICENSE) for full details.