Skip to main content

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 enter Plan mode via /plan
ActionPermission
Read filesAllowed
Write/edit filesAllowed
Bash commandsAllowed
Read .env filesAsk (requires confirmation)

Plan mode​

A read-only session mode, not an agent. Enter it with /plan or let the agent enter it on its own via the plan_enter tool — the session becomes read-only (everything except the plan file is blocked) and the agent explores your codebase and writes a structured plan without making changes. Leave it with /task (or plan_exit) to implement.

# inside a session
/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)
  • Switch back with /task or when the agent calls plan_exit
  • Injects a system prompt enforcing strict read-only behavior
  • Self-initiated — any agent can call plan_enter on its own when a task looks complex, ambiguous, or risky; usually it still confirms before big changes
ActionPermission
Read filesAllowed
Write/edit filesDenied (except .tfcode/plans/)
Bash commandsAllowed (read-only usage)

Workflow: Plan → Build

  1. /plan (or the agent calls plan_enter itself), then the agent explores and creates a structured plan in .tfcode/plans/
  2. When ready, the agent offers to switch to task mode via plan_exit
  3. The active agent 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
ActionPermission
Read filesAllowed
Write/edit filesAsk (requires confirmation)
Bash commandsAsk (requires confirmation)
TF MCP toolsAllowed (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​

CategoryToolsAuth Required
Agent ManagementCreate, get, update, delete, list, search agentsYes
Agent Functions/ToolsCreate, get, update, delete, list functionsYes
AuthorisationsCreate, get, update, delete, list auth configsYes
SecretsCreate, delete secrets (AWS Secrets Manager)Yes
Documents / Knowledge BaseCreate, get, update, delete, list, search documentsYes
EntitiesCreate, get, update, delete, list, search entitiesYes
FoldersCreate, get, update, delete, list, get folder treeYes
ChatsCreate, get, list, delete chats; list messages; send messagesYes
PromptsCreate, get, update, delete, list prompt templatesYes
MembersCreate, get, update, delete workspace membersYes
ChannelsCreate, get, update, delete, list channelsYes
ConnectionsCreate, get, delete model connectionsYes
BenchmarksCreate, get, update, delete, list benchmarksYes
Benchmark RunsRun, get, list, cancel, wait for benchmark runsYes
HooksCreate, get, update, delete, list hooksYes
Scheduled JobsCreate, get, update, delete, list scheduled jobsYes
SitesGet, update, delete, list sitesYes
Fine-TuningList trainable models, start/cancel training, generate datasetsYes
Training DataGenerate training data from chats or filesYes
DocumentationSearch docs, search API endpoints, get agent creation guideNo
Release NotesList, get, search release notesNo
Skills & GuidesList skills, get skill guide, recommend skill for operationNo
Credential ValidationValidate API key + workspace ID + regionYes
BillingGet monthly usage/costsYes
EmbeddingsCreate text embeddingsYes

Execution hooks (cloud code execution)​

TF Engineer can run Python code inside execution hooks (Custom Code Execution Environments) — server-side sandboxes whose credentials never leave the cloud. Three native tools drive them:

ToolPurpose
tf_hooksList the workspace's hooks; pass a hook id/name for its full code-generation context (instructions, predefined code, libraries, secret names, sandbox conventions)
tf_hook_executeExecute code in the hook's server sandbox via POST /execute. For dynamic hooks TF Engineer writes the Python locally, grounded on the hook's context; the backend resolves secrets/docs server-side and runs it in the CodeInterpreter
tf_hook_downloadDownload the execution's output files (S3 keys) to .tfcode/hook-outputs/<messageid>/ using the same presigned-URL flow as the TF app

For static-script hooks (hardcodedScript), omit code and the hook's predefined code runs verbatim. Secret values are injected as environment variables server-side (os.environ["SECRET_NAME"]) — the agent never sees raw credentials.

TF Orchestrate​

The ToothFairyAI orchestrator. A concierge that bridges cloud agents (ToothFairyAI platform coder agents) with local agents (TF Code subagents). One entry point to delegate work to one or more agents — cloud, local, or both — across au/eu/us regions.

tfcode run --agent "TF Orchestrate" "Fan this refactor out to the code agents and integrate the results"
  • Cloud agents — delegates to synced ToothFairyAI coder agents via tf_cloud_agent (SSE chat) and tf_orchestrator (planner-driven execution)
  • Raw AI endpoints — tf_predict (OpenAI-style predictions), tf_search (semantic search), tf_dispatch + tf_dispatch_status (fire-and-forget async runs)
  • Local subagents — fans out via the task tool
  • Bounded worker/critic loops — inspired by the gauntlet pattern: a worker produces, an independent critic issues VERDICT: PASS/FAIL, and the loop is capped (default 3, max 5 passes) — see Loops
  • Streams everything live into the session via per-tool metadata
ActionPermission
Read filesAllowed
Write/edit filesAsk (requires confirmation)
Bash commandsAsk (requires confirmation)
TF AI endpointsAllowed (exclusive)
TF MCP toolsAllowed (exclusive)

Comparison​

FeatureBuildTF EngineerTF Orchestrate
PurposeExecute & implementManage ToothFairyAI workspaceOrchestrate cloud + local agents
File editingAllowedAsk (requires confirmation)Ask (requires confirmation)
Bash commandsAllowedAsk (requires confirmation)Ask (requires confirmation)
TF MCP toolsNo accessExclusive accessExclusive access
Execution hooksNoYes (exclusive)No
Default agentYesNoNo
Custom system promptNoYes (MCP-first behavior)Yes (orchestration behavior)

Agent perks​

Agent-level perks let a workspace ship its own versions of the native ToothFairyAI agents. Setting perk on a custom agent makes it inherit the full behaviour of that native agent — prompt, permission defaults, MCP access and exclusive TF tool access — while the custom name, description, model and permission overrides still apply on top.

{
"agent": {
"acme_engineer": {
"perk": "tf_engineer",
"name": "Acme Engineer",
"description": "Acme's workspace engineer — deploy-focused",
"prompt": "Acme-specific conventions: always run tf_mcp doc searches before creating agents.",
"model": "toothfairyai/mystica"
},
"acme_orchestrate": {
"perk": "tf_orchestrate",
"name": "Acme Orchestrate",
"description": "Acme's delivery orchestrator"
}
}
}
PerkInherits fromWhat the agent gets
"tf_engineer"TF EngineerNative prompt + your appended instructions, tf_mcp access, execution-hook tools (tf_hooks, tf_hook_execute, tf_hook_download), reviewer/model-swap defaults
"tf_orchestrate"TF OrchestrateNative prompt + your appended instructions, tf_mcp access, orchestration tools (tf_cloud_agent, tf_orchestrator, tf_predict, tf_search, tf_dispatch, tf_dispatch_status), reviewer/model-swap defaults

Inheritance details:

  • Prompt — the native prompt is the base; your custom prompt is appended to it, so the native tool-usage behaviour is preserved under your customisation. Omitting prompt uses the native prompt as-is.
  • Permissions — the native base (edit/bash ask, reviewer/model-swap allow) merged with your global and per-agent permission config.
  • Multiple versions — define as many perk agents as you like; each is an independent, selectable agent (e.g. one TF Engineer version per team).
  • Reviewer / model swap — perk agents count as their donor class: wherever tf_engineer is in a reviewer.enabled_for / model_swap.enabled_for list, every tf_engineer-perk agent is included (and vice versa).
note

perk is a config-level field (project or workspace-managed tfcode.json). Agents created as markdown files (.tfcode/agent/*.md) or synced as cloud coder agents don't carry it.

Perks also exist at the session level for on-demand capabilities (computer use, voice) — see Config → Perks. The two are independent: session perks toggle capabilities; agent perks define identity.

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", "tf_orchestrate"],
"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​

FocusWhen to use
architectureDesign decisions, structure, patterns
securityVulnerabilities, auth issues, data exposure
performanceSpeed, memory, scaling concerns
correctnessLogic 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", "tf_orchestrate"],
"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 TF Orchestrate its own set of models:

{
"model_swap": {
"enabled_for": ["build", "tf_engineer", "tf_orchestrate"],
"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": {
"tf_orchestrate": [
{
"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​

FieldTypeDescription
enabledbooleanDefaults to true when the section is present. Set to false to disable.
enabled_forstring[]Agents that receive the steering. Defaults to ["build", "tf_engineer"]. Agent names match case-insensitively; spaces are treated as underscores (e.g. TF Engineer matches tf_engineer).
validatebooleanRun 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_dirstringDirectory 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.
embeddingsobjectReserved 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:

  1. Correction — Did the user correct my approach or state a preference worth remembering?
  2. Repeated pattern — Did I hit a non-obvious gotcha or workflow that cost extra turns?
  3. 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:

  1. skill_manage search to find an existing skill to update.
  2. 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 product does not block toothfairyai-product-references.
  3. skill_manage create or update — with a reason and a scope. These always write, except for a missing description in create (a SKILL.md must have a description).
  4. Self-improved writes are stamped with provenance: source: self_improve, the reason, updated_at, and scope (meta for scaffold/config edits; object for reusable task routines).
  5. If validate is on, a judge pass runs and appends advisory notes to the output. Flagged skills are still written and marked validation: flagged — refine later, never retry just because validation fired.
  6. On every update, the previous version is snapshotted to history_dir. Use skill_manage history and skill_manage restore to 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 sync pulls coder agents from ToothFairyAI into tools.json (overwrite, not merge)
  • At runtime, Agent.list() merges local agents (from .tfcode/agent/*.md and config) with TF-synced agents (from tools.json) into one unified list
  • If a local and TF-synced agent share the same name, the local one takes precedence
  • The agent tool only writes to local files — it never touches tools.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.
note

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​

FieldTypeDescription
descriptionstringWhen to use this agent
modesubagent | primary | allAgent visibility and role (see Agent modes)
modelstringModel in provider/model format. Optional — inherits session model if omitted.
hiddenbooleanHide from @ autocomplete (subagents only)
colorstringHex color or theme name
stepsnumberMax agentic iterations
permissionobjectPermission rules (see Permissions)
temperaturenumberTemperature for the agent's model
top_pnumberTop_p for the agent's model
variantstringDefault model variant for this agent

The markdown body becomes the agent's system prompt.

Agent modes​

ModeAppears in /agents dialogAppears in @ autocompleteAvailable as task subagentUse case
primaryYesNoNoMain agents you switch between (Build, TF Engineer, TF Orchestrate)
subagentNoYesYesSpecialists invoked by other agents via the task tool
allYesYesYesBoth 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.