@tai42_app.tools.tool, and name its module in the manifest. Importing the module runs the decorator, which registers the tool on the server.
Write the tool module
Put your function in a module in your own package and register it through thetai42_app handle. The decorator returns the function unchanged, so the module stays ordinary Python.
myapp/tools.py
Load it from the manifest
Name the module undertools[].module. Each entry imports the module; include filters which tool names to expose (omit it to expose every tool the module defines).
manifest.yml
PYTHONPATH.
Run and call it
1
Start the server
Point the server at your manifest and start it.
2
Confirm it registered
List the registered tools and inspect one tool’s schema.
3
Run it
Call the tool synchronously and print its result. Pass arguments with the repeatable
--kw key=value (each value is parsed as JSON), or a whole JSON object with --kwargs.Fenced tools
A tool declares a registration tier to mark it admin-only. Declaring thefenced (or secret) tier gates both authoring a preset over the tool and
running it: only an administrator may run a fenced tool, and a preset authored
over one inherits the fence at run time. A tool with no declaration, or a read /
write one, carries no extra execution gate.
Declare it on the decorator:
403, an MCP tool error, or a recorded failed run on a
detached door), never silently dropped. The built-in sandbox_exec tool declares
fenced for exactly this reason — running arbitrary code is an admin act.
With access control off every caller resolves as an administrator, so the fence
bites only where the platform fences at all.
Tools that can pause
A tool that can pause — it parks, asks withmode="async", or waits on a participant
out of band — declares meta={"tai42/pauses": True} (TOOL_META_PAUSES from
tai42_contract.tools):
UndeclaredPauseError naming it.
The refusal holds on every door that recognises a park: the HTTP run-tool route answers
501, the MCP edge answers a tool error, and an agent run that called the tool ends failed
rather than handing its model a tool error to retry around. A
Babelfish flow node awaits an
undeclared tool inside the node; a declared one pauses the run.
See also
- Tools and extensions — what a tool is and how an extension wraps one.
- The manifest — every section a server loads at startup.
- Apply an extension — clip a wrapper or transformer onto a tool.
- CLI reference — the full
tai toolssurface.

