Ship a team of specialized AI agents β with human-in-the-loop approvals, full observability, real enterprise connectors, and defense-in-depth security β to production.
Quickstart Β· Architecture Β· Features Β· API Β· Deployment Β· Docs Β· Roadmap Β· Contributing
- What is ForgeFlow?
- Why ForgeFlow?
- Features
- Architecture
- Technology Stack
- Quickstart
- Configuration
- Usage Examples
- Workflows & Connectors
- API Reference
- Security
- Performance & Scalability
- Deployment
- Developer Guide
- Project Structure
- Roadmap
- Contributing
- License
ForgeFlow is an open-source platform for building, running, and operating multi-agent AI workflows in the enterprise. Instead of a single monolithic prompt, ForgeFlow orchestrates a supervisor agent that routes work to a team of specialists β a researcher, an analyzer, and an executor β each grounded in real tools and real data, and gated by human approval before any high-impact side effect.
It ships three named workflow domains out of the box:
| Workflow | Pipeline | Status | Connector |
|---|---|---|---|
sales_ops |
qualify β research β analyze β propose β approve β execute | β Production | HubSpot CRM (upsert-by-email, idempotent deals, 429 backoff) |
support_ops |
triage β investigate β respond β escalate β resolve | Pairs with Jira / ServiceNow | |
finance_recon |
ingest β match β flag variance β approve β post | Pairs with QuickBooks / SAP |
support_opsandfinance_reconare honest scaffolds β they raise on.run()unlessdry_run=TrueorFORGEFLOW_ALLOW_TEMPLATE_WORKFLOWS=1is set, and the React console labels them as such. Three named templates β three production workflows.sales_opsis the fully-wired reference path: follow docs/sales-ops-production.md to run it against a real HubSpot account on Fly.io in under an hour.
Most "agent demos" collapse the moment they meet production reality: there's no audit trail, no cost ceiling, no way to pause for a human, secrets leak into prompts, a single flaky API takes down the whole run, and swapping a mock tool for a real one means rewriting the agent. ForgeFlow is the opinionated reference implementation of everything that sits around the LLM call to make agentic automation safe to deploy:
- Durable state β every node is checkpointed to PostgreSQL, so any worker can resume any run after a crash.
- Human-in-the-loop β workflows pause via LangGraph
interrupt_beforeand resume on an approve/reject webhook or Slack button. - Pluggable tools β agents talk to the world through the Model Context Protocol (MCP), so you swap a mock CRM for HubSpot without touching agent code.
- Defense in depth β PII redaction, prompt-injection guards, SSRF protection, untrusted-tool-output quarantine, and an outbound-email allowlist.
- Cost & resilience controls β per-run budget guard, circuit breakers, retry-with-backoff, and token-level cost tracking.
- Full observability β LangSmith / Phoenix / Langfuse tracing, Prometheus metrics, immutable audit log, and LLM-as-judge evaluation.
| Audience | What ForgeFlow gives you |
|---|---|
| Platform / ML engineers | A batteries-included blueprint for shipping agents with checkpointing, RBAC, observability, and connectors already wired. |
| Enterprises | Human approvals, audit trails, cost ceilings, multi-tenancy, and on-prem / air-gapped deployment paths. |
| OSS contributors | A clean, typed, well-tested (306 tests) codebase with clear extension points β connectors, MCP tools, and workflow templates. |
| Recruiters & evaluators | A demonstration of production agentic-AI engineering: LangGraph, MCP, A2A, Kubernetes, Terraform, and a polished React 19 console. |
- π§ Supervisor multi-agent orchestration β deterministic, auditable hub-and-spoke routing built on LangGraph
StateGraph. - π 8 real enterprise connectors β HubSpot, Salesforce, Jira, ServiceNow, GitHub, SAP S/4HANA, QuickBooks Online, and Microsoft Graph β all behind a single resilient connector base.
- π‘οΈ Security-first by design β see SECURITY_AUDIT.md for the full threat model and the fixes that close each finding.
- π Provider-agnostic β OpenAI, Anthropic Claude, or a fully local Ollama daemon (privacy / air-gapped mode).
- π Operate it, don't just run it β a 13-view React console for runs, approvals, cost, audit, memory, agents, and evaluations.
- π’ Deploy anywhere β Docker Compose, Kubernetes, Helm, Terraform (AWS), Fly.io, and an offline bundle for air-gapped sites.
π€ AI-Powered Multi-Agent Development
- Supervisor agent emits a structured
RoutingDecision(never calls tools directly) so routing stays deterministic and auditable β forgeflow/agents/supervisor.py - Researcher agent β web search + URL scraping + enrichment, with SSRF-guarded fetches
- Analyzer agent β 0β10 ICP scoring with risk flags and a recommended action
- Executor agent β drafts proposals, writes to the CRM, and sends pinned-recipient email
- Pluggable LLM providers β OpenAI (default), Anthropic Claude, or local Ollama via a single
get_model()factory β forgeflow/models/provider.py - Agent-to-Agent (A2A) protocol β JSON-RPC 2.0,
AgentCardcapability discovery, and an in-workflow dispatch registry β forgeflow/a2a/
π Workflow Automation & Orchestration
- LangGraph
StateGraphwith PostgreSQL checkpointing β every node persisted, any worker resumes anythread_idβ forgeflow/graph/ - Human-in-the-loop via
interrupt_before+ approve/reject webhooks and Slack deep-link buttons β forgeflow/api/routers/approvals.py - Approval escalation β a background job ratchets stale approvals through level 1 β 2 β auto-reject β forgeflow/jobs/escalation.py
- SSE streaming β stream agent reasoning + tool calls live with
astream()overStreamingResponse - Event-driven mode β consume Redis Streams or Kafka events into a shared
EventDispatcherβ forgeflow/events/ - Dry-run simulation β run the full LLM plan with all side effects (CRM writes, emails, Slack) skipped
- Workflow template marketplace β file-based registry with a
manifest.yamlschema and a CLI validator β forgeflow/marketplace/, templates/
π§ͺ Testing, Evaluation & Validation
- 306 tests across unit + integration suites β tests/
- LLM-as-judge evaluation β faithfulness, relevance, coherence, and hallucination detection in one pass β forgeflow/evaluation/judge.py
- Eval regression gate in CI β
.github/workflows/eval.ymlchecks scores against a baseline (tests/eval_baseline.json) - HubSpot pre-flight validator β probes your real CRM end-to-end before deploy β scripts/validate_hubspot.py
- Type + lint gates β
ruff(E/F/I/UP/B/SIM/ANN) andmypyenforced in CI
π‘οΈ Security (Defense in Depth)
- PII redactor β conservative regex scrubbing of common identifiers β forgeflow/security/pii_redactor.py
- Prompt-injection guard β heuristic risk scoring on inbound text β forgeflow/security/prompt_guard.py
- SSRF guard β blocks private IPs, IMDS, and non-http(s) schemes on every agent-controlled URL β forgeflow/security/ssrf_guard.py
- Tool-output quarantine β wraps tool results in an
<UNTRUSTED_TOOL_OUTPUT>envelope to defeat 2nd-order injection β forgeflow/security/tool_output_guard.py - Outbound-email allowlist β pins recipients so an LLM can't exfiltrate via
email_sendβ forgeflow/security/email_allowlist.py - JWT + RBAC, immutable partitioned audit log, rate limiting, and a CORS allowlist (never
*) β forgeflow/middleware/
π Observability & Cost Control
- Tracing β pick LangSmith, Phoenix, Langfuse, or none via
TRACING_PROVIDER; OTel auto-configures for OTLP backends β forgeflow/observability/tracing_provider.py - Prometheus β
/metrics/prometheusexposition endpoint - Cost tracking β
tiktoken-based token counting with a per-model cost table and per-agent breakdown β forgeflow/observability/cost_tracker.py - Budget guard β halts a workflow before projected spend exceeds
BUDGET_LIMIT_USDβ forgeflow/resilience/budget_guard.py - Circuit breaker β CLOSED/OPEN/HALF_OPEN state machine stops cascading failures β forgeflow/resilience/circuit_breaker.py
- Opt-in anonymous telemetry β off by default, PII-clean allowlist β forgeflow/telemetry/
π’ Enterprise & Platform
- Multi-tenancy β
workspacesas the tenant root with a nullableworkspace_idon every tenant-scoped row (query scoping in progress) β forgeflow/api/routers/workspaces.py - Multi-modal input β PDF text extraction + vision-LLM image description β forgeflow/multimodal/
- Semantic memory β pgvector cosine recall, namespace-scoped β forgeflow/memory/pgvector_store.py
- Deployment targets β Docker Compose, Kubernetes, Helm, Terraform (AWS), Fly.io, and an air-gapped offline bundle
π Deep dive: docs/architecture.md has the full component design, API request lifecycle, workflow execution, agent, and auth flows as Mermaid diagrams; docs/database.md has the schema + ER diagram.
ForgeFlow is a hub-and-spoke system: a FastAPI control plane drives a checkpointed LangGraph state machine, agents reach the outside world only through an MCP tool server, and a React console operates the whole thing.
graph TB
subgraph Client["π₯οΈ Presentation"]
Console["React 19 Console :8501<br/>13 views Β· landing Β· architecture"]
end
subgraph ControlPlane["βοΈ Control Plane β FastAPI :8000"]
API["REST + SSE API"]
MW["Middleware stack<br/>RBAC Β· RateLimit Β· Security Β· Audit"]
Jobs["Escalation job Β· Event dispatcher"]
end
subgraph Orchestration["π§ Orchestration β LangGraph"]
Supervisor["Supervisor Agent<br/>structured routing"]
Researcher["Researcher"]
Analyzer["Analyzer"]
Executor["Executor"]
Human["βΈ Human Approval<br/>interrupt_before"]
end
subgraph Tools["π MCP Tool Server :8001 β FastMCP"]
Search["Web search"]
Connectors["8 connectors:<br/>HubSpot Β· Salesforce Β· Jira Β·<br/>ServiceNow Β· GitHub Β· SAP Β·<br/>QuickBooks Β· MS Graph"]
MultiModal["PDF Β· Image tools"]
end
subgraph Data["πΎ State & Memory"]
PG["PostgreSQL 16 + pgvector<br/>checkpoints Β· audit Β· memory Β· tenants"]
end
subgraph Observe["π Observability"]
Trace["LangSmith / Phoenix / Langfuse"]
Prom["Prometheus"]
end
Console -->|nginx proxy /api/*| API
API --> MW --> Supervisor
Jobs --> Supervisor
Supervisor -->|qualify| Researcher
Supervisor -->|analyze| Analyzer
Supervisor -->|propose| Executor
Supervisor -->|await| Human
Human -->|approve| Executor
Researcher --> Tools
Executor --> Tools
Connectors --> External["External SaaS APIs"]
Orchestration -->|checkpoint every node| PG
Researcher -->|semantic recall| PG
API --> Observe
Orchestration --> Observe
POST /workflows/run ββ
βΌ
RBAC β RateLimit β Security β Audit middleware
βΌ
LangGraph compiled graph (PostgreSQL-checkpointed)
βΌ
QUALIFY ββ Researcher ββΊ MCP: web_search / scrape_url (SSRF-guarded)
βΌ
ANALYZE ββ Analyzer βββΊ ICP score 0β10 + risk flags
β score < 4.0 ββΊ DISQUALIFIED
βΌ score β₯ 4.0
PROPOSE ββ Executor βββΊ draft_proposal (LLM) ββΊ PostgreSQL proposals
βΌ
APPROVE ββ Human ββββββΊ βΈ interrupt_before β Slack card / POST /approvals/{token}/approve
β rejected ββΊ DONE
βΌ approved
EXECUTE ββ Executor βββΊ MCP: send_email (pinned) + CRM upsert ββΊ mark "proposed"
βΌ
DONE (cost tracked Β· evaluated Β· audited Β· traced)
| Decision | Choice | Why |
|---|---|---|
| Orchestration | LangGraph | Built-in interrupt_before, PostgreSQL checkpointing, and streaming β production-proven |
| Tool discovery | MCP | Swap backends without touching agent code; a fast-growing open standard |
| Agent comms | A2A (JSON-RPC 2.0) | Capability-based discovery; swappable to gRPC for scale |
| Memory | PostgreSQL + pgvector | Co-locate semantic + transactional data; one datastore to operate |
| Evaluation | LLM-as-judge | Faithfulness, relevance, coherence, and hallucination in a single pass |
| Resilience | Circuit breaker + tenacity | Stops cascading failures at the API boundary |
| Frontend | React 19 + Vite + nginx | Single-origin SPA, reverse-proxied /api/*, hand-authored CSS with oklch tokens |
| Layer | Technologies |
|---|---|
| Orchestration | LangGraph Β· LangChain Core Β· langgraph-checkpoint-postgres |
| LLM providers | OpenAI Β· Anthropic Claude Β· Ollama (local) |
| Tools | MCP (FastMCP, streamable-HTTP) Β· langchain-mcp-adapters Β· Tavily |
| API | FastAPI Β· Uvicorn Β· Pydantic v2 Β· pydantic-settings |
| Data | PostgreSQL 16 Β· pgvector Β· asyncpg Β· psycopg3 Β· Alembic |
| Frontend | React 19 Β· Vite Β· TanStack Router + Query Β· TypeScript |
| Resilience | tenacity Β· custom circuit breaker Β· budget guard |
| Observability | LangSmith Β· OpenTelemetry Β· Phoenix Β· Langfuse Β· Prometheus Β· tiktoken |
| Security | PyJWT Β· custom RBAC Β· PII / prompt / SSRF / tool-output guards |
| Events | Redis Streams Β· Kafka (aiokafka) |
| Infra | Docker Compose Β· Kubernetes Β· Helm Β· Terraform (AWS) Β· Fly.io |
| Quality | pytest Β· pytest-asyncio Β· ruff Β· mypy |
For a real HubSpot pipeline on Fly.io, jump to docs/sales-ops-production.md. The runbook below is for local evaluation.
- Docker + Docker Compose
- An LLM provider β one of:
- an OpenAI API key (default), or
- an Anthropic API key, or
- a local Ollama daemon (privacy / air-gapped mode)
- (Optional) a Tavily API key for real web search, and a LangSmith key for tracing
- (Optional, for the
sales_opsproduction path) a HubSpot Private App token with the 6 CRM scopes in the production runbook
git clone https://github.com/JoelJohnsonThomas/forgeflow.git
cd forgeflow
cp .env.example .env
# Edit .env β at minimum set OPENAI_API_KEY, API_SECRET_KEY, POSTGRES_PASSWORD, DEV_LOGIN_PASSWORDGenerate a strong secret with
openssl rand -hex 32forAPI_SECRET_KEY. Startup fails fast without it.
docker compose --profile migration run --rm migrate # apply Alembic migrations once
docker compose up # start the stack| Service | URL | Description |
|---|---|---|
| React Console | http://localhost:8501 | Landing page + 13-view operations console (nginx, proxies /api/*) |
| FastAPI | http://localhost:8000/docs | REST API + interactive OpenAPI UI |
| MCP Server | http://localhost:8001 | Tool server for agents |
| PostgreSQL | localhost:5432 | Database + pgvector |
Every API call requires a bearer JWT. With DEV_LOGIN_ENABLED=true, mint one
from /auth/login using a seeded demo user (rep-1 has the sales_rep role),
then trigger a run:
# 1. Get a token (password = your DEV_LOGIN_PASSWORD; .env.example default shown). Requires jq.
TOKEN=$(curl -s http://localhost:8000/auth/login \
-H "Content-Type: application/json" \
-d '{"user_id": "rep-1", "password": "change-me-locally-only"}' | jq -r .access_token)
# 2. Trigger a workflow
curl -X POST http://localhost:8000/workflows/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"lead_data": {"company_name": "Stripe"}, "workflow_type": "sales_ops"}'Or use the demo script β it mints its own tokens and auto-approves the proposal. It runs on the host (not in the container), so install the package first:
pip install -e . # once β pulls httpx + script deps
export DEV_LOGIN_PASSWORD=change-me-locally-only # match your .env
python scripts/run_demo.py "Stripe" approvecurl http://localhost:8000/health
# β {"status":"healthy","database":"connected","graph":"compiled"}Then open http://localhost:8501 and watch the run land in /console/runs. π
Hit a snag? See docs/troubleshooting.md β it covers 401s, port conflicts, slow startup, and other common first-run issues.
π Local-first mode (privacy / air-gapped with Ollama)
ForgeFlow can run entirely against a local Ollama daemon β no data leaves your machine.
pip install 'forgeflow[ollama]'
ollama pull llama3.2:3b # worker model (fast)
ollama pull llama3.1:8b # supervisor + judge (stronger)
echo "LLM_PROVIDER=ollama" >> .env
echo "OLLAMA_BASE_URL=http://localhost:11434" >> .env
docker compose upNote: pgvector embeddings currently call OpenAI. Fully-offline embeddings are tracked in the roadmap. Anthropic Claude is also supported:
pip install 'forgeflow[anthropic]'and setLLM_PROVIDER=anthropic.
All configuration is environment-based and loaded through Pydantic Settings (forgeflow/config.py). Copy .env.example to .env β the key knobs:
| Variable | Default | Purpose |
|---|---|---|
LLM_PROVIDER |
openai |
openai Β· ollama Β· anthropic |
OPENAI_API_KEY |
β | Required when LLM_PROVIDER=openai |
API_SECRET_KEY |
β | Required. Signs JWTs β generate with openssl rand -hex 32 |
POSTGRES_PASSWORD |
β | Required by docker-compose |
DEV_LOGIN_ENABLED / DEV_LOGIN_PASSWORD |
true / β |
Demo /auth/login. Set false in production and front with an OIDC IdP |
DOCS_ENABLED |
true |
Disable /docs + /redoc in production |
CORS_ALLOW_ORIGINS |
localhost:5173,8501 |
Comma-separated allowlist β never * |
BUDGET_LIMIT_USD |
5.0 |
Per-workflow spend ceiling enforced by the budget guard |
TRACING_PROVIDER |
langsmith |
langsmith Β· phoenix Β· langfuse Β· none |
TAVILY_API_KEY |
β | Real web search (optional) |
SLACK_BOT_TOKEN |
β | HITL approval cards in Slack (optional) |
Optional extras gate heavier dependencies:
[ollama],[anthropic],[otel],[multimodal],[events],[events-kafka]. Install with e.g.pip install 'forgeflow[otel,multimodal]'.
π Full reference: every environment variable with its default is documented in docs/configuration.md.
Every example assumes a
$TOKENfrom the login step above. Roles enforce separation of duties:sales_repexecutes workflows,managerapproves them (see RBAC policies).
curl -X POST http://localhost:8000/workflows/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"lead_data": {"company_name": "Acme Corp", "industry": "fintech"},
"workflow_type": "sales_ops"
}'curl -N -X POST http://localhost:8000/workflows/stream \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"lead_data": {"company_name": "Stripe"}, "workflow_type": "sales_ops"}'Approvals require the manager role, so mint a manager token first:
MGR=$(curl -s http://localhost:8000/auth/login -H "Content-Type: application/json" \
-d '{"user_id": "manager-1", "password": "change-me-locally-only"}' | jq -r .access_token)
# 1. See what's waiting
curl http://localhost:8000/approvals/pending -H "Authorization: Bearer $MGR"
# 2. Approve (or /reject) β the workflow resumes from the checkpoint.
# Body fields: {"note": "..."} for approve, {"reason": "..."} for reject.
curl -X POST http://localhost:8000/approvals/<token>/approve \
-H "Authorization: Bearer $MGR" \
-H "Content-Type: application/json" \
-d '{"note": "Good fit, proceed"}'curl -X POST http://localhost:8000/workflows/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"lead_data": {"ticket": "Login broken"}, "workflow_type": "support_ops", "dry_run": true}'curl "http://localhost:8000/memory/search?q=enterprise%20fintech%20leads&limit=5" \
-H "Authorization: Bearer $TOKEN"# Pass the manifest file (not the directory). See templates/community/lead_triage/ for a working example.
python scripts/marketplace.py validate templates/community/lead_triage/manifest.yamlConnectors are real (non-mock) integrations exposed to agents as MCP tools. All are built on a single resilient base (forgeflow/connectors/base.py) that honors Retry-After on 429s, applies exponential backoff with jitter on 502/503/504, and distinguishes RetryableError from PermanentError. Each degrades gracefully when credentials are absent.
| Connector | Pairs with | Notes |
|---|---|---|
| HubSpot | sales_ops |
Upsert-by-email contacts, idempotent forgeflow_run_id deals |
| Salesforce | sales_ops |
Leads + opportunities + SOQL |
| Jira Cloud | support_ops |
Issue create + transitions |
| ServiceNow | Incident mgmt | Table API incidents + change requests |
| GitHub | DevOps / PR review | Issues, PRs, releases, repo metadata |
| SAP S/4HANA | finance_recon |
OData v2 + CSRF for orders + invoices |
| QuickBooks Online | finance_recon |
Ledger + journal entries (OAuth 2.0) |
| Microsoft Graph | HITL approvals | Teams / Outlook / Calendar (Slack alternative) |
The MCP server mounts 14 tool routers (search, CRM, email, data, Slack, + the 8 connectors above, plus multi-modal) β see forgeflow/mcp/server/main.py.
π Setup: each connector's environment variables and how to obtain the credentials are in docs/connectors.md.
Interactive OpenAPI docs live at http://localhost:8000/docs. For a written reference with authentication requirements, per-role access, and error semantics, see docs/api-reference.md. Core endpoints:
Workflows
POST /workflows/run Trigger a workflow (sync)
POST /workflows/stream Trigger with SSE streaming
GET /workflows/{id} Run status + state
GET /workflows/{id}/trace Per-agent execution traces
Approvals Β· Agents Β· Memory
GET /approvals/pending Proposals awaiting review
POST /approvals/{token}/approve Resume (approved)
POST /approvals/{token}/reject Resume (rejected)
GET /agents Registered A2A agents
GET /agents/dispatch A2A capability resolution map
GET /agents/{id}/status Agent health + run count
POST /agents/{id}/message Send an A2A message
POST /memory/store Store semantic memory
GET /memory/search?q= Cosine similarity search
DELETE /memory/{id} Delete a memory
Metrics Β· Audit Β· Marketplace Β· Workspaces Β· Auth
GET /metrics/ System KPIs (total_runs, success_rate, avg_cost_usdβ¦)
GET /metrics/cost Cost by agent
GET /metrics/cost/by_workflow_type
GET /metrics/cost/top_runs Top N most expensive runs
GET /metrics/cost/alerts Budget alert state
GET /metrics/evaluation LLM-judge score aggregates
GET /metrics/runs Recent run history
GET /metrics/prometheus Prometheus exposition
GET /audit/search Filterable, paginated audit log
GET /audit/stats Audit aggregates over N days
GET /marketplace/templates List installable templates
GET /marketplace/templates/{name}
POST /marketplace/templates/refresh
GET /workspaces/ List tenants
POST /workspaces/ Create a tenant
GET /workspaces/{slug}
POST /auth/login Issue access + refresh tokens (dev path; gate behind DEV_LOGIN_ENABLED)
POST /auth/refresh Rotate refresh token β new access + refresh (reuse-detecting)
POST /auth/logout Revoke the access jti + the refresh-token family
POST /auth/introspect Decode + validate an access JWT
POST /auth/mfa/enroll Begin TOTP MFA enrollment (authenticated)
POST /auth/mfa/verify Confirm + enable TOTP MFA (authenticated)
POST /auth/oidc/exchange Exchange an external IdP id_token for local tokens
Authentication. Every non-public route requires a bearer JWT (Authorization: Bearer <token>) β there is no header-based fallback; unauthenticated requests fail closed with 401. The middleware maps role β permissions (forgeflow/middleware/auth.py). For local development, /auth/login issues an access + refresh token pair when DEV_LOGIN_ENABLED=true (rotate via /auth/refresh). In production, disable dev login and front the API with an OIDC IdP via /auth/oidc/exchange. TOTP MFA is available via /auth/mfa/*.
Errors. Standard HTTP semantics β 401 (no/invalid token), 403 (insufficient role), 422 (validation), 429 (rate-limited), 5xx (upstream/LLM failure surfaced after retries + circuit breaker).
ForgeFlow ships a documented threat model and the controls that close each finding β see SECURITY_AUDIT.md.
Built-in controls
- Prompt-injection guard scores inbound text; tool-output guard wraps every tool result in an
<UNTRUSTED_TOOL_OUTPUT>envelope to blunt 2nd-order injection. - SSRF guard rejects private IPs, cloud metadata (IMDS), and non-http(s) schemes on every agent-controlled URL.
- PII redactor scrubs common identifiers (conservative β prefers over-redaction).
- Outbound-email allowlist pins recipients so the LLM can't choose where mail goes.
- JWT + RBAC, an immutable partitioned audit log, rate limiting, and a strict CORS allowlist (never
*).
Best practices
- Set a strong
API_SECRET_KEY(openssl rand -hex 32); never commit.env. - Set
DEV_LOGIN_ENABLED=falseandDOCS_ENABLED=falsein production. - Use a secrets manager (AWS Parameter Store, GCP Secret Manager, Vault) β
.envis for local only. - The SPA authenticates per-user via
/auth/login; nginx no longer injects a shared admin secret.
Full auth model β tokens, refresh rotation + reuse detection, TOTP MFA, OIDC SSO, and the RBAC matrix β is documented in docs/auth.md.
Reporting a vulnerability. Please do not open a public issue for security reports. See SECURITY.md for the private disclosure process; SECURITY_AUDIT.md documents the threat model and prior findings.
| Concern | Approach |
|---|---|
| Horizontal scaling | The API is stateless β workers share one PostgreSQL checkpointer, so any worker resumes any thread_id. Scale out behind a load balancer or a Kubernetes HPA (api 2β10, mcp 1β5). Note: docker compose --scale api=N requires removing the static 8000:8000 port mapping first, since a fixed host port can't bind N times. |
| Memory at scale | ivfflat cosine index works well for <1M vectors; switch to HNSW for higher recall at scale. |
| MCP transport | Defaults to streamable-http; co-located deployments can use stdio for lower latency. |
| Cost control | BudgetGuard blocks an LLM call before projected spend exceeds BUDGET_LIMIT_USD; cost is tracked per token, per agent, per workflow. |
| Resilience | Circuit breaker + tenacity retries isolate flaky upstreams; Retry-After honored on 429s. |
| Resource baseline | A full local stack (Postgres + MCP + API + frontend) runs comfortably on ~4 GB RAM / 2 vCPU for evaluation. |
β οΈ Illustrative only β not a benchmark. These figures come from an LLM judge over 20 synthetic test cases and exist to demonstrate the evaluation harness (scripts/run_eval.py), not to claim production accuracy. Re-generate them yourself before citing.
| Metric | Score | Notes |
|---|---|---|
| Faithfulness | 0.91 | Outputs grounded in research context |
| Relevance | 0.88 | Proposals matched to company-specific signals |
| Coherence | 0.93 | Well-structured, internally consistent |
| Hallucination rate | 3.2% | Invented specifics caught by the judge |
| Avg cost / run | $0.042 | gpt-4o-mini workers, gpt-4o supervisor |
| Avg latency | 12.4s | Full qualify β propose pipeline |
| Qualification accuracy | 91% | vs. a 20-example manually-labeled set |
Scores generated by an LLM judge on 20 synthetic test cases β illustrative, not a benchmark.
| Target | Where | Notes |
|---|---|---|
| Docker Compose | docker-compose.yml Β· docker-compose.prod.yml | Local + single-host production |
| Kubernetes | k8s/ | StatefulSet + Deployments + HPAs + NetworkPolicies + Ingress |
| Helm | helm/forgeflow/ | Templated chart with an Alembic pre-upgrade hook |
| Terraform (AWS) | terraform/aws/ | VPC + EKS + RDS PG16 (pgvector) + Secrets Manager + ECR + IRSA |
| Fly.io | fly/ Β· scripts/deploy_fly.sh | 3 apps + managed Postgres + 6PN networking |
| Air-gapped | docs/deployment/AIRGAPPED.md Β· scripts/build_offline_bundle.sh | Offline bundle builder |
Backup & disaster recovery β Postgres is the single source of truth; see docs/operations/backup-dr.md for backup, restore, RPO/RTO, and DR-runbook guidance.
# Install dev dependencies
pip install -e '.[dev]' # or: pip install -r requirements-dev.txt
# Quality gates
make lint # ruff + mypy
make fmt # ruff format
make test # full suite with coverage
make test-unit # fast unit tests only
# Start just the DB for local API dev
docker compose up postgres
# Run the API locally (hot-reload)
uvicorn forgeflow.api.main:app --reload
# Run the React console (Vite dev server, HMR, proxies /api β :8000)
cd frontend && npm install && npm run dev # β http://localhost:5173VS Code Dev Containers β "Reopen in Container" uses .devcontainer/devcontainer.json to give you Python 3.11 + Node + the
[dev]deps preinstalled. Services still come up withdocker compose up.
| Extend⦠| Pattern to copy | Add |
|---|---|---|
| A new connector | forgeflow/connectors/github.py | A Connector subclass + a matching MCP tool router under forgeflow/mcp/server/tools/ |
| A new MCP tool | any router in forgeflow/mcp/server/tools/ | Mount it in forgeflow/mcp/server/main.py |
| A new workflow | forgeflow/workflows/sales_ops/ | models.py, prompts.py, stages.py, pipeline.py + a manifest.yaml template |
| A new LLM provider | forgeflow/models/provider.py | A lazy-imported branch in get_model() |
| A new tracing backend | forgeflow/observability/tracing_provider.py | A TRACING_PROVIDER branch |
forgeflow/
βββ agents/ # Supervisor, Researcher, Analyzer, Executor
βββ graph/ # LangGraph StateGraph wiring + PostgreSQL checkpointer
βββ state/ # Shared WorkflowState schema
βββ mcp/ # FastMCP server (14 tool routers) + MCP client adapter
βββ connectors/ # 8 enterprise connectors on a resilient base
βββ a2a/ # A2A protocol, registry, transport, dispatcher
βββ memory/ # pgvector semantic store + relational store
βββ workflows/ # sales_ops Β· support_ops Β· finance_recon pipelines
βββ api/ # FastAPI app, routers, schemas, dependencies
βββ middleware/ # RBAC + JWT, audit, rate limiter, security
βββ auth/ Β· rbac/ # JWT issuance + role policies
βββ security/ # PII Β· prompt Β· SSRF Β· tool-output Β· email guards
βββ resilience/ # Retry (tenacity), circuit breaker, budget guard
βββ observability/ # Tracing providers, cost tracker, metrics, Prometheus
βββ evaluation/ # LLM judge, metrics, dataset, eval runner
βββ events/ # Redis Streams + Kafka consumers + dispatcher
βββ jobs/ # Approval escalation background job
βββ marketplace/ # File-based template registry
βββ multimodal/ # PDF + image ingestion
βββ telemetry/ # Opt-in anonymous usage emitter
βββ notifications/ # Slack HITL cards
frontend/ # React 19 + Vite SPA (13 console views + landing + architecture)
tests/ # unit/ + integration/ (344 tests)
scripts/ # seed_db Β· run_demo Β· run_eval Β· validate_hubspot Β· deploy_fly Β· marketplace
alembic/ # 9 migrations (schema Β· pgvector Β· RBAC Β· escalation Β· multi-tenant Β· auth hardening)
k8s/ Β· helm/ Β· terraform/ Β· fly/ # Deployment targets
templates/ # Built-in + community workflow templates
docs/ # Production runbook Β· air-gapped guide Β· images
Phases 0β6 are shipped (full history in ROADMAP.md). Highlights and what's next:
β Shipped β supervisor multi-agent core Β· PostgreSQL checkpointing Β· MCP tool server Β· A2A protocol Β· pgvector memory Β· JWT + RBAC + audit Β· cost tracking + budget guard Β· circuit breaker Β· LLM-as-judge evals Β· 8 enterprise connectors Β· Prometheus + OTel + Phoenix/Langfuse tracing Β· Slack HITL Β· approval escalation Β· event-driven mode (Redis/Kafka) Β· multi-modal (PDF + images) Β· template marketplace Β· React 19 console Β· K8s/Helm/Terraform(AWS)/Fly.io/air-gapped deploys.
π§ In progress / next (good first issues β see ROADMAP.md)
- Multi-tenant query scoping β extend
workspace_idfiltering to all tenant-scoped endpoints (foundation + reference endpoints shipped). - Embeddings provider abstraction β
get_embeddings()factory for Ollama/Cohere/Voyage to unblock 100%-offline mode. - Terraform for GCP & Azure β mirror the AWS module with GKE/Cloud SQL and AKS/Flexible Server.
- Voice / Whisper transcription β
transcribe_audioMCP tool alongside the PDF/image pipeline.
Contributions are welcome! Start with CONTRIBUTING.md and the Code of Conduct.
- Fork & branch β
git checkout -b feat/your-feature(orfix/β¦,docs/β¦). - Set up β
pip install -e '.[dev]'anddocker compose up postgres. - Code to the standards β keep it typed;
make lint(ruff + mypy) andmake fmtmust pass. - Test β add tests next to the suite;
make testmust stay green (306+ and counting). - Open a PR β describe the change, link any issue, and ensure CI is green. Issues tagged
good first issueandhelp wantedare great entry points.
See COMMUNITY.md for discussion channels.
Licensed under the Apache License 2.0.
Built for the bleeding edge of agentic AI deployment.
β Star the repo if ForgeFlow helps you ship agents to production.
