API-first AI social content agent. Generate on-brand posts and comments with Claude (multi-provider), schedule across platforms, and publish through official APIs — X, Instagram Graph (business/creator), with LinkedIn and Bluesky on the roadmap.
Built and maintained by VeyraLabs. A hard fork of Riona-AI-Agent by David-patrick-chuks (MIT) — see NOTICE. VeyraCast re-centers the project on official-API publishing (lower ban risk than browser automation), swaps the content engine to a pluggable multi-provider layer defaulting to Claude, and adds brand-voice guardrails and an approval queue.
⚠️ Instagram note. The legacy stealth-browser Instagram path is retained only as an explicit opt-in (IG_MODE=stealth) and is off by default — it violates Meta's ToS and risks account bans. The default IG path targets the official Instagram Graph API for business/creator accounts.
The fastest way to run the whole stack (API + PostgreSQL):
cp .env.example .env # add your ANTHROPIC_API_KEY, and set JWT_SECRET / SESSION_SECRET
docker compose upThe API comes up on http://localhost:3000 and the dashboard on http://localhost:3000/dashboard. PostgreSQL runs alongside it and the schema is applied on startup.
The image skips the headless-browser download by default (the official-API path doesn't need it). To use the stealth Instagram mode (IG_MODE=stealth), build with a Chrome-enabled base image.
The compose file ships throwaway dev values for
JWT_SECRETandSESSION_SECRETso it boots out of the box. Set real values in.envbefore exposing it to anyone.
The agent generates schema-constrained JSON via a pluggable provider. Select with AI_PROVIDER:
AI_PROVIDER |
Backend | Notes |
|---|---|---|
anthropic (default) |
Claude | Structured outputs (output_config.format); model via ANTHROPIC_MODEL (default claude-opus-4-8) |
gemini |
Gemini | Original behavior: JSON mode + API-key rotation |
Set ANTHROPIC_API_KEY (and optionally ANTHROPIC_MODEL) for the default provider.
Before running automation, you can shape the agent with:
- YouTube video URLs
- Audio files
- Portfolio or website links
- Documents and text files including PDF, DOC, DOCX, and TXT
- Instagram automation with cookies, relogin handling, posting, scheduling, and interactions
- AI-generated captions and comments with schema-guided responses
- Multi-account and profile-based operation support
- PostgreSQL-backed action logs, summaries, and optional persistence
- Simple dashboard for runtime health and latest activity
- Logging, environment validation, and utility scripts for operations
- Complete X/Twitter workflow coverage
- GitHub automation
- Additional analytics, reporting, and compliance controls
- Clone the repository:
git clone https://github.com/veyralabsgroup/veyracast.git
cd veyracast- Install dependencies:
This is a pnpm workspace monorepo. Install pnpm, then:
pnpm install- Set up environment variables:
Copy
.env.exampleto.envin the repo root and add your credentials. All apps read from this file.
This repository is a pnpm workspace with one app and shared tooling:
| Package | Path | Description |
|---|---|---|
@veyracast/api |
apps/api/ |
Main API, Instagram/X automation, dashboard |
@veyracast/tsconfig |
packages/tsconfig/ |
Shared TypeScript config |
pnpm install # install all workspace deps
pnpm dev # run API (@veyracast/api)
pnpm --filter @veyracast/api <script> # run any API scriptFull layout, paths, and contributor workflow: Guides/Monorepo.md.
The app uses PostgreSQL for action logs. If DATABASE_URL is not set, action logs fall back to apps/api/logs/actionLogs.json.
pnpm db:upThis starts PostgreSQL on port 5432 with credentials that match .env.example.
Install PostgreSQL locally, create a database, and point .env at it:
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/veyracastCreate the database if needed:
createdb veyracastSchema is applied automatically on startup. To run migrations manually:
pnpm db:migratedocker compose ps
# or
psql "$DATABASE_URL" -c '\dt'Stop Docker Postgres:
pnpm db:downIf your fork still uses MONGODB_URI, merge this branch and update .env:
- Remove
MONGODB_URI/MONGODB_REQUIRED - Add
DATABASE_URLandDB_REQUIRED=false(see.env.example) - Run
pnpm install - Start Postgres with
pnpm db:upor use your local instance
No data migration script is provided — MongoDB action logs were optional and the app still works without a database.
- Run the agent:
pnpm start
# or during development:
pnpm devThis starts the API server on port 3000 and opens the dashboard at http://localhost:3000/dashboard. The Instagram browser only launches when you log in or trigger interactions — it does not auto-comment on its own unless IG_AGENT_ENABLED=true.
- Log in and trigger interactions:
curl -X POST http://localhost:3000/api/login \
-H "Content-Type: application/json" \
-d '{"username":"YOUR_IG_USERNAME","password":"YOUR_IG_PASSWORD"}'Then open the dashboard or call POST /api/interact with your session cookie to start liking and commenting on feed posts.
- Optional: auto-run the Instagram agent loop
Set
IG_AGENT_ENABLED=truein.envto run the interaction loop continuously. - Post a photo (by URL)
curl -X POST http://localhost:3000/api/post-photo \\
-H "Content-Type: application/json" \\
--cookie "token=YOUR_JWT_TOKEN" \\
-d '{"imageUrl":"https://example.com/photo.jpg","caption":"Hello IG!"}'- Post a photo (file upload)
curl -X POST http://localhost:3000/api/post-photo-file \\
-H "Content-Type: multipart/form-data" \\
--cookie "token=YOUR_JWT_TOKEN" \\
-F "image=@/path/to/photo.jpg" \\
-F "caption=Hello IG!"- Schedule a photo post
curl -X POST http://localhost:3000/api/schedule-post \\
-H "Content-Type: application/json" \\
--cookie "token=YOUR_JWT_TOKEN" \\
-d '{"imageUrl":"https://example.com/photo.jpg","caption":"Scheduled post","cronTime":"0 9 * * *"}'Open http://localhost:3000/dashboard for live status, the last IG run summary, recent
actions, application logs, and errors.
| Command | Description |
|---|---|
pnpm check |
Lint + typecheck + test + format (CI parity) |
pnpm test |
Run API test suite |
pnpm test:coverage |
Tests with coverage report |
pnpm lint |
ESLint on apps/api |
pnpm format |
Prettier write |
pnpm check:env |
Validate required env vars |
pnpm setup |
Setup health check |
pnpm dev |
API dev server (@veyracast/api) |
pnpm dev:all |
All apps in parallel |
pnpm build |
Build all packages |
- Guides/Monorepo.md — workspace layout & commands
Guides/Instagram-Bot.mdGuides/Operations.mdGuides/API.mdGuides/Env.mdGuides/Testing.mdGuides/CI.mdGuides/Scripts.mdGuides/Training.mdGuides/FAQ.mdGuides/Logging.md
| Variable | Type | Default | Description |
|---|---|---|---|
IGusername |
string | Instagram username | |
IGpassword |
string | Instagram password | |
IG_RUN_PROFILE |
string | standard |
Run profile: safe, standard, aggressive |
IG_AGENT_ENABLED |
boolean | false |
Auto-run Instagram agent loop |
IG_AGENT_INTERVAL_MS |
number | 30000 |
Agent loop interval in ms |
IG_DAILY_MAX_ACTIONS |
number | 0 |
Daily max IG actions (0 = unlimited) |
IG_MAX_POSTS_PER_RUN |
number | Max posts per run (overrides profile) | |
IG_ACTION_DELAY_MIN_MS |
number | Min action delay (overrides profile) | |
IG_ACTION_DELAY_MAX_MS |
number | Max action delay (overrides profile) | |
IG_COOLDOWN_MINUTES |
number | Cooldown duration in minutes | |
IG_COMMENT_ALLOWLIST |
string | Comma-separated allowed comment terms | |
IG_COMMENT_DENYLIST |
string | Comma-separated blocked comment terms | |
IG_COMMENT_SENTIMENT |
string | any |
Sentiment filter: any, positive, neutral |
IG_COMMENT_MIN_LENGTH |
number | Minimum allowed comment length (chars) | |
IG_COMMENT_MAX_LENGTH |
number | Maximum allowed comment length (chars) | |
IG_AD_MARKERS |
string | sponsored,paid partnership,paid partnership with |
Comma-separated ad markers |
IG_AD_BUTTON_MARKERS |
string | learn more,shop now,sign up,install now,get offer,subscribe,book now |
Comma-separated ad button markers |
| Variable | Type | Default | Description |
|---|---|---|---|
Xusername |
string | X/Twitter username | |
Xpassword |
string | X/Twitter password |
| Variable | Type | Default | Description |
|---|---|---|---|
GEMINI_API_KEY |
string | Primary Gemini API key | |
GEMINI_API_KEY_1 |
string | Secondary Gemini API key | |
GEMINI_API_KEY_2 |
string | Tertiary Gemini API key |
| Variable | Type | Default | Description |
|---|---|---|---|
DATABASE_URL |
string | PostgreSQL connection URL | |
DB_REQUIRED |
boolean | false |
Require PostgreSQL connection (exit if missing) |
| Variable | Type | Default | Description |
|---|---|---|---|
LOGGER |
string | console |
Logging backend: winston or console |
Create apps/api/src/config/accounts.json (not committed) based on apps/api/src/config/accounts.example.json.
Then pass account in /api/login to select which account to use.
CONTRIBUTING.mdCODE_OF_CONDUCT.mdSECURITY.mdLICENSE
apps/
api/ @veyracast/api — REST API, agent loop, IG/X clients, dashboard
src/
Agent/ AI training, characters, schema
client/ Instagram & X/Twitter automation
config/ accounts, igProfile, logger, database
routes/ Express API (api.ts)
services/ action logs, webhooks, metrics, igChallenge
views/ Admin dashboard HTML
scripts/ env check, setup, DB migrate
packages/
tsconfig/ @veyracast/tsconfig — shared compiler base
Guides/ Documentation
docker-compose.yml
pnpm-workspace.yaml
See Guides/Monorepo.md for paths, runtime directories, and CI details.
Winston writes rotating logs to apps/api/logs/. Set LOGGER=console to log only to stdout. See Guides/Logging.md.
Process-level error handlers are set up to catch unhandled promise rejections, uncaught exceptions, and process warnings. Errors are logged using the custom logger.
Contributions are welcome and appreciated.
- Fork the repository.
- Create a feature branch.
- Install deps:
pnpm install - Run checks:
pnpm check - Commit your changes and open a pull request.
See CONTRIBUTING.md and Guides/Monorepo.md.
This project is licensed under the MIT License. See the LICENSE file for details.
Thank you to all our supporters!
- GitHub Discussions: use the Discussions tab for Q&A
- Issues: bug reports and feature requests
- Maintained by VeyraLabs