Agents
TF Code ships with three built-in agents. Switch between them with Tab in the TUI or the --agent flag in CLI mode.
Build
The default agent. Full read/write access for executing and implementing.
tfcode run "Add error handling to src/api.ts"
- Full read/write access to files
- Can execute bash commands
- Uses all built-in tools (Bash, Read, Edit, Write, Glob, Grep, WebFetch, etc.)
- Has access to synced workspace content (coder agents, agent skills) but NOT live MCP tools
- Can switch into Plan mode via
plan_enter
| Action | Permission |
|---|---|
| Read files | Allowed |
| Write/edit files | Allowed |
| Bash commands | Allowed |
Read .env files | Ask (requires confirmation) |
Plan
Read-only planning agent. Explores your codebase and creates a plan without making changes.
tfcode run --agent plan "Analyze the auth flow and propose improvements"
- Read-only — cannot edit, write, or modify any files
- Writes plans to
.tfcode/plans/*.md(the only write exception) - Can switch to Build via
plan_exit - Injects a system prompt enforcing strict read-only behavior
| Action | Permission |
|---|---|
| Read files | Allowed |
| Write/edit files | Denied (except .tfcode/plans/) |
| Bash commands | Allowed (read-only usage) |
Workflow: Plan → Build
- Plan explores and creates a structured plan in
.tfcode/plans/ - When ready, Plan offers to switch to Build
- Build receives the plan context and begins implementation
TF Engineer
The ToothFairyAI workspace agent. Automatically connected to the ToothFairyAI MCP server with exclusive access to live workspace management tools.
tfcode run --agent "TF Engineer" "Create a retriever agent called SupportBot"
tfcode run --agent "TF Engineer" "Search documents about refund policy"
- Exclusive access to ToothFairyAI MCP tools — no other agent can use them
- Can still read local files and use built-in tools
- Edit and bash commands require confirmation (ask permission)
- Always asks for confirmation before destructive operations
- Connected via SSE to
https://mcp.{region}.toothfairyai.com/sse
| Action | Permission |
|---|---|
| Read files | Allowed |
| Write/edit files | Ask (requires confirmation) |
| Bash commands | Ask (requires confirmation) |
| TF MCP tools | Allowed (exclusive) |
MCP Connection
TF Engineer automatically connects using your profile credentials. Credentials are injected as an x-api-key header and auto-filled parameters — the model never sees your API key, workspace ID, or region. They are stripped from the tool schema and added server-side.
MCP Tool Categories
| Category | Tools | Auth Required |
|---|---|---|
| Agent Management | Create, get, update, delete, list, search agents | Yes |
| Agent Functions/Tools | Create, get, update, delete, list functions | Yes |
| Authorisations | Create, get, update, delete, list auth configs | Yes |
| Secrets | Create, delete secrets (AWS Secrets Manager) | Yes |
| Documents / Knowledge Base | Create, get, update, delete, list, search documents | Yes |
| Entities | Create, get, update, delete, list, search entities | Yes |
| Folders | Create, get, update, delete, list, get folder tree | Yes |
| Chats | Create, get, list, delete chats; list messages; send messages | Yes |
| Prompts | Create, get, update, delete, list prompt templates | Yes |
| Members | Create, get, update, delete workspace members | Yes |
| Channels | Create, get, update, delete, list channels | Yes |
| Connections | Create, get, delete model connections | Yes |
| Benchmarks | Create, get, update, delete, list benchmarks | Yes |
| Benchmark Runs | Run, get, list, cancel, wait for benchmark runs | Yes |
| Hooks | Create, get, update, delete, list hooks | Yes |
| Scheduled Jobs | Create, get, update, delete, list scheduled jobs | Yes |
| Sites | Get, update, delete, list sites | Yes |
| Fine-Tuning | List trainable models, start/cancel training, generate datasets | Yes |
| Training Data | Generate training data from chats or files | Yes |
| Documentation | Search docs, search API endpoints, get agent creation guide | No |
| Release Notes | List, get, search release notes | No |
| Skills & Guides | List skills, get skill guide, recommend skill for operation | No |
| Credential Validation | Validate API key + workspace ID + region | Yes |
| Billing | Get monthly usage/costs | Yes |
| Embeddings | Create text embeddings | Yes |
Comparison
| Feature | Build | Plan | TF Engineer |
|---|---|---|---|
| Purpose | Execute & implement | Explore & plan | Manage ToothFairyAI workspace |
| File editing | Allowed | Denied | Ask (requires confirmation) |
| Bash commands | Allowed | Allowed | Ask (requires confirmation) |
| TF MCP tools | No access | No access | Exclusive access |
| Default agent | Yes | No | No |
| Custom system prompt | No | Yes (read-only enforcement) | Yes (MCP-first behavior) |
Set Default Agent
{
"default_agent": "build"
}
Reviewer
The Reviewer lets you attach a stronger AI model to your agents so they can get a second opinion before making decisions. When enabled, agents gain access to a reviewer tool they can call for expert analysis.
{
"reviewer": {
"model": "toothfairyai/glm-5p2",
"enabled_for": ["build", "tf_engineer", "plan"],
"temperature": 0.3,
"max_tokens": 8192
}
}
The model field uses the provider/model format. Available models are dynamically discovered from your configured providers — ToothFairyAI models are fetched at runtime based on your workspace credentials, so you don't need to hardcode model IDs. To see what's available, use /models in the TUI or tfcode agent in CLI mode. The reviewer is a one-shot call — it doesn't run tools, doesn't loop, and doesn't modify anything.
Focus Areas
| Focus | When to use |
|---|---|
architecture | Design decisions, structure, patterns |
security | Vulnerabilities, auth issues, data exposure |
performance | Speed, memory, scaling concerns |
correctness | Logic errors, edge cases, test coverage |
general (default) | Broad review across all areas |
Permissions
The reviewer permission defaults to allow for built-in agents. Override:
{
"agent": {
"build": {
"permission": {
"reviewer": "ask"
}
}
}
}
To disable for a specific agent, remove it from enabled_for. To disable entirely, remove the reviewer section from config.
Model swap
Model swap lets agents change the active model mid-session when the task calls for different capabilities or cost. When enabled, agents gain access to a model_swap tool. They describe the current task, and the tool picks the best model from the configured list for the rest of the session.
{
"model_swap": {
"enabled_for": ["build", "tf_engineer", "plan"],
"models": [
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for deep reasoning, architecture, and security review"
},
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for writing and editing code"
},
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for quick, low-cost lookups"
}
]
}
}
The id field uses the provider/model format. Available models are discovered dynamically from your ToothFairyAI workspace — use /models in the TUI to see what's available. You can mix providers in the same list if you have multiple configured.
Each model's instruction tells the agent when to swap to it. The tool matches the agent's description against these instructions and swaps to the best fit. The next steps in the session then use the new model.
Per-agent lists
You can override the global list for specific agents. For example, give Plan its own set of models:
{
"model_swap": {
"enabled_for": ["build", "tf_engineer", "plan"],
"models": [
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for deep reasoning, architecture, and security review"
},
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for writing and editing code"
}
],
"agents": {
"plan": [
{
"id": "toothfairyai/glm-5p2",
"instruction": "Use for planning and design decisions"
}
]
}
}
}
Permissions
The model_swap permission defaults to allow for built-in agents. Override:
{
"agent": {
"build": {
"permission": {
"model_swap": "ask"
}
}
}
}
To disable for a specific agent, remove it from enabled_for. To disable entirely, remove the model_swap section from config.
Self-improving skills
Self-improving skills steers eligible agents to refine their own skills based on user feedback, corrections, and insights from task execution, using the skill and skill_manage tools you already have. When enabled, an instruction block is injected into the agent's system prompt with an explicit insight checklist and refinement flow. No new tool is added — the agent is nudged to use the skill tools proactively.
{
"self_improve_skills": true
}
The simplest form is a boolean. Set true to enable steering for the default agents (build, tf_engineer, plan); omit it or set false to disable.
For more control, use the object form:
{
"self_improve_skills": {
"enabled": true,
"enabled_for": ["build", "tf_engineer"],
"validate": false,
"history_dir": "~/.local/share/tfcode/skill-history",
"embeddings": {
"enabled": false,
"backend": "ngram"
}
}
}
Fields
| Field | Type | Description |
|---|---|---|
enabled | boolean | Defaults to true when the section is present. Set to false to disable. |
enabled_for | string[] | Agents that receive the steering. Defaults to ["build", "tf_engineer", "plan"]. Agent names match case-insensitively; spaces are treated as underscores (e.g. TF Engineer matches tf_engineer). |
validate | boolean | Run an advisory judge pass before committing a self-improved skill. If a reviewer model is configured, it evaluates the skill against a rubric; otherwise a rule-based gate is used. The judge is advisory — it never blocks create/update; flagged skills are still written and stamped validation: flagged. Defaults to false. |
history_dir | string | Directory for skill version snapshots. Defaults to the tfcode xdg data dir (e.g. ~/.local/share/tfcode/skill-history). Override with the TFCODE_SKILL_HISTORY_DIR env var. Snapshots are kept outside your working repo. |
embeddings | object | Reserved embedding backend config. The default is a local, dependency-free hashed n-gram matcher that works offline. WASM embeddings are a planned opt-in. |
How it works
Before declaring a task done, the agent runs through an insight checklist:
- Correction — Did the user correct my approach or state a preference worth remembering?
- Repeated pattern — Did I hit a non-obvious gotcha or workflow that cost extra turns?
- Stale/misleading skill — Did a loaded skill mislead me or lack a step I had to invent?
If none apply, the agent continues normally. If one clearly applies, it runs the refinement flow:
skill_manage searchto find an existing skill to update.- If the name is a genuine near-duplicate (exact match, obvious typo, or whole-word prefix/suffix), the tool blocks the new skill and redirects to update the existing one. Arbitrary substring containment is NOT a duplicate — e.g., an existing
productdoes not blocktoothfairyai-product-references. skill_manage createorupdate— with areasonand ascope. These always write, except for a missingdescriptionincreate(aSKILL.mdmust have a description).- Self-improved writes are stamped with provenance:
source: self_improve, the reason,updated_at, andscope(metafor scaffold/config edits;objectfor reusable task routines). - If
validateis on, a judge pass runs and appends advisory notes to the output. Flagged skills are still written and markedvalidation: flagged— refine later, never retry just because validation fired. - On every update, the previous version is snapshotted to
history_dir. Useskill_manage historyandskill_manage restoreto roll back.
Skill frontmatter
---
name: lint-after-edit
description: Run lint after edits in this repo
source: self_improve
reason: User reminded me to lint after edits.
updated_at: "2026-07-19T10:00:00.000Z"
scope: meta
---
# Lint After Edit
Always run `bun run lint` from the package dir after editing files.
The steering is injected only when the skill permission is not denied for the agent. Agents create and update skill files at .tfcode/skill/<name>/SKILL.md.
{
"agent": {
"build": {
"permission": {
"skill": "ask"
}
}
}
}
To disable for a specific agent, remove it from enabled_for (or set enabled: false). To disable entirely, remove the self_improve_skills section from config — or set it to false.
Custom Agent Management
Beyond defining agents statically in the config JSON, agents can be created and managed at runtime using the agent tool. This tool provides full CRUD (create, read, update, delete) for local agent markdown files stored in .tfcode/agent/<name>.md.
How it works
When an agent (e.g. Build) calls the agent tool, it can:
- list all agents — local, native, and TF-synced — with source labels
- read a specific agent's full config (frontmatter + prompt)
- create a new agent by writing a markdown file with YAML frontmatter
- update an existing local agent's frontmatter and/or prompt (merges with existing)
- delete a local agent file
TF-synced agents (from ToothFairyAI tfcode sync) and native agents (build, plan, etc.) are read-only — they cannot be edited or deleted through the tool.
To upload a local agent back to your workspace as a coder agent (including the skills it references), use tfcode agent share. See Workspace Sync & Share.
Merging with TF sync
Local agents coexist with TF-synced agents:
tfcode syncpulls coder agents from ToothFairyAI intotools.json(overwrite, not merge)- At runtime,
Agent.list()merges local agents (from.tfcode/agent/*.mdand config) with TF-synced agents (fromtools.json) into one unified list - If a local and TF-synced agent share the same name, the local one takes precedence
- The
agenttool only writes to local files — it never touchestools.json
Creating an agent at runtime
Ask the agent to create one for you:
> Create a translator subagent that specializes in Japanese technical docs
The agent will call the agent tool with action: "create", providing the name, description, mode, and prompt. The agent file is written to .tfcode/agent/<name>.md and is immediately available for use.
Manual creation
You can also create agent files manually. Create a markdown file at .tfcode/agent/<name>.md with YAML frontmatter:
---
description: Translate content for a specified locale while preserving technical terms
mode: subagent
temperature: 0.3
permission:
edit: deny
bash: deny
---
You are a professional translator and localization specialist.
Focus on preserving technical terminology while translating content.
The model field is optional. When omitted, the agent inherits the session's active model — which is dynamically resolved from your ToothFairyAI workspace at runtime. Only set model if you want the agent to always use a specific model regardless of what the user has selected.
Frontmatter fields
| Field | Type | Description |
|---|---|---|
description | string | When to use this agent |
mode | subagent | primary | all | Agent visibility and role (see Agent modes) |
model | string | Model in provider/model format. Optional — inherits session model if omitted. |
hidden | boolean | Hide from @ autocomplete (subagents only) |
color | string | Hex color or theme name |
steps | number | Max agentic iterations |
permission | object | Permission rules (see Permissions) |
temperature | number | Temperature for the agent's model |
top_p | number | Top_p for the agent's model |
variant | string | Default model variant for this agent |
The markdown body becomes the agent's system prompt.
Agent modes
| Mode | Appears in /agents dialog | Appears in @ autocomplete | Available as task subagent | Use case |
|---|---|---|---|---|
primary | Yes | No | No | Main agents you switch between (Build, Plan) |
subagent | No | Yes | Yes | Specialists invoked by other agents via the task tool |
all | Yes | Yes | Yes | Both switchable and invocable as a subagent |
Use mode: subagent for specialized reviewers or helpers that other agents call. Use mode: primary for agents you want to switch to manually. Use mode: all for agents that should work both ways.
See Tools → Agent Management for full parameter reference.