@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.
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.

