Agent Tools¶
Tools are LLM-callable functions assembled at startup from config.toml.
Each row below lists the public tool name exposed to the model, how it is enabled,
and the intended use.
Tool Surface¶
Group |
Tool |
Availability |
Purpose |
|---|---|---|---|
Chat history |
|
Always available |
Inspect the current conversation history size. |
Chat history |
|
Always available |
Remove old history entries for the current conversation. |
Runtime |
|
Always available |
Read-only report of what this instance is running: version, config path, channels, LLM provider and
model, enabled tools with their non-secret settings, agents, and whether tasks, the scheduler and the
vault are on. A feature that is off is absent. Never returns tokens, API keys or credential URLs. A
specialist that sets |
Runtime |
|
|
Read-only access to the documentation bundled with the installed version: list pages, search by words, or
read one page (config sections are expanded to their field reference). Turn it off with
|
Memory |
|
|
Save, update, retrieve, search, list, and delete persistent user notes. One tool per operation, so a pattern such as |
Relation graph |
|
|
Store and traverse typed, owner-scoped relationships between entities. One tool per operation, so a pattern such as |
Utility |
|
|
Return the current UTC datetime using an optional |
Utility |
|
|
Pause execution for a given number of milliseconds (clamped to |
Utility |
|
|
Evaluate bounded arithmetic with Decimal precision. |
Response |
|
Always available |
Declare final-answer metadata before answering: |
HTTP |
|
|
Fetch HTTP/HTTPS resources with size limits and optional managed-file spillover. HTML is rendered as compact semantic text (links, forms, inputs and tables kept; classes, styles and scripts dropped). |
Host execution |
|
|
Run host Python code with timeout, output caps, sandbox mode, and artifact export. |
Host execution |
|
|
Inspect the Python runtime used by |
Host execution |
|
|
Run shell commands through |
Editing |
|
|
Apply structured add/update/delete/move patches under the configured workspace. |
Managed files |
|
|
List managed files and folders under a folder path. |
Managed files |
|
|
Return size, MIME type, and timestamps for a managed path. |
Managed files |
|
|
Create or overwrite a managed text file. |
Managed files |
|
|
Move or rename a managed file. |
Managed files |
|
|
Delete a managed file or folder permanently. |
Managed files |
|
|
Deliver a managed file to the active conversation channel. |
Managed files |
|
|
List managed files matching a glob pattern. |
Managed files |
|
|
Read a complete managed text file. |
Managed files |
|
|
Read a bounded line window from a managed text file. |
Managed files |
|
|
Search managed files with regex or fixed-string matching. |
Managed files |
|
|
Inject a managed file or image into the active runtime context. |
Audio |
|
|
Transcribe or translate managed audio files with faster-whisper. |
Scheduled prompts |
|
|
Create a one-time or recurring scheduled prompt. The old |
Scheduled prompts |
|
|
List scheduled prompts for the current owner/chat context. |
Scheduled prompts |
|
|
Mark a scheduled prompt as cancelled. |
Scheduled prompts |
|
|
Cancel and remove a scheduled prompt. |
Delegation |
|
Enabled when agent definitions exist |
Inspect a specialist’s definition and defaults, and list the providers a delegation can target. |
Skills |
|
|
Discover current skills from configured skill directories. |
Skills |
|
|
Load full instructions for a discovered skill. |
Skills |
|
|
Preview or install a published skill from GitHub or an archive URL. |
Async tasks |
|
|
Queue a background worker task whose result comes back to the main agent as a new turn; with
|
Async tasks |
|
|
Queue a background worker task whose answer goes straight to the user. Same parameters as
|
Async tasks |
|
|
Cancel an active background task by ID. |
Async tasks |
|
|
List persisted background tasks and their terminal state. |
Async tasks |
|
|
Retrieve one task’s result, structured progress, and compact event history. |
MCP |
|
|
Dynamically discovered Model Context Protocol tools. |
RAG / vector store |
|
|
Index text files into the configured vector store and retrieve semantically relevant chunks. |
Scripting |
|
|
Run a short Python script in a sandbox that calls the agent’s other tools and returns only its printed output and final value. See Codemode scripts below. |
Credential vault |
|
|
List the names of stored secrets; values are never exposed. See Credential Vault. |
Agent management |
|
|
Re-read agent definition files and report which names were added, removed or updated. A failed reload leaves the previous roster in place. See Multi-Agent Orchestration. |
Agent management |
|
|
Create, replace or remove a model-authored specialist. Every call is validated against the
owner’s ceiling before anything is written, and a successful write refreshes the roster. The
bundled |
Runtime Notes¶
Tool defaults are defined in
minibot.adapters.config.schemaand configured inconfig.toml.[tools.file_storage]is the shared managed-file root used by file, grep, HTTP spillover, and audio tools.[tools.tool_output_spill]generalizes spillover to every tool binding (main agent, delegated agents, and task workers), not justhttp_request: an oversized result is swapped for a preview plus a managed-file pointer the agent can read back withgrep,code_read,read_file, orbash. Tools inexclude_tools(http_requestandpre_responseby default) are skipped since they already manage their own output size.activate_skillspills only past 64,000 characters (orspill_after_chars, if larger), so skill instructions normally arrive inline. Spill does not apply to calls made from arun_tools_scriptscript: the result goes to the script, not the model, so the script can filter it, and the script’s own output limits protect the context.[tools.audio_transcription]requires thesttextra:pip install "minibot[stt]".[tools.http_client]needs no extra: selectolax ships with the base install and renders HTML as compact semantic text instead of plain-text extraction.[tools.mcp]needs no extra: the MCP client is a JSON-RPC implementation with no third-party SDK.[tasks]gates the task tools and the consumer.backend = "sqlite"(the recommended default) needs no broker and no extra;backend = "rabbitmq"requires therabbitmqextra and a broker configured in[rabbitmq]. See Architecture for the trade-off.[tools.rag]requires theragextra (pip install "minibot[rag]") for PDF ingestion and the SQLite backend’s numpy, plus torch and sentence-transformers installed manually. The defaultbackend = "sqlite"needs no service;"qdrant"needs a running instance. See RAG & Persistent Knowledge.The relation graph requires the
graphextra and theminibot.extensions.tools.graphextension. It persists typed edges in SQLite; see Relation graph.[tools.codemode]requires thecodemodeextra (pip install "minibot[codemode]", orpoetry install --extras codemode); enabling it without the extra stops startup with that hint.Hidden compatibility aliases are normalized at execution time; prefer the public names in the table.
Codemode scripts¶
run_tools_script lets the model write one short Python script instead of making a tool call per step. The
script calls other tools, combines and filters their results, and returns only what matters: each nested result
stays out of the model’s context, and independent calls run in parallel with asyncio.gather. It is off by
default; enable it with [tools.codemode] enabled = true (see Configuration Reference).
[tools.codemode]
enabled = true
timeout_seconds = 60 # wall-clock limit for the whole script, nested tool calls included
max_tool_calls = 50 # tool calls one script may make
max_memory_mb = 64 # heap limit of the script itself
max_output_chars = 20000 # cap on the printed output and on the returned value
exclude = ["mcp_mail__*"] # tool names scripts can never call
Scripts run in Pydantic Monty, a Python interpreter written in Rust that
runs in a pool of worker subprocesses, so a crash cannot take the daemon down. It implements a subset of Python:
no file system, network, environment or third-party imports, and the only way to act on the world is the tools
namespace. Scripts call tools as await tools.<name>(keyword=value), keyword arguments only; every character of
a tool name that is not valid in a Python identifier becomes _ (mcp_exa__web_search is unchanged,
my-tool.v2 becomes my_tool_v2). The tool description lists a one-line signature per available tool,
generated from its JSON schema (capped at about 6000 characters; tools beyond the cap are omitted from the list).
A script prints with print and returns by ending on an expression or with a top-level return:
import asyncio
first, second = await asyncio.gather(
tools.memory_search(query="trip"),
tools.current_datetime(),
)
try:
await tools.http_request(url="https://example.org/missing")
except ValueError as exc:
print("skipped:", exc)
{"now": second, "titles": [entry["title"] for entry in first["entries"]][:5]}
MCP tools are ordinary tools to a script, with three differences to keep in mind. In bridge mode each remote tool is
tools.<prefix>_<server>__<remote_tool>(...) and returns {"ok", "server", "tool", "is_error", "result"}, where
result is usually text (the joined text parts, often JSON that needs json.loads). An error reported by the MCP
server does not raise: it comes back with ok: false / is_error: true, so the script must check it. In lazy mode the
server exposes <prefix>_<server>__list_tools() (the catalog with each input_schema) and
<prefix>_<server>__call_tool(tool_name=..., arguments={...}), which returns the same dict.
import asyncio, json
found = await tools.mcp_mail__imap_search_messages(query="invoice")
if not found["ok"]:
return {"error": found["result"]}
ids = json.loads(found["result"])["ids"][:5]
msgs = await asyncio.gather(*[tools.mcp_mail__imap_get_message(id=i) for i in ids])
return [json.loads(m["result"])["subject"] for m in msgs if m["ok"]]
A call whose result feeds the next one is a plain sequence of await statements. When python_execute is
available, a script can pass it data with tools.python_execute(code=...) for computation the sandbox cannot do.
The result is {"ok": true, "output": "<printed text>", "result": <final value>}. Output and the final value are
each cut to max_output_chars keeping their start and end, with a marker for what was omitted.
- What a script can call
The tools the agent sees after its
tools_allow/tools_denyand ownership filtering, built after approval, event and output-spill wrapping, minus the delegation tools and anything matchingexclude(below). A tool the agent cannot see is not callable from a script, and a tool listed inrequire_approvalstill asks the owner for every nested call. A tool that raises reaches the script as an exception (ValueErrorfor rejected arguments,PermissionErrorfor a denied approval,RuntimeErrorotherwise); catch it to continue. A script that ends on an uncaughtPermissionErrorfrom a denial returns thetool_approval:deniederror, like a direct call; a denial the script wraps in another exception type is an ordinarycodemode:script_error. The delegation tools (delegate,spawn_task,fetch_agent_info,list_tasks,get_task,cancel_task),run_tools_scriptitself and anything matchingexcludeare never exposed, and nested calls do not count against the agent’s own per-turn tool-call cap. MCP tools appear under their exposed names; for lazy MCP servers that meansmcp_<server>__list_toolsandmcp_<server>__call_tool. Large nested results arrive as a preview plus a file path, as they do for a direct call, and a tool that returns a file or a message directive (send_file) loses the directive when called from a script.- Time and call limits
timeout_secondsis wall-clock time for the whole script, nested calls included, except the time a nested call spends waiting for an owner approval ([tools.approval]): the clock stops while any approval is pending, so a slow decision never ends the script, and the approval’s owntimeout_secondsstill bounds the wait.max_tool_callscaps how many tool calls one script makes; the call past the cap raises aValueErrorwhose text starts withcodemode:tool_call_limit(listed intool_errorstoo), which the script may catch.- Failures
A script that fails returns
{"ok": false, "error_code": ..., "error": ..., "output": <partial output>}.error_codeiscodemode:syntax_error,codemode:timeout,codemode:memory_limit,codemode:script_error(any uncaught exception, with ahintwhen it named a tool that does not exist) orcodemode:sandbox_failed.tool_errorslists the nested calls that failed, as tool name and error code (the tool’s ownerror_codewhen it raised one,tool_execution_failedotherwise). Each failed nested call is also logged at warning level with the tool name and error code, never its arguments or message. Calls that already ran are not undone, and calls still running at a timeout are cancelled.- Nested calls and events
Every nested call publishes its own
ToolCallEventwhoseparent_call_idis thecall_idof therun_tools_scriptcall (see Events). The web chat and the console subscribe to these events; Telegram does not.- Specialists
In task workers the tool is opt-in like the other bundled extensions: list
"codemode"in[tasks] worker_extensionsand namerun_tools_scriptin a specialist’stools_allow; its scripts then call the tools that specialist itself has. Atools_deny-only specialist gets it too, and a task without an agent never does.- Trust model
Monty keeps the script itself away from the file system, network and environment, and every effect is a tool call that already passed the existing gates. That narrows the surface but is not containment: MiniBot is still not a security boundary, and deployment isolation (see Security & Sandboxing) still applies.
Implementation Reference¶
Long-term user-memory tools backed by KeyValueMemory, one tool per operation.
- class minibot.llm.tools.http_client.HTTPClientTool(config, storage=None)[source]¶
Fetch HTTP/HTTPS resources on behalf of the LLM.
Enabled by
[tools.http_client]inconfig.toml.Exposes the
http_requestLLM tool supporting GET, POST, PUT, DELETE, PATCH, HEAD, and OPTIONS.Response handling:
HTML responses are rendered as compact semantic text by default (
response_processing_mode = "auto"): links keep their targets, forms keep their action/method, inputs keep type and name, while classes, styles,data-*, scripts and SVG are dropped."text"restores the older plain-text extraction.Whitespace is normalized when
normalize_whitespace = true(plain text and"text"mode only; compact output uses newlines and indentation as structure).When the processed body exceeds
spill_after_charscharacters and[tools.file_storage]is enabled, the raw body is saved to a managed temp file and a short preview is returned inline.
Key config options:
timeout_seconds,max_bytes— request limits.follow_redirects,max_redirects— redirects are returned as-is unlessfollow_redirectsis on.max_parse_bytes— how much HTML is decoded before compacting.max_chars— inline body character cap (falls back tomax_bytes).spill_to_managed_file,spill_after_chars,spill_preview_chars,max_spill_bytes.
- Parameters:
config (HTTPClientToolConfig)
storage (FileStorage | None)
- class minibot.llm.tools.file_storage.FileStorageTool(storage, event_bus=None)[source]¶
Managed file operations scoped to a configured root directory.
Enabled by
[tools.file_storage]inconfig.toml.Exposes nine LLM tools:
list_files— list files and folders under a folder path.glob_files— list files matching a glob pattern.file_info— metadata for one path.write_file— create or overwrite a text file.read_file— read a full text file.move_file— move or rename a file.delete_file— delete a file or folder.send_file— deliver a file to the active conversation channel.self_insert_artifact— inject a managed file or image into the active conversation context.
All paths are relative to
root_dir.allow_outside_root = falseprevents path traversal. Incoming uploads are saved touploads_subdirwhensave_incoming_uploads = true.Key config options:
root_dir— managed storage root.max_write_bytes— per-write size limit.allow_outside_root— disable path-escape guard (not recommended).
- Parameters:
storage (FileStorage)
event_bus (EventPublisher | None)
- class minibot.llm.tools.grep.GrepTool(storage, config)[source]¶
Regex or fixed-string search over managed files.
Enabled by
[tools.file_storage]inconfig.toml(requires file storage). The grep config is read from[tools.grep].Exposes the
grepLLM tool.Supports recursive search, case-insensitive matching, fixed-string (literal) mode, hidden file inclusion, and configurable context lines before/after each match. Files exceeding
max_file_size_bytesare skipped.Key config options:
max_matches— global per-call match cap.max_file_size_bytes— skip files larger than this.
- Parameters:
storage (FileStorage)
config (GrepToolConfig)
- class minibot.llm.tools.bash.BashTool(config, storage=None)[source]¶
Execute shell commands via
/bin/bash -c(-lcwhenpass_parent_envis on).Enabled by
[tools.bash]inconfig.toml.Key config options:
default_timeout_seconds/max_timeout_seconds— execution time limits.pass_parent_env— pass the full parent environment; defaults tofalse, so only keys inenv_allowlistare forwarded.max_output_bytes— combined stdout+stderr cap; excess is truncated.spill_to_managed_file— whentrue, output exceedingspill_after_charsis saved to a managed temp file instead of being returned inline.
Returns
ok,exit_code,stdout,stderr,timed_out,truncated, andduration_ms.- Parameters:
config (BashToolConfig)
storage (FileStorage | None)
- class minibot.llm.tools.python_exec.HostPythonExecTool(config, storage=None)[source]¶
Execute Python code on the host with configurable sandbox controls.
Enabled by
[tools.python_exec]inconfig.toml.Exposes two LLM tools:
python_executeandpython_environment_info.Sandbox modes (
sandbox_mode):basic— no isolation, same process user.rlimit— POSIX resource limits (CPU, memory, file size, open files).cgroup— Linux only; wraps execution withsystemd-run --scope.jail— arbitrary command prefix (e.g.nsjail,firejail).
Artifacts: when
save_artifacts = trueand[tools.file_storage]is enabled, generated files matchingartifact_globsare copied into managed storage after execution.Key config options:
default_timeout_seconds/max_timeout_secondsmax_output_bytes— combined stdout+stderr cap.python_path/venv_path— override the Python interpreter.artifacts_enabled,artifacts_default_subdir,artifacts_max_files.
- Parameters:
config (PythonExecToolConfig)
storage (FileStorage | None)
- class minibot.llm.tools.audio_transcription.AudioTranscriptionTool(config, storage, facade=None)[source]¶
Transcribe or translate audio files using faster-whisper.
Enabled by
[tools.audio_transcription]inconfig.toml. Requires thesttextra:poetry install --extras stt. Also requires[tools.file_storage]to resolve managed audio paths.Exposes the
transcribe_audioLLM tool with two task modes:transcribe— output in the source language.translate— output translated to English.
Auto-transcription: when
auto_transcribe_short_incoming = true, incoming voice messages shorter thanauto_transcribe_max_duration_secondsare transcribed automatically before the LLM processes them.Key config options:
model— Whisper model size (tiny,base,small,medium,large-v3).device—auto,cpu, orcuda.compute_type— quantization (int8,float16, etc.).beam_size,vad_filter.server_url— whisper.cpp server inference URL; when set, audio is sent there instead of loading faster-whisper locally.
- Parameters:
config (AudioTranscriptionToolConfig)
storage (FileStorage)
facade (AudioTranscriptionFacade | None)
- class minibot.llm.tools.scheduler.SchedulePromptTool(service, min_recurrence_interval_seconds=60)[source]¶
Create, list, cancel, and delete scheduled prompt jobs.
Enabled by
[scheduler.prompts]inconfig.toml.Exposes four LLM tools:
schedule_prompt— create a future prompt job.list_scheduled_prompts— list jobs for the current owner/chat context.cancel_scheduled_prompt— mark a job as cancelled.delete_scheduled_prompt— cancel and permanently remove a job.
Recurrence: set
recurrence_type = "interval"and providerecurrence_interval_seconds(minimum enforced bymin_recurrence_interval_seconds), or setrecurrence_type = "cron"and provide a standard 5-fieldrecurrence_cron_expression(e.g."0 9 * * 1-5"for weekdays at 9am,"0 0 2 * *"for day 2 of every month) for schedules that don’t map to a fixed interval.Prompt roles:
user(bot answers),assistant(sent directly to the user),system, ordeveloper.Key config options:
sqlite_url— SQLite backend for job persistence.poll_interval_seconds— how often due jobs are dispatched.min_recurrence_interval_seconds— floor for recurring intervals.
- Parameters:
service (ScheduledPromptService)
min_recurrence_interval_seconds (int)
- class minibot.llm.tools.mcp_bridge.MCPToolBridge(*, server_name, client, name_prefix='mcp', enabled_tools=None, disabled_tools=None)[source]¶
Bridge Model Context Protocol (MCP) servers to LLM tool bindings.
Enabled by
[tools.mcp]inconfig.toml. Each entry under[[tools.mcp.servers]]creates one bridge instance. Needs no extra: the MCP client is a self-contained JSON-RPC implementation with no third-party SDK dependency.Remote tools are exposed with the naming convention:
<name_prefix>_<server_name>__<remote_tool_name>The default prefix is
mcp.Filtering:
enabled_tools— whitelist; only listed remote tool names are exposed.disabled_tools— blacklist; listed names are always excluded.
Key config options:
name_prefix— prefix for all bridged tool names (default:"mcp").timeout_seconds— call timeout.[[tools.mcp.servers]]— list of server definitions; each supportstransport,command,args,env,cwd,url,headers,enabled_tools,disabled_tools.
- class minibot.llm.tools.skill_loader.SkillLoaderTool(registry, managed_storage=None, bash_enabled=False)[source]¶
Discover and load agent skills at runtime.
Enabled when
[tools.skills]is configured inconfig.toml(skill discovery paths are set viaskills.paths).Exposes two LLM tools:
list_skills— returns up to 8 skills ranked by relevance to an optional search query. Ranking order: exact match → prefix → substring → description substring → fuzzy similarity.activate_skill— loads the full instructions for a named skill and injects them into the context.
Skills are markdown files (
SKILL.md) discovered from the configured paths; the registry refreshes automatically when files change.managed_storageandbash_enableddescribe which writer can actually reach the skill write directory, reported aswrite_dir_access. Both are needed:write_fileis confined to its root unlessallow_outside_rootis set, andbashis absent unless[tools.bash]is enabled — so “not reachable by write_file” does not imply “reachable by bash”.- Parameters:
registry (SkillCatalog)
managed_storage (FileStorage | None)
bash_enabled (bool)
- class minibot.llm.tools.skill_installer.SkillInstallerTool(registry, *, parse_skill, native_skills_dir)[source]¶
Install skills from GitHub or an archive URL into the skill write directory.
Enabled by
[tools.skills] install = true. Exposesinstall_skill, a Python counterpart ofnpx skills add:owner/repo,owner/repo@skill,owner/repo/path, GitHubtree/blobURLs, and.zip/.tar.gz/SKILL.mdURLs over HTTPS. Every candidate is validated with the same parser the runtime uses; the installed skill is recorded inskills-lock.jsonnext to it, in the npmskillstool’s format. Nothing is activated after installing.- Parameters:
registry (SkillCatalog)
parse_skill (Callable[[Path, Path, SkillSource], SkillSpec])
native_skills_dir (Path)