Skip to main content

Worker manifests

A worker manifest tells Warden which LLM to use and which MCP servers to connect to. Run warden deploy -f config/<worker-manifest>.yaml to save the configuration in Postgres.

Keep in mind that deploying this manifest doesn't start a worker process. It saves the config to the database. When your running worker pulls a task from the outbox, it reads this saved definition to figure out how to execute the step.

This page covers required fields, providers, and MCP setup. Saga steps point to a worker by matching its name and version. We'll connect them in the next guide on Saga manifests.

Required fields

Every worker manifest needs identity, model, and a system prompt:

kind: worker
namespace: default
name: my-worker
version: 0.1.0
provider: openai
model_name: gpt-4o
system_prompt: |
You are a helpful assistant.

name, namespace, and version identify the saved worker (see Manifests and artifacts → Deploy and identity). Saga steps reference it with worker + worker_version. Steps use the saga's namespace — you don't set namespace on the step itself.

Providers

Warden currently supports three inference providers:

ProviderCredentialsNotes
openaiOPENAI_API_KEY (or provider_secrets row)Any OpenAI-compatible cloud model
localNone — optional WARDEN_LOCAL_LLM_BASE_URLOpenAI-compatible local endpoint (Ollama, vLLM, etc.). Under Compose, see Configuration → Local LLM under Docker (Ollama)
mockNoneCredential-free demo — Demo: Mock LLM and MCP

YAML accepts other provider names (like anthropic), but they fail at runtime until you add an adapter. See Extending Warden — LLM providers.

MCP tool sources

Warden workers use the Model Context Protocol (MCP) to talk to external APIs. List the servers your agent can reach under tool_sources in the worker manifest; saga steps narrow that list with their own tools.allow.

When a worker picks up a step, it opens a connection for each source. For stdio sources, that means spawning a subprocess that stays alive until the step finishes or times out — stdin/stdout carry messages between the MCP server and your agent loop. For sse sources, the worker connects over HTTP to a server that's already running elsewhere.

TransportConfigHow it connects
sse (default)urlHTTP SSE client to a running MCP server
stdiocommand, argsSpawns a subprocess; MCP speaks over stdin/stdout

SSE — for an MCP server your worker reaches over the network (Compose service, k8s sidecar, hosted endpoint):

tool_sources:
- name: my-mcp
transport: sse
url: http://mcp-service:8765/sse
headers:
Authorization: "Bearer ${ENV:COMPANY_MCP_TOKEN}"
X-Api-Key: "${ENV:GATEWAY_KEY}"

Set COMPANY_MCP_TOKEN and GATEWAY_KEY on the worker service (.env or Compose env_file) — not in the manifest. Literal header values work too when you skip ${ENV:…} placeholders. The worker needs network access to the URL.

Stdio — for a local process the worker starts per connection (a binary on disk or docker run, as in the GitHub demo):

tool_sources:
- name: github
transport: stdio
command: docker
args:
- run
- --rm
- -i
- -e
- GITHUB_PERSONAL_ACCESS_TOKEN
- ghcr.io/github/github-mcp-server
env_inherit:
- GITHUB_PERSONAL_ACCESS_TOKEN

Pass secrets on the worker service (.env), not in the manifest. Use env: for explicit values, env_inherit: to copy names from the worker process, or docker run -e VAR in args. See the GitHub MCP demo for a Docker stdio example on the dev stack.

Omit tool_sources if the worker doesn't need MCP tools.

Optional fields

Everything beyond the required fields is optional. Common additions:

FieldDefaultPurpose
descriptionShort note for your team or deploy listings
temperature0.0LLM sampling temperature
tool_sources[]MCP servers — see MCP tool sources
adapterlangchainHow the worker runs agent steps internally. Leave at default unless you ship a custom adapter. Not the same as saga-step agent-adapter: react | simple — see Saga manifests → Reason step execution
compensation_promptBuilt-in compensation promptMulti-tool compensation only — ignored when compensation YAML has exactly one tools.allow entry

Compensation prompt

The usual path is one tool in your compensation YAML's tools.allow. The worker calls it once — no LLM, same as a commit step. compensation_prompt is ignored on that path.

Use compensation_prompt only when compensation allows multiple tools and needs a ReAct loop. The worker prepends this text before that loop (or a built-in default if the field is empty). max_turns on the compensation file caps the loop.

Even with a custom prompt, the engine's core safety rules still apply — your agent won't auto-retry or diagnose errors during an active rollback. For most workflows, skip compensation_prompt and stick to a single, direct undo tool. See Compensation.

How many times the agent can loop (max_turns)

This setting actually lives on each individual kind: reason step inside your saga YAML — not here on the worker manifest.

For a standard react step, your agent will keep calling tools and talking to the LLM until it decides to run the special _submit tool. max_turns acts as a safety valve to cap those back-and-forth rounds (default is 10, max is 200). If you use a simple step, it only makes a single LLM call and ignores this cap entirely.

Most of your undo paths will just call a single MCP tool without any agent logic at all. But if you have a complex, multi-tool undo sequence that needs a short reasoning loop, you can set a custom max_turns value inside your compensation YAML file too.

See Saga manifests → Step budgets for defaults and examples.

What's next

Next up: Saga manifests — connect this worker to your steps, set tool allowlists, and add policy and HITL gates.