An autonomous multi-agent system that runs your business on autopilot. Nine specialized AI agents handle social media, competitor research, email outreach, ads management, customer support, code generation, business planning, finance, and orchestration — all powered by Claude Code CLI in headless mode.
┌─────────────────────────────────────────────────────────┐
│ nginx │
│ / → frontend /api/ → backend │
└────────────────┬────────────────────┬───────────────────┘
│ │
┌────────▼──────┐ ┌────────▼──────────┐
│ Next.js 14 │ │ FastAPI (Python) │
│ (frontend) │ │ + WebSocket │
└───────────────┘ └────────┬───────────┘
│
┌───────────────────────┼───────────────────┐
│ │ │
┌────────▼────────┐ ┌──────────▼──────┐ ┌────────▼──────┐
│ PostgreSQL 16 │ │ Redis + Celery │ │ ChromaDB │
│ (15 tables) │ │ (task queue) │ │ (vector mem) │
└─────────────────┘ └──────────────────┘ └───────────────┘
| Agent | Responsibility | Schedule |
|---|---|---|
| Orchestrator | Writes morning plan + evening summary | 06:00 / 20:00 |
| Business Planning | Strategy, KPIs, growth recommendations | Daily |
| Competitor Research | Web search, profile updates | Daily |
| Social Media | Draft + post tweets | Every 2h |
| Email Outreach | Prospect finding + cold email sequences | Every 3h |
| Customer Support | Read inbox, draft replies | Every 3h |
| Ads Management | Google + Meta campaign optimization | Every 6h |
| Code Generation | Ship features, open PRs | On demand |
| Finance | Stripe revenue sync, spend tracking | Every 6h |
Each agent calls claude -p "..." --output-format json as a subprocess. No API key is needed — the Claude Code CLI authenticates via OAuth stored at ~/.claude.
- Docker + Docker Compose
- Claude Code CLI installed and authenticated (
claude login) - (Optional for real operations) Stripe, Twitter, SendGrid, Tavily, Google Ads, Meta Ads accounts
# 1. Clone and configure
git clone <repo>
cd polsia
cp .env.example .env
# Edit .env — at minimum set API_KEY and SANDBOX_MODE=true
# 2. Start all services
docker-compose up -d
# 3. Initialize the database and seed company data
make init-db
# 4. Open the dashboard
open http://localhostThe stack is up when http://localhost/api/v1/health returns {"status": "ok"}.
| Variable | Description |
|---|---|
API_KEY |
Secret key for the dashboard API (X-API-Key header) |
SANDBOX_MODE |
true = no real posts/emails/charges (default) |
CLAUDE_CLI_PATH |
Path to the claude binary (default /usr/local/bin/claude) |
The Claude CLI authenticates via the ~/.claude directory on your host, which is mounted read-only into the containers. Run claude login on your host once before starting the stack.
Fill in the relevant sections of .env to activate each integration:
- Twitter/X — Post social content
- SendGrid + IMAP — Send cold emails, read support inbox
- Tavily — Web search for competitor research
- Google Ads / Meta Ads — Campaign management
- Stripe — Revenue and expense tracking
- GitHub — Open PRs from the code generation agent
make up # Start all Docker services
make down # Stop all services
make build # Rebuild images
make logs # Tail all logs
make shell-backend # Open a shell in the backend container
make migrate # Run Alembic migrations
make seed # Seed company data
make init-db # migrate + seed
make test # Run unit + integration tests
make test-unit # Unit tests only
make lint # Ruff + mypy + ESLint
make reset-db # Drop and recreate schemacd backend
CLAUDE_CLI_MOCK=true pytest tests/unit/ -v --cov=appThe CLAUDE_CLI_MOCK=true flag makes all agents return a mock response without invoking the CLI binary. This is also how CI works.
polsia/
├── backend/
│ ├── app/
│ │ ├── agents/ # 9 agent implementations
│ │ │ ├── base_agent.py # call_claude() subprocess wrapper
│ │ │ ├── crew_factory.py # AGENT_MAP registry
│ │ │ ├── orchestrator/
│ │ │ ├── social_media/
│ │ │ ├── competitor_research/
│ │ │ ├── business_planning/
│ │ │ ├── email_outreach/
│ │ │ ├── customer_support/
│ │ │ ├── ads_management/
│ │ │ ├── code_generation/
│ │ │ └── finance/
│ │ ├── api/v1/ # REST endpoints + WebSocket
│ │ ├── core/ # DB, Redis, ChromaDB, security, retry
│ │ ├── models/ # SQLAlchemy ORM (15 tables)
│ │ ├── schemas/ # Pydantic request/response models
│ │ └── services/ # Business logic layer
│ ├── celery_app/ # Celery worker, Beat schedule, tasks
│ ├── alembic/ # Database migrations
│ └── tests/
│ ├── unit/ # SQLite in-memory, CLAUDE_CLI_MOCK=true
│ └── integration/ # Testcontainers (real Postgres + Redis)
├── frontend/
│ └── src/
│ ├── app/ # Next.js 14 pages (9 routes)
│ ├── components/ # ActivityFeed, MetricsCard, AgentStatusGrid, Sidebar
│ ├── hooks/ # useActivityFeed (WebSocket), useAgentStatus (polling)
│ └── lib/ # Typed API client
├── e2e/ # Playwright end-to-end tests
├── nginx/ # Reverse proxy config
├── scripts/ # init_db.sh, seed_company.py
├── docker-compose.yml
├── docker-compose.ci.yml # CI override (CLAUDE_CLI_MOCK=true, no nginx)
└── Makefile
Three GitHub Actions workflows run automatically:
| Workflow | Trigger | Jobs |
|---|---|---|
ci.yml |
PR + push to main | Lint (ruff, mypy, ESLint), unit tests |
integration.yml |
Push to main | Integration tests (testcontainers), Playwright E2E |
docker-build.yml |
Push to main | Build all images, health-check the stack |
All CI jobs set CLAUDE_CLI_MOCK=true — no Claude credentials are needed in GitHub Actions.
When you're ready to let agents operate for real:
- Set
SANDBOX_MODE=falsein.env - Fill in the relevant API keys for the integrations you want active
- Restart the stack:
make down && make up
Agents will now post to Twitter, send emails, create ad campaigns, and issue Stripe operations.