---
title: "MiniAgent"
id: "1700"
type: "page"
slug: "mini-agent"
published_at: "2026-09-20T19:50:18+00:00"
modified_at: "2026-09-21T01:36:28+00:00"
url: "https://xedant.com/agents/agent/docs/mini-agent"
markdown_url: "https://xedant.com/agents/agent/docs/mini-agent.md"
excerpt: "MiniAgent is the built-in coding agent: a fully self-contained backend compiled right into Xedant Agent…"
---

# MiniAgent

[https://xedant.com/agents/agent/docs/mini-agent.md](https://xedant.com/agents/agent/docs/mini-agent.md)

**MiniAgent** is the built-in coding agent: a fully self-contained backend compiled right into Xedant Agent (a C# library, a minimal Pi-style agent rewritten from scratch). It needs no external program and has nothing to install — Xedant Agent and MiniAgent are one whole and **fully self-sufficient out of the box**.

MiniAgent is part of Xedant Agent’s backend system and is selected with the `AGENT_BACKEND=mini` variable. For the general overview of backends, see the [Backends](/agents/agent/docs/backends)
 page.

## Why this matters for your business

Regular backends are third-party programs downloaded and installed through a package manager. MiniAgent is different: it lives **inside** Xedant Agent itself, which means:

- **Independence from third-party developers.** The agent’s work does not depend on someone else’s projects and their updates — the engine is always at the server’s side.
- **Supply security.** No packages installed from third-party sources — the very risk of receiving a compromised installer disappears.
- **Self-sufficiency out of the box.** MiniAgent is already inside the product: nothing to download, install, or update separately.
- **Everything on your server.** The agent runs wherever Xedant Agent runs: your data never leaves your infrastructure.

## Capabilities

It is a full agent with everything real work needs:

- **Tools**`read`, `write`, `edit`, `bash`, `parallel_bash`, `grep`, `find`, `ls`, `glob`, `load_skill`, and `todo_write` — reading, editing, and creating files, running commands, search, and skill loading;
- **Persistent sessions** — the conversation is saved in JSONL format and resumes after a restart;
- **Model and reasoning-level switching on the fly** — right in the middle of a dialog, losing nothing;
- **Automatic context compaction** — long conversations do not “forget” their beginning;
- **Retries on transient provider failures** and protection from lost replies;
- **Token and cost accounting** — in the chat and in analytics;
- **Project context** — reads `CLAUDE.md`/`AGENTS.md` itself (`CLAUDE.md` takes priority) and finds the `.claude/skills` skills on its own;
- **Interactive forms and buttons** (`agent.form`/`agent.button`) — right in the system prompt, with no separate extensions.

*Note: passing images into the chat is not wired up yet — images are ignored on send with a warning in the log.*

## Connecting it

MiniAgent is selected with the `AGENT_BACKEND=mini` variable. The easiest way is to create a model from a ready provider template that already carries the MiniAgent backend: **Anthropic, DeepSeek, z.ai, BigModel, OpenRouter, xAI, MiniMax, Moonshot, OpenAI, OpenCode Go/Zen**. The template fills in the backend and the connection parameters for you:

- `MINI_BASE_URL` — the provider address;
- `MINI_API` — the protocol format: `anthropic-messages` or `openai-completions`;
- `MINI_AUTH` — the authorization type: `api-key` or `bearer`;
- `MINI_API_KEY` — the access key.

The model is set in the “provider/model:thinking” format, for example `MODEL=anthropic/claude-sonnet-5:medium`. The `:thinking` suffix sets the reasoning level: `off`, `minimal`, `low`, `medium`, `high`. A model the templates do not know is assembled automatically from the parameters above; when a `~/.mini/models.json` file exists (a Pi-compatible format), it takes priority. If no model is set at all, `deepseek/deepseek-v4-flash` is used. The default provider can be set with the `MINI_PROVIDER` variable — it applies when the model name has no “provider/” prefix.

## Data

MiniAgent’s data is stored in the `~/.mini` folder (overridable with the `MINI_AGENT_DIR` variable):

- `models.json` — the model configuration;
- `agent-sessions` — sessions in JSONL format;
- `skills` — additional skills;
- `CLAUDE.md` — the global context.

## MiniAgent profiles

**A profile is a named set of settings for the built-in agent**: which context files to load, which tools it may use, how long a single call may run, and the token ceiling for requests. Profiles let you keep several modes of working in one project: a “safe” one without `bash` for sensitive repositories, a “draft” one with a long timeout for heavy tasks, a “read-only” one for reviews — and switch between them just by changing the model.

Profiles live in the `miniagent.yml` file in the project’s brand folder (`.xedant/`). The root map is `profiles:` — the key is the profile name, the value is its settings:

```
# miniagent.yml
profiles:
  safe:                       # safe mode: no bash, a short timeout
    disabledTools:
      - bash
    toolCallTimeout: 60
    loadAgentsMd: false

  readonly:                   # read-only: only the search tools are allowed
    enabledTools:
      - read
      - grep
      - find
      - glob
      - ls
```

The model picks the profile with a `mini:name` suffix in the `AGENT_BACKEND` variable of the model’s configuration on the [Models](/agents/agent/docs/models)
 page — for example, `AGENT_BACKEND=mini:safe`. The profile name is lowercased and looked up case-insensitively; the legacy alias `mini-agent:safe` works too. A plain `AGENT_BACKEND=mini` without a suffix, an empty suffix, or a **nonexistent name** all give the built-in defaults — a missing profile logs a warning. Only the MiniAgent backend understands the colon suffix; other backends take the `AGENT_BACKEND` value as a whole.

## Profile settings

Every profile field is optional: a missing field, an empty `{}` profile, or a missing file all mean the built-in defaults.

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| loadClaudeMd | bool | true | loads CLAUDE.md into the context |
| loadAgentsMd | bool | true | loads AGENTS.md into the context |
| enabledTools | list of names | none (all 11 enabled) | the tool allowlist; an empty list is an error; mutually exclusive with disabledTools |
| disabledTools | list of names | none (all enabled) | the tool denylist; mutually exclusive with enabledTools |
| toolCallTimeout | int, seconds | 300 | the ceiling on a single tool call |
| maxOutputTokens | int | 131072 | the request’s output-token ceiling; overrides the model’s maxTokens |
| thinkingBudget | int | 65536 | the thinking budget for every reasoning level except off; applied on anthropic endpoints |
| parallelBashThreads | int | 5 | how many commands of one parallel_bash call run at once |
| systemPrompt | string | built-in | replaces the built-in base system prompt; empty also means built-in |
| sessionHeader | string | none (X-Agent-Session, X-Opencode-Session on opencode) | the name of the HTTP header carrying the session id on every provider request; a headers entry in models.json with the same name takes priority |

The tool names are exactly the 11 built-in ones: `read`, `bash`, `parallel_bash`, `edit`, `write`, `grep`, `find`, `glob`, `ls`, `load_skill`, `todo_write`. **Both `enabledTools` and `disabledTools` in one profile is an error** (in the yml and in environment variables alike): allowing and forbidding the same tool makes no sense. An empty `enabledTools` is rejected — it would leave the profile with no tools at all — while an empty `disabledTools` only produces a warning.

Each setting’s priority: **environment variable > profile > built-in default**. The profile lays on top of the defaults, and the variable on top of the profile.

**The session header.** Every provider request carries the session id in an HTTP header — the receiving provider can tell MiniAgent chats apart: group traffic, rate-limit requests, or keep per-session storage without parsing the conversation. By default the header is named `X-Agent-Session`; on opencode providers (a provider id starting with `opencode` or an address on `opencode.ai`) — `X-Opencode-Session`. The name is changed by the profile’s `sessionHeader` field or the `MINI_PROFILE_SESSION_HEADER` variable; an explicit `headers` entry in models.json with the same name beats the automatic stamp. The `sessionHeader` key has no editor in the settings dialog — you write it into `miniagent.yml` by hand or set the variable; the dialog passes a hand-set value through unchanged. A request sent before the session id exists carries no header.

## Environment variables

Any profile setting can be overridden at the process level with a `MINI_PROFILE_*` variable — it applies on top of the selected profile (or the defaults, when no profile is set):

| Variable | Overrides |
| --- | --- |
| MINI_PROFILE_LOAD_CLAUDE_MD | loadClaudeMd |
| MINI_PROFILE_LOAD_AGENTS_MD | loadAgentsMd |
| MINI_PROFILE_ENABLED_TOOLS | enabledTools (comma-separated names) |
| MINI_PROFILE_DISABLED_TOOLS | disabledTools (comma-separated names) |
| MINI_PROFILE_TOOL_CALL_TIMEOUT | toolCallTimeout |
| MINI_PROFILE_MAX_OUTPUT_TOKENS | maxOutputTokens |
| MINI_PROFILE_THINKING_BUDGET | thinkingBudget |
| MINI_PROFILE_PARALLEL_BASH_THREADS | parallelBashThreads |
| MINI_PROFILE_SYSTEM_PROMPT | systemPrompt |
| MINI_PROFILE_SESSION_HEADER | sessionHeader |

**An empty variable value counts as unset** — the setting comes from the profile or the default, so you can “clear” an override with an empty string. Both list variables at once (`MINI_PROFILE_ENABLED_TOOLS` and `MINI_PROFILE_DISABLED_TOOLS`) is a hard error, as is an unparseable value (not `true`/`false`, not a positive number): the session is not created, and the error names the variable.

Example — a Docker container with a 120-second tool-call timeout and `bash` disabled for all chats:

```
docker run -e MINI_PROFILE_TOOL_CALL_TIMEOUT=120 \
           -e MINI_PROFILE_DISABLED_TOOLS=bash \
           xedant/agent
```

MiniAgent, like the other backends, respects the network variables `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY`: when the server reaches the internet through a proxy, provider requests go through it too, while addresses from `NO_PROXY` go direct. Details on the [Models](/agents/agent/docs/models)
 page.

## The parallel_bash tool

`parallel_bash` is MiniAgent’s tool for running **several independent commands in one call**. The model decides which commands do not depend on each other (this independence contract is fixed in the tool’s description) and combines them into a single call:

```
parallel bash:
  - git status --short
  - ls pages/ | wc -l
  - df -h /project
```

The commands run concurrently: `parallelBashThreads` (5 by default) limits how many run at once, the rest wait in the queue. The call finishes after every command answers, and the result returns **ordered `[i] command` sections — one per command, in input order**, so the agent can match each output to its command. The trivial difference from `bash`: `bash` runs one command, `parallel_bash` runs a batch; both work on the shared `ShellCommand` core, and `bash` behavior is unchanged.

## The profiles dialog in settings

The dialog opens from the **“MiniAgent”** card in the **Configuration** group of the settings hub (the gear in the header) — more about the hub on the [Settings](/agents/agent/docs/settings)
 page. The dialog edits the same `miniagent.yml` a text YAML editor would, but as a form:

- **Profile list** — create, rename, and delete. The name follows the mask `^[a-z0-9][a-z0-9_-]*$`: a lowercase letter or digit, then lowercase letters, digits, hyphens, and underscores — and it doubles as the `mini:name` suffix;
- **Profile editor** — the `loadClaudeMd`/`loadAgentsMd` toggles, tool toggles with an “N of M tools enabled” readout (they edit `disabledTools`), numeric fields with default-value hints, and a system-prompt editor with a preview of the built-in one. The **Reset to default** button clears the prompt text — the built-in one is taken fresh from every application update, never copied;
- **Built-in defaults summary** — shown next to the list;
- **Conflict protection** — every save passes a checksum check (md5): when the file has changed in the meantime (an edit in another client, a text editor, or the Project Settings tab), the server answers `409` and offers to reload the dialog — your edits are never silently overwritten;
- **The same validation as YAML** — saving from the form and editing as text pass the same rules (profile names, mutually exclusive lists, number ranges) and give the same errors; the validator runs as a pseudo-build.

**Settings freeze at session creation**: a live chat works with the profile it was created with, and edits apply to new sessions — switching the profile or the model recreates the session. One more subtlety: when the profile disables the `load_skill` tool, the “Start by loading the … skill” line disappears from the system prompt — demanding a skill load from a tool that does not exist makes no sense.

## A practical example

**The “safe” profile — bash off, a 60-second call timeout.** Create it in the dialog: **Settings → Configuration → MiniAgent → “New profile”**, name it `safe`, turn the `bash` toggle off, set `toolCallTimeout: 60`, and save. The equivalent file:

```
profiles:
  safe:
    disabledTools:
      - bash
    toolCallTimeout: 60
```

Now assign it to a model: in the model wizard on the [Models](/agents/agent/docs/models)
 page, set the `AGENT_BACKEND=mini:safe` variable (in yml — a line in the `variables:` list). Chats on that model will run without shell commands and cap every tool call at 60 seconds — everything else stays built-in.

## Related pages

- [Settings](/agents/agent/docs/settings) — the MiniAgent card and the settings hub;
- [Models](/agents/agent/docs/models) — the `AGENT_BACKEND` variable and the model’s profile choice;
- [Skills](/agents/agent/docs/skills) — skills in the chat and the `load_skill` tool.

**← Back:** [Backends](/agents/agent/docs/backends)

**Next:** [Tips & Troubleshooting](/agents/agent/docs/tips)
 →
