Skip to content
Conduit

mcp server

ZeroHuman-Agency

Self-hosted AI content team — research, score, draft, multi-agent review, publish. Learns from your social metrics. You approve every post.

davidesilver/ZeroHuman-Agencycommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 21, 2026

ZeroHuman — Content Engine

Your self-hosted AI content team: research → score → draft → multi-agent review → publish — and it learns from what works.

ZeroHuman runs your whole content pipeline on your own infrastructure: it researches your topics, scores what matters, writes platform-native drafts, has a four-agent panel review them, and publishes on schedule. Social metrics flow back into scoring weights, so every cycle gets sharper. And you stay in the loop — nothing ships without your approval, and the humanizer writes in your voice from your own gold examples.

Topics + Sources → Research → Scoring → Draft → Review → Publish
                                                 ↑
                                       Metrics feedback loop

Built for: indie creators shipping daily, solo founders doing build-in-public, newsletter writers — and agencies managing multiple brands.


What it does

CapabilityDescription
ResearchPulls from RSS feeds, search APIs, and video platforms in parallel; deduplicates by URL and semantic similarity
ScoringRates each item across configurable dimensions (relevance, credibility, trend signal, alignment with your voice)
Content generationProduces platform-native drafts (LinkedIn, X, Instagram, newsletter, blog) with a Writer → Editor pipeline
Multi-agent reviewOptional four-agent GOD mode: critic, fact-checker, creative enhancer, synthesis verdict
HumanizerStrips AI-isms and re-applies your brand voice using your own gold examples and top performers
Writing LabChallenger/champion rounds for experimental content iteration
NewsletterCompose from approved drafts, preview, and send via transactional email
Social publishingPublish now or schedule via a self-hosted or cloud social publishing satellite
Image generationGenerate images per draft using any compatible image backend
Feedback loopSocial metrics flow back into scoring weights — high-performing content influences future research
ObservabilityCost tracking, agent heartbeats, LLM fallback logs, pipeline health dashboard
NotificationsTelegram bot with lifecycle alerts, daily digest, bot commands, and activity feed
Deep ResearchLong-form research via local-deep-research Docker sidecar
Competitor WatchMonitor competitor content and extract signal for your pipeline
Video intelligenceYouTube trend retrieval and video content analysis
Email marketingBrevo integration for list management and campaign analytics
CLI / MCPCommand-line interface and MCP server for agent-to-agent integration
Brand vaultPer-brand encrypted credential storage — API keys never leave your database unencrypted

Everything is multi-tenant: each brand has isolated data, its own sources, tone of voice, scoring weights, and agent configuration.


Why not just Postiz or n8n?

Use them — ZeroHuman does, happily (Postiz is our optional publishing satellite, behind the social Docker profile). The difference is what happens before scheduling:

Postizn8n + promptsZeroHuman
Scheduling & publishing✅ corevia nodes✅ built-in / via Postiz
Research & scoring of sources—DIY✅ configurable dimensions
Multi-agent editorial review—DIY✅ critic / fact-checker / creative / synthesis
Learns from your social metrics——✅ metrics feed scoring weights
Your voice from your gold examples——✅ humanizer

If all you need is scheduling, Postiz alone is great. ZeroHuman is for when the bottleneck is what to publish, not when.


How it works

┌─────────────────────────────────────────────────────────┐
│                     Browser / API Client                │
└────────────────────────┬────────────────────────────────┘
                         │ HTTPS
┌────────────────────────▼────────────────────────────────┐
│                    Next.js Frontend                     │
│   Dashboard · Auth · Direct DB reads · Proxy to API     │
└──────────┬────────────────────────────────┬─────────────┘
           │ Supabase SDK                   │ HTTP proxy
┌──────────▼───────────┐     ┌─────────────▼─────────────┐
│   Supabase / Postgres │     │    FastAPI Backend         │
│   Auth · RLS · Storage│     │  Research · Scoring       │
│   Migrations 001-042  │     │  Generation · Agents      │
│   pgvector · pg_cron  │     │  Scheduler · Analytics    │
└──────────────────────┘     └─────────────┬─────────────┘
                                            │ HTTP (optional)
                              ┌─────────────▼─────────────┐
                              │   Postiz Satellite         │
                              │  Social publishing & OAuth │
                              │  (self-hosted via Docker)  │
                              └───────────────────────────┘

The frontend handles authentication, the dashboard UI, and direct database reads. Heavy orchestration (research, scoring, generation, scheduling) runs in the FastAPI backend. The database enforces tenant isolation at the row level — no tenant can read another tenant's data even if the application layer has a bug.


Usage modes

Minimal — content drafting only

You can run the platform without any social publishing or image generation. Connect one LLM provider, set up Supabase, and use it purely as a research-to-draft pipeline. The social and image sections of the dashboard will be inactive.

Standard — full content pipeline

Add a search API key for web research, configure sources per brand, enable the feedback loop. Drafts flow through Writer → Editor → GOD mode → Humanizer → approval.

Full — publish and schedule

Connect a social publishing satellite (self-hosted Docker or cloud). The platform handles OAuth delegation and scheduling. Metrics flow back to influence scoring.

Multi-tenant / agency

Create multiple brands, each with its own sources, tone, agents, scoring weights, and social accounts. A single deployment serves all tenants with strict data isolation.


Stack

LayerTechnology
FrontendNext.js 16 (App Router), React 19, TypeScript, Tailwind CSS 4
UI systemBase UI primitives, light-mode-first design tokens, Linear/Sentry/YouTube Studio patterns
BackendPython, FastAPI, uvicorn
DatabasePostgreSQL via Supabase (auth, RLS, storage, vector search)
Social publishingPostiz (self-hosted Docker or cloud — optional)
Package managementnpm (frontend), uv (Python backend)

Quick start

Fastest path — Docker

./setup.sh                                      # generates .env.local interactively
docker compose -f docker-compose.full.yaml --env-file .env.local up -d
# → http://localhost:3000

You need a free Supabase project and one LLM API key (Anthropic or OpenRouter). Everything else is optional: video tooling and the Postiz social stack live behind Docker profiles (--profile video, --profile social).

Prefer to run things directly? The manual path follows.

Prerequisites

  • Node.js 20+
  • Python 3.14+
  • uv (pip install uv or brew install uv)
  • A Supabase project (free tier works)
  • At least one LLM provider API key

1 — Database

Create a Supabase project, then apply the complete schema:

# Fresh setup — apply the consolidated schema in one shot
psql "$DATABASE_URL" -f supabase/schema_complete.sql

schema_complete.sql is the canonical source of truth. It creates all extensions, types, tables, functions, RLS policies, and indexes in a single idempotent file. Individual migration files are not published to this repository.

2 — Environment

cp .env.example .env.local

Open .env.local and fill in the required values (marked # required). See the full variable reference below.

3 — Frontend

npm install
npm run dev
# → http://localhost:3000

4 — Backend

cd python
uv sync
uv run uvicorn src.content_engine.main:app --reload --port 8000
# → http://localhost:8000

5 — First brand

  1. Open http://localhost:3000 and sign up with your email.
  2. Go to Settings → Brands → Add brand and fill in your name, topics, and RSS sources.
  3. Go to Research and click Run research to pull your first batch of items.
  4. Score items, approve the ones you like, then generate your first draft.

That's it. You're in the pipeline.


Environment variables

Required

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

# Backend location (frontend proxies heavy ops here)
PYTHON_BACKEND_URL=http://localhost:8000

# For API text mode, at least one LLM provider
ANTHROPIC_API_KEY=
OPENROUTER_API_KEY=          # used as fallback or primary (many free models available)

# Scheduler security (generate with: openssl rand -hex 32)
SCHEDULER_SECRET=

For an owner-operated local engine, text can instead use your ChatGPT plan through the official Codex CLI: run codex login as the backend user and set LLM_MODE=codex_subscription in .env.local. No text API key is needed in this mode; login or quota failures stop the request without paid fallback. Optional images, embeddings and research services still have their own requirements. See subscription engine setup.

Research (add what you need)

SERPER_API_KEY=              # web search
YOUTUBE_API_KEY=             # YouTube trends
FIRECRAWL_API_KEY=           # premium content extraction (optional; falls back to trafilatura)

Publishing and delivery

RESEND_API_KEY=              # newsletter send
POSTIZ_MODE=disabled         # disabled | self_hosted | cloud
POSTIZ_API_URL=              # required if POSTIZ_MODE != disabled
POSTIZ_API_KEY=              # required if POSTIZ_MODE != disabled

Image generation (pick one or leave as mock)

DEFAULT_IMAGE_BACKEND=mock   # mock | replicate | openai | openrouter | anthropic | pillo
DEFAULT_IMAGE_MODEL=         # backend-specific model identifier
REPLICATE_API_TOKEN=

Operations

ALLOWED_ORIGINS=http://localhost:3000   # comma-separated — must match the Next.js port you use
NEWSLETTER_FROM_EMAIL=hello@yourdomain.com
NEWSLETTER_FROM_NAME=Your Newsletter
TELEGRAM_BOT_TOKEN=          # optional: alert channel
TELEGRAM_CHAT_ID=

Full reference with descriptions: .env.example


Architecture overview

Research pipeline

Each research run fans out across all configured retrievers in parallel. Items are deduplicated first by normalized URL, then by semantic similarity using vector embeddings. Only novel items reach the scoring phase.

Brand config (topics, sources)
        ↓
┌───────────────────────────┐
│  Retrievers (parallel)    │
│  RSS · Search · YouTube   │
│  Manual URL ingestion     │
└───────────────────────────┘
        ↓ deduplicate (URL + vectors)
research_items (status: new)
        ↓
Scoring agent → scores table
        ↓
content_drafts (status: draft)

Content generation

The Writer agent produces an initial draft using brand tone, principles, and gold examples. The Editor agent refines it. Each step reads agent identity and skills from the database — you can customize prompts per brand without touching code.

research_item → Writer → Editor → draft
                                    ↓
                     ┌──────────────┴──────────────┐
                     │        (optional)            │
                  GOD mode                     Humanizer
                  4-agent review               voice calibration
                  critic · factcheck           remove AI patterns
                  creative · synthesis         double-pass refinement
                     └──────────────┬──────────────┘
                                    ↓
                              approved draft
                                    ↓
                    Publish now · Schedule · Newsletter

Agent configuration

Every agent in the system (writer, editor, GOD mode advocates, humanizer) loads its identity and skills from the database at runtime. This means you can:

  • Give each brand a different writer persona
  • Attach specialized skills (e.g., "always end with a question", "use data-driven openings")
  • Update behavior without redeploys

The system falls back to hardcoded defaults if no database configuration exists, so it works out of the box.

Multi-tenancy

Every table that holds operational data has a brand_id foreign key. Row Level Security policies are enforced at the database layer — the application cannot accidentally serve one tenant's data to another. The backend JWT middleware extracts brand_id from the session token and attaches it to every request.


Project structure

/
├── src/                          # Next.js frontend (App Router)
│   ├── app/
│   │   ├── (auth)/               # Login page
│   │   ├── (dashboard)/          # All dashboard pages
│   │   │   ├── page.tsx          # Home / overview
│   │   │   ├── content-hub/      # Draft listing and editor
│   │   │   ├── research/         # Research runs and item management
│   │   │   ├── newsletter/       # Newsletter composition
│   │   │   ├── social/           # Social publishing
│   │   │   ├── writing-lab/      # Experimental writing sessions
│   │   │   ├── metrics/          # Analytics
│   │   │   ├── settings/         # Brand settings, agents, social connections
│   │   │   └── ...
│   │   └── api/                  # Next.js route handlers
│   │       ├── brands/           # Brand CRUD + assets
│   │       ├── content/          # Drafts, generation (proxy)
│   │       ├── research/         # Research trigger + items
│   │       ├── social/           # Publish + schedule (proxy)
│   │       ├── images/           # Image generation (proxy)
│   │       ├── newsletter/       # Send + preview (proxy)
│   │       └── system/           # Health, costs, config
│   ├── components/               # Shared UI components
│   └── lib/                      # Supabase clients, types, helpers
│
├── python/src/content_engine/    # FastAPI backend
│   ├── api/
│   │   ├── routes.py             # Core routes (research, scoring, generation)
│   │   ├── routes_agents.py      # Agent config/skills CRUD
│   │   ├── routes_images.py      # Image generation
│   │   └── routes_postiz.py      # Social publishing bridge
│   ├── agents/                   # Writer, Editor, GOD mode, Humanizer, Adapter
│   ├── orchestrator/             # Research and content pipeline orchestration
│   ├── retrievers/               # RSS, Search, YouTube retrievers
│   ├── scoring/                  # Scoring engine
│   ├── services/                 # Newsletter, Postiz, image backends, scheduler
│   ├── monitoring/               # Pipeline health and fallback monitoring
│   ├── utils/                    # LLM client, cost tracker, rate limiter, SSRF guard
│   └── config/settings.py        # Pydantic settings (all from env)
│
├── supabase/
│   ├── schema_complete.sql       # Canonical schema — apply this for fresh setup
│   └── functions/                # Edge functions (analytics sync)
│
├── docker-compose.postiz.yaml    # Optional social publishing satellite
└── docs/                         # Extended documentation

Social publishing (Postiz satellite)

By default POSTIZ_MODE=disabled and social features are hidden. To enable:

Self-hosted (recommended for full control)

# Start the Postiz stack
docker compose -f docker-compose.postiz.yaml up -d

# Set in .env.local
POSTIZ_MODE=self_hosted
POSTIZ_API_URL=http://localhost:3001
POSTIZ_API_KEY=your-postiz-api-key

Connect your social accounts in the Postiz UI at http://localhost:4200, then paste the integration IDs into Settings → Social Connections in the Content Engine dashboard.

Cloud — Postiz.com managed service

  1. Sign up at postiz.com (free tier supports 3 channels)
  2. Go to Settings → API → generate an API key
  3. Set in .env.local:
POSTIZ_MODE=cloud
POSTIZ_API_URL=https://api.postiz.com
POSTIZ_API_KEY=<your-postiz-api-key>

Cloud — self-managed Postiz on a VPS

Deploy Postiz via its own Docker Compose on any VPS (Hetzner, DigitalOcean, fly.io…), then:

POSTIZ_MODE=cloud
POSTIZ_API_URL=https://postiz.yourdomain.com
POSTIZ_API_KEY=<your-postiz-api-key>

Postiz handles all platform OAuth, rate limiting, and post retry logic. Content Engine stores only opaque integration IDs — no social platform tokens are held in the Content Engine database.


Image generation

Configure per brand in Settings → Image Generation. Available backends:

BackendKey neededExample model
mock—mock-v1 — free placeholder, good for development
replicateREPLICATE_API_TOKENblack-forest-labs/flux-schnell
openaiOPENAI_API_KEYdall-e-3
openrouterOPENROUTER_API_KEYopenai/dall-e-3
anthropicANTHROPIC_API_KEYmodel string from Anthropic docs
pilloPILLO_API_KEYcarousel-v1 — carousel specialist

Set DEFAULT_IMAGE_BACKEND=mock to disable image costs during development. Each brand can override the default in Settings → Image Generation.


Deployment

The platform runs as three services: the Next.js frontend, the FastAPI backend, and Supabase (managed). In production:

  • Deploy the frontend to any Node.js host (Vercel, Fly.io, Railway, etc.)
  • Deploy the backend to any container host; expose port 8000 only to the frontend's network
  • Set SCHEDULER_SECRET and configure your cron system to call /api/scheduler/daily-research and /api/scheduler/publish-scheduled on a schedule

Detailed production checklist: docs/DEPLOYMENT.md


Extending the system

Add a retriever

Create a class in python/src/content_engine/retrievers/ that implements the BaseRetriever interface, then register it in the orchestrator. The base class handles deduplication and DB insertion.

Add an agent

Add an entry to agent_configs in the database with a new agent_key. The agent loader will pick it up. Attach skills via agent_skills without touching code.

Add an image backend

Implement the backend class in python/src/content_engine/services/image_backends/ following the existing pattern, then register it in the image generator's backend registry.

Add a platform

Add the platform to the platform enum in a new migration, add platform-specific formatting rules to the adapter agent, and add the platform's UI entry in the social settings page.


Documentation

DocumentWhat's inside
docs/SETUP.mdPrerequisites, local setup, environment variables, smoke tests
docs/ARCHITECTURE.mdService boundaries, request flow, auth, security controls
docs/AGENTS.mdAgent configuration model, skills system, resolution logic
docs/API.mdRoute inventory, auth model, request/response shapes
docs/ONBOARDING.mdHow to create and configure a new tenant
docs/DEPLOYMENT.mdProduction topology, environment variables, scheduling
docs/POSTIZ_SATELLITE.mdSocial publishing setup, self-hosted vs cloud
docs/database/SCHEMA.mdFull schema reference, migrations, RLS policies

Security notes

  • All backend routes require a valid JWT from the Supabase session (except public health probes)
  • Scheduler endpoints are protected by a separate secret (SCHEDULER_SECRET)
  • Row Level Security is enabled on every tenant-scoped table — isolation is enforced at the database layer
  • Media URLs passed to external services are validated against an SSRF blocklist (no private IPs, no non-HTTPS schemes)
  • CORS is configured with an explicit allowlist (ALLOWED_ORIGINS) — no wildcards
  • API keys and secrets are masked in all log output

Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feat/my-feature
  3. Apply schema locally: psql "$DATABASE_URL" -f supabase/schema_complete.sql
  4. Make your changes, add tests where applicable
  5. Ensure the build passes: npm run lint && npm run build
  6. Ensure backend tests pass: cd python && uv run pytest
  7. Open a pull request with a clear description of what changed and why

See CONTRIBUTING.md and CODE_OF_CONDUCT.md.


License

This project is licensed under the MIT License - see the LICENSE file for details.

What this means for you:

  • ✅ Commercial Use: You can use this code to build products, services, or businesses
  • ✅ Modification: You can modify the code to fit your needs
  • ✅ Distribution: You can distribute your modified versions
  • ✅ Private Use: You can use it privately without sharing your changes
  • ✅ Sublicensing: You can incorporate it into larger projects with different licenses

Only requirement: Keep the license and copyright notice in any distributed copies.

This license is ideal for:

  • Building commercial SaaS products
  • Creating agency solutions for clients
  • Developing internal tools for your company
  • Starting a content automation business
↑↓ navigate openesc close