Configuration
Fabric is configured via environment variables (.env file), a TOML config file, or CLI flags. Resolution order (lowest to highest precedence):
- Built-in defaults
- TOML config file (
fabric.toml) - Environment variables /
.envfile - CLI flags
Quick Start
Section titled “Quick Start”Copy the example .env and fill in the keys you need:
cp .env.example .envOnly DATABASE_URL is required. Everything else is optional — Fabric auto-detects available providers and falls back gracefully when keys are missing.
Config File Discovery
Section titled “Config File Discovery”Fabric looks for a TOML config file in this order:
--config <path>CLI flagFABRIC_CONFIGenv var./fabric.toml(current directory)$XDG_CONFIG_HOME/fabric/config.toml(or~/.config/fabric/config.toml)
Database
Section titled “Database”Fabric requires a Postgres database.
Local development — start Postgres via Docker Compose:
just infra-up-dbThis starts Postgres on localhost:5432 with the default credentials. Then set:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/fabricProduction — use your hosted Postgres (Supabase, Neon, RDS, etc.) and set the connection string:
DATABASE_URL=postgres://user:password@host:5432/fabric| Variable | Default | Description |
|---|---|---|
DATABASE_URL | (required) | Postgres connection string |
DATABASE_DIRECT_URL | — | Bypasses connection pooler (for LISTEN/NOTIFY + migrations). Falls back to DATABASE_URL. |
DATABASE_MIGRATION_URL | — | Separate connection string for migrations (overrides DATABASE_DIRECT_URL) |
DATABASE_POOL_MAX | 15 | Maximum connections in the pool |
DATABASE_POOL_MIN | 2 | Minimum idle connections in the pool |
AI Providers (Remote)
Section titled “AI Providers (Remote)”Each provider is auto-enabled when its API key is set. You only need the providers your workflows use — Fabric routes to the cheapest available provider by default.
OpenAI
Section titled “OpenAI”Used for: text generation, image generation (DALL-E), embeddings.
- Go to platform.openai.com/api-keys
- Click “Create new secret key”
- Copy the key (starts with
sk-) - Add to
.env:
OPENAI_API_KEY=sk-proj-...Anthropic (Claude)
Section titled “Anthropic (Claude)”Used for: text generation.
- Go to console.anthropic.com/settings/keys
- Click “Create Key”
- Copy the key (starts with
sk-ant-) - Add to
.env:
ANTHROPIC_API_KEY=sk-ant-...Google Gemini
Section titled “Google Gemini”Used for: text generation, image generation (Imagen), vision.
- Go to aistudio.google.com/apikey
- Click “Create API key” and select a project
- Copy the key (starts with
AIza) - Add to
.env:
GOOGLE_API_KEY=AIza...Used for: image generation (Flux), video generation (Kling, Seedance), TTS (Kokoro), lip sync.
- Go to fal.ai/dashboard/keys
- Click “Create Key”
- Copy the key ID and secret (format:
key-id:key-secret) - Add to
.env:
FAL_API_KEY=0723b521-...:31d73b24...ElevenLabs
Section titled “ElevenLabs”Used for: high-quality text-to-speech.
- Go to elevenlabs.io and sign up
- Click your profile icon → “Profile + API key”
- Copy the API key (starts with
sk_) - Add to
.env:
ELEVENLABS_API_KEY=sk_...Replicate
Section titled “Replicate”Used for: various ML models on demand.
- Go to replicate.com/account/api-tokens
- Copy your API token
- Add to
.env:
REPLICATE_API_TOKEN=r8_...BytePlus / Seedance
Section titled “BytePlus / Seedance”Used for: Seedance video generation.
- Go to console.byteplus.com and create an account
- Navigate to API Keys in your account settings
- Create and copy an API key
- Add to
.env:
BYTEPLUS_API_KEY=your_key_hereUsed for: semantic web search in research workflows (deep-research, problem-intelligence).
- Go to dashboard.exa.ai/api-keys
- Click “Create API Key”
- Copy the key
- Add to
.env:
EXA_API_KEY=your_key_hereFirecrawl
Section titled “Firecrawl”Used for: web page scraping and content extraction.
- Go to firecrawl.dev and sign up
- Navigate to your dashboard and copy your API key
- Add to
.env:
FIRECRAWL_API_KEY=fc-...HuggingFace
Section titled “HuggingFace”Used for: downloading gated models (Llama, Mistral, etc.) for local inference.
- Go to huggingface.co/settings/tokens
- Click “New token” with at least
readaccess - Copy the token (starts with
hf_) - Add to
.env:
HF_TOKEN=hf_...Optionally set a custom cache directory:
HF_HOME=/path/to/huggingface/cacheStock Media
Section titled “Stock Media”Pexels
Section titled “Pexels”Used for: free stock video footage for b-roll.
- Go to pexels.com/api
- Click “Your API Key” (sign up if needed)
- Describe your project and submit
- Copy the API key from your email or dashboard
- Add to
.env:
PEXELS_API_KEY=your_key_hereUnsplash
Section titled “Unsplash”Used for: free stock images.
- Go to unsplash.com/developers
- Click “Your apps” → “New Application”
- Accept the terms and create the app
- Copy the Access Key (not the Secret Key)
- Add to
.env:
UNSPLASH_ACCESS_KEY=your_access_keySocial Media APIs
Section titled “Social Media APIs”These power research and ingestion workflows. Each one is optional — Fabric falls back to web search scraping when API keys are missing.
Used by: deep-research, problem-intelligence, trend-analyst, reddit-stories.
Without credentials, Reddit scraping is rate-limited to ~10 req/min and increasingly returns 403 errors. The free OAuth2 API gives 100 req/min.
- Go to reddit.com/prefs/apps (log in first)
- Scroll to the bottom and click “create another app…”
- Fill in:
- name:
fabric(or any name) - type: select script
- description: optional
- about url: leave blank
- redirect uri:
http://localhost(required but unused for script apps)
- name:
- Click “create app”
- Copy the values:
- client ID — the string under the app name (e.g.
a1b2c3d4e5f6g7) - client secret — labeled “secret”
- client ID — the string under the app name (e.g.
- Add to
.env:
REDDIT_CLIENT_ID=a1b2c3d4e5f6g7REDDIT_CLIENT_SECRET=your_secret_hereTwitter / X
Section titled “Twitter / X”Used by: problem-intelligence, trend-analyst, post-engagement.
- Go to developer.x.com/en/portal/dashboard
- Sign up for a developer account (free tier available)
- Create a Project and an App within it
- Go to Keys and tokens → Bearer Token
- Click “Generate” and copy the token
- Add to
.env:
TWITTER_BEARER_TOKEN=AAAA...Used by: problem-intelligence, trend-analyst, post-engagement.
Requires a Meta Business account with an Instagram Business or Creator account connected.
- Go to developers.facebook.com and create an app
- Add the Instagram Graph API product
- Connect your Instagram Business account
- Go to Tools → Graph API Explorer
- Select your app, then generate a User Token with
instagram_basicandinstagram_manage_insightspermissions - Copy the access token
- Add to
.env:
INSTAGRAM_ACCESS_TOKEN=your_token_hereYouTube Data API
Section titled “YouTube Data API”Used by: post-engagement (Shorts metrics).
- Go to console.cloud.google.com/apis/library
- Search for “YouTube Data API v3” and click Enable
- Go to Credentials → Create Credentials → API key
- Copy the API key
- Add to
.env:
YOUTUBE_DATA_API_KEY=AIza...Email & Notifications
Section titled “Email & Notifications”Resend
Section titled “Resend”Used for: transactional email (invitations, notifications).
- Go to resend.com and sign up
- Navigate to API Keys in the dashboard
- Click “Create API Key” with sending access
- Copy the key (starts with
re_) - Add to
.env:
RESEND_API_KEY=re_...Optionally configure the sender:
FABRIC_EMAIL_FROM=noreply@yourdomain.com| Variable | Default | Description |
|---|---|---|
RESEND_API_KEY | — | Resend API key for transactional email |
FABRIC_EMAIL_FROM | noreply@fabric.local | Default sender email address |
FABRIC_INVITE_TOKEN_KEY | auto-generated | 64-char hex string (32-byte BLAKE3 key) for invitation tokens |
FABRIC_INVITE_REDIRECT_URL | — | URL to redirect to after invitation accept |
Authentication
Section titled “Authentication”Native Auth
Section titled “Native Auth”Generate a signing secret for OAuth tokens:
openssl rand -hex 32Add to .env:
OAUTH_SIGNING_SECRET=your_64_char_hex_string| Variable | Default | Description |
|---|---|---|
OAUTH_SIGNING_SECRET | — | Secret for signing native OAuth tokens |
JWT_SECRET | — | Secret for JWT token validation |
PUBLIC_BASE_URL | — | Public API base URL (for email links) |
AUTH_SITE_URL | — | Frontend URL for auth redirects |
AUTH_CALLBACK_REDIRECT_URL | — | OAuth callback redirect URL |
Social Login (Google)
Section titled “Social Login (Google)”- Go to console.cloud.google.com/apis/credentials
- Click “Create Credentials” → “OAuth client ID”
- Select Web application
- Add your callback URL to Authorized redirect URIs (e.g.
http://localhost:3000/auth/callback/google) - Copy the Client ID and Client Secret
- Add to
.env:
GOOGLE_CLIENT_ID=123456789-abc.apps.googleusercontent.comGOOGLE_CLIENT_SECRET=GOCSPX-...Social Login (GitHub)
Section titled “Social Login (GitHub)”- Go to github.com/settings/developers
- Click “New OAuth App”
- Set the Authorization callback URL (e.g.
http://localhost:3000/auth/callback/github) - Click “Register application”
- Copy the Client ID, then click “Generate a new client secret” and copy that too
- Add to
.env:
GITHUB_CLIENT_ID=Ov23li...GITHUB_CLIENT_SECRET=your_secret_hereAI Providers (Local)
Section titled “AI Providers (Local)”Local providers run on your machine — no API keys needed, but they require the services to be running.
Ollama
Section titled “Ollama”Run local LLMs (Llama, Mistral, Gemma, etc.):
- Install Ollama from ollama.com
- Pull a model:
ollama pull llama3.2 - Ollama runs automatically on
localhost:11434 - Add to
.env:
OLLAMA_ENABLED=trueOLLAMA_URL=http://localhost:11434Whisper (Transcription)
Section titled “Whisper (Transcription)”Local audio transcription:
- Start a Whisper-compatible server (e.g. faster-whisper-server)
- Add to
.env:
WHISPER_URL=http://localhost:8000WHISPER_MODEL=large-v3 # optional: override model selectionPiper (TTS)
Section titled “Piper (TTS)”Free local text-to-speech:
- Start a Piper server (included in
just infra-up-ai) - Add to
.env:
PIPER_URL=http://localhost:5000Chatterbox (Voice Cloning)
Section titled “Chatterbox (Voice Cloning)”Local voice cloning TTS:
- Start a Chatterbox server
- Add to
.env:
CHATTERBOX_URL=http://localhost:8001ComfyUI (Image Generation)
Section titled “ComfyUI (Image Generation)”Local Stable Diffusion image generation:
- Install ComfyUI and start it
- Add to
.env:
COMFYUI_ENABLED=trueCOMFYUI_URL=http://localhost:8188Local LLM Server (vLLM / LM Studio / LocalAI)
Section titled “Local LLM Server (vLLM / LM Studio / LocalAI)”Use any OpenAI-compatible local server:
LOCAL_INFERENCE_URL=http://localhost:8080/v1Also accepts VLLM_URL or FABRIC_LOCAL_URL as aliases.
| Variable | Default | Description |
|---|---|---|
OLLAMA_ENABLED | false | Enable Ollama LLM provider |
OLLAMA_URL | http://localhost:11434 | Ollama server URL |
WHISPER_URL | — | Whisper transcription server URL |
WHISPER_MODEL | — | Whisper model selection override |
PIPER_URL | — | Piper TTS server URL |
CHATTERBOX_URL | — | Chatterbox voice cloning server URL |
COMFYUI_ENABLED | false | Enable ComfyUI image generation |
COMFYUI_URL | http://localhost:8188 | ComfyUI server URL |
ONNX_MODEL_DIR | — | ONNX model directory |
CANDLE_ENABLED | true | Enable Candle ML inference |
LLAMA_CPP_MODEL | — | Path to GGUF model file (requires llama-cpp feature) |
LOCAL_INFERENCE_URL | — | Local LLM server URL (also accepts VLLM_URL or FABRIC_LOCAL_URL) |
FABRIC_DIFFUSERS_ENABLED | true | Enable Python Diffusers model server |
Model Server
Section titled “Model Server”The model server auto-spawns during workflow execution to host local ML models (Diffusers, Kokoro, Whisper). No manual setup needed — it starts automatically when a workflow requires a local model.
| Variable | Default | Description |
|---|---|---|
FABRIC_MODEL_SERVER_URL | http://localhost:8199 | Model server endpoint |
FABRIC_MODEL_SERVER_PORT | 8199 | Model server port |
FABRIC_MODEL_WARM_TTL | 1800 | Seconds to keep models loaded in memory after last use |
FABRIC_MODEL_STORE | — | S3/GCS bucket for model storage (e.g. s3://my-models) |
FABRIC_NO_MODEL_SERVER | — | Set to 1 to disable the auto-spawned model server |
FABRIC_GPU_COUNT | auto-detected | Override GPU count detection |
FABRIC_GPU_TIMEOUT | 600 | GPU operation timeout in seconds |
Model Overrides
Section titled “Model Overrides”Override the default model for any operation by setting FABRIC_<OPERATION>_MODEL to a model ID or skip to disable.
# Use Gemini Flash for text (cheapest)FABRIC_TEXT_MODEL=gemini-2.5-flash
# Use Imagen for thumbnails (fast, renders text natively)FABRIC_THUMBNAIL_MODEL=imagen-4.0-fast-generate-001
# Disable avatar generation entirelyFABRIC_AVATAR_MODEL=skip
# Use FAL for b-roll videoFABRIC_BROLL_MODEL=fal-ai/veo3.1/fastAll available overrides:
| Variable | Description |
|---|---|
FABRIC_TEXT_MODEL | Text generation / LLM |
FABRIC_VISION_MODEL | Vision / image understanding |
FABRIC_IMAGE_MODEL | Image generation |
FABRIC_IMAGE_FAST_MODEL | Fast image generation (lower quality) |
FABRIC_IMAGE_EDIT_MODEL | Image-to-image editing |
FABRIC_THUMBNAIL_MODEL | Thumbnail generation |
FABRIC_POST_MODEL | Social media post image generation |
FABRIC_KEYFRAME_GRID_MODEL | Keyframe grid generation |
FABRIC_AVATAR_MODEL | Avatar generation |
FABRIC_VIDEO_MODEL | Video generation |
FABRIC_BROLL_MODEL | B-roll video generation |
FABRIC_BROLL_FAST_MODEL | Fast b-roll generation |
FABRIC_BROLL_FLF_MODEL | B-roll first/last frame generation |
FABRIC_BROLL_I2V_MODEL | B-roll image-to-video |
FABRIC_BROLL_REF2V_MODEL | B-roll reference-to-video |
FABRIC_TTS_MODEL | Text-to-speech |
FABRIC_TRANSCRIPTION_MODEL | Audio transcription |
FABRIC_MUSIC_MODEL | Music generation |
FABRIC_LIPSYNC_MODEL | Lip sync |
FABRIC_PERCEPTION_MODEL | Perceptual analysis |
Asset Storage
Section titled “Asset Storage”Configure where Fabric stores workflow artifacts (generated images, videos, audio).
Local development (default):
ASSET_STORE_URL=file:///tmp/fabric/assetsS3-compatible storage (production):
ASSET_STORE_URL=s3://my-fabric-assetsAWS_ACCESS_KEY_ID=AKIA...AWS_SECRET_ACCESS_KEY=...AWS_REGION=us-east-1# For MinIO, Supabase Storage, or other S3-compatible services:# AWS_ENDPOINT=https://s3.example.comGoogle Cloud Storage:
ASSET_STORE_URL=gs://my-fabric-assets| Variable | Default | Description |
|---|---|---|
ASSET_STORE_URL | — | Storage backend: file:///path, s3://bucket, gs://bucket, memory:// |
ASSET_TTL_HOURS | 72 | Auto-expire workflow assets (0 = never) |
ASSET_REAPER_INTERVAL_SECS | 300 | Cleanup poll interval in seconds |
Server & Runtime
Section titled “Server & Runtime”Server
Section titled “Server”| Variable | Default | Description |
|---|---|---|
HOST | 127.0.0.1 | HTTP bind address |
PORT | 3001 | HTTP port |
GRPC_PORT | 3002 | gRPC port |
RUST_LOG | info | Log level filter (tracing) |
Runtime
Section titled “Runtime”| Variable | Default | Description |
|---|---|---|
FABRIC_ENV | development | Set to production to disable dev-header auth |
FABRIC_MODE | server | server (default) or request-only (stateless/serverless) |
FABRIC_DEV_MODE | — | Set to 1 or true to force dev-header auth regardless of FABRIC_ENV |
FABRIC_API_KEY | — | Admin API key for CLI subcommands (fab_* prefix) |
FABRIC_API_URL | — | API server endpoint (for SDK/worker connections) |
FABRIC_CONFIG | — | Explicit path to fabric.toml config file |
FABRIC_WORKFLOW_DIRS | — | Comma-separated list of extra directories to load workflow YAMLs from |
FABRIC_KEEP_WORKDIR | — | Set to 1 to retain workflow working directories after execution (useful for debugging) |
FABRIC_STRICT_WIRING | — | Enforce strict type checking on workflow task wiring |
FABRIC_INTERNAL_SECRET | — | Shared secret for service-to-service authentication |
FABRIC_ORGANIZATION_ID | — | Default organization ID for workflow execution context |
FABRIC_QUALITY | — | Quality profile selection (overrides per-workflow defaults) |
FABRIC_VIDEO_BACKEND | ffmpeg | Video processing backend: ffmpeg (default) or gstreamer |
FABRIC_LOCAL_ONLY | false | Disable all remote providers |
FABRIC_ROUTING_STRATEGY | cheapest_qualified | Default routing strategy (local_first, fastest, best_quality, balanced) |
FABRIC_PREFER_LOCAL | 1 | Prefer local backends when available |
| Variable | Default | Description |
|---|---|---|
CORS_ALLOWED_ORIGINS | — | Comma-separated list of allowed origins (e.g. http://localhost:3000,http://localhost:5173) |
Rate Limiting
Section titled “Rate Limiting”| Variable | Default | Description |
|---|---|---|
RATE_LIMIT_MAX_REQUESTS | 200 | Max requests per window |
RATE_LIMIT_WINDOW_SECS | 60 | Rate limit window in seconds |
RATE_LIMIT_BACKEND | memory | Backend: memory or redis |
Workers
Section titled “Workers”| Variable | Default | Description |
|---|---|---|
FABRIC_WORKERS | 1 | Number of worker threads |
FABRIC_WORKER_ID_PREFIX | fabric-worker | Worker ID prefix |
FABRIC_WORKER_POLL_INTERVAL | 2.0 | Poll interval in seconds |
FABRIC_WORKER_TAGS | — | Comma-separated list of worker capability tags (e.g. python,ai) |
Scheduler
Section titled “Scheduler”| Variable | Default | Description |
|---|---|---|
CRON_POLL_INTERVAL_SECS | 30 | Cron job poll interval in seconds |
Logging & Debug
Section titled “Logging & Debug”| Variable | Default | Description |
|---|---|---|
FAB_QUIET | — | Suppress workflow log output |
NO_COLOR | — | Disable colored log output |
CLI Flags
Section titled “CLI Flags”Control Plane (fabric serve)
Section titled “Control Plane (fabric serve)”fabric serve --host 0.0.0.0 --port 8080 --grpc-port 9090fabric serve --database-url postgres://user:pass@host/dbfabric serve --oauth-signing-secret $(openssl rand -hex 32)fabric serve --openai-api-key sk-... --anthropic-api-key sk-ant-...fabric serve --ollama-enabled --ollama-url http://gpu-server:11434fabric serve --comfyui-enabled --comfyui-url http://localhost:8188fabric serve --fabric-env productionExecution Plane (fabric executor)
Section titled “Execution Plane (fabric executor)”fabric executor --concurrency 8 --worker-id gpu-worker-1fabric executor --poll-interval 500 --lease-seconds 60 --max-retries 5Stateless Mode
Section titled “Stateless Mode”For serverless environments (Lambda, Modal, microVMs):
FABRIC_MODE=request-only fabric serve --database-url postgres://...This disables gRPC, background tasks, and SSE streaming. Workflow execution runs inline.
TOML Config File
Section titled “TOML Config File”All settings can also be set in fabric.toml:
[server]host = "0.0.0.0"port = 8080grpc_port = 9090
[database]url = "postgres://fabric:fabric@localhost:5432/fabric"# direct_url = "postgres://..." # bypasses pooler for LISTEN/NOTIFY + migrationspool_max = 15pool_min = 2
[auth]oauth_signing_secret = "your-secret-here"
[providers]openai_api_key = "sk-..."anthropic_api_key = "sk-ant-..."ollama_enabled = trueollama_url = "http://localhost:11434"
# Custom OpenAI-compatible endpoints (LocalAI, vLLM, LM Studio)[[providers.custom_openai_endpoints]]name = "localai"url = "http://localhost:8080/v1"api_key = "no-key"model = "mistral-7b"tier = "basic"
[assets]store_url = "file:///tmp/fabric/assets"generated_asset_ttl_hours = 72
[workers]count = 2tags = ["python", "ai"]
[runtime]env = "development"
[cors]allowed_origins = ["http://localhost:3000"]Infrastructure (Docker Compose)
Section titled “Infrastructure (Docker Compose)”just infra-up # Full stack (Postgres + Ollama + Whisper + ComfyUI)just infra-up-db # Postgres onlyjust infra-up-ai # Postgres + AI servicesjust infra-down # Stop everythingjust infra-reset # Fresh start (delete volumes)just infra-psql # Open psql shelljust infra-migrate # Re-apply migrationsjust infra-smoke-test # Verify migrations on clean DBjust ollama-pull <model> # Pull an Ollama modeljust ollama-list # List available Ollama modelsDevelopment Commands
Section titled “Development Commands”just dev # Start control plane + executorjust run # Start control plane onlyjust fmt # Format all codejust clippy # Lint with -D warningsjust test # Run all testsjust doc # Build documentationjust ci # All of the above