Wire a storage provider
Storage is dead by default — the skeleton ships no provider. Name a provider module in the manifest to turn the storage surface on:examples/storage/storage_provider_manifest.yaml
tai storage info reports the empty state and every CRUD door answers a 501.
The raw resource surface
tai storage is the raw provider-resource surface — upload, list, stat, download, and delete resources by id:
--text (stored verbatim) or --base64 (decoded to bytes); an existing id is overwritten. A resource id must be a relative path with no .. segment. The full subcommand set:
examples/storage/storage_help.sh
Upload and list templates
Upload a local file as a template under a key, then list what is stored.Render a template
Render a stored template byid, or inline content, as one --text JSON object carrying the source plus any render kwargs (read it from a file or stdin with --text-file to keep a secret off the command line).
fanout report, so a worker it could not reach is named rather than left stale.
You only need it for an out-of-band edit made directly on the provider side:
a template write or delete through the platform’s own surface already evicts every
worker automatically.
Load content in and out
The resource manager loads content by storage id or URL and returns it as text or media. To load a stored resource or a URL from within a tool run, enable the file-loader built-in tool, which returns a file’s content as text or media:manifest.yml
upload_template, get_resource_by_id, and list_resources — are operations. Each is always a route and a CLI command, and projects as an MCP tool when api_tools allows it, so a tool run or an MCP client reaches the same surface the CLI does:
get_resource_by_id takes a resource_id and optional render kwargs; with no kwargs it returns the loaded content as-is, and with kwargs (any object, including {}) it renders text as a Jinja template, refusing media with a 400. list_resources answers {"resources": [...]} — the sorted resource ids from the active provider — and upload_template takes a path and returns {"path", "uploaded": true}.
The storage provider is a plugin, so where content lives is swappable. The text and media surfaces are the same regardless of backend — a text-only backend satisfies the binary surface through built-in bridging.
See also
- Storage and resources — the resource manager and the load-by-id / URL / file paths.
- Config and secrets — selecting the storage provider.
- CLI reference — the full
tai templatessurface.

