Skip to content

Configuration Reference

Configure your Helix AI platform via a single helix.yaml file. This file controls agent behavior, RAG pipeline settings, LLM providers, security policies, observability, clustering, and all component parameters. It is automatically loaded from the current working directory when running helix run.


Table of Contents


Configuration File Location

The CLI looks for helix.yaml in the current working directory. If the file is missing, sensible defaults are used.

Environment Variable Resolution

All string values in helix.yaml support environment variable substitution:

# Basic substitution
api_key: "${OPENAI_API_KEY}"

# With default value
port: "${SERVER_PORT:-8080}"

# Nested in connection strings
connection: "postgres://${DB_USER:-admin}:${DB_PASS}@${DB_HOST:-localhost}:5432/${DB_NAME}"

The syntax is: - ${VAR} -- replaced with the environment variable value (empty string if unset) - ${VAR:-default} -- replaced with the environment variable value, or default if unset or empty

Full Reference

helix:
  # Application name (used in logs, metrics labels, tracing service name)
  name: my-app

  # Component-specific configuration overrides
  # Keys are component scheme names, values are key-value maps
  components:
    kafka:
      brokers: "kafka1:9092,kafka2:9092"
    redis:
      addr: "redis:6379"
      password: "${REDIS_PASSWORD}"

  # Management REST API
  management:
    enabled: true        # Enable the management API
    port: 9090           # Listen port (default: 9090)

  # Health check HTTP endpoints
  health:
    enabled: true        # Enable /health and /ready endpoints
    port: 8081           # Listen port (default: 8081)

  # Prometheus metrics
  metrics:
    prometheus:
      enabled: true      # Enable /metrics endpoint
      port: 9100         # Listen port (default: 9100)

  # Distributed tracing
  tracing:
    opentelemetry:
      enabled: true      # Enable tracing
      endpoint: "http://otel-collector:4318"  # OTel collector endpoint (empty = log exporter)

  # Graceful shutdown
  shutdown:
    drain_timeout: "30s" # Max wait for in-flight exchanges to complete (Go duration)

  # Structured logging
  logging:
    level: "info"        # Global log level: debug, info, warn, error
    format: "json"       # Output format: text, json
    components:          # Per-component level overrides
      kafka: "debug"     # More verbose for Kafka
      http: "warn"       # Less verbose for HTTP
      connector: "debug"

  # Multi-tenancy
  tenant:
    enabled: true
    header_name: "X-Tenant-ID"   # Message header containing tenant ID (default: X-Tenant-ID)
    required: true                # Reject exchanges without tenant header
    allowed_tenants:              # Restrict to specific tenant IDs (empty = allow all)
      - tenant-a
      - tenant-b
      - tenant-c

  # Audit logging
  audit:
    enabled: true
    store: "memory"       # Storage backend: "memory" (ring buffer) or "log" (slog + ring buffer)
    max_entries: 10000    # Ring buffer size (default: 10000)
    body_preview: 256     # Max bytes of message body to capture (0 = none, default: 256)

  # A2A (Agent-to-Agent) protocol servers
  a2a:
    servers:
      - enabled: true
        addr: "0.0.0.0:9000"        # Listen address (default: 0.0.0.0:9000)
        name: "my-agent"             # Agent name in Agent Card
        description: "My AI Agent"   # Agent description in Agent Card
        version: "1.0.0"             # Agent version in Agent Card

  # AG-UI (Agent-User Interaction) protocol servers
  agui:
    servers:
      - enabled: true
        addr: "0.0.0.0:4100"        # Listen address (default: 0.0.0.0:4100)
        path: "/agent"               # HTTP path (default: /agent)
        name: "my-chatbot"           # Agent name

  # A2UI (Agent to UI) protocol servers
  a2ui:
    servers:
      - enabled: true
        addr: "0.0.0.0:4200"        # Listen address (default: 0.0.0.0:4200)
        path: "/surface"             # HTTP path (default: /surface)
        name: "my-ui-agent"          # Agent name

Section Details

name

The application name is used as: - The service name in distributed traces - A label in Prometheus metrics - The context name in management API responses - The log prefix

components

Component-specific configuration overrides. Each key is a component scheme name, and the value is a map of key-value pairs. These are made available to components at startup.

components:
  kafka:
    brokers: "host1:9092,host2:9092"
    sasl_mechanism: "SCRAM-SHA-256"
  postgres:
    pool_max_conns: "20"
  openai:
    api_key: "${OPENAI_API_KEY}"

management

The management REST API provides runtime control and observation endpoints. When enabled, it listens on the configured port and exposes:

Endpoint Method Description
/api/info GET Instance info (name, state, uptime, counts)
/api/workflows GET List all routes with state
/api/workflows/{id} GET Single workflow detail with metrics
/api/workflows/{id}/start POST Start a stopped workflow
/api/workflows/{id}/stop POST Stop a running workflow
/api/workflows/{id}/suspend POST Suspend a running workflow
/api/workflows/{id}/resume POST Resume a suspended workflow
/api/components GET List registered component schemes
/api/health GET Health check results
/api/metrics GET Metrics snapshot
/api/config GET Configuration dump
/api/agents GET List registered agents
/api/audit GET Recent audit entries
/api/tracer GET Backlog tracer status
/api/tracer/enable POST Enable backlog tracer
/api/tracer/disable POST Disable backlog tracer

health

When enabled, the health manager listens on the configured port and exposes:

Endpoint Description
/health Full health check with per-component results (JSON). Returns 200 if all UP, 503 if any DOWN.
/ready Readiness probe. Returns 200 (READY) or 503 (NOT_READY).

Health check response format:

{
  "status": "UP",
  "checks": {
    "helix": {"status": "UP"},
    "kafka": {"status": "UP", "details": {"brokers": 3}},
    "postgres": {"status": "DOWN", "details": {"error": "connection refused"}}
  }
}

metrics

When Prometheus metrics are enabled, the /metrics endpoint serves metrics in Prometheus text exposition format. Available metric types:

  • Counters: helix_exchanges_total, helix_exchanges_failed_total
  • Gauges: helix_exchanges_inflight, helix_workflows_total
  • Histograms: helix_exchange_duration_seconds

All metrics are labeled with workflow (workflow ID).

tracing

When OpenTelemetry tracing is enabled, every exchange is wrapped in a span. The tracer: - Generates W3C Trace Context IDs (128-bit trace ID, 64-bit span ID) - Propagates trace context via exchange properties - Records span attributes: workflow ID, trigger URI, exchange pattern, component scheme - Reports span events for errors - Exports to an OTel collector endpoint, or to structured logs if no endpoint is configured

shutdown

The drain_timeout controls how long the engine waits for in-flight exchanges to complete during graceful shutdown. If the timeout elapses, remaining exchanges are abandoned and the engine shuts down.

Default: 30 seconds.

logging

Helix uses Go's log/slog for structured logging. The logging section controls:

  • level: Global minimum log level. Messages below this level are dropped.
  • format: Output format. text produces human-readable lines; json produces JSON-encoded log records.
  • components: Per-component overrides. Components are identified by the component attribute in log records.

The per-component overrides allow verbose logging for specific components without increasing overall noise. For example, setting kafka: debug while the global level is info will show debug messages only from the Kafka component.

tenant

Multi-tenancy isolates exchanges by tenant. When enabled, the tenant interceptor:

  1. Extracts the tenant ID from the configured message header
  2. If required: true, rejects exchanges without a tenant header
  3. If allowed_tenants is non-empty, rejects unknown tenants
  4. Sets the helix.tenant exchange property for downstream use

Downstream processors, metrics, and routing can use the helix.tenant property for tenant-aware behavior.

audit

The audit interceptor records exchange lifecycle events. Each audit entry captures:

Field Description
timestamp When the event occurred
exchange_id Exchange identifier
workflow_id Route that processed the exchange
from_uri Source URI
operation "completed" or "failed"
duration_ns Processing duration
error Error message (if failed)
headers Message headers
body_preview First N bytes of message body

Storage backends: - memory -- in-memory ring buffer, queryable via the management API /api/audit endpoint - log -- writes entries to slog AND stores in a ring buffer for API queries

a2a

The A2A section configures Agent-to-Agent protocol servers. Each server exposes Helix agents as A2A-compliant endpoints with Agent Cards for discovery. Multiple servers can run simultaneously on different ports.

Field Default Description
enabled false Enable this A2A server instance
addr 0.0.0.0:9000 Listen address (increments port for additional servers)
name helix-a2a-{index} Agent name in Agent Card
description Helix AI Agent Agent description in Agent Card
version 1.0.0 Agent version in Agent Card

The server auto-discovers agents from the agent:// component and invocable workflows (direct://, seda://), exposing them as A2A skills. Uses the official github.com/a2aproject/a2a-go SDK.

agui

The AG-UI section configures Agent-User Interaction protocol servers for real-time streaming to frontend applications. Each server exposes an HTTP POST endpoint that accepts RunAgentInput JSON and streams SSE events back.

Field Default Description
enabled false Enable this AG-UI server instance
addr 0.0.0.0:4100 Listen address (increments port for additional servers)
path /agent HTTP endpoint path
name helix-agui-{index} Agent name

Uses the official github.com/ag-ui-protocol/ag-ui/sdks/community/go SDK. Compatible with CopilotKit and other AG-UI clients.

a2ui

The A2UI section configures Agent to UI protocol servers for rich declarative UI generation. Each server exposes an SSE endpoint that streams A2UI JSONL messages (components, data model updates, rendering directives).

Field Default Description
enabled false Enable this A2UI server instance
addr 0.0.0.0:4200 Listen address (increments port for additional servers)
path /surface HTTP endpoint path
name helix-a2ui-{index} Agent name

GET requests stream A2UI component updates; POST requests receive client-side userAction events. Uses github.com/burka/a2ui-go SDK.

Workflow Authentication

Workflows support declarative authentication via the auth: block. The auth processor runs before any workflow steps -- unauthenticated requests are rejected immediately with a 401 response.

workflows:
  - id: my-workflow
    trigger:
      uri: http-server://0.0.0.0:8080/api/data
    auth:
      # Choose one auth type per workflow: apikey, jwt, basic, or oauth2
      type: apikey                              # required: apikey|jwt|basic|oauth2

      # API Key authentication (when type: apikey)
      apikey:
        header: X-API-Key                     # header to check (default: X-API-Key)
        keys:
          - "${env:API_KEY_1}"
          - "${vault:secret/api-keys#key2}"

      # JWT authentication (when type: jwt)
      # jwt:
      #   secret: "${env:JWT_SECRET}"            # HMAC secret or RSA/EC public key
      #   issuer: "https://auth.example.com"     # required issuer claim (optional)
      #   audience: "my-api"                     # required audience claim (optional)

      # Basic authentication (when type: basic)
      # basic:
      #   users:                                 # map of username to bcrypt hash
      #     admin: "${env:ADMIN_PASSWORD}"
      #     reader: "${vault:secret/basic-auth#reader}"

      # OAuth2 token introspection (when type: oauth2)
      # oauth2:
      #   token-url: "https://auth.example.com/oauth2/introspect"
      #   client-id: "${env:OAUTH2_CLIENT_ID}"
      #   client-secret: "${env:OAUTH2_CLIENT_SECRET}"
      #   scopes:
      #     - read
      #     - write
    steps:
      - log:
          message: "Authenticated request received"

Only one auth type should be specified per workflow. Secrets support resolution via ${env:VAR}, ${vault:path#key}, and ${aws-sm:secret-name}.

See the User Guide Authentication section for full examples including JWKS rotation, scope-based authorization, and per-workflow auth composition.

OCR

Configure OCR (Optical Character Recognition) for document intelligence in RAG pipelines. The OCR backend processes scanned PDFs, images with text, and complex document layouts into structured text for downstream chunking and embedding.

helix:
  ocr:
    backend: docling            # OCR backend (see table below)
    endpoint: http://localhost:5001  # Backend service endpoint
    api_key: ${OCR_API_KEY}     # API key for paid services (Azure, Unstructured)
    timeout: 120s               # Request timeout (default: 120s)
    max_pages: 100              # Max pages to process per document (default: 100)
Backend Description Self-Hosted API Key Required
docling IBM Docling -- best balance of accuracy and speed Yes No
marker Marker -- fast PDF-to-markdown Yes No
tesseract Tesseract OCR -- widely deployed, many languages Yes No
surya Surya -- multilingual OCR with layout detection Yes No
unstructured Unstructured.io -- enterprise document parsing Yes Optional
azure-doc-intelligence Azure AI Document Intelligence No (cloud) Yes
vision-llm Use a vision-capable LLM (GPT-4o, Claude) for OCR N/A Yes (LLM key)

When backend: vision-llm is selected, the OCR step sends document pages as images to the configured LLM provider. This works well for complex layouts but is slower and more expensive than dedicated OCR backends.

Session

Configure per-session memory isolation for agents. When enabled, each unique session ID gets its own memory instance, preventing cross-user context leakage.

helix:
  session:
    header: X-Session-ID        # Header name to extract session ID from (default: X-Session-ID)
    timeout: 1h                  # Session inactivity timeout (default: 1h)
    max_sessions: 10000          # Max concurrent sessions in cache (default: 10000)

Session IDs are extracted from the specified request header. If the header is missing, the exchange ID is used as a fallback, giving that request a one-shot memory. See the AI Agents Guide for detailed usage.

SmartMemory

SmartMemory is a token-aware memory backend for tool-using agents. It tracks token consumption rather than message count and intelligently compresses large tool results to stay within budget.

Configure SmartMemory on a per-agent basis in the agent's memory: block:

agents:
  - id: code-agent
    type: react
    model:
      provider: anthropic
      model: claude-sonnet-4-20250514
    memory:
      enabled: true
      type: smart          # or "code" (alias for smart)
      max_tokens: 100000   # token budget for conversation history
Field Type Default Description
type string -- smart or code (alias). Activates token-managed memory
max_tokens integer 100000 Maximum tokens allowed in conversation history before eviction

Behavior: - Tracks tokens per message, not turn count - Large tool results (file contents, command output) are compressed to first 10 + last 10 lines - Tool call and tool response pairs are always evicted together - Evicted messages are summarized in a context map appended to the system prompt - The system message is never evicted

See the AI Agents Guide for a detailed explanation of the compression and eviction algorithm.

Built-in Function Security

The built-in function registry provides 14 ready-to-use tools for agents. Security-sensitive functions (shell.exec, fs.write, fs.delete, fs.edit) can be configured in the agent YAML or globally in helix.yaml:

helix:
  builtin_functions:
    shell:
      timeout: 30s                    # Max execution time for shell.exec (default: 30s)
      blocked_commands:               # Commands rejected by shell.exec
        - "rm -rf /"
        - "shutdown"
        - "reboot"
        - "mkfs"
        - "dd"
      allowed_dirs:                   # Restrict file system access to these dirs (empty = cwd)
        - "/home/user/project"
    web:
      max_response_size: 30720       # Max bytes for web.fetch response (default: 30KB)
      timeout: 30s                    # HTTP request timeout (default: 30s)
Key Type Default Description
shell.timeout duration 30s Kill shell commands after this duration
shell.blocked_commands list (see above) Commands rejected outright
shell.allowed_dirs list (empty) Restrict file/shell ops to these directories
web.max_response_size integer 30720 Truncation limit for web.fetch (bytes)
web.timeout duration 30s HTTP timeout for web.fetch

When allowed_dirs is empty, file system operations are restricted to the working directory passed via --dir to helix chat or the current working directory for helix run.

MCP Servers

The mcps: top-level section configures MCP (Model Context Protocol) servers that expose agents, pipelines, and workflows as tools to LLM clients like Claude Desktop.

mcps:
  # Public MCP server — exposes 3 agents as tools
  - id: public-tools
    addr: 0.0.0.0:3100
    transport: http            # http, sse, or stdio
    expose:                    # Agent/workflow ID to expose (empty = all)
      - code-assistant
      - math-agent
      - summarizer

    # Security
    api_keys:                  # API keys for direct access (Bearer or X-API-Key)
      - mcp-public-key-2026
    rate_limit: 120            # Max requests per minute (0 = unlimited)
    cors_origins:              # Allowed CORS origins (empty = none)
      - "http://localhost:3000"
      - "http://localhost:5173"
    max_body_bytes: 2097152    # Max request body (default: 1MB)
    trusted_proxies:           # IPs that skip auth (gateway proxy)
      - "127.0.0.1"
      - "::1"
    allowed_tools: []          # Whitelist (empty = all exposed tools allowed)
    blocked_tools: []          # Blacklist (always blocked even if in allowed)

  # Admin MCP server — separate port, separate key, restricted
  - id: admin-tools
    addr: 0.0.0.0:3101
    transport: http
    expose:
      - admin-tool
      - code-assistant
    api_keys:
      - mcp-admin-key-2026
    rate_limit: 30
    trusted_proxies:
      - "127.0.0.1"
      - "::1"
    blocked_tools:
      - summarizer             # Block summarizer even if exposed
Field Type Default Description
id string required Unique MCP server identifier
addr string 0.0.0.0:3100+i Listen address
transport string http Transport: http, sse, or stdio
expose list [] (all) Agent/workflow ID to expose as tools
api_keys list [] Allowed API keys for direct access
rate_limit integer 0 Max requests/minute (0 = unlimited)
cors_origins list [] CORS allowed origins
max_body_bytes integer 1048576 Max request body size
trusted_proxies list [] IPs that skip auth (e.g., gateway)
allowed_tools list [] Tool whitelist (empty = all)
blocked_tools list [] Tool blacklist (always blocked)

Security layers (applied in order): 1. CORS — checks Origin header against cors_origins 2. Trusted proxy — requests from trusted_proxies IPs skip auth 3. IP allowlist — restricts by client IP (if configured) 4. API key auth — validates Authorization: Bearer <key> or X-API-Key 5. Rate limiting — token-bucket per minute 6. Body size — rejects oversized payloads 7. Tool filtering — blocked_tools checked at call time (returns isError: true)

WebSocket

WebSocket endpoints provide bidirectional real-time communication. Define them as workflows:

workflows:
  # WebSocket AI Chat
  - id: ws-chat
    trigger:
      uri: ws-server://0.0.0.0:8200/ws
    steps:
      - agent:
          id: ws-agent
          type: react
          model:
            provider: openai
            model: gpt-4o-mini
            api_key: ${OPENAI_API_KEY}
          system_prompt: You are a chat assistant on WebSocket.
          max_iterations: 3

  # WebSocket Echo
  - id: ws-echo
    trigger:
      uri: ws-server://0.0.0.0:8201/ws
    steps:
      - log:
          message: "echo: ${body}"

The ws-server:// component: - Accepts RFC 6455 WebSocket connections - Runs incoming messages through the workflow pipeline - Returns the pipeline output as the WebSocket response - Supports text and binary frames - Manages multiple concurrent client connections - Each port hosts one WebSocket endpoint

The ws:// client component can connect to external WebSocket servers from within workflows.

SynaptX Integration

Helix integrates with SynaptX AI gateway for enterprise features:

helix:
  management:
    enabled: true
    port: 9999          # SynaptX discovers Helix via this port

agents:
  - id: code-assistant
    model:
      provider: openai
      model: gpt-4o-mini
      api_key: sk-vk-xxxxx              # SynaptX virtual key
      base_url: http://localhost:7080/ai/openai  # Route through SynaptX

Virtual keys — SynaptX provides per-agent API keys with: - Budget limits (daily/monthly USD) - Rate limits (RPM, TPM, RPD) - Provider/model access control - Usage tracking and billing

SynaptX provides (when fronting Helix): - Prompt injection guard (16 patterns, per-workflow) - PII detection and blocking (SSN, credit card, API keys) - WAF (SQL injection, XSS) - Governance policies (ABAC/RBAC, agent budgets, inter-agent rules) - MCP tool filtering (allowed_tools, blocked_tools at gateway level) - A2A/AG-UI protocol proxying - Audit trail and compliance logging

Discovery — SynaptX auto-discovers Helix agents via: - GET http://localhost:9999/.well-known/helix-manifest.json - Returns: agents, MCP servers, workflows, capabilities

Architecture:

Client → SynaptX (:7080) → Helix Agents
           ├─ /ai/*     → LLM providers (virtual key auth)
           ├─ /a2a/     → A2A server (:9100)
           ├─ /agui/    → AG-UI server (:4100)
           ├─ /mcp/     → MCP public (:3100)
           ├─ /mcp-admin/ → MCP admin (:3101)
           └─ /ws/      → WebSocket (:8200)

CLI Flags

In addition to the configuration file, the run command supports these flags:

Flag Description
--watch, -w Enable hot reload: watch files for changes and reload workflows

Minimal Configuration

The smallest valid helix.yaml:

helix:
  name: my-app

Everything else uses defaults: - Management API on port 9090 (enabled) - Health checks on port 8081 (enabled) - Metrics disabled - Tracing disabled - 30s drain timeout - Info-level text logging - Multi-tenancy disabled - Audit disabled

Production Configuration Example

helix:
  name: order-service

  management:
    enabled: true
    port: 9090

  health:
    enabled: true
    port: 8081

  metrics:
    prometheus:
      enabled: true
      port: 9100

  tracing:
    opentelemetry:
      enabled: true
      endpoint: "http://otel-collector:4318"

  shutdown:
    drain_timeout: "60s"

  logging:
    level: "info"
    format: "json"
    components:
      kafka: "warn"
      postgres: "warn"

  tenant:
    enabled: true
    header_name: "X-Tenant-ID"
    required: true
    allowed_tenants:
      - acme-corp
      - globex

  audit:
    enabled: true
    store: "log"
    max_entries: 50000
    body_preview: 512