Skip to Content
How-To GuidesGeneralEditing the Golem Application Manifest (golem.yaml)

Editing the Golem Application Manifest (golem.yaml)

The golem.yaml file in the project root is the Golem Application Manifest. It defines the entire application: components, agents, build steps, environments, HTTP/MCP deployments, and more.

Manifest version: The manifestVersion field at the top of the file identifies the application manifest document version. Do not change it.

Top-Level Structure

manifestVersion: "1.5.0" # Manifest document version — do not change app: my-app # Application name includes: # (optional) Glob patterns for additional manifest fragments - "components/*/golem.yaml" componentTemplates: # Reusable property layers (build, env, plugins, files) <template-name>: { ... } components: # Component definitions by name (namespace:name) <ns:name>: { ... } tools: # Canonical tool implementation declarations <tool-name>: { ... } agents: # Agent type definitions by PascalCase name <AgentName>: { ... } environments: # Deployment environments (local, cloud, custom) <env-name>: { ... } version: # (optional) Logical version attached to each deployment git: { ... } # git: | env: <VAR> | "1.2.3" (literal) httpApi: # HTTP API domain deployments deployments: { ... } mcp: # MCP (Model Context Protocol) deployments deployments: { ... } bridge: # Bridge SDK generation configuration ts: { ... } rust: { ... } customCommands: # User-defined CLI commands <command-name>: [...] clean: # Extra paths for `golem clean` - "path/to/clean" secretDefaults: # Secret defaults per environment <env-name>: {...} retryPolicyDefaults: # Retry policy defaults per environment <env-name>: {...} resourceDefaults: # Quota resource defaults per environment <env-name>: {...}

Components

Components are keyed by namespace:name (e.g., my-app:billing).

components: my-app:billing: dir: billing # Base directory (relative to golem.yaml). Use "." for single-component apps templates: # Parent template names (inherit build, env, plugins, files) - rust componentWasm: target/wasm32-wasip2/debug/billing.wasm # Path to built WASM outputWasm: golem-temp/billing.wasm # Path to final output WASM build: # Build commands (see Build Commands below) - command: cargo build --target wasm32-wasip2 env: # Environment variables LOG_LEVEL: info tools: # Owner authorization; inherited by the component's agents search: {} plugins: # Plugin installations - name: otlp-exporter version: "0.1.0" files: # Initial filesystem entries - sourcePath: ./data/config.json targetPath: /etc/config.json clean: # Extra clean paths - target/ presets: # Named presets with overrides debug: default: true env: LOG_LEVEL: debug release: env: LOG_LEVEL: warn

Key component fields

FieldTypeDescription
dirstringBase directory for resolving paths. "." for single-component apps
templatesstring or string[]Parent template name(s) to inherit from
componentWasmstringPath to the built WASM component
outputWasmstringPath for the final output WASM ready for upload
buildarrayBuild commands (see Build Commands)
envmapEnvironment variables (string → string)
envMergeModeenumupsert (default), replace, or remove
toolsmapTool bindings authorized for component owners and inherited by the component’s agents
toolsMergeModeenumupsert (default), replace, or remove
pluginsarrayPlugin installations
pluginsMergeModeenumappend (default), prepend, or replace
filesarrayInitial filesystem entries
filesMergeModeenumappend (default), prepend, or replace
configanyArbitrary configuration passed to agent
wasiConfigmapWASI configuration variables (string → string)
wasiConfigMergeModeenumupsert (default), replace, or remove
customCommandsmapComponent-level custom commands
cleanstring[]Extra clean paths
presetsmapNamed presets (see Presets)

Component Templates

Templates define reusable property layers. Components reference them via templates:.

componentTemplates: my-rust: templates: [rust] # Inherits the built-in "rust" template (build, guestLanguage) env: RUST_LOG: info components: my-app:service: templates: [my-rust] # Inherits from "my-rust" and, through it, from "rust" dir: service

Templates support the same fields as components except dir. Templates can themselves reference other templates via templates:, but a template may be inherited only through a single path: using two templates that both inherit the same template (e.g. templates: [my-ts, ts-extra] where both inherit ts) is rejected. The same applies to the templates lists of agents and tools. The built-in templates (rust, ts, effect, scala and moonbit) are provided by the CLI; don’t define templates with these names.

Templates can declare the guest language of the components built with them via guestLanguage (ts, effect, rust, scala or moonbit). The built-in templates declare it, so templates inheriting them don’t need to. A custom template that builds a component on its own (without inheriting a built-in template) should declare it, otherwise language-specific CLI features (dependency checks, bridge generation, REPL) are unavailable for its components. The templates applied to a component must not declare different languages.

Agents

Agent types are keyed by PascalCase name. They support the same cascading property fields as components (env, plugins, files, config, wasiConfig) but NOT build-related fields. Agents can also inherit from templates via templates:.

agents: MyAgent: templates: [shared-runtime] # Inherit env/plugins/files from a template env: CACHE_TTL: "300" plugins: - name: otlp-exporter version: "0.1.0" files: - sourcePath: ./agent-data/model.bin targetPath: /data/model.bin presets: debug: default: true env: CACHE_TTL: "60"

Config and WASI Config

The config field accepts arbitrary YAML values (objects, arrays, scalars) passed as typed configuration to the agent at runtime. The wasiConfig field is a string-to-string map of WASI-level configuration variables.

components: my-app:service: config: model: gpt-4o-mini temperature: 0.2 features: - summarize - translate wasiConfig: WASI_FLAG: enabled agents: MyAgent: config: max_retries: 3 wasiConfig: AGENT_WASI_OPT: "true"

Both fields follow the cascade hierarchy and support merge modes (wasiConfigMergeMode for wasiConfig).

Cascade / Merge System

Properties cascade from general to specific:

componentTemplates → components → agents → presets

Each level can override or merge with its parent using merge modes:

PropertyMerge Mode FieldTypeDefaultOptions
envenvMergeModemapupsertupsert, replace, remove
wasiConfigwasiConfigMergeModemapupsertupsert, replace, remove
pluginspluginsMergeModevecappendappend, prepend, replace
filesfilesMergeModevecappendappend, prepend, replace
buildbuildMergeModevecappendappend, prepend, replace
toolstoolsMergeModemapupsertupsert, replace, remove

Component tool bindings authorize fresh component owners (including tools-only MCP calls) and default into real agents exported by that component. An agent-only binding does not authorize a fresh component owner. To opt an agent out of an inherited tool, remove it explicitly:

components: my-app:service: tools: search: {} agents: RestrictedAgent: toolsMergeMode: remove tools: search: {}

When agents should not receive the defaults, prefer a separate component with no agents as the tool owner.

Presets

Both components and agents support presets — named configurations that can override the properties allowed at that level. Component presets can override component-layer fields (build, env, plugins, files, config, wasiConfig, clean, customCommands); agent presets can override agent-layer fields (env, plugins, files, config, wasiConfig). Presets cannot override structural fields like dir or templates. Mark one preset as default with default: true.

components: my-app:service: presets: debug: default: true # Selected by default env: LOG_LEVEL: debug release: env: LOG_LEVEL: warn

Build Commands

The build array contains commands executed during golem build. Each entry is one of:

External command (most common)

build: - command: cargo build --target wasm32-wasip2 dir: . # Optional working directory env: # Optional extra env vars RUSTFLAGS: "-C opt-level=2" rmdirs: [target/old] # Directories to delete before running (runs before mkdirs) mkdirs: [target/new] # Directories to create before running (runs after rmdirs) sources: ["src/**/*.rs"] # Inputs for up-to-date checks targets: ["target/wasm32-wasip2/debug/*.wasm"] # Outputs for up-to-date checks

TypeScript/QuickJS-specific commands

build: - generateQuickjsCrate: golem-temp/quickjs-crate # Generate QuickJS Rust crate wit: wit jsModules: { "main.js": "esm" } world: my-world # Optional WIT world - generateQuickjsDts: golem-temp/bindings.d.ts # Generate TypeScript declarations wit: wit - injectToPrebuiltQuickjs: golem-temp/quickjs.wasm # Inject JS into prebuilt QuickJS module: dist/bundle.js into: golem-temp/output.wasm - preinitializeJs: golem-temp/output.wasm # Pre-initialize JS runtime into: golem-temp/preinit.wasm

Custom Commands

Define CLI commands at the application or component level:

customCommands: test: - command: cargo test --target wasm32-wasip2 dir: . lint: - command: cargo clippy --target wasm32-wasip2

Run with golem exec <name> (e.g., golem exec test).

customCommands can only contain command:-style external commands; they do not support generateQuickjsCrate, injectToPrebuiltQuickjs, or other build-specific command types.

Environments

Environments configure where and how the application is deployed.

environments: local: default: true # First environment is default if not specified server: local # Built-in local server cli: format: text autoConfirm: true cloud: server: cloud # Golem Cloud staging: server: # Custom server url: https://staging.example.com auth: oauth2: true # or: staticToken: "my-token" workerUrl: https://staging-workers.example.com # Optional separate worker URL allowInsecure: false # Optional, allow insecure connections componentPresets: [release] # Preset names to activate cli: format: json redeployAgents: true # Delete and recreate agents; agent state is lost deployment: compatibilityCheck: true versionCheck: true securityOverrides: false

Server options

ValueDescription
localBuilt-in local Golem server
cloudGolem Cloud
{ url, auth, ... }Custom server (see Custom Server below)

Custom server auth

# OAuth2 (interactive login) auth: oauth2: true # Static token auth: staticToken: "my-secret-token"

CLI options

FieldDescription
formatDefault output: text, json, yaml, pretty, pretty-json, pretty-yaml, toon
autoConfirmAuto-confirm prompts (true)
redeployAgentsEquivalent to --redeploy-agents: delete and recreate agents; agent state is lost
resetEquivalent to --reset: delete existing agents for the deployed components after deployment, losing their state, and enable incompatibility-replacement fallbacks; the environment itself is retained

Configure at most one destructive default. If both are enabled, reset takes precedence.

When format: toon is used, structured stdout is emitted as framed TOON documents. Parse exact @toon and @end marker lines, and treat the content between them as one TOON document. Stderr may still contain progress or diagnostics and should not be parsed as the structured payload.

Deployment options

FieldTypeDescription
compatibilityCheckboolCheck component compatibility before deploying
versionCheckboolReject a deploy whose logical version already exists in the environment (enforce version uniqueness). Default false
securityOverridesboolAllow security scheme overrides

Deployment Version

version: (top-level) and environments.<name>.version: (per-environment override) configure the logical version attached to each deployment — derived from a git tag, the git commit hash, a static string, or an environment variable. This is orthogonal to versionCheck above (which enforces uniqueness of that version).

version: # application-wide default git: tagPattern: "v*" # required for git tag mode; "*" = all tags hashFallback: true # untagged repo → short commit hash staticFallback: "v0.0.0" # no git / not a repo → this value environments: local: version: git: allowDirty: true # partial override; inherits the rest from the root

Load golem-deployment-version for the full field reference (git tag/hash modes, commitInfo, hashFallback, staticFallback, allowDirty, per-environment overrides, and how the version interacts with versionCheck).

HTTP API Deployments

Configure HTTP API domain deployments per environment.

Each deployment must define exactly one of:

  • subdomain: a single DNS label resolved through the target environment server (my-app.localhost:9006 locally by default, my-app.apps.golem.cloud on built-in cloud).
  • domain: a full custom domain such as api.example.com for custom DNS or custom server environments.

The optional scheme field is the public http or https scheme advertised in OpenAPI. Omission defaults to http for built-in local and implicit local environments and https for built-in cloud. Explicit values override these defaults. Custom server environments require an explicit value; the management URL scheme is not inferred. This does not configure the listener.

httpApi: deployments: local: - subdomain: my-app # resolves to my-app.localhost:9006 by default webhookUrl: /webhooks/ # Optional webhook path prefix agents: TaskAgent: {} # No auth SecureAgent: securityScheme: my-oidc # OIDC security scheme name DevAgent: testSessionHeaderName: X-Test-Auth # Test auth header cloud: - subdomain: my-app # resolves to my-app.apps.golem.cloud agents: TaskAgent: {} SecureAgent: securityScheme: prod-google-oidc

Agent names use PascalCase matching the agent type name in code.

MCP Deployments

Configure MCP (Model Context Protocol) deployments per environment.

Each deployment must define exactly one of:

  • subdomain: a single DNS label resolved through the target environment server (my-mcp.localhost:9007 locally by default, my-mcp.mcps.golem.cloud on built-in cloud).
  • domain: a full custom domain such as mcp.example.com for custom DNS or custom server environments.
components: my-app:search-implementation: componentWasm: build/search-implementation.wasm my-app:tool-owner: componentWasm: build/tool-owner.wasm tools: search: {} tools: search: component: my-app:search-implementation mcp: deployments: local: - subdomain: my-mcp # resolves to my-mcp.localhost:9007 by default tools: search: ownerComponent: my-app:tool-owner include: [query]

The MCP tool must also have a top-level implementation declaration and a components.my-app:tool-owner.tools.search binding. No agent is required. The implementation and owner components may differ; include/exclude selects exported commands. A remote declaration requires an environment grant, which application deployment automatically reconciles when the deploy actor has permission.

Bridge SDK Generation

Generate typed client SDKs for calling agents from external code. The agents field accepts "*" (all agents), or a list of agent type names or component names (namespace:name).

bridge: ts: external: agents: "*" # Generate for all agents outputDir: ./bridge-sdk/ts # Optional custom output directory rust: external: agents: - MyAgent # Agent type name - my-app:billing # Component name (all agents in that component) outputDir: ./bridge-sdk/rust additionalDerives: - '^Order.*=PartialEq,Eq' - 'Response$=custom_derive::ApiType' additionalDependencies: anyhow: "1" custom_derive: path: ./crates/custom-derive # Relative to this manifest file package: custom-derive-macros features: [api] defaultFeatures: false git_derive: git: https://github.com/example/derive-macros tag: v1.2.3 # Use at most one of branch/tag/rev

additionalDerives entries are <regex>=Trait,Trait; every matching final generated Rust type name receives the merged, deduplicated derives. additionalDependencies accepts a version string or one source (version, path, or git) plus package, features, and defaultFeatures; git accepts one of branch, tag, or rev. Workspace and optional dependencies are not supported. These Rust-only fields are valid under bridge.rust.external and bridge.rust.internal for agent bridges only. An internal entry using them must select agents; tool bridge generation is unchanged.

The low-level equivalent uses repeatable options and parses each dependency as Cargo TOML:

golem generate-bridge --language rust \ --derive-rule '^Order.*=PartialEq,Eq' \ --rust-dependency 'custom_derive = { package = "custom-derive-macros", path = "./crates/custom-derive", features = ["api"], default-features = false }'

CLI paths are relative to the invocation directory; manifest paths are relative to the directory containing the bridge declaration.

Plugin Installations

Plugins are installed at any cascade level (template, component, agent, preset).

plugins: - name: otlp-exporter version: "0.1.0" account: golem # Optional account parameters: # Optional key-value config endpoint: http://localhost:4317 protocol: grpc

Initial Files

Mount files into the agent’s virtual filesystem.

files: - sourcePath: ./data/config.json # Local path or URL targetPath: /etc/app/config.json # Absolute path in agent filesystem permissions: read-only # read-only (default) or read-write - sourcePath: ./static-assets/ # Directory — recursively included targetPath: /var/www/static/ - sourcePath: https://example.com/model.bin # Remote URL targetPath: /data/model.bin

Template Substitution

Environment variable values support {{ VAR_NAME }} syntax. At deploy time, these resolve against the host machine’s environment:

env: API_KEY: "{{ MY_API_KEY }}" DB_URL: "prefix-{{ DB_HOST }}-suffix"

Missing host variables cause deployment failure.

Secret Defaults

Secret defaults per environment use the same nested object style as config:

secretDefaults: local: apiKey: "test-key-123" prod: apiKey: "{{ PROD_API_KEY }}"

Retry Policy Defaults

Named retry policies created in the environment during deployment:

retryPolicyDefaults: local: default-retry: priority: 10 predicate: "true" # Always match policy: countBox: maxRetries: 3 inner: exponential: baseDelay: { secs: 1, nanos: 0 } factor: 2.0

Retry policy types

TypeFieldsDescription
"immediate"—Retry immediately
"never"—Never retry
periodic{ secs, nanos }Fixed delay between retries
exponential{ baseDelay, factor }Exponentially increasing delay
fibonacci{ first, second }Fibonacci-sequence delays
countBox{ maxRetries, inner }Limit total retry count
timeBox{ limit, inner }Limit total retry time
clamp{ minDelay, maxDelay, inner }Clamp delay range
addDelay{ delay, inner }Add fixed delay to inner policy
jitter{ factor, inner }Add random jitter
filteredOn{ predicate, inner }Apply only when predicate matches
andThen[policy1, policy2]Sequential composition
union[policy1, policy2]Union of two policies
intersect[policy1, policy2]Intersection of two policies

Retry predicates

TypeFieldsDescription
"true"—Always matches
"false"—Never matches
propEq{ property, value }Property equals value
propNeq{ property, value }Property not equal
propGt / propGte{ property, value }Greater than / greater or equal
propLt / propLte{ property, value }Less than / less or equal
propExistsstringProperty exists
propIn{ property, values }Property in set
propMatches{ property, pattern }Regex match
propStartsWith{ property, prefix }Starts with prefix
propContains{ property, substring }Contains substring
and[pred1, pred2]Logical AND
or[pred1, pred2]Logical OR
notpredicateLogical NOT

Predicate values are typed: { text: "..." }, { integer: 42 }, or { boolean: true }.

Resource Quota Defaults

Quota resource definitions created during deployment:

resourceDefaults: local: api-calls: limit: type: Rate value: 100 period: minute max: 1000 enforcementAction: reject # reject, throttle, or terminate unit: request units: requests storage: limit: type: Capacity value: 1073741824 # 1 GB enforcementAction: reject unit: byte units: bytes connections: limit: type: Concurrency value: 50 enforcementAction: throttle unit: connection units: connections

Resource limit types

TypeRequired FieldsDescription
Ratevalue, period, maxRate limit per time period. period: second/minute/hour/day/month/year
CapacityvalueTotal capacity limit
ConcurrencyvalueConcurrent usage limit

Enforcement actions

ActionDescription
rejectReject requests exceeding the limit
throttleSlow down requests exceeding the limit
terminateTerminate the agent when limit is exceeded

Common Edit Patterns

Add a new component

Insert a new key under components::

components: my-app:new-service: dir: new-service templates: [rust]

Add environment variables to an agent

agents: MyAgent: env: NEW_VAR: "value"

Add a plugin to a component

components: my-app:service: plugins: - name: my-plugin version: "1.0.0" parameters: key: value

Add a new environment

environments: staging: server: url: https://staging.example.com auth: staticToken: "{{ STAGING_TOKEN }}"

Add HTTP API deployment for a new environment

httpApi: deployments: staging: - domain: api-staging.example.com scheme: https agents: MyAgent: {}

Add clean paths

Root-level clean paths apply to golem clean globally; component-level clean paths are scoped to that component:

clean: - golem-temp/ - dist/ components: my-app:web: clean: - node_modules/.cache/ - build/

Field Scope Matrix

This table shows where each property can be defined:

FieldRootComponent TemplateComponentAgentComponent PresetAgent Preset
templates—✅✅✅——
guestLanguage—✅————
build—✅✅—✅—
env—✅✅✅✅✅
wasiConfig—✅✅✅✅✅
plugins—✅✅✅✅✅
files—✅✅✅✅✅
config—✅✅✅✅✅
tools—✅✅✅✅✅
customCommands✅✅✅—✅—
clean✅✅✅—✅—
dir——✅———
componentWasm—✅✅—✅—
outputWasm—✅✅—✅—

Edit Guardrails

  • Do not invent fields: most manifest objects use additionalProperties: false — only use fields documented above.
  • Preserve manifestVersion: never change the manifest document version.
  • Agent names use PascalCase: matching the class/trait name in code (e.g., MyAgent, not my-agent).
  • Component names use namespace:name format (e.g., my-app:billing).
  • Only one default: true preset per preset map.
  • Merge modes are intentional: env, wasiConfig, plugins, files, and build respect merge modes. Don’t silently replace arrays/maps unless a merge mode of replace is set.
  • Template substitution ({{ VAR }}) in env values resolves from host environment at deploy time. Missing variables cause deployment failure.