tai42_app handle. It depends only on tai42-contract (and tai42-kit for shared helpers) — never on the skeleton — so it stays a pure, contract-facing package the host loads from the manifest. The reference implementation is tai42-toolbox, the ecosystem’s contrib tool set.
Register through the handle
Decorate each function with@tai42_app.tools.tool. The function’s signature becomes the input schema and its docstring the description. Keep one tool per module so a manifest can enable them one at a time.
examples/tool/forecast_tool.py
dict (or a pydantic model), and its return annotation becomes the output schema.
Gate heavy dependencies
Keep the base install light. Gate a module that needs a heavy dependency behind an optional extra, and fail loudly at import if the extra is missing — never a silent skip. Gate an HTTP tool behind an[http] extra, for example, and have the module raise an install <package>[http] hint at import when the extra is absent.
Package layout
- Ship each tool in its own module under your package (
your_package.tools.<name>). - Depend on
tai42-contractonly (plustai42-kitfor shared clients or helpers). - Never import the skeleton — a tool plugin is contract-facing.
- Type the package (
py.typed) and keep the type-checker clean.
Load it
The host enables a tool module by naming it undertools[].module:
manifest.yml
Shipped implementations
tai42-toolbox— the reference tool set (utility, HTTP, and embedding tools).
See also
- Tools and extensions — the tool model.
- The standard toolbox — using the shipped tool set.
- Python SDK reference — the
tai42_app.toolssurface. - Ecosystem catalog — every shipped tool.

