Flixty is a self-hosted social media management platform. Write once, publish everywhere X, LinkedIn, Facebook, Instagram, TikTok, and YouTube with AI-assisted content, scheduling, live streaming, and audience targeting. No SaaS fees, no vendor lock-in.
- Multi-platform publishing post to X, LinkedIn, Facebook, Instagram, TikTok, and YouTube from one interface
- AI Assist generate and rewrite content per platform using Claude (Anthropic) with platform-specific tone and character limits
- Scheduler schedule posts with a calendar view; a built-in cron job publishes them automatically
- Live Streaming create YouTube and Facebook live broadcasts and get RTMP credentials for OBS or any streaming software
- Live Preview see exactly how your post will look on each platform before publishing
- Audience & Targeting configure age, gender, location, language, interest, industry, device, and relationship targeting
- MCP server connect an MCP-compatible chatbot to publish, schedule, manage, and analyze content using your Flixty account
- Google Sign-In users can register and log in with email/password or Google OAuth
- Responsive full mobile UI with bottom navigation and slide-in drawer
| Layer | Technology |
|---|---|
| Backend | Node.js 18+, Express |
| Auth | express-session, crypto (scrypt), Google OAuth 2.0 |
| AI | Anthropic Claude API (@anthropic-ai/sdk) |
| Database | PostgreSQL with startup migrations |
| MCP | Model Context Protocol SDK, Streamable HTTP, OAuth 2.1 + PKCE |
| Scheduling | node-cron |
| File uploads | multer |
| Frontend | Vanilla JS, Tailwind CSS (CDN), Material Symbols |
- Node.js 18 or higher
- npm
- PostgreSQL (required)
- A server or cloud platform (see Deployment)
- API credentials for the platforms you want to enable (all are optional except
SESSION_SECRET)
git clone https://github.com/nexusrun/flixty.git
cd flixty
npm install
cp .env.example .env
# Edit .env and set DATABASE_URL, SESSION_SECRET, and any provider credentials
npm run devOpen http://localhost:3000 in your browser.
npm run devstarts with--watch(auto-restarts on file changes)npm startproduction start
Copy .env.example to .env and fill in the values you need. All platform keys are optional only configure the platforms you intend to use.
PORT=3000
BASE_URL=https://your-domain.com # public URL, used to build OAuth redirect URIs
SESSION_SECRET=replace-with-a-long-random-string
# PostgreSQL (required)
DATABASE_URL=postgres://user:password@host:5432/flixty
# X / Twitter
X_CLIENT_ID=
X_CLIENT_SECRET=
# LinkedIn
LINKEDIN_CLIENT_ID=
LINKEDIN_CLIENT_SECRET=
LINKEDIN_ENABLE_ORGANIZATIONS=false
# Facebook + Instagram
FB_APP_ID=
FB_APP_SECRET=
# TikTok
TIKTOK_CLIENT_KEY=
TIKTOK_CLIENT_SECRET=
# Google (YouTube + Google Sign-In share one client)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
# Anthropic (AI Assist)
ANTHROPIC_API_KEY=
# Optional AI Assist server fallbacks (users can also configure providers in AI Settings)
OPENROUTER_API_KEY=
OPENROUTER_BASE_URL=
OPENAI_API_KEY=
OPENAI_BASE_URL=
GEMINI_API_KEY=
GEMINI_BASE_URL=Important:
BASE_URLmust match the public URL of your deployment exactly (no trailing slash). All OAuth redirect URIs are constructed from this value.
DATABASE_URL is required. Flixty applies the SQL files in lib/db/migrations/ automatically during startup, including the MCP OAuth tables. Keep data/uploads/ on persistent storage in production because uploaded media is stored locally.
Both YouTube publishing and Google Sign-In use the same Google OAuth client.
- Go to Google Cloud Console → APIs & Services → Credentials
- Create an OAuth 2.0 Client ID (Web application)
- Enable these APIs in your project:
- YouTube Data API v3
- YouTube Analytics API (optional)
- Add these Authorized redirect URIs:
https://your-domain.com/auth/youtube/callback https://your-domain.com/api/user/google/callback http://localhost:3000/auth/youtube/callback (local dev) http://localhost:3000/api/user/google/callback (local dev) - Copy
Client ID→GOOGLE_CLIENT_IDandClient Secret→GOOGLE_CLIENT_SECRET - Add your Google account as a Test User under OAuth consent screen → Test users (required while the app is in Testing mode for YouTube scopes)
Facebook and Instagram share a single OAuth flow.
- Go to Facebook Developers → Create App
- Add these products: Facebook Login, Instagram Basic Display
- Required permissions:
pages_show_listpages_manage_postspages_read_engagementinstagram_content_publishpublish_video(required for Facebook Live)
- Add the redirect URI in Facebook Login → Settings → Valid OAuth Redirect URIs:
https://your-domain.com/auth/facebook/callback - Set
FB_APP_IDandFB_APP_SECRETfrom Settings → Basic - Instagram requires a Facebook Page linked to an Instagram Professional account
Note: Facebook requires App Review for production use. In development mode, add test users under Roles → Test Users.
- Go to LinkedIn Developers → Create app
- Request the Share on LinkedIn and Sign In with LinkedIn products
- Add the redirect URI:
https://your-domain.com/auth/linkedin/callback - Copy
Client IDandClient Secretto your.env
Warning: X API free tier no longer includes posting credits. You need the Basic plan ($200/month) or higher to post via the API.
- Go to X Developer Portal → Create Project & App
- Enable OAuth 2.0 with PKCE
- Set app permissions to Read and Write
- Add the callback URL:
https://your-domain.com/auth/x/callback - Copy
Client IDandClient Secretto your.env
- Go to TikTok Developers → Create app
- Enable the Content Posting API
- Add the redirect URI:
https://your-domain.com/auth/tiktok/callback - Set
TIKTOK_CLIENT_KEYandTIKTOK_CLIENT_SECRET
Note: TikTok requires manual app review before the Content Posting API works in production. In sandbox mode, add your TikTok account as a test user.
AI Assist supports Anthropic, OpenRouter, OpenAI, and Google Gemini. Configure a provider and key in the dashboard’s AI Settings, or set a server fallback key in .env:
- Anthropic API keys —
ANTHROPIC_API_KEY - OpenRouter API keys —
OPENROUTER_API_KEY - OpenAI API keys —
OPENAI_API_KEY - Google AI Studio keys —
GEMINI_API_KEY
OpenAI uses its compatible chat endpoint, while Gemini uses Google’s native generateContent API. Gemini’s default base URL is https://generativelanguage.googleapis.com/v1beta.
AI Assist preserves supplied facts, names, numbers, URLs, and handles and tailors output to each platform’s tone and character limit.
Flixty includes a remote Model Context Protocol (MCP) server. An MCP-compatible chatbot can use the server to publish content, schedule posts, cancel scheduled posts, list publishing history, and inspect engagement analytics.
The MCP server is a remote Streamable HTTP endpoint:
https://your-domain.com/mcp
It uses Flixty's built-in OAuth 2.1 authorization server with dynamic client registration and PKCE. A chatbot does not need a manually-created client secret. The first connection opens Flixty's consent screen; after approval, the chatbot receives a short-lived access token and a refresh token.
- Deploy Flixty at a public HTTPS URL.
localhostis suitable only for local clients running on the same machine. - Configure
BASE_URLto the exact public origin, with no trailing slash. - Configure
DATABASE_URLand start Flixty once so all migrations are applied. - Create a Flixty user account and sign in.
- Connect the social accounts you want to use from the Flixty dashboard. MCP uses the same per-user platform connections as the web app; it does not bypass platform OAuth.
- Confirm that
https://your-domain.com/healthreturns{ "ok": true }.
In the chatbot's MCP, Connectors, or Custom Integrations settings, add the remote server URL:
https://your-domain.com/mcp
Allow the chatbot to discover the OAuth endpoints and complete the browser login/consent flow. If the client asks for an authorization server URL, use:
https://your-domain.com/.well-known/oauth-authorization-server
If it asks for the protected resource metadata URL, use:
https://your-domain.com/.well-known/oauth-protected-resource
Examples:
- Claude.ai or another hosted chatbot: add the URL as a custom/remote connector, then sign in to Flixty when the consent window appears.
- Claude Desktop or another desktop MCP client: use its remote MCP/HTTP connector configuration and enter the same URL. Client configuration names vary by version; use the OAuth discovery flow rather than pasting a bearer token.
- ChatGPT or another MCP-enabled chatbot: add the endpoint under its MCP, Apps, or Connectors settings, then complete Flixty's OAuth flow. Availability and UI labels depend on the client plan and version.
After the connection succeeds, try a read-only request such as:
Show my Flixty publishing overview for the last 30 days.
For a write request, clearly identify the target platforms and media. For example:
Publish this announcement to LinkedIn and Facebook: "We just launched our new community program."
The chatbot should ask for confirmation according to its own safety settings before calling a write tool.
Flixty exposes these protocol endpoints from the same origin as the app:
| Method | Endpoint | Purpose |
|---|---|---|
GET |
/.well-known/oauth-authorization-server |
OAuth server discovery metadata |
GET |
/.well-known/oauth-protected-resource |
MCP resource metadata |
POST |
/oauth/register |
Dynamic public-client registration |
GET / POST |
/oauth/authorize |
Login and user consent |
POST |
/oauth/token |
Exchange authorization codes or rotate refresh tokens |
POST |
/mcp |
Streamable HTTP MCP requests |
For an MCP client that does not provide automatic discovery, the connection sequence is:
- Read
/.well-known/oauth-protected-resourceto find the authorization server. - Read
/.well-known/oauth-authorization-serverto find registration, authorization, and token endpoints. - Register a public client with
POST /oauth/register, supplying the chatbot'sclient_nameand OAuthredirect_uris. - Generate a PKCE verifier/challenge pair and open the authorization endpoint with
response_type=code,client_id,redirect_uri,code_challenge,code_challenge_method=S256, and a randomstate. - Let the user log in and approve access in Flixty, then validate
stateand exchange the returned code at/oauth/tokenwith the PKCE verifier. - Send MCP requests to
/mcpwithAuthorization: Bearer <access_token>. Refresh the token when it expires.
The authorization code flow requires S256 PKCE. Access tokens expire after one hour; refresh tokens expire after 90 days and are rotated when used. Token values are stored as SHA-256 hashes, and every MCP request is mapped to the Flixty user who approved the connection. A client can access only that user's connected accounts, posts, schedules, and analytics.
To verify that the protected endpoint is active without exposing a token:
curl -i https://your-domain.com/mcpThe expected response is 401 Unauthorized with a WWW-Authenticate header pointing to the protected-resource metadata endpoint. Do not put access or refresh tokens in the README, shell history, screenshots, or issue reports.
All tools are registered for the authenticated Flixty user.
| Tool | What it does |
|---|---|
create_post |
Publishes immediately to one or more connected platforms |
schedule_post |
Schedules a future publication using an ISO 8601 date-time |
list_posts |
Lists recent published posts, newest first; limit is 1–50 and defaults to 10 |
list_scheduled |
Lists upcoming scheduled posts |
cancel_scheduled |
Cancels a scheduled post by its numeric id |
get_overview |
Returns totals and per-platform engagement for 7d, 30d, or 90d |
get_top_posts |
Ranks posts by likes + comments + shares for a selected range, optionally filtered by platform |
get_hashtag_performance |
Groups engagement by hashtag for a selected range |
create_post and schedule_post accept:
linkedin, facebook, instagram, youtube, tiktok
X/Twitter is intentionally not exposed through MCP because posting requires the paid X API tier in this project; use the Flixty web UI for the supported manual/web-publishing flow. TikTok publishing is sandbox/private-account only until the app is approved for public Content Posting API access. Instagram publishing uses the connected Facebook/Instagram integration.
Both publishing tools support:
imageUrl— a public HTTP(S) image URL for Facebook or InstagramvideoUrl— a public HTTP(S) video URL for YouTube or FacebookimageData/videoData— base64 media for files that are not publicly hostedmediaMimeType— required with inline data; supported types include JPEG, PNG, GIF, WebP, MP4, QuickTime, and WebMthumbnailUrlorthumbnailData— an optional YouTube thumbnailthumbnailMimeType— required when usingthumbnailDatacampaignName— optional campaign name; for YouTube it is used as the video title
Inline media is capped at approximately 45 MB decoded, and the /mcp request body limit is 65 MB. URL downloads accept only HTTP(S), do not follow redirects, reject private/internal IP addresses, and allow only the media MIME types listed above. For scheduled video posts, Flixty downloads the media while scheduling so it is available when the scheduler runs.
- OAuth discovery fails: check that
BASE_URLis public HTTPS and has no trailing slash. Verify both.well-knownURLs in a browser or withcurl. - The chatbot connects but sees no platforms: log in to Flixty and connect the desired social accounts in the dashboard. Reconnect the MCP client after changing account connections if necessary.
- A tool reports an expired token: reconnect the chatbot or allow it to use its refresh token. Access tokens last one hour.
- A media request fails: use a public URL with an allowed MIME type, or provide valid base64 plus its MIME type. For larger files, host the file at a public HTTPS URL.
- A TikTok post is private: this is expected in the current sandbox implementation until TikTok approves public posting for the app.
- A request to X fails: X is not one of the MCP publishing targets; publish it through the Flixty web interface.
Flixty is optimized for deployment on NEXUS AI.
- Push your code to GitHub
- Connect your repo in the NexusAI dashboard
- Add all environment variables from your
.envin Settings → Environment Variables - Set
BASE_URLto your NexusAI app URL (e.g.https://your-app.nexusai.run) - Deploy
Flixty requires a PostgreSQL database. The included Dockerfile builds the app container; provision PostgreSQL separately or attach a managed PostgreSQL service and set DATABASE_URL.
# Clone and install
git clone https://github.com/your-username/flixty.git
cd flixty
npm install
# Configure
cp .env.example .env
nano .env # fill in DATABASE_URL, BASE_URL, SESSION_SECRET, and provider keys
# Run with PM2 (recommended for production)
npm install -g pm2
pm2 start server.js --name flixty
pm2 saveUse nginx as a reverse proxy:
server {
listen 80;
server_name your-domain.com;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}Then add SSL with Certbot:
certbot --nginx -d your-domain.comFlixty stores application data in PostgreSQL. Database migrations run automatically when the server starts. The database includes:
- User accounts and connected platform OAuth tokens
- Published posts and platform results
- Scheduled posts and live stream sessions
- Analytics metrics and AI insights
- MCP clients, authorization codes, access tokens, and refresh tokens
Uploaded images, videos, and thumbnails are stored under data/uploads/, not in PostgreSQL. For production, mount data/ on persistent storage as well as provisioning persistent PostgreSQL. Losing data/uploads/ can make scheduled media unavailable.
data/is in.gitignoreby default — tokens and user data are never committed.
flixty/
├── server.js # Express app entry point
├── lib/
│ ├── auth.js # Password hashing (scrypt), requireAuth middleware
│ ├── db/ # PostgreSQL pool, migrations, and schema
│ ├── mcp/ # MCP tools and safe media resolution
│ ├── mcpOAuth/ # MCP OAuth 2.1 / PKCE persistence and URLs
│ ├── scheduler.js # node-cron job for scheduled posts
│ └── store.js # PostgreSQL data access helpers
├── routes/
│ ├── user.js # Register, login, logout, Google Sign-In
│ ├── auth.js # Platform OAuth flows (X, LinkedIn, Facebook, YouTube, TikTok)
│ ├── posts.js # Publish now, schedule, list posts
│ ├── ai.js # AI content generation (Anthropic)
│ ├── live.js # Live stream create/end/status
│ ├── analytics.js # Engagement and AI insights
│ ├── oauthServer.js # MCP OAuth discovery, registration, consent, tokens
│ └── mcp.js # Bearer-protected Streamable HTTP MCP endpoint
├── platforms/
│ ├── twitter.js
│ ├── linkedin.js
│ ├── facebook.js
│ ├── instagram.js
│ ├── youtube.js
│ └── tiktok.js
├── public/
│ └── index.html # Single-page frontend (Vanilla JS + Tailwind)
├── data/ # Auto-created at runtime (gitignored)
│ └── uploads/ # Local media files used by publishing/scheduling
├── .env.example
└── package.json
| Method | Path | Description |
|---|---|---|
POST |
/api/user/register |
Register with name, email, password |
POST |
/api/user/login |
Login with email, password |
POST |
/api/user/logout |
End session |
GET |
/api/user/me |
Get current user |
GET |
/api/user/google |
Initiate Google Sign-In |
GET |
/api/user/google/callback |
Google OAuth callback |
| Method | Path | Description |
|---|---|---|
GET |
/auth/status |
Connection status for all platforms |
GET |
/auth/{platform} |
Initiate OAuth for platform |
GET |
/auth/{platform}/callback |
OAuth callback |
DELETE |
/auth/{platform} |
Disconnect platform |
Platforms: x, linkedin, facebook, youtube, tiktok
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/publish |
Required | Publish to selected platforms |
POST |
/api/schedule |
Required | Schedule a post |
GET |
/api/posts |
— | List published posts |
GET |
/api/scheduled |
— | List scheduled posts |
DELETE |
/api/scheduled/:id |
Required | Cancel a scheduled post |
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/ai/generate |
Required | Generate content for a platform |
POST |
/api/ai/improve |
Required | Improve existing content |
POST |
/api/ai/adapt |
Required | Adapt content for a target platform |
POST |
/api/ai/hashtags |
Required | Suggest relevant hashtags |
POST |
/api/ai/image |
Required | Generate an image and save it to uploads |
POST |
/api/ai/video |
Required | Start an asynchronous video generation job |
GET |
/api/ai/video/status/:jobId |
Required | Poll a video generation job |
GET / PUT |
/api/ai/settings |
Required | Read or update the user's AI provider settings |
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/api/live/start |
Required | Create YouTube/Facebook broadcast |
POST |
/api/live/:id/end |
Required | End a broadcast |
GET |
/api/live/:id/status |
Required | Poll viewer counts |
GET |
/api/live |
Required | List stream history |
The MCP endpoint is protected by OAuth bearer tokens. MCP clients should use the discovery and authorization flow described in MCP Server and Chatbot Integration rather than hard-coding tokens.
| Method | Path | Auth | Description |
|---|---|---|---|
GET |
/.well-known/oauth-authorization-server |
Public | OAuth server metadata |
GET |
/.well-known/oauth-protected-resource |
Public | Protected MCP resource metadata |
POST |
/oauth/register |
Public | Register an MCP public client dynamically |
GET / POST |
/oauth/authorize |
Session / consent | Authenticate and approve an MCP client |
POST |
/oauth/token |
Public | Exchange a code or rotate a refresh token |
POST |
/mcp |
Bearer token | Handle MCP JSON-RPC / Streamable HTTP requests |
- X/Twitter requires a paid API plan ($200/month Basic) for posting — the free tier has no write credits
- TikTok and Instagram Live streaming have no public API — RTMP credentials are not available for these platforms
- MCP publishing supports LinkedIn, Facebook, Instagram, YouTube, and TikTok; X/Twitter is not exposed as an MCP publishing target
- Storage uses PostgreSQL, while uploaded media remains on the local filesystem; use persistent database and file storage for production
- Sessions are in-memory — users are logged out on server restart unless you add a session store (e.g. connect-redis)
Pull requests are welcome. For major changes, please open an issue first to discuss what you'd like to change.
- Fork the repo
- Create a feature branch (
git checkout -b feature/my-feature) - Commit your changes
- Push and open a Pull Request
Flixty is an open-source project released under the MIT license. You may use, modify, self-host, and redistribute it under the terms in LICENSE.
