config.toml in the working directory; override it with the CONFIG_PATH environment variable.
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:
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:
- If only one config is loaded, it is always used (the
modelfield is ignored). - Otherwise,
modelis matched first, thenDEFAULT_AGENTifmodelis absent. - Returns a 400 error if multiple configs are loaded and neither
modelnorDEFAULT_AGENTis supplied at all. - Returns a 404 error if a
modelorDEFAULT_AGENTvalue is supplied but matches no loaded config.
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"
provider = "anthropic"
provider = "bedrock"
Uses AWS credentials from the environment (AWS profile, IAM role, or environment variables). No API key field.
provider = "gemini"
provider = "ollama"
No API key required. Defaults to http://localhost:11434.
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.
[mcp]
Configures Model Context Protocol (MCP) tool servers.
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.
transport = "http_streamable" (recommended)
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.
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_filterand[orchestration.worker.<name>].mcp_filter[hitl].require_approval[agent].client_tool_filter- The keys of
[mcp.servers.<name>.scratchpad]
Patterns follow these rules:
- A pattern matches the whole tool name, not part of it.
list_*matcheslist_podsbut notk8s_list_pods. - Matching is case-sensitive.
List*doesn’t matchlist_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.
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]:
create_issue. The namespace appears in these places:
tool_namespaceon HITL approval webhook items and onaura.approval_requestedandaura.approval_pendingevents. See Human-in-the-Loop Approval Gates.- The
tool.namespaceattribute onmcp.tool_callspans. See Tracing & Span Layout. namespaceon 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.
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.
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 byin_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: A2Amessage: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.
[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).

