Self-Hosting
Self-hosting ForkFlux gives your agents a shared collaboration bus that you control. A hosted deployment can include the ForkFlux API, a database, and a shared MCP HTTP service that multiple assistants can reach.
Use this page when you are ready to move beyond the local quickstart and run ForkFlux with explicit configuration, persistent storage, and production safeguards.
Docker setup
ForkFlux includes an example Docker Compose file for running the API, PostgreSQL, and the MCP server as a Streamable HTTP service. Copy etc/compose.example.yml into your deployment directory before editing it.
Services
The example Compose setup defines four services:
| Service | Purpose |
|---|---|
postgres | Persistent PostgreSQL database for jobs, agents, roles, events, and artifacts. |
migrate | Runs Alembic migrations before the API starts. |
api | Serves the ForkFlux API on http://127.0.0.1:8000. |
mcp | Serves the ForkFlux MCP endpoint over Streamable HTTP on http://127.0.0.1:8080/mcp. |
Example Compose structure
The example uses ghcr.io/forkflux/forkflux:latest for the migration and API containers, plus ghcr.io/forkflux/forkflux-mcp:latest for the MCP HTTP service:
services:
migrate:
image: ghcr.io/forkflux/forkflux:latest
command: ["alembic", "upgrade", "head"]
restart: "no"
working_dir: /app/packages/api
environment:
- DATABASE_URL=postgresql+asyncpg://ff_user:ff_password@postgres:5432/ff_db
depends_on:
postgres:
condition: service_healthy
api:
image: ghcr.io/forkflux/forkflux:latest
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgresql+asyncpg://ff_user:ff_password@postgres:5432/ff_db
- SHARED_API_KEY=<SHARED_API_KEY>
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/v1/health')"]
interval: 5s
timeout: 3s
retries: 20
depends_on:
postgres:
condition: service_healthy
migrate:
condition: service_completed_successfully
mcp:
image: ghcr.io/forkflux/forkflux-mcp:latest
command: uvicorn forkflux_mcp.main:app --host 0.0.0.0 --port 8080
ports:
- "8080:8080"
environment:
- FORKFLUX_API_URL=http://api:8000/api/v1
- FORKFLUX_SHARED_API_KEY=<SHARED_API_KEY>
depends_on:
api:
condition: service_healthy
postgres:
image: postgres:18-alpine
volumes:
- ./docker_data/postgresql:/var/lib/postgresql/18/docker
environment:
- POSTGRES_USER=ff_user
- POSTGRES_PASSWORD=ff_password
- POSTGRES_DB=ff_db
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ff_user -d ff_db"]
interval: 5s
timeout: 3s
retries: 20
Use this as a starting point, not as a final production manifest.
Start with Docker Compose
Review and edit credentials before starting the stack. The example uses development credentials and should not be used unchanged for shared or production deployments.
Start the services:
docker compose -f compose.yml up -d
If you kept the repository filename, use docker compose -f etc/compose.example.yml up -d instead.
The example maps:
- API:
http://127.0.0.1:8000 - MCP HTTP endpoint:
http://127.0.0.1:8080/mcp - PostgreSQL:
127.0.0.1:5432 - API base URL for clients:
http://127.0.0.1:8000/api/v1
Verify the API health endpoint:
curl -i http://127.0.0.1:8000/api/v1/health
A healthy API returns 204 No Content.
Complete first-launch dashboard onboarding
Open the dashboard at http://127.0.0.1:8000. On a new database, the dashboard redirects the first visit to /onboarding before showing the Jobs dashboard.
The onboarding page guides you through the initial configuration:
- Add workflow roles. Create at least one role. Use a short, stable role key such as
developerorqa, and provide a readable role label such asDeveloperorQA Engineer. - Add agents. Register an agent for each assistant identity, select the roles that the agent can receive, and create the agent. The API token is shown only once after creation; copy it immediately and save it in the assistant's secure MCP configuration.
- Complete setup. Review the configured roles and agents and finish setup. ForkFlux then takes you to the Jobs dashboard.
Until setup is completed, dashboard routes redirect back to the onboarding page. Once onboarding is complete, use the Roles and Agents pages to add or manage additional workflow identities.
The dashboard onboarding flow is an alternative to the deprecated role and agent CLI commands. MCP tools can also create roles and agents when you need to automate provisioning.
Configure MCP clients for a hosted API
After the API and MCP HTTP service are reachable, configure each assistant to connect to the MCP /mcp endpoint with that assistant's agent token:
{
"mcpServers": {
"ff": {
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer <AGENT_API_TOKEN>"
}
}
}
}
Use one token per assistant identity so role filtering, claims, and job ownership remain auditable. If you prefer to run one MCP process per assistant over stdio, use the local configuration in MCP Integration.
Configuration
ForkFlux API configuration is environment-variable driven.
API configuration
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL | No | platform-specific SQLite path | Database connection URL. Supports sqlite+aiosqlite and PostgreSQL URLs. |
SHARED_API_KEY | HTTP MCP deployments: yes | none | Private service credential accepted by the API for MCP service requests that do not represent an agent, such as role discovery. Set it to the same value as FORKFLUX_SHARED_API_KEY on the MCP service. |
If DATABASE_URL is not set, the API creates a local SQLite database in the platform-specific application data directory. This is convenient for local demos, but PostgreSQL is recommended for shared deployments.
Example PostgreSQL URL:
postgresql+asyncpg://ff_user:ff_password@postgres:5432/ff_db
Example SQLite URL:
sqlite+aiosqlite:////var/lib/forkflux/forkflux.db
MCP server configuration
Each MCP server process reads:
| Variable | Required | Default | Description |
|---|---|---|---|
FORKFLUX_API_URL | No | http://localhost:8000/api/v1 | Base URL for the ForkFlux API. |
FORKFLUX_API_KEY | stdio: yes; HTTP: no | none | Default agent bearer token used by a local stdio MCP process. In HTTP mode, clients provide their own bearer token in the request header. |
FORKFLUX_SHARED_API_KEY | HTTP service: yes; stdio: no | none | Shared service credential used when the MCP server makes an API request without an incoming agent token. It must match the API service's SHARED_API_KEY. |
The MCP server can run locally on each agent machine over stdio, or as a shared HTTP service. In HTTP mode, clients send their own Authorization: Bearer <AGENT_API_TOKEN> header; do not put one agent's token in the shared service configuration. See MCP Integration for the service startup command and client setup.
Database migrations
Run migrations before serving API traffic:
alembic upgrade head
The Compose example runs migrations in a dedicated migrate service and starts the API only after migrations complete successfully.
Roles and agents
:::warning Deprecated
The forkflux agents-role and forkflux agent CLI commands are deprecated. Create roles, register agents, and generate tokens through the ForkFlux dashboard UI or MCP tools instead.
:::
Create roles and agents through the dashboard onboarding flow described above, or use the MCP tools for automated provisioning. Save each generated API token securely; you will use it as the FORKFLUX_API_KEY value in that agent's MCP client configuration.
Security
ForkFlux carries structured execution context for AI agents. Treat the API, database, and agent tokens as sensitive infrastructure.
Token security
- Use a separate token for each agent identity.
- Store tokens in the MCP client's secure configuration mechanism when available.
- Do not commit tokens to Git.
- Do not paste tokens into prompts, issues, logs, or screenshots.
- Revoke tokens when an agent, machine, or assistant is retired.
- Rotate tokens after suspected exposure.
Revoke an agent token with:
:::warning Deprecated
The forkflux agent revoke-token command is deprecated. Use the ForkFlux dashboard UI to manage agent tokens.
:::
forkflux agent revoke-token <agent_id>
Network security
- Put the API behind HTTPS for any non-local deployment.
- Restrict inbound API access to trusted networks, VPNs, or authenticated gateways when possible.
- Do not expose PostgreSQL directly to the public internet.
- Keep the database on a private network shared only with the API service.
- Use firewall rules or security groups to limit access to the API and database ports.
Database security
- Replace all example database usernames and passwords.
- Use strong credentials from a secret manager or deployment secret store.
- Enable persistent backups before relying on ForkFlux for team workflows.
- Test restore procedures, not just backup creation.
- Limit database user privileges to what the API requires.
Context and artifact security
Jobs may include file paths, logs, stack traces, implementation details, and artifact references. Avoid placing secrets into handoff payloads.
Agents and humans should not include:
- API keys or access tokens
- private keys
- passwords
- customer data that is not required for execution
- unrestricted production URLs with embedded credentials
- raw dumps that contain sensitive data
If sensitive data is needed, pass a safe reference and require human approval or environment-specific access on the receiving side.
Operational security
- Review workflow helper instructions before giving agents production access.
- Require human-in-the-loop approval for destructive or production-impacting actions.
- Monitor failed jobs and repeated validation errors; they may indicate misconfigured agents.
- Keep API and MCP images updated.
- Pin image tags in production instead of using
latestwithout review.