A ready-to-run example is available here!File-based agents let you define specialized sub-agents using Markdown files. Each file declares the agent’s name, description, tools, and system prompt — the same things you’d pass to
register_agent() in code, but without writing any Python.
This is the fastest way to create reusable, domain-specific agents that can be invoked via delegation.
Agent File Format
An agent is a single.md file with YAML frontmatter and a Markdown body:
Frontmatter Fields
<example> Tags
Add <example> tags inside the description to help the orchestrating agent know when to delegate to this agent:
when_to_use_examples on the AgentDefinition object. They can be used by routing logic (or prompt-building) to help decide when to delegate to the right sub-agent.
Directory Conventions
Place agent files in these directories, scanned in priority order (first match wins):my-project/
.agents
agents
code-reviewer.md
tech-writer.md
security-auditor.md
src/
...
- Only top-level
.mdfiles are loaded (subdirectories are skipped) README.mdfiles are automatically skipped- Project-level agents take priority over user-level agents with the same name
Built-in Agents
Theopenhands-tools package ships with built-in sub-agents as Markdown files in openhands/tools/preset/subagents/.
They can be registered via register_builtins_agents() and become available for delegation tasks.
By default, all agents include finish tool and the think tool.
Available Built-in Sub-Agents
When
enable_browser=False, browser-dependent agents like web-researcher are not registered.
Deprecated names: The following legacy names are deprecated (since v1.12.0) and will be removed in version 2.0.0:
default→ usegeneral-purposedefault cli mode→ usegeneral-purposeexplore→ usecode-explorerbash→ usebash-runner
Registering Built-in Sub-Agents
Callregister_builtins_agents() to register all built-in sub-agents. This is typically done once before creating a conversation:
Overall Priority
When the same agent name is defined in multiple places, the highest-priority source wins. Registration is first-come first-win.Auto-Registration
The simplest way to use file-based agents is auto-registration. Callregister_file_agents() with your project directory, and all discovered agents are registered into the delegation system:
Manual Loading
For more control, load and register agents explicitly:Key Functions
load_agents_from_dir()
Scans a directory for .md files and returns a list of AgentDefinition objects:
agent_definition_to_factory()
Converts an AgentDefinition into a factory function (LLM) -> Agent:
- Maps tool names from the frontmatter to
Toolobjects - Appends the Markdown body to the parent system message via
AgentContext(system_message_suffix=...) - Respects the
modelfield ("inherit"keeps the parent LLM; an explicit model name creates a copy)
load_project_agents() / load_user_agents()
Load agents from project-level or user-level directories respectively:
Using with Delegation
File-based agents are designed to work with theTaskToolSet. Once registered, the orchestrating agent can delegate tasks to them by name through the task tool’s subagent_type parameter:
Example Agent Files
Code Reviewer
Technical Writer
Advanced Features
MCP Servers
File-based agents can define MCP server configurations inline, giving them access to external tools without any Python code:mcp_servers field uses the same format as the MCP configuration — each key is a server name, and the value contains command and args for launching the server.
Environment Variable Resolution
All string values in MCP server configurations support${VAR} (and $VAR) environment variable references, which are resolved from os.environ at load time. This lets you forward secrets and dynamic paths without hard-coding them in Markdown:
command, args, url, headers, env, and any other string values in the server config. If a referenced variable is not set, the placeholder is left unchanged (e.g., ${NONEXISTENT_VAR} stays as-is).
Hooks
File-based agents can define lifecycle hooks that run at specific points during execution:pre_tool_use— Runs before tool execution (can block with exit code 2)post_tool_use— Runs after tool executionuser_prompt_submit— Runs before processing user messagessession_start/session_end— Run when conversation starts/endsstop— Runs when agent tries to finish (can block)
"*"— Matches all tools- Exact name — e.g.,
"terminal"matches only that tool - Regex patterns — e.g.,
"/file_.*/"matches tools starting withfile_
Permission Mode
Control how a file-based agent handles action confirmations with thepermission_mode field:
When
permission_mode is omitted (or set to None), the subagent inherits the confirmation policy from its parent conversation.
Permission mode is particularly useful for specialized sub-agents. For example, a “read-only explorer” agent might use
never_confirm since it only reads files, while a “deploy” agent might use always_confirm for safety.Agents in Plugins
Plugins bundle agents, tools, skills, and MCP servers into reusable packages. Learn more about plugins here.File-based agents can also be bundled inside plugins. Place them in the
agents/ directory of your plugin:
my-plugin/
.plugin
plugin.json
agents
code-reviewer.md
tech-writer.md
.md format and are registered automatically when the plugin is loaded. They have higher priority than file-based agents but lower than programmatic register_agent() calls.
Ready-to-run Example
This example is available on GitHub: examples/01_standalone_sdk/42_file_based_subagents.py
AgentDefinition directly. File-based agents are loaded into the same AgentDefinition objects (from Markdown) and registered the same way.
examples/01_standalone_sdk/42_file_based_subagents.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Next Steps
- TaskToolSet - Delegate work to specialized sub-agents
- Skills - Add specialized knowledge and triggers to agents
- Plugins - Bundle agents, skills, hooks, and MCP servers together
- Custom Agent - Create agents programmatically for more control

