Skip to main content
AURA is configured with a single TOML file. The file path defaults to config.toml in the working directory; override it with the CONFIG_PATH environment variable.
To validate a config file, start the web server or CLI against it. Both validate immediately and exit with a clear error if parsing fails, before binding to any port or entering the REPL:

Environment Variable Interpolation

Any string value in the config can reference an environment variable using {{ env.VAR_NAME }}. An optional | default: 'value' fallback prevents a hard error when the variable is unset.

Root-Level Fields


[agent]

Defines the agent identity, system prompt, and behavioral settings.

Multiple Agents

CONFIG_PATH can point to a single TOML file or a directory of .toml files. When pointed at a directory, AURA loads every .toml file and serves each as a selectable agent:
Each agent is identified by its alias (if set) or name. Clients discover available agents via GET /v1/models and select one by passing its identifier as the model field in chat completion requests. The same field tools like LibreChat, OpenWebUI, and CLI clients use to present a model picker. Agent selection follows this order:
  1. If only one config is loaded, it is always used (the model field is ignored).
  2. Otherwise, model is matched first, then DEFAULT_AGENT if model is absent.
  3. Returns a 400 error if multiple configs are loaded and neither model nor DEFAULT_AGENT is supplied at all.
  4. Returns a 404 error if a model or DEFAULT_AGENT value is supplied but matches no loaded config.
Aliases must be unique across all loaded configs. If two configs share the same name and neither has an alias, loading fails with a validation error. Hidden agents are excluded from GET /v1/models and the CLI’s /model list but remain fully accessible when a caller targets them by exact name or alias. Set hidden = true to hide agents that are in development, restricted to known callers, or should not appear in model pickers (LibreChat, OpenWebUI, etc.):

[agent.llm]

Configures the LLM provider. The provider field is a discriminant that selects the variant and its required fields.

Common Fields

These fields are available on all providers except where noted.

provider = "openai"

Extra fields:

provider = "anthropic"

Extra fields:

provider = "bedrock"

Uses AWS credentials from the environment (AWS profile, IAM role, or environment variables). No API key field.
Extra fields:

provider = "gemini"

Extra fields:

provider = "ollama"

No API key required. Defaults to http://localhost:11434.
Extra fields:

provider = "openrouter"

Access 300+ models through a single API key. Uses OpenRouter’s reasoning wire format (reasoning + reasoning_details). For other OpenAI-compatible APIs (Fireworks, Together), use provider = "openai" with base_url instead.
Extra fields:

[mcp]

Configures Model Context Protocol (MCP) tool servers.
A per-server headers = { "User-Agent" = "..." } entry replaces the header for that server only. The handshake still announces the name and version from user_agent.

[mcp.servers.<name>]

Each server is a named entry under [mcp.servers]. The transport field selects the connection type. The server’s key (<name>) is also the namespace of its tools. Use it in a tool-name pattern to select tools from this server only. When more than one server advertises the same tool name, see Tool Names Shared by Multiple Servers. Connects to an MCP server over HTTP using the current MCP streamable transport (post-2025-11-05).

transport = "sse"

Connects using the legacy SSE-based MCP protocol. Supports the same headers, headers_from_request, and scratchpad options as http_streamable.

transport = "stdio"

Spawns a local child process. Each agent request creates its own process instance. cmd is a list where cmd[0] is the executable and cmd[1..] are fixed arguments that are part of the command (e.g. a script path). args are additional arguments appended after.

Per-Server user_agent

Every transport accepts an optional user_agent that replaces [mcp].user_agent for that server. On http_streamable and sse it also replaces the HTTP User-Agent header; on every transport, including stdio, it replaces the handshake’s clientInfo.name and clientInfo.version. Use it when one server expects a particular product token, or when you want one server to see a deployment tag that the others should not.

Static Headers

Add static headers to every request to an HTTP or SSE server:

Header Forwarding (headers_from_request)

Forward headers from the incoming API request to the MCP server. The table maps outgoing header name → incoming request header name. Useful for per-user auth delegation.
When headers_from_request is set, the forwarded header takes precedence over any matching static header from headers.

Per-Tool Scratchpad Thresholds

Override when a tool’s output gets intercepted by the scratchpad system. Keys are tool-name patterns matched against this server’s tool names; the most specific (longest) pattern wins.

Tool Names Shared by Multiple Servers

AURA presents MCP tools to the model by their bare names, so only one server’s tool can hold a given name. When more than one server advertises the same tool name, the agent gets the tool from the server whose [mcp.servers.<name>] key sorts first, counting only servers whose tool passes the agent’s or worker’s mcp_filter. For example, [mcp.servers.alpha] wins over [mcp.servers.beta], whatever transport each server uses. The other servers’ tools with that name are unreachable, including through text-fallback tool calls (fallback_tool_parsing). To use the tool from a different server, scope mcp_filter to that server, for example mcp_filter = ["beta:*"], or rename the tool on all but one server. The web server logs a warning for each shared name at startup, and governance catalog sync logs the same warning. The warning names every server that advertises the tool and the server that sorts first. It doesn’t account for mcp_filter, so an agent’s filter can select a different server than the warning names. To find shared names, the web server connects to each agent’s MCP servers once before it starts accepting requests. The servers are checked one at a time, and each connection can take up to [mcp].connect_timeout_secs, so leave room for the check in startup and readiness probe timeouts. The check starts each stdio server’s command and sends only static headers. A server that needs headers from headers_from_request logs a connection warning at startup, and the web server still starts.

Tool-Name Patterns

Several fields select tools by name, and they all use the same pattern syntax:
  • [agent].mcp_filter and [orchestration.worker.<name>].mcp_filter
  • [hitl].require_approval
  • [agent].client_tool_filter
  • The keys of [mcp.servers.<name>.scratchpad]
AURA checks every pattern when it loads the config. A pattern outside this syntax stops the web server or CLI from starting, and the error names the column of the problem. If you’re upgrading a config written for an earlier AURA release, see Breaking Changes: 5 October 2026. A pattern is built from these parts: Patterns follow these rules:
  • A pattern matches the whole tool name, not part of it. list_* matches list_pods but not k8s_list_pods.
  • Matching is case-sensitive. List* doesn’t match list_pods.
  • No other characters are allowed, including spaces and \. There is no escape character, and a pattern can’t be empty.
  • A class holds only letters, digits, _, -, /, and ., so [*] is invalid.
  • An alternative can contain wildcards and classes, but not another {...}.
  • A run of letters, digits, _, -, /, and . can be at most 64 characters long. A wildcard, a class, a {, ,, or }, or the : ends the run, and a class’s contents don’t count toward it.

Scope a Pattern to One MCP Server

Prefix a pattern with a namespace and : to match tools from one MCP server. The namespace is the server’s key in [mcp.servers.<name>], so github:create_issue matches create_issue from [mcp.servers.github] and no other server. A pattern without : matches tools from any server. Both segments accept the full pattern syntax, so *:list_pods and git{hub,lab}:list_* are valid. A pattern can contain only one :, and neither segment can be empty. A namespaced pattern never matches a tool that doesn’t come from an MCP server, such as a filesystem tool from [tools].filesystem or a client-side tool. The namespace form is most useful in these fields:
  • mcp_filter: Select tools from one server, or pick which server provides a shared tool name.
  • [hitl].require_approval: Gate a tool from one server without gating a tool with the same name from another.
In client_tool_filter, a namespaced pattern is accepted but never matches, because client-side tools have no MCP server. In a [mcp.servers.<name>.scratchpad] key, the namespace is compared with that table’s own server key. Under [mcp.servers.github.scratchpad], the key github:get_report matches the same tool as get_report, and gitlab:get_report matches nothing. This example assumes the config defines [mcp.servers.github] and [mcp.servers.gitlab]:
The model never sees the namespace. It always receives the bare tool name, such as create_issue. The namespace appears in these places:
  • tool_namespace on HITL approval webhook items and on aura.approval_requested and aura.approval_pending events. See Human-in-the-Loop Approval Gates.
  • The tool.namespace attribute on mcp.tool_call spans. See Tracing & Span Layout.
  • namespace on each tool entry in the governance catalog.

[agent.scratchpad]

Controls context window management. When enabled, large MCP tool outputs are saved to disk and replaced with a file pointer. The agent then uses eight exploration tools (head, slice, grep, schema, item_schema, get_in, iterate_over, read) to selectively read the data it needs. See Scratchpad for the full feature guide. Requires memory_dir to be set at the root level and context_window to be set on [agent.llm]. Orchestration also accepts the legacy [orchestration.artifacts].memory_dir as a fallback when the top-level field is absent.

[agent.skills]

Points the agent at directories of on-demand skills. Skills follow the Agent Skills specification: each skill is a subdirectory containing a SKILL.md file with YAML frontmatter (name, description). The name must match the directory name and consist of lowercase alphanumerics and hyphens only (1–64 characters, no leading/trailing/consecutive hyphens). See Skills for the full feature guide.
A load_skill tool is exposed to the agent that loads and executes skills on demand, along with a read_skill_file tool for fetching individual resource files from a skill’s directory. Skills the agent loads stay in context on later turns of the same chat session. See Skill Persistence Across Turns.

[[vector_stores]]

Configures RAG (Retrieval-Augmented Generation) stores. Each entry creates a vector_search_<name> tool the agent can call. Multiple stores create multiple search tools.

type = "qdrant"

type = "in_memory"

type = "bedrock_kb"

Managed RAG uses AWS credentials, so no embedding model is needed.
Extra fields: When you set profile, the Knowledge Base client uses only that AWS profile’s credentials, even if static AWS environment credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY) are also present. When you omit profile, it falls back to the default AWS credential chain. This makes profile-based cross-account access reliable alongside static environment credentials used elsewhere in the deployment. For example, an IRSA (IAM Roles for Service Accounts) profile that assumes a role via web identity. Both managed and classic Bedrock knowledge bases handle embeddings for you. The managed flag only selects which kind of knowledge base the store points at. If you leave managed unset or false for a managed knowledge base, retrieve requests fail with a ValidationException. The full error reads: Incompatible configuration: vectorSearchConfiguration is not supported for managed knowledge bases. Use managedSearchConfiguration instead. Set managed = true to resolve it.

Embedding Models

Used by in_memory and qdrant types.

[tools]

Enables built-in server-side tools.

[hitl]

Human-in-the-loop (HITL) approval gates let an agent ask for permission before running selected MCP tools. [hitl] is the enable bit — there is no separate enabled field; presence of the table turns it on, and route is required when it’s present. See HITL for the full route contracts, SSE lifecycle events, and current scope (single-agent vs. orchestration worker gating).

[hitl.route]

Tagged by mode: "conversational" or "webhook".

Session Store (Durable and Multi-Pod Deployments)

Unlike every other section on this page, the session store is not configured in TOML. It’s deployment infrastructure (one instance per server, not per-agent), so it’s configured only via environment variables. By default, cross-request session state (A2A tasks, parked HITL approvals, and skill-invocation logs) lives in process memory. Correct for a single pod, the CLI, and local dev. Behind a load balancer with multiple replicas, configure a shared Redis/Valkey backend and every cross-request flow works no matter which pod serves each request: A2A message:send → poll → list → history-by-context, A2A subscribe/cancel against a task executing on another pod, and conversational HITL approvals resolved by a POST /v1/approvals/{id} that lands away from the pod that parked them.
AURA_SESSION_STORE_SKILLS_TTL_SECS sets how long a chat session’s skill-invocation log lives after the agent last calls load_skill or read_skill_file. It defaults to 86400 (24 hours), and 0 disables expiry. The Redis and file backends apply it. The memory backend has no expiry and clears its logs on restart. See Skill Persistence Across Turns. The server pings the backend at startup and fails fast if it is unreachable; /health reports the backend and its ping latency. The Redis backend requires building with the session-store-redis cargo feature (cargo build --release --features aura-cli/session-store-redis). The in-memory backend is always available. See the session storage design doc for the design and Helm packaging roadmap.

[orchestration]

Enables multi-agent orchestration mode. A coordinator agent decomposes user queries into tasks and delegates them to specialized worker agents for parallel execution. The coordinator’s system prompt comes from [agent].system_prompt. Workers are defined in [orchestration.worker.<name>] sections. Execution loop:
  • Plan: coordinator decomposes the request into a task DAG.
  • Execute: dependency-ready tasks run in parallel waves on worker agents.
  • Continue: coordinator consolidates worker outputs and routes to a final response, replan, or clarification.
Workers run with isolated task context windows and filtered MCP/vector-store access based on each worker block.

[orchestration.timeouts]

See request lifecycle for the operational guidance and caveats on this timeout.

[orchestration.artifacts]

Controls persistence and artifact promotion.

[orchestration.worker.<name>]

Defines a specialized worker. Worker names must be unique case-insensitively (to avoid filesystem collisions) and non-empty.

Per-Worker LLM Override

Workers inherit [agent.llm] by default. Provide [orchestration.worker.<name>.llm] to use a different model for a specific worker (e.g. a cheaper model for simple tasks).

Per-Worker Scratchpad Override

Per-Worker Skills Override

None (field absent) inherits [agent.skills]. An explicit empty list disables skills. A non-empty list replaces the agent’s skills entirely (no merging).

Complete Examples

Minimal: OpenAI

Single Agent with MCP Tools

Single Agent with Scratchpad

Large tool outputs are intercepted and saved to disk; the agent uses exploration tools to read what it needs.

Multi-Agent Orchestration with Per-Worker Models

RAG with Qdrant

Local Ollama (No API Key)

AWS Bedrock with Knowledge Base