fracta init --scaffold <mode> from your own git repository. The scaffold drops a complete deployment tree under deployment/ plus a top-level fracta.yaml — see the fracta init reference and the per-mode guides linked below.
Mode Summary
| Local Daemon | Docker Compose | Kubernetes | |
|---|---|---|---|
| Scaffold command | fracta init --scaffold local | fracta init --scaffold docker-compose | fracta init --scaffold k8s |
| Operator config | fracta.yaml (runtime.backend: local) | fracta.yaml (thin client) + deployment/configs/ | fracta.yaml (thin client) + deployment/k8s/manifests/ |
| Agents run as | Local subprocesses (git worktrees) | Container subprocesses (directory workspaces) | K8s Jobs |
| Control plane | Local daemon process (:9090) | Container (:9090) | Pod (:9090) |
| Gateway | Subprocess managed by CP daemon (:8080) | Separate container (:8080) | Separate deployment (:8080) |
| State backend | SQLite | Postgres | Postgres |
| Queue | In-process | Postgres | Postgres |
| Client attachment | RemoteControlPlaneClient → localhost:9090 | RemoteControlPlaneClient → localhost:19090 | RemoteControlPlaneClient → in-cluster Service :9090 (via port-forward / LoadBalancer / Ingress) |
| MCP backends | Host stdio (your own MCP servers) | Add to deployment/docker-compose.yml | Add to deployment/k8s/manifests/ |
One mode per project. fracta init --scaffold refuses to re-scaffold an existing project as a different mode (the resulting tree would be incoherent). See Switching modes below.
Thin-Client Architecture
All deployment modes share the same client boundary:LocalControlPlaneClient runs only inside the control plane process.
1. Local Daemon Mode
The simplest mode. A local daemon process runs the full control plane. Agents are local subprocesses with git-worktree isolation.Scaffold
Architecture
Runtime Mechanics
Local daemon mode has two different fracta MCP surfaces:fracta serveis the host-facing MCP server. Claude/Codex/OpenCode on the developer machine starts it over stdio. It is a thin client that forwards lifecycle calls to the control plane API.fracta serve --gateway-modeis the agent-facing HTTP MCP gateway. Spawned agents connect to it atgateway.url, usuallyhttp://localhost:8080/agents/<agent>/mcp.
fracta serve has confirmed that the control plane is healthy, it no longer waits on the daemon. The long-running ownership tree is:
gateway.url must be set in fracta.yaml (e.g. gateway.url: http://localhost:8080) for spawned agents to discover gateway-proxied MCP tools.
Config
The scaffoldedfracta.yaml works out of the box for local development. The relevant fields:
Auto-start and config forwarding
fracta serve auto-starts the daemon if not running. The --config flag is forwarded to the daemon process. If no config is found, the daemon starts with bare defaults (no queue, no logging, no connections) and logs a warning.
You can also manage the daemon explicitly:
Prerequisites
- FalkorDB running locally (
redis://localhost:6379). - Any MCP backend tools you reference in your config available locally (often via
podmanoruvx). - Environment variables for secrets (typically via
op run --env-file,doppler run, or similar).
When to use
- Day-to-day development.
- Debugging agent behavior with local logs.
- When git-worktree merge semantics are needed.
- When container/K8s infrastructure isn’t needed.
2. Docker Compose Mode
Same architecture, containerized. UsesDirectoryWorkspace (not git) with the host project bind-mounted at /workspace.
Scaffold
Architecture
Start
Secrets
Inject API credentials and other secrets into the compose stack with whatever secret manager you already use. Compose interpolates${VAR} from the host environment, so any tool that sets env vars works (1Password op run, Doppler, Vault Agent, sops, plain .env for dev):
Auth helpers
Edit (or replace)deployment/auth-helpers/fetch-token-example to fetch a token for your provider. The file’s header comments include reference snippets for AWS Bedrock STS, Vertex AI via gcloud, mounted Anthropic API keys, and custom HTTP token proxies.
The compose file bind-mounts ./deployment/auth-helpers/ into every fracta service container at /opt/fracta/auth-helpers/, so resolver command: references find your helper on PATH.
Workspace Semantics
Compose usesDirectoryWorkspace (not GitWorkspace). The host project directory is bind-mounted into containers at /workspace. Agent subprocesses create per-agent subdirectories under /workspace/agents/<id>. Merge/integration and base-branch semantics are disabled. For git-based workflows, use local daemon mode.
When to use
- Testing the full multi-service architecture locally.
- When you want Postgres state without K8s.
- CI/CD environments that support Docker Compose.
- Sharing a reproducible dev environment.
3. Kubernetes Mode
The orchestrator runs as an in-cluster Deployment. Agents run as K8s Jobs. The control plane is exposed as a Kubernetes Service on:9090; the host’s thin client talks HTTP to that Service. The golden path is to run fracta serve on the host as an MCP server in your AI CLI’s config — your CLI talks MCP to it, it talks HTTP to the in-cluster control plane Service. The same thin client also works from the command line (fracta spawn, fracta list, …).
Scaffold
Architecture
Config
The scaffoldedfracta.yaml is the host-side thin-client config:
deployment/k8s/manifests/fracta-controlplane.yaml and deployment/k8s/manifests/fracta-gateway.yaml.
Reaching the control plane Service from the host
The host needs to reach the in-clusterfracta-controlplane Service on :9090. The transport depends on your cluster:
type: LoadBalancer, the Service may already be directly accessible at localhost:9090. For real clusters, expose the Service via an Ingress and point control_plane_api.url in fracta.yaml at that address. None of these change the architecture — they’re just transports for the same host → Service :9090 hop.
Deploy
Auth helpers
Edit (or replace)deployment/auth-helpers/fetch-token-example, then package the directory into the fracta-auth-helpers ConfigMap:
runtime.kubernetes.extra_volumes block (already in the scaffolded ConfigMap) mounts that ConfigMap into every spawned agent pod at /opt/fracta/auth-helpers/, so command: references resolve on PATH. See Kubernetes runtime configuration for the full ConfigMap workflow.
Agent Permissions
Agent tool permissions are controlled byproject.allowed_tools in the controlplane config (deployment/k8s/manifests/fracta-controlplane.yaml), not the host-side thin-client fracta.yaml. This is because the controlplane owns agent lifecycle — it bakes permissions into each pod’s .claude/settings.json at spawn time.
PermissionBaseline (git, go, ls, cat, find, grep). Without explicit allowed_tools, agents only get the baseline.
For Codex agents, permissions are managed by Codex’s own --full-auto sandbox policy. For OpenCode agents, permissions are written to opencode.json with "task":"deny" by default. See runtime configuration for details.
Permissions are independent per project — each fracta.yaml (or controlplane ConfigMap, in k8s mode) declares its own allowed_tools.
Auth
Auth is runtime-specific. Each runtime references a credential profile defined in the controlplane ConfigMap. See authentication & credentials for the full guide. The scaffolded controlplane config ships anexample profile that points at fetch-token-example — replace it with profiles for your real auth provider (Bedrock STS, Vertex, Anthropic API key, etc.).
RBAC: the controlplane Deployment uses serviceAccountName: fracta-agent with permissions for configmaps, secrets, jobs, and pods (defined in deployment/k8s/manifests/rbac.yaml).
When to use
- Production-like local testing.
- When you need K8s Job isolation for agents.
- When iterating on agent/gateway behavior without rebuilding the orchestrator.
Comparison: What Runs Where
| Component | Local Daemon | Docker Compose | Kubernetes |
|---|---|---|---|
| MCP stdio server | Host | Host | Host |
| Control plane | Host (daemon) | Container | Pod |
| Queue workers | Daemon (in-process) | Container (in-process) | Pod (in-process) |
| Reaper | Daemon (in-process) | Container (in-process) | Pod (in-process) |
| Agent execution | Subprocess | Container subprocess | K8s Job |
| Gateway | Daemon subprocess | Container | Pod |
| Strategy runner | Gateway subprocess | Sidecar container (shared socket) | Sidecar container (shared socket) |
| State store | SQLite | Postgres (container) | Postgres (pod) |
| Graph | Host Docker / local | Container | Pod |
| MCP backends | Host stdio | Container stdio / HTTP | Pod HTTP |
| Workspace type | GitWorkspace | DirectoryWorkspace | DirectoryWorkspace |
Switching modes
fracta init --scaffold is single-mode per project. A given project declares one runtime.backend in fracta.yaml and ships one deployment/ tree (matching that mode). fracta init refuses to re-scaffold a project as a different mode, because the result would be a tree where the manifests, configs, and fracta.yaml disagree about what’s running.
If you try, you’ll see:
- Separate projects — one repo per mode.
fracta.yamlanddeployment/live independently. Organizations often factor out the shared config into a custom scaffold and pull both projects from--source github:org/my-app-scaffolds@v1. - Separate worktrees — same git repo, different branches per mode. Less ceremony than separate repos, but CI must be aware that different branches deploy to different targets.
Migration Path
The three modes form a progression:RemoteControlPlaneClient → HTTP → control plane API.
To migrate, scaffold a fresh project at the new mode (in a separate directory or branch) and copy over your agents.agent_runtimes, auth.credentials.profiles, and project.allowed_tools settings.
