Architecture
Sola Merlino runs as two cooperating processes — a Fastify application server on port 44887 and a dedicated antidetect engine on port 3500 — backed by three local SQLite stores.
Sola Merlino is a standalone clone of a larger monorepo with the AI content forges stripped out. What remains is the syndication and account-management core: a server that turns a brand's own source content into platform-adapted posts and publishes them from a fleet of real, warmed, account-safe browser identities. The platform is designed for legitimate business syndication — account safety here means IP and network hygiene (a consistent fingerprint, an assigned proxy, and human cadence), never content manipulation.
Two processes
Sola Merlino is split into two independent processes so that the application logic and the browser-isolation layer can be scaled, restarted, and reasoned about separately. The server owns orchestration and persistence; the antidetect engine owns identity coherence at the network and browser-fingerprint level.
Sola Merlino server
A Fastify application on PORT 44887. Entry point is content-distribution/src/index.ts, launched with node --import tsx/esm content-distribution/src/index.ts. It hosts the dashboard, the full API surface, and all orchestration of brands, personas, content, and warming.
Antidetect Engine
A separate process on PORT 3500 responsible for fingerprint isolation and proxy isolation. It injects canvas/WebGL noise, prevents WebRTC IP leaks, masks audio-context and font enumeration, and binds each profile to its proxy so every identity stays consistent.
The dashboard is served from http://localhost:44887/ui/; the root path / redirects there. In desktop mode a local admin is auto-injected, so no login is required when running locally.
Inside the server
The :44887 server is organized into four broad responsibilities. Together they take a source asset from the DAM, ground a platform-adapted post against it, and dispatch publication through a warmed identity.
Ops routes
Operational and monitoring surfaces: queues, errors, alerts, health probes, audit, scheduler, account health, and automation health. These keep the fleet observable and let operators see what is running, what failed, and what is due.
/ops/*Account management
Brand workspaces and their avatar tiers, syndication personas, imported Gmail accounts, account pools, and the warming subsystem that ages each identity from created to ready over a 30-day campaign.
/api/gmail/accountsContent engine
The Universal Writer, mounted at /api/universal-writer/*. It produces platform-adapted social posts grounded in DAM source content, scored on hook strength, platform fit, and engagement before they are queued for syndication.
Engine bridge
The server's connection to the antidetect engine on :3500. It manages profiles, proxies, and behavioral binding, exposing the engine's capabilities to runners through the server's own API rather than direct cross-process calls from the UI.
/api/antidetect/*From source to social
A request flows from the Ponmelli DAM through the Universal Writer and on to the runners, which drive real browsers under antidetect protection:
Source
The Ponmelli DAM supplies one of its source assets as grounding material for the post.
Adapt
The Universal Writer (
socialtype) generates per-platform variants, grounded in the source via RAG and scored before staging.Dispatch
The cascade and syndication runners pick up due work and bind each action to a persona's stable fingerprint and assigned proxy region.
Publish
Posts go out to YouTube, Twitter, Facebook, and LinkedIn at human cadence — and only when the identity's aging stage allows.
Persistence
All state is local. Sola Merlino keeps three SQLite stores on disk, with no external database server required. Redis runs in memory-fallback mode, so any ECONNREFUSED for Redis in the logs is harmless.
| Store | Path | Holds |
|---|---|---|
| Application database | data/content-distribution.db | Brand workspaces, personas, Gmail accounts, account pools, warming campaigns, syndication state. |
| Ponmelli DAM | data/ponmelli/assets.db | The asset catalog — 621 source assets across article, social, blog, gbp, pbn, podcast, review, video-script, image, voice-dna, template, and keyword-card types, each moving through a draft to archived lifecycle. |
| Engine store | data/ghost-engine | The antidetect engine's persisted profiles, proxy bindings, and behavioral state. |
The application database location is configured by DATABASE_URL, which in desktop mode points at the absolute path of content-distribution.db:
DATABASE_URL=file:<abs>/data/content-distribution.db
Because node_modules is bundled, there is no npm install step, and there is no per-machine lock — the same data directory runs on any machine.
Runtime notes
The server validates a small set of environment expectations at startup and falls back gracefully where it can. The defaults below are what desktop mode assumes.
| Variable | Value | Meaning |
|---|---|---|
PORT | 44887 | Fastify server port. |
DEPLOY_MODE | desktop | Validated at startup; enables the auto-injected local admin. |
REDIS_MODE | memory | In-memory fallback; no external Redis needed. |
CSRF_PROTECTION | false | Disabled for local desktop operation. |
DEPLOY_MODE=desktop is validated when the server boots. REDIS_MODE=memory means Redis runs entirely in process, so a Redis ECONNREFUSED line in the logs is expected and harmless. Node 20 or newer is required.
The engine bridge keeps an internal /ghost-engine/* route prefix used between the server and the antidetect engine. This is an implementation detail — the UI never calls it directly. Application code reaches the engine through the server's /api/antidetect/* surface instead.
Sola Merlino · social syndication + account automation · documentation generated 2026-06-27