Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Porting tracker

Port of Postiz at commit e424fb5 (v1.47.0). The original copyright notice is preserved in LICENSE. Status: ✅ ported, tested against mocks · 🟡 partial · ⬜ not done · ➖ removed by design

Nothing here has been tested against a real platform, email service or storage bucket. Most provider code was machine-ported from the TypeScript and checked by its tests. X, LinkedIn, Instagram, Facebook, Threads, YouTube, TikTok, Reddit, Pinterest, Bluesky, Mastodon, Discord, Slack and Telegram also had a machine-run line-by-line comparison with upstream, not a human review. The other providers had spot checks only.

Architecture

PostizThis port
NestJS + Next.js + orchestrator✅ one binary
Temporal + Postgres + Elasticsearch✅ jobs table and in-process worker
Postgres (Prisma)✅ SQLite in WAL mode; same table and column names, no data migration tool
Redis✅ OAuth state is in SQLite; request limits are in-process and per server process
@mastra/mcp✅ rmcp, spec 2026-07-28 and older
Mastra / LangChain / CopilotKit agents➖ agents bring their own LLM
Next.js frontend, calendar, visual editor➖ no GUI
Sentry➖ tracing logs

Providers: 35 of 36

All 35 are ✅: bluesky, dev.to, discord, dribbble, facebook, farcaster (wrapcast), gmb, hashnode, instagram, instagram-standalone, kick, lemmy, linkedin, linkedin-page, listmonk, mastodon, mastodon-custom, medium, mewe, moltbook, nostr, pinterest, reddit, slack, telegram, threads, tiktok, tiktok-business, tumblr, twitch, vk, whop, wordpress, x, youtube.

➖ skool: it only works through the Chrome extension, which was removed.

Known provider differences:

  • image replaces sharp, and a hand-built PDF replaces pdfkit, so output bytes differ. X and LinkedIn uploads need checking against the real APIs.
  • X articles use a small HTML parser instead of parse5.
  • Rust’s regex has no lookaround, so a few patterns were rewritten as equivalents.
  • Farcaster doesn’t validate BIP-39 words. Its Neynar endpoints come from public docs because the SDK source wasn’t available.
  • Analytics dates use UTC rather than server-local time.

Engine

WorkflowStatus
Publishing, threads, pending media, token refresh, duplicate protection, repeats✅
Missing posts and token refresh sweeps✅
Plugs (global and internal)✅ dispatch tested at provider level
RSS autopost✅ posts feed items as they are; LLM rewrite and image generation removed by design
Streak, digest and transactional email✅ Resend tested against a mock; SMTP/SES are config-tested only
Media✅ JPEG conversion works on local and object storage (mock store in tests); thumbnails need ffmpeg
Short links (Dub, Short.io, Kutt, LinkDrip)✅ Short.io stats read up to 10 pages

API and MCP

AreaStatus
Public API /public/v1, including analytics, webhooks, tags, sets, signatures, customers, posting times✅
MCP: 31 tools covering channels, posts, media, analytics, management, plugs, autopost✅
CLI for agents over the public API✅ channels connect not run against a real login
Edit and reschedule posts, media delete, mention lookup✅
Headless connections for every provider (Telegram, Moltbook, Farcaster included)✅ mock servers only
Provider readiness (providers/status, early refusal when credentials are missing)✅
MCP OAuth: PKCE, Client ID Metadata Documents, DCR for older clients✅
MCP Tasks extension, polling✅ type: "now" only
MCP URL elicitation for login links🟡 implemented, no test with a real client
MCP subscriptions/listen✅ polls the database; slow-client drop is untested
Storage: local, S3, R2🟡 S3/R2 use a mock store in tests
Docker image⬜ Dockerfile exists, not built in this port

Removed by design

Users, login, teams and invites (the API key identifies an organization), Stripe billing and credits, admin, marketplace, the Chrome extension, the Node SDK, all media generation (image, video, slides, clipping, HeyGen, ReelFarm, Seedance), HubSpot, and upstream’s LLM draft splitting (/posts/separate-posts). Agents bring their own LLM and media tools.

Deliberate behaviour changes

  • A stray job for an already-published post finishes silently; Postiz marks the post ERROR.
  • Unknown publish errors wait 5 seconds before retrying.
  • Request bodies are redacted before being stored in Errors.
  • The server refuses to start without JWT_SECRET; rustiz init generates it.
  • Only creating posts over REST uses API_LIMIT, as upstream. /mcp and other API routes get a separate REQUEST_LIMIT, and OAuth endpoints have per-address limits.
  • Media delete keeps the stored file, as upstream does.
  • Importing data from an existing Postiz is not offered: hosted users’ account tokens stay on Postiz’s servers, so they would reconnect anyway.
  • /mcp/{key} is gone: API keys only travel in headers.
  • previewUrl is gone from schedulePostTool results, since there is no preview page.